From 893ad50b9cce75842a6593411003efaec63aacbd Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Wed, 19 Oct 2016 22:43:05 +1100 Subject: [PATCH 001/247] Updated schema.rb --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 5ce855fe08f..21fd8494ccc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -832,7 +832,7 @@ ActiveRecord::Schema.define(version: 20161017095000) do t.integer "builds_access_level" t.datetime "created_at" t.datetime "updated_at" - t.integer "repository_access_level", default: 20, null: false + t.integer "repository_access_level", default: 20, null: false end add_index "project_features", ["project_id"], name: "index_project_features_on_project_id", using: :btree From ccdaa8abc8ef6033148b6a0151d5d13e4df8a9d4 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Thu, 20 Oct 2016 15:44:10 +1100 Subject: [PATCH 002/247] Add hover to trash icon in notes --- app/views/projects/notes/_note.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 73fe6a715fa..ab719e38904 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -57,7 +57,7 @@ = link_to '#', title: 'Edit comment', class: 'note-action-button js-note-edit' do = icon('pencil', class: 'link-highlight') = link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button hidden-xs js-note-delete danger' do - = icon('trash-o') + = icon('trash-o', class: 'danger-highlight') .note-body{class: note_editable ? 'js-task-list-container' : ''} .note-text.md = preserve do From 5b2200777231367cb402898af4f31cef2e63b1a1 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Fri, 14 Oct 2016 10:57:10 -0500 Subject: [PATCH 003/247] Smaller min-width for MR pipeline table --- app/assets/stylesheets/pages/pipelines.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 247339648fa..dfaf1ab732d 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -643,6 +643,10 @@ &.pipelines { + .ci-table { + min-width: 900px; + } + .content-list.pipelines { overflow: auto; } From 16fffa9061f72971f37ef13ed0656712e20084f4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 18 Oct 2016 17:03:36 +0100 Subject: [PATCH 004/247] Fixed height of issue board blank state --- app/assets/stylesheets/pages/boards.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index 6e81c12aa55..d8fabbdcebe 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -1,4 +1,3 @@ -lex [v-cloak] { display: none; } @@ -132,7 +131,7 @@ lex } .board-blank-state { - height: 100%; + height: calc(100% - 49px); padding: $gl-padding; background-color: #fff; } From f488b9f765346d9f7e918c31cb5bd07717b5989a Mon Sep 17 00:00:00 2001 From: Callum Dryden Date: Thu, 6 Oct 2016 15:19:27 +0000 Subject: [PATCH 005/247] Differentiate the expire from leave event At the moment we cannot see weather a user left a project due to their membership expiring of if they themselves opted to leave the project. This adds a new event type that allows us to make this differentiation. Note that is not really feasable to go back and reliably fix up the previous events. As a result the events for previous expire removals will remain the same however events of this nature going forward will be correctly represented. --- CHANGELOG.md | 1 + app/models/concerns/expirable.rb | 6 ++- app/models/event.rb | 9 +++- app/models/members/project_member.rb | 6 ++- app/services/event_create_service.rb | 4 ++ features/dashboard/dashboard.feature | 13 ------ features/steps/dashboard/dashboard.rb | 27 ------------ lib/event_filter.rb | 11 ++++- .../project_member_activity_index_spec.rb | 41 +++++++++++++++++++ spec/models/concerns/expirable_spec.rb | 31 ++++++++++++++ spec/models/event_spec.rb | 27 ++++++++++++ spec/models/members/project_member_spec.rb | 11 +++++ spec/services/event_create_service_spec.rb | 19 +++++++++ 13 files changed, 161 insertions(+), 45 deletions(-) create mode 100644 spec/features/dashboard/project_member_activity_index_spec.rb create mode 100644 spec/models/concerns/expirable_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b018fc0d57..8cb848c3957 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) + - Adds user project membership expired event to clarify why user was removed (Callum Dryden) ## 8.13.0 (2016-10-22) diff --git a/app/models/concerns/expirable.rb b/app/models/concerns/expirable.rb index be93435453b..b66ba08dc59 100644 --- a/app/models/concerns/expirable.rb +++ b/app/models/concerns/expirable.rb @@ -5,11 +5,15 @@ module Expirable scope :expired, -> { where('expires_at <= ?', Time.current) } end + def expired? + expires? && expires_at <= Time.current + end + def expires? expires_at.present? end def expires_soon? - expires_at < 7.days.from_now + expires? && expires_at < 7.days.from_now end end diff --git a/app/models/event.rb b/app/models/event.rb index 0764cb8cabd..3993b35f96d 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -12,6 +12,7 @@ class Event < ActiveRecord::Base JOINED = 8 # User joined project LEFT = 9 # User left project DESTROYED = 10 + EXPIRED = 11 # User left project due to expiry RESET_PROJECT_ACTIVITY_INTERVAL = 1.hour @@ -115,6 +116,10 @@ class Event < ActiveRecord::Base action == LEFT end + def expired? + action == EXPIRED + end + def destroyed? action == DESTROYED end @@ -124,7 +129,7 @@ class Event < ActiveRecord::Base end def membership_changed? - joined? || left? + joined? || left? || expired? end def created_project? @@ -184,6 +189,8 @@ class Event < ActiveRecord::Base 'joined' elsif left? 'left' + elsif expired? + 'removed due to membership expiration from' elsif destroyed? 'destroyed' elsif commented? diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index 125f26369d7..e4880973117 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -121,7 +121,11 @@ class ProjectMember < Member end def post_destroy_hook - event_service.leave_project(self.project, self.user) + if expired? + event_service.expired_leave_project(self.project, self.user) + else + event_service.leave_project(self.project, self.user) + end super end diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb index 07fc77001a5..e24cc66e0fe 100644 --- a/app/services/event_create_service.rb +++ b/app/services/event_create_service.rb @@ -62,6 +62,10 @@ class EventCreateService create_event(project, current_user, Event::LEFT) end + def expired_leave_project(project, current_user) + create_event(project, current_user, Event::EXPIRED) + end + def create_project(project, current_user) create_event(project, current_user, Event::CREATED) end diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature index 1f4c9020731..b1d5e4a7acb 100644 --- a/features/dashboard/dashboard.feature +++ b/features/dashboard/dashboard.feature @@ -31,19 +31,6 @@ Feature: Dashboard And I click "Create Merge Request" link Then I see prefilled new Merge Request page - @javascript - Scenario: I should see User joined Project event - Given user with name "John Doe" joined project "Shop" - When I visit dashboard activity page - Then I should see "John Doe joined project Shop" event - - @javascript - Scenario: I should see User left Project event - Given user with name "John Doe" joined project "Shop" - And user with name "John Doe" left project "Shop" - When I visit dashboard activity page - Then I should see "John Doe left project Shop" event - @javascript Scenario: Sorting Issues Given I visit dashboard issues page diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index a7d61bc28e0..b2bec369e0f 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -33,33 +33,6 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps expect(find("input#merge_request_target_branch").value).to eq "master" end - step 'user with name "John Doe" joined project "Shop"' do - user = create(:user, { name: "John Doe" }) - project.team << [user, :master] - Event.create( - project: project, - author_id: user.id, - action: Event::JOINED - ) - end - - step 'I should see "John Doe joined project Shop" event' do - expect(page).to have_content "John Doe joined project #{project.name_with_namespace}" - end - - step 'user with name "John Doe" left project "Shop"' do - user = User.find_by(name: "John Doe") - Event.create( - project: project, - author_id: user.id, - action: Event::LEFT - ) - end - - step 'I should see "John Doe left project Shop" event' do - expect(page).to have_content "John Doe left project #{project.name_with_namespace}" - end - step 'I have group with projects' do @group = create(:group) @project = create(:project, namespace: @group) diff --git a/lib/event_filter.rb b/lib/event_filter.rb index 96e70e37e8f..21f6a9a762b 100644 --- a/lib/event_filter.rb +++ b/lib/event_filter.rb @@ -45,9 +45,16 @@ class EventFilter when EventFilter.comments actions = [Event::COMMENTED] when EventFilter.team - actions = [Event::JOINED, Event::LEFT] + actions = [Event::JOINED, Event::LEFT, Event::EXPIRED] when EventFilter.all - actions = [Event::PUSHED, Event::MERGED, Event::COMMENTED, Event::JOINED, Event::LEFT] + actions = [ + Event::PUSHED, + Event::MERGED, + Event::COMMENTED, + Event::JOINED, + Event::LEFT, + Event::EXPIRED + ] end events.where(action: actions) diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb new file mode 100644 index 00000000000..ba77093a6d4 --- /dev/null +++ b/spec/features/dashboard/project_member_activity_index_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +feature 'Project member activity', feature: true, js: true do + include WaitForAjax + + let(:user) { create(:user) } + let(:project) { create(:empty_project, :public, name: 'x', namespace: user.namespace) } + + before do + project.team << [user, :master] + end + + def visit_activities_and_wait_with_event(event_type) + Event.create(project: project, author_id: user.id, action: event_type) + visit activity_namespace_project_path(project.namespace.path, project.path) + wait_for_ajax + end + + subject { page.find(".event-title").text } + + context 'when a user joins the project' do + before { visit_activities_and_wait_with_event(Event::JOINED) } + + it { is_expected.to eq("#{user.name} joined project") } + end + + context 'when a user leaves the project' do + before { visit_activities_and_wait_with_event(Event::LEFT) } + + it { is_expected.to eq("#{user.name} left project") } + end + + context 'when a users membership expires for the project' do + before { visit_activities_and_wait_with_event(Event::EXPIRED) } + + it "presents the correct message" do + message = "#{user.name} removed due to membership expiration from project" + is_expected.to eq(message) + end + end +end diff --git a/spec/models/concerns/expirable_spec.rb b/spec/models/concerns/expirable_spec.rb new file mode 100644 index 00000000000..f7b436f32e6 --- /dev/null +++ b/spec/models/concerns/expirable_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Expirable do + describe 'ProjectMember' do + let(:no_expire) { create(:project_member) } + let(:expire_later) { create(:project_member, expires_at: Time.current + 6.days) } + let(:expired) { create(:project_member, expires_at: Time.current - 6.days) } + + describe '.expired' do + it { expect(ProjectMember.expired).to match_array([expired]) } + end + + describe '#expired?' do + it { expect(no_expire.expired?).to eq(false) } + it { expect(expire_later.expired?).to eq(false) } + it { expect(expired.expired?).to eq(true) } + end + + describe '#expires?' do + it { expect(no_expire.expires?).to eq(false) } + it { expect(expire_later.expires?).to eq(true) } + it { expect(expired.expires?).to eq(true) } + end + + describe '#expires_soon?' do + it { expect(no_expire.expires_soon?).to eq(false) } + it { expect(expire_later.expires_soon?).to eq(true) } + it { expect(expired.expires_soon?).to eq(true) } + end + end +end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 733b79079ed..aca49be2942 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -40,6 +40,33 @@ describe Event, models: true do end end + describe '#membership_changed?' do + context "created" do + subject { build(:event, action: Event::CREATED).membership_changed? } + it { is_expected.to be_falsey } + end + + context "updated" do + subject { build(:event, action: Event::UPDATED).membership_changed? } + it { is_expected.to be_falsey } + end + + context "expired" do + subject { build(:event, action: Event::EXPIRED).membership_changed? } + it { is_expected.to be_truthy } + end + + context "left" do + subject { build(:event, action: Event::LEFT).membership_changed? } + it { is_expected.to be_truthy } + end + + context "joined" do + subject { build(:event, action: Event::JOINED).membership_changed? } + it { is_expected.to be_truthy } + end + end + describe '#note?' do subject { Event.new(project: target.project, target: target) } diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index d85a1c1e3b2..b2fe96e2e02 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -54,6 +54,17 @@ describe ProjectMember, models: true do master_todos end + it "creates an expired event when left due to expiry" do + expired = create(:project_member, project: project, expires_at: Time.now - 6.days) + expired.destroy + expect(Event.first.action).to eq(Event::EXPIRED) + end + + it "creates a left event when left due to leave" do + master.destroy + expect(Event.first.action).to eq(Event::LEFT) + end + it "destroys itself and delete associated todos" do expect(owner.user.todos.size).to eq(2) expect(master.user.todos.size).to eq(3) diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb index 16a9956fe7f..b7dc99ed887 100644 --- a/spec/services/event_create_service_spec.rb +++ b/spec/services/event_create_service_spec.rb @@ -110,4 +110,23 @@ describe EventCreateService, services: true do end end end + + describe 'Project' do + let(:user) { create :user } + let(:project) { create(:empty_project) } + + describe '#join_project' do + subject { service.join_project(project, user) } + + it { is_expected.to be_truthy } + it { expect { subject }.to change { Event.count }.from(0).to(1) } + end + + describe '#expired_leave_project' do + subject { service.expired_leave_project(project, user) } + + it { is_expected.to be_truthy } + it { expect { subject }.to change { Event.count }.from(0).to(1) } + end + end end From 7077162af28b589c00bed5603cc4f18653cc5678 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Wed, 19 Oct 2016 21:58:12 +0200 Subject: [PATCH 006/247] Simpler arguments passed to named_route on toggle_award_url helper method --- CHANGELOG.md | 1 + app/helpers/award_emoji_helper.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cb848c3957..dfde2cc81e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - Adds user project membership expired event to clarify why user was removed (Callum Dryden) + - Simpler arguments passed to named_route on toggle_award_url helper method ## 8.13.0 (2016-10-22) diff --git a/app/helpers/award_emoji_helper.rb b/app/helpers/award_emoji_helper.rb index 592ffe7b89f..167b09e678f 100644 --- a/app/helpers/award_emoji_helper.rb +++ b/app/helpers/award_emoji_helper.rb @@ -3,8 +3,8 @@ module AwardEmojiHelper return url_for([:toggle_award_emoji, awardable]) unless @project if awardable.is_a?(Note) - # We render a list of notes very frequently and calling the specific method is a lot faster than the generic one (6.5x) - toggle_award_emoji_namespace_project_note_url(namespace_id: @project.namespace, project_id: @project, id: awardable.id) + # We render a list of notes very frequently and calling the specific method is a lot faster than the generic one (4.5x) + toggle_award_emoji_namespace_project_note_url(@project.namespace, @project, awardable.id) else url_for([:toggle_award_emoji, @project.namespace.becomes(Namespace), @project, awardable]) end From 6278ee5ab0c4c48d3c8a12ade85c263fefb935d2 Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Thu, 20 Oct 2016 08:57:23 +0900 Subject: [PATCH 007/247] Fix a broken table in Project API doc --- CHANGELOG.md | 1 + doc/api/projects.md | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfde2cc81e5..399a7f65267 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -135,6 +135,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Delete dynamic environments - Fix buggy iOS tooltip layering behavior. - Make guests unable to view MRs on private projects + - Fix broken Project API docs (Takuya Noguchi) ## 8.12.7 diff --git a/doc/api/projects.md b/doc/api/projects.md index b7791b4748a..77d6bd6b5c2 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -1333,8 +1333,8 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `query` (required) - A string contained in the project name -| `per_page` (optional) - number of projects to return per page -| `page` (optional) - the page to retrieve -| `order_by` (optional) - Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields +| `query` | string | yes | A string contained in the project name | +| `per_page` | integer | no | number of projects to return per page | +| `page` | integer | no | the page to retrieve | +| `order_by` | string | no | Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields | | `sort` | string | no | Return requests sorted in `asc` or `desc` order | From 6fd561d282098e71a523cf1b73396b440ef13e63 Mon Sep 17 00:00:00 2001 From: Takuya Noguchi Date: Thu, 20 Oct 2016 08:58:35 +0900 Subject: [PATCH 008/247] Remove pagination description from individual doc --- doc/api/projects.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/api/projects.md b/doc/api/projects.md index 77d6bd6b5c2..b69db90e70d 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -1334,7 +1334,5 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `query` | string | yes | A string contained in the project name | -| `per_page` | integer | no | number of projects to return per page | -| `page` | integer | no | the page to retrieve | | `order_by` | string | no | Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields | | `sort` | string | no | Return requests sorted in `asc` or `desc` order | From 7a184617199fa01c040857ed3a5d2a071944760a Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Wed, 19 Oct 2016 19:43:04 +0300 Subject: [PATCH 009/247] Refactoring find_commits functionality --- app/controllers/projects/commits_controller.rb | 2 +- app/models/repository.rb | 9 ++++++--- lib/gitlab/project_search_results.rb | 6 +----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index a52c614b259..c2e7bf1ffec 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -13,7 +13,7 @@ class Projects::CommitsController < Projects::ApplicationController @commits = if search.present? - @repository.find_commits_by_message(search, @ref, @path, @limit, @offset).compact + @repository.find_commits_by_message(search, @ref, @path, @limit, @offset) else @repository.commits(@ref, path: @path, limit: @limit, offset: @offset) end diff --git a/app/models/repository.rb b/app/models/repository.rb index 72e473871fa..1b7f20a2134 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -109,6 +109,10 @@ class Repository end def find_commits_by_message(query, ref = nil, path = nil, limit = 1000, offset = 0) + unless exists? && has_visible_content? && query.present? + return [] + end + ref ||= root_ref args = %W( @@ -117,9 +121,8 @@ class Repository ) args = args.concat(%W(-- #{path})) if path.present? - git_log_results = Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:chomp) - commits = git_log_results.map { |c| commit(c) } - commits + git_log_results = Gitlab::Popen.popen(args, path_to_repo).first.lines + git_log_results.map { |c| commit(c.chomp) }.compact end def find_branch(name, fresh_repo: true) diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb index 5b9cfaeb2f8..24733435a5a 100644 --- a/lib/gitlab/project_search_results.rb +++ b/lib/gitlab/project_search_results.rb @@ -73,11 +73,7 @@ module Gitlab end def commits - if project.empty_repo? || query.blank? - [] - else - project.repository.find_commits_by_message(query).compact - end + project.repository.find_commits_by_message(query) end def project_ids_relation From 17ae807ae3e03fcc67f557c4ad7d5c6e0502065e Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Fri, 14 Oct 2016 19:38:41 -0300 Subject: [PATCH 010/247] Create project feature when project is created --- CHANGELOG.md | 1 + app/models/project.rb | 7 +---- ...5_generate_project_feature_for_projects.rb | 28 +++++++++++++++++++ db/schema.rb | 2 +- spec/models/project_spec.rb | 14 ++++++++-- 5 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20161019213545_generate_project_feature_for_projects.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 399a7f65267..670404e4fce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun) - Cancelled pipelines could be retried. !6927 - Updating verbiage on git basics to be more intuitive + - Fix project_feature record not generated on project creation - Clarify documentation for Runners API (Gennady Trafimenkov) - The instrumentation for Banzai::Renderer has been restored - Change user & group landing page routing from /u/:username to /:username diff --git a/app/models/project.rb b/app/models/project.rb index 653c38322c5..6685baab699 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -32,8 +32,8 @@ class Project < ActiveRecord::Base default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled } after_create :ensure_dir_exist + after_create :create_project_feature, unless: :project_feature after_save :ensure_dir_exist, if: :namespace_id_changed? - after_initialize :setup_project_feature # set last_activity_at to the same as created_at after_create :set_last_activity_at @@ -1310,11 +1310,6 @@ class Project < ActiveRecord::Base "projects/#{id}/pushes_since_gc" end - # Prevents the creation of project_feature record for every project - def setup_project_feature - build_project_feature unless project_feature - end - def default_branch_protected? current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_FULL || current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_DEV_CAN_MERGE diff --git a/db/migrate/20161019213545_generate_project_feature_for_projects.rb b/db/migrate/20161019213545_generate_project_feature_for_projects.rb new file mode 100644 index 00000000000..4554e14b0df --- /dev/null +++ b/db/migrate/20161019213545_generate_project_feature_for_projects.rb @@ -0,0 +1,28 @@ +class GenerateProjectFeatureForProjects < ActiveRecord::Migration + DOWNTIME = true + + DOWNTIME_REASON = <<-HEREDOC + Application was eager loading project_feature for all projects generating an extra query + everytime a project was fetched. We removed that behavior to avoid the extra query, this migration + makes sure all projects have a project_feature record associated. + HEREDOC + + def up + # Generate enabled values for each project feature 20, 20, 20, 20, 20 + # All features are enabled by default + enabled_values = [ProjectFeature::ENABLED] * 5 + + execute <<-EOF.strip_heredoc + INSERT INTO project_features + (project_id, merge_requests_access_level, builds_access_level, + issues_access_level, snippets_access_level, wiki_access_level) + (SELECT projects.id, #{enabled_values.join(',')} FROM projects LEFT OUTER JOIN project_features + ON project_features.project_id = projects.id + WHERE project_features.id IS NULL) + EOF + end + + def down + "Not needed" + end +end diff --git a/db/schema.rb b/db/schema.rb index f777ed39378..f5c01511195 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161018024550) do +ActiveRecord::Schema.define(version: 20161019213545) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index e6d98e25d0b..f4dda1ee558 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -67,6 +67,14 @@ describe Project, models: true do it { is_expected.to have_many(:notification_settings).dependent(:destroy) } it { is_expected.to have_many(:forks).through(:forked_project_links) } + context 'after create' do + it "creates project feature" do + project = FactoryGirl.build(:project) + + expect { project.save }.to change{ project.project_feature.present? }.from(false).to(true) + end + end + describe '#members & #requesters' do let(:project) { create(:project, :public) } let(:requester) { create(:user) } @@ -531,9 +539,9 @@ describe Project, models: true do end describe '#has_wiki?' do - let(:no_wiki_project) { build(:project, wiki_enabled: false, has_external_wiki: false) } - let(:wiki_enabled_project) { build(:project) } - let(:external_wiki_project) { build(:project, has_external_wiki: true) } + let(:no_wiki_project) { create(:project, wiki_access_level: ProjectFeature::DISABLED, has_external_wiki: false) } + let(:wiki_enabled_project) { create(:project) } + let(:external_wiki_project) { create(:project, has_external_wiki: true) } it 'returns true if project is wiki enabled or has external wiki' do expect(wiki_enabled_project).to have_wiki From 89408aed1f32d760a879c9e26563b956f498793d Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 20 Oct 2016 12:10:27 +0200 Subject: [PATCH 011/247] Make label API spec independent of order --- spec/requests/api/labels_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index 1da9988978b..867bc615b97 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -22,8 +22,7 @@ describe API::API, api: true do expect(response).to have_http_status(200) expect(json_response).to be_an Array expect(json_response.size).to eq(2) - expect(json_response.first['name']).to eq(group_label.name) - expect(json_response.second['name']).to eq(label1.name) + expect(json_response.map { |l| l['name'] }).to match_array([group_label.name, label1.name]) end end From ae0a9336f106b14a7abc39e5a32fe8491dd9b544 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 20 Oct 2016 10:27:30 +0100 Subject: [PATCH 012/247] Removed code from project members controller This code was meant to be added to another branch as an expirement, but instead was commited to wrong branch --- .../projects/project_members_controller.rb | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 37a86ed0523..2a07d154853 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -32,21 +32,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController current_user: current_user ) - if params[:group_ids].present? - group_ids = params[:group_ids].split(',') - groups = Group.where(id: group_ids) - - groups.each do |group| - next unless can?(current_user, :read_group, group) - - project.project_group_links.create( - group: group, - group_access: params[:access_level], - expires_at: params[:expires_at] - ) - end - end - redirect_to namespace_project_project_members_path(@project.namespace, @project) end From 583b79a46875b14405061f3036cf041c44241c62 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 20 Oct 2016 12:59:39 +0200 Subject: [PATCH 013/247] Restrict ProjectCacheWorker jobs to one per 15 min This ensures ProjectCacheWorker jobs for a given project are performed at most once per 15 minutes. This should reduce disk load a bit in cases where there are multiple pushes happening (which should schedule multiple ProjectCacheWorker jobs). --- CHANGELOG.md | 3 +- app/workers/project_cache_worker.rb | 27 ++++++++++++++++ spec/workers/project_cache_worker_spec.rb | 38 +++++++++++++++++------ 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 670404e4fce..98cffab8c03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - Adds user project membership expired event to clarify why user was removed (Callum Dryden) - - Simpler arguments passed to named_route on toggle_award_url helper method + - Simpler arguments passed to named_route on toggle_award_url helper method ## 8.13.0 (2016-10-22) @@ -36,6 +36,7 @@ Please view this file on the master branch, on stable branches it's out of date. - AbstractReferenceFilter caches project_refs on RequestStore when active - Replaced the check sign to arrow in the show build view. !6501 - Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar) + - ProjectCacheWorker updates caches at most once per 15 minutes per project - Fix Error 500 when viewing old merge requests with bad diff data - Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar) - Speed-up group milestones show page diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb index ccefd0f71a0..0d524e88dc3 100644 --- a/app/workers/project_cache_worker.rb +++ b/app/workers/project_cache_worker.rb @@ -1,9 +1,30 @@ +# Worker for updating any project specific caches. +# +# This worker runs at most once every 15 minutes per project. This is to ensure +# that multiple instances of jobs for this worker don't hammer the underlying +# storage engine as much. class ProjectCacheWorker include Sidekiq::Worker sidekiq_options queue: :default + LEASE_TIMEOUT = 15.minutes.to_i + def perform(project_id) + if try_obtain_lease_for(project_id) + Rails.logger. + info("Obtained ProjectCacheWorker lease for project #{project_id}") + else + Rails.logger. + info("Could not obtain ProjectCacheWorker lease for project #{project_id}") + + return + end + + update_caches(project_id) + end + + def update_caches(project_id) project = Project.find(project_id) return unless project.repository.exists? @@ -15,4 +36,10 @@ class ProjectCacheWorker project.repository.build_cache end end + + def try_obtain_lease_for(project_id) + Gitlab::ExclusiveLease. + new("project_cache_worker:#{project_id}", timeout: LEASE_TIMEOUT). + try_obtain + end end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index 5785a6a06ff..f5b60b90d11 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -6,21 +6,39 @@ describe ProjectCacheWorker do subject { described_class.new } describe '#perform' do - it 'updates project cache data' do - expect_any_instance_of(Repository).to receive(:size) - expect_any_instance_of(Repository).to receive(:commit_count) + context 'when an exclusive lease can be obtained' do + before do + allow(subject).to receive(:try_obtain_lease_for).with(project.id). + and_return(true) + end - expect_any_instance_of(Project).to receive(:update_repository_size) - expect_any_instance_of(Project).to receive(:update_commit_count) + it 'updates project cache data' do + expect_any_instance_of(Repository).to receive(:size) + expect_any_instance_of(Repository).to receive(:commit_count) - subject.perform(project.id) + expect_any_instance_of(Project).to receive(:update_repository_size) + expect_any_instance_of(Project).to receive(:update_commit_count) + + subject.perform(project.id) + end + + it 'handles missing repository data' do + expect_any_instance_of(Repository).to receive(:exists?).and_return(false) + expect_any_instance_of(Repository).not_to receive(:size) + + subject.perform(project.id) + end end - it 'handles missing repository data' do - expect_any_instance_of(Repository).to receive(:exists?).and_return(false) - expect_any_instance_of(Repository).not_to receive(:size) + context 'when an exclusive lease can not be obtained' do + it 'does nothing' do + allow(subject).to receive(:try_obtain_lease_for).with(project.id). + and_return(false) - subject.perform(project.id) + expect(subject).not_to receive(:update_caches) + + subject.perform(project.id) + end end end end From bd3548c19e00cfadbc5d2c122b968090a160afbc Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 13 Oct 2016 13:58:31 -0500 Subject: [PATCH 014/247] Change input order on Sign In form for better tabbing. This *unreverts* 8751491b, which was mistakenly reverted in !6328. It also changes the implementation of the original commit to work with the new login styling and markup. cc: @ClemMakesApps --- app/assets/stylesheets/pages/login.scss | 17 +++++++++++++++++ app/views/devise/sessions/_new_base.html.haml | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index e6d9be5185d..bdb13bee178 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -53,6 +53,7 @@ margin: 0 0 10px; } + .login-footer { margin-top: 10px; @@ -246,3 +247,19 @@ padding: 65px; // height of footer + bottom padding of email confirmation link } } + +// For sign in pane only, to improve tab order, the following removes the submit button from +// normal document flow and pins it to the bottom of the form. For context, see !6867 & !6928 + +.login-box { + .new_user { + position: relative; + padding-bottom: 35px; + } + + .move-submit-down { + position: absolute; + width: 100%; + bottom: 0; + } +} diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index a96b579c593..525e7d99d71 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -5,6 +5,8 @@ %div.form-group = f.label :password = f.password_field :password, class: "form-control bottom", required: true, title: "This field is required." + %div.submit-container.move-submit-down + = f.submit "Sign in", class: "btn btn-save" - if devise_mapping.rememberable? .remember-me.checkbox %label{for: "user_remember_me"} @@ -12,5 +14,3 @@ %span Remember me .pull-right = link_to "Forgot your password?", new_password_path(resource_name) - %div.submit-container - = f.submit "Sign in", class: "btn btn-save" From a2f64619af8da5c5b09ead7554e5613368f80dae Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Sun, 18 Sep 2016 17:20:40 +0100 Subject: [PATCH 015/247] Added tooltip with jobs full name to build items in graph Added status to build tooltip and removed status icon tooltip Added Pipelines class to force tooltips ontop of the dropdown, we cannot do this with data attributes because dropdown toggle is already set Corrected dispatcher invocation --- app/assets/javascripts/pipelines.js.es6 | 11 +++++++++++ app/helpers/ci_status_helper.rb | 4 ++-- app/views/projects/commit/_pipeline_stage.html.haml | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/pipelines.js.es6 b/app/assets/javascripts/pipelines.js.es6 index a7624de6089..dd320c52e44 100644 --- a/app/assets/javascripts/pipelines.js.es6 +++ b/app/assets/javascripts/pipelines.js.es6 @@ -4,6 +4,17 @@ constructor() { $(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph); this.addMarginToBuildColumns(); + this.initGroupedPipelineTooltips(); + } + + initGroupedPipelineTooltips() { + $('.dropdown-menu-toggle', $('.grouped-pipeline-dropdown').parent()).each(function() { + const $this = $(this); + $this.tooltip({ + title: $this.data('tooltip-title'), + placement: 'bottom' + }); + }); } toggleGraph() { diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index b7f48630bd4..0e727f3dcf0 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -71,10 +71,10 @@ module CiStatusHelper Ci::Runner.shared.blank? end - def render_status_with_link(type, status, path = nil, tooltip_placement: 'auto left', cssclass: '', container: 'body') + def render_status_with_link(type, status, path = nil, tooltip_placement: 'auto left', cssclass: '', container: 'body', show_tooltip: true) klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}" title = "#{type.titleize}: #{ci_label_for_status(status)}" - data = { toggle: 'tooltip', placement: tooltip_placement, container: container } + data = { toggle: 'tooltip', placement: tooltip_placement, container: container } if show_tooltip if path link_to ci_icon_for_status(status), path, diff --git a/app/views/projects/commit/_pipeline_stage.html.haml b/app/views/projects/commit/_pipeline_stage.html.haml index 289aa5178b1..993fc89d23d 100644 --- a/app/views/projects/commit/_pipeline_stage.html.haml +++ b/app/views/projects/commit/_pipeline_stage.html.haml @@ -5,7 +5,7 @@ - is_playable = status.playable? && can?(current_user, :update_build, @project) %li.build{ class: ("playable" if is_playable) } .curve - .build-content + .build-content{ { data: { toggle: 'tooltip', title: "#{group_name} - #{status.status}", placement: 'bottom' } } } = render "projects/#{status.to_partial_path}_pipeline", subject: status - else %li.build From 33f3c3792abe2cbf1b68c0ce3414edb8e199be1e Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Fri, 7 Oct 2016 19:30:34 +0100 Subject: [PATCH 016/247] Added dyanmic position adjustment Added tooltips for dropdown items Reverted pretty much everything in favour of a DOM approach Simplified JS --- app/assets/javascripts/pipelines.js.es6 | 11 ----------- app/assets/stylesheets/pages/pipelines.scss | 14 ++++++++++---- app/helpers/ci_status_helper.rb | 4 ++-- .../projects/ci/builds/_build_pipeline.html.haml | 4 ++-- .../projects/commit/_pipeline_stage.html.haml | 2 +- .../commit/_pipeline_status_group.html.haml | 2 +- .../_generic_commit_status_pipeline.html.haml | 13 +++++++------ 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/pipelines.js.es6 b/app/assets/javascripts/pipelines.js.es6 index dd320c52e44..a7624de6089 100644 --- a/app/assets/javascripts/pipelines.js.es6 +++ b/app/assets/javascripts/pipelines.js.es6 @@ -4,17 +4,6 @@ constructor() { $(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph); this.addMarginToBuildColumns(); - this.initGroupedPipelineTooltips(); - } - - initGroupedPipelineTooltips() { - $('.dropdown-menu-toggle', $('.grouped-pipeline-dropdown').parent()).each(function() { - const $this = $(this); - $this.tooltip({ - title: $this.data('tooltip-title'), - placement: 'bottom' - }); - }); } toggleGraph() { diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index dfaf1ab732d..5b8dc7f8c40 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -369,10 +369,6 @@ &:hover { background-color: $gray-lighter; - - .dropdown-menu-toggle { - background-color: transparent; - } } &.playable { @@ -402,6 +398,15 @@ } } + .tooltip { + white-space: nowrap; + + .tooltip-inner { + overflow: hidden; + text-overflow: ellipsis; + } + } + .ci-status-text { width: 135px; white-space: nowrap; @@ -419,6 +424,7 @@ } .dropdown-menu-toggle { + background-color: transparent; border: none; width: auto; padding: 0; diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 0e727f3dcf0..b7f48630bd4 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -71,10 +71,10 @@ module CiStatusHelper Ci::Runner.shared.blank? end - def render_status_with_link(type, status, path = nil, tooltip_placement: 'auto left', cssclass: '', container: 'body', show_tooltip: true) + def render_status_with_link(type, status, path = nil, tooltip_placement: 'auto left', cssclass: '', container: 'body') klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}" title = "#{type.titleize}: #{ci_label_for_status(status)}" - data = { toggle: 'tooltip', placement: tooltip_placement, container: container } if show_tooltip + data = { toggle: 'tooltip', placement: tooltip_placement, container: container } if path link_to ci_icon_for_status(status), path, diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml index 017d3ff6af2..55965172d3f 100644 --- a/app/views/projects/ci/builds/_build_pipeline.html.haml +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -1,10 +1,10 @@ - is_playable = subject.playable? && can?(current_user, :update_build, @project) - if is_playable - = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do + = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, data: { toggle: 'tooltip', title: "#{subject.name} - play", container: '.pipeline-graph', placement: 'bottom' } do = render_status_with_link('build', 'play') .ci-status-text= subject.name - elsif can?(current_user, :read_build, @project) - = link_to namespace_project_build_path(subject.project.namespace, subject.project, subject) do + = link_to namespace_project_build_path(subject.project.namespace, subject.project, subject), data: { toggle: 'tooltip', title: "#{subject.name} - #{subject.status}", container: '.pipeline-graph', placement: 'bottom' } do %span.ci-status-icon = render_status_with_link('build', subject.status) .ci-status-text= subject.name diff --git a/app/views/projects/commit/_pipeline_stage.html.haml b/app/views/projects/commit/_pipeline_stage.html.haml index 993fc89d23d..289aa5178b1 100644 --- a/app/views/projects/commit/_pipeline_stage.html.haml +++ b/app/views/projects/commit/_pipeline_stage.html.haml @@ -5,7 +5,7 @@ - is_playable = status.playable? && can?(current_user, :update_build, @project) %li.build{ class: ("playable" if is_playable) } .curve - .build-content{ { data: { toggle: 'tooltip', title: "#{group_name} - #{status.status}", placement: 'bottom' } } } + .build-content = render "projects/#{status.to_partial_path}_pipeline", subject: status - else %li.build diff --git a/app/views/projects/commit/_pipeline_status_group.html.haml b/app/views/projects/commit/_pipeline_status_group.html.haml index 5d0d5ba0262..f2d71fa6989 100644 --- a/app/views/projects/commit/_pipeline_status_group.html.haml +++ b/app/views/projects/commit/_pipeline_status_group.html.haml @@ -1,5 +1,5 @@ - group_status = CommitStatus.where(id: subject).status -%button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } } +%button.dropdown-menu-toggle.has-tooltip{ type: 'button', data: { toggle: 'dropdown', title: "#{name} - #{group_status}" } } %span.ci-status-icon = render_status_with_link('build', group_status) %span.ci-status-text diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml index 0a66d60accc..c45b73e4225 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml @@ -1,9 +1,10 @@ -- if subject.target_url - = link_to subject.target_url do +%a{ data: { toggle: 'tooltip', title: "#{subject.name} - #{subject.status}", container: '.pipeline-graph', placement: 'bottom' } } + - if subject.target_url + = link_to subject.target_url do + %span.ci-status-icon + = render_status_with_link('commit status', subject.status) + %span.ci-status-text= subject.name + - else %span.ci-status-icon = render_status_with_link('commit status', subject.status) %span.ci-status-text= subject.name -- else - %span.ci-status-icon - = render_status_with_link('commit status', subject.status) - %span.ci-status-text= subject.name From b6c859974307b71a82544cb137196b1bcd7ef7ef Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 19 Oct 2016 16:53:12 +0100 Subject: [PATCH 017/247] Revert "Add #closed_without_source_project?" This reverts commit 31c37c6c38258684fc92e0d91119c33872e39034. See #23341 --- app/models/merge_request.rb | 10 ++---- .../projects/merge_requests/_show.html.haml | 31 ++++++++---------- spec/models/merge_request_spec.rb | 32 ------------------- 3 files changed, 16 insertions(+), 57 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 0cc0b3c2a0e..d32bc9f882f 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -333,11 +333,7 @@ class MergeRequest < ActiveRecord::Base end def closed_without_fork? - closed? && forked_source_project_missing? - end - - def closed_without_source_project? - closed? && !source_project + closed? && (forked_source_project_missing? || !source_project) end def forked_source_project_missing? @@ -348,9 +344,7 @@ class MergeRequest < ActiveRecord::Base end def reopenable? - return false if closed_without_fork? || closed_without_source_project? || merged? - - closed? + source_branch_exists? && closed? end def ensure_merge_request_diff diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index cd98aaf8d75..fe90383b00f 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -26,19 +26,17 @@ %ul.dropdown-menu.dropdown-menu-align-right %li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch) %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff) - - unless @merge_request.closed_without_fork? - .normal - %span Request to merge - %span.label-branch= source_branch_with_namespace(@merge_request) - %span into - %span.label-branch - = link_to @merge_request.target_branch, namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch) - - if @merge_request.open? && @merge_request.diverged_from_target_branch? - %span (#{pluralize(@merge_request.diverged_commits_count, 'commit')} behind) + .normal + %span Request to merge + %span.label-branch= source_branch_with_namespace(@merge_request) + %span into + %span.label-branch + = link_to @merge_request.target_branch, namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch) + - if @merge_request.open? && @merge_request.diverged_from_target_branch? + %span (#{pluralize(@merge_request.diverged_commits_count, 'commit')} behind) - - unless @merge_request.closed_without_source_project? - = render "projects/merge_requests/show/how_to_merge" - = render "projects/merge_requests/widget/show.html.haml" + = render "projects/merge_requests/show/how_to_merge" + = render "projects/merge_requests/widget/show.html.haml" - if @merge_request.source_branch_exists? && @merge_request.mergeable? && @merge_request.can_be_merged_by?(current_user) .light.prepend-top-default.append-bottom-default @@ -52,11 +50,10 @@ = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'notes', toggle: 'tab' } do Discussion %span.badge= @merge_request.mr_and_commit_notes.user.count - - unless @merge_request.closed_without_source_project? - %li.commits-tab - = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do - Commits - %span.badge= @commits_count + %li.commits-tab + = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do + Commits + %span.badge= @commits_count - if @pipeline %li.pipelines-tab = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 6db5e7f7d80..ee003a9d18f 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1274,38 +1274,6 @@ describe MergeRequest, models: true do end end - describe '#closed_without_source_project?' do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:fork_project) { create(:project, forked_from_project: project, namespace: user.namespace) } - let(:destroy_service) { Projects::DestroyService.new(fork_project, user) } - - context 'when the merge request is closed' do - let(:closed_merge_request) do - create(:closed_merge_request, - source_project: fork_project, - target_project: project) - end - - it 'returns false if the source project exists' do - expect(closed_merge_request.closed_without_source_project?).to be_falsey - end - - it 'returns true if the source project does not exist' do - destroy_service.execute - closed_merge_request.reload - - expect(closed_merge_request.closed_without_source_project?).to be_truthy - end - end - - context 'when the merge request is open' do - it 'returns false' do - expect(subject.closed_without_source_project?).to be_falsey - end - end - end - describe '#reopenable?' do context 'when the merge request is closed' do it 'returns true' do From f00ee5c2ed9a0812b6337e52814756c560c879c8 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 19 Oct 2016 17:13:04 +0100 Subject: [PATCH 018/247] Fix the merge request view when source projects or branches are removed --- .../projects/merge_requests_controller.rb | 2 +- app/helpers/merge_requests_helper.rb | 10 +++++++--- app/models/merge_request.rb | 15 ++++++--------- app/views/projects/merge_requests/_show.html.haml | 13 ++++++++----- .../merge_requests/created_from_fork_spec.rb | 14 ++++++++++++++ 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 0f593d1a936..55ea31e48a0 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -554,7 +554,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController def define_pipelines_vars @pipelines = @merge_request.all_pipelines - if @pipelines.any? + if @pipelines.present? @pipeline = @pipelines.first @statuses = @pipeline.statuses.relevant end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 249cb44e9d5..a6659ea2fd1 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -86,11 +86,15 @@ module MergeRequestsHelper end def source_branch_with_namespace(merge_request) - branch = link_to(merge_request.source_branch, namespace_project_commits_path(merge_request.source_project.namespace, merge_request.source_project, merge_request.source_branch)) + namespace = merge_request.source_project_namespace + branch = merge_request.source_branch + + if merge_request.source_branch_exists? + namespace = link_to(namespace, project_path(merge_request.source_project)) + branch = link_to(branch, namespace_project_commits_path(merge_request.source_project.namespace, merge_request.source_project, merge_request.source_branch)) + end if merge_request.for_fork? - namespace = link_to(merge_request.source_project_namespace, - project_path(merge_request.source_project)) namespace + ":" + branch else branch diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index d32bc9f882f..45fa8af60e5 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -333,7 +333,7 @@ class MergeRequest < ActiveRecord::Base end def closed_without_fork? - closed? && (forked_source_project_missing? || !source_project) + closed? && forked_source_project_missing? end def forked_source_project_missing? @@ -344,7 +344,7 @@ class MergeRequest < ActiveRecord::Base end def reopenable? - source_branch_exists? && closed? + closed? && !source_project_missing? && source_branch_exists? end def ensure_merge_request_diff @@ -656,7 +656,7 @@ class MergeRequest < ActiveRecord::Base end def has_ci? - source_project.ci_service && commits.any? + source_project.try(:ci_service) && commits.any? end def branch_missing? @@ -688,12 +688,9 @@ class MergeRequest < ActiveRecord::Base @environments ||= begin - environments = source_project.environments_for( - source_branch, diff_head_commit) - environments += target_project.environments_for( - target_branch, diff_head_commit, with_tags: true) - - environments.uniq + envs = target_project.environments_for(target_branch, diff_head_commit, with_tags: true) + envs.concat(source_project.environments_for(source_branch, diff_head_commit)) if source_project + envs.uniq end end diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index fe90383b00f..0e19d224fcd 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -35,7 +35,9 @@ - if @merge_request.open? && @merge_request.diverged_from_target_branch? %span (#{pluralize(@merge_request.diverged_commits_count, 'commit')} behind) - = render "projects/merge_requests/show/how_to_merge" + - if @merge_request.source_branch_exists? + = render "projects/merge_requests/show/how_to_merge" + = render "projects/merge_requests/widget/show.html.haml" - if @merge_request.source_branch_exists? && @merge_request.mergeable? && @merge_request.can_be_merged_by?(current_user) @@ -50,10 +52,11 @@ = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'notes', toggle: 'tab' } do Discussion %span.badge= @merge_request.mr_and_commit_notes.user.count - %li.commits-tab - = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do - Commits - %span.badge= @commits_count + - if @merge_request.source_project + %li.commits-tab + = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do + Commits + %span.badge= @commits_count - if @pipeline %li.pipelines-tab = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index a506624b30d..cfc1244429f 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -25,6 +25,20 @@ feature 'Merge request created from fork' do expect(page).to have_content 'Test merge request' end + context 'source project is deleted' do + background do + MergeRequests::MergeService.new(project, user).execute(merge_request) + fork_project.destroy! + end + + scenario 'user can access merge request' do + visit_merge_request(merge_request) + + expect(page).to have_content 'Test merge request' + expect(page).to have_content "(removed):#{merge_request.source_branch}" + end + end + context 'pipeline present in source project' do include WaitForAjax From f118d2fc7394cbbd71a8c97e0c186581c045fb47 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 19 Oct 2016 17:48:30 +0100 Subject: [PATCH 019/247] Fix two CI endpoints for MRs where the source project is deleted --- app/controllers/projects/merge_requests_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 55ea31e48a0..2ee53f7ceda 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -398,7 +398,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController status ||= "preparing" else - ci_service = @merge_request.source_project.ci_service + ci_service = @merge_request.source_project.try(:ci_service) status = ci_service.commit_status(merge_request.diff_head_sha, merge_request.source_branch) if ci_service if ci_service.respond_to?(:commit_coverage) From 51fbb9bfa90f293447cf3f338bdc0a189b601d0e Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 19 Oct 2016 19:33:51 +0100 Subject: [PATCH 020/247] Rename forked_source_project_missing? to source_project_missing? --- app/models/merge_request.rb | 6 +++--- spec/models/merge_request_spec.rb | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 45fa8af60e5..c476a3bb14e 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -326,17 +326,17 @@ class MergeRequest < ActiveRecord::Base def validate_fork return true unless target_project && source_project return true if target_project == source_project - return true unless forked_source_project_missing? + return true unless source_project_missing? errors.add :validate_fork, 'Source project is not a fork of the target project' end def closed_without_fork? - closed? && forked_source_project_missing? + closed? && source_project_missing? end - def forked_source_project_missing? + def source_project_missing? return false unless for_fork? return true unless source_project diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index ee003a9d18f..6e5137602aa 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1198,7 +1198,7 @@ describe MergeRequest, models: true do end end - describe "#forked_source_project_missing?" do + describe "#source_project_missing?" do let(:project) { create(:project) } let(:fork_project) { create(:project, forked_from_project: project) } let(:user) { create(:user) } @@ -1211,13 +1211,13 @@ describe MergeRequest, models: true do target_project: project) end - it { expect(merge_request.forked_source_project_missing?).to be_falsey } + it { expect(merge_request.source_project_missing?).to be_falsey } end context "when the source project is the same as the target project" do let(:merge_request) { create(:merge_request, source_project: project) } - it { expect(merge_request.forked_source_project_missing?).to be_falsey } + it { expect(merge_request.source_project_missing?).to be_falsey } end context "when the fork does not exist" do @@ -1231,7 +1231,7 @@ describe MergeRequest, models: true do unlink_project.execute merge_request.reload - expect(merge_request.forked_source_project_missing?).to be_truthy + expect(merge_request.source_project_missing?).to be_truthy end end end From 25447b46c6adf62a0aafc0da38d456ef80e489f3 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 19 Oct 2016 18:09:33 +0100 Subject: [PATCH 021/247] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98cffab8c03..4f163f323e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ Please view this file on the master branch, on stable branches it's out of date. - ProjectCacheWorker updates caches at most once per 15 minutes per project - Fix Error 500 when viewing old merge requests with bad diff data - Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar) + - Fix viewing merged MRs when the source project has been removed !6991 - Speed-up group milestones show page - Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps) - Extract project#update_merge_requests and SystemHooks to its own worker from GitPushService From 3ab461dc64d8cadd61a67e632fde309fb887d1e8 Mon Sep 17 00:00:00 2001 From: Airat Shigapov Date: Thu, 15 Sep 2016 18:45:22 +0300 Subject: [PATCH 022/247] Render hipchat notification descriptions as HTML instead of raw markdown --- .../project_services/hipchat_service.rb | 9 +++------ .../project_services/hipchat_service_spec.rb | 20 +++++++++---------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index afebd3b6a12..98f0312d84e 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -144,8 +144,7 @@ class HipchatService < Service message = "#{user_name} #{state} #{issue_link} in #{project_link}: #{title}" if description - description = format_body(description) - message << description + message << format_body(Banzai::Filter::MarkdownFilter.renderer.render(description)) end message @@ -167,8 +166,7 @@ class HipchatService < Service "#{project_link}: #{title}" if description - description = format_body(description) - message << description + message << format_body(Banzai::Filter::MarkdownFilter.renderer.render(description)) end message @@ -219,8 +217,7 @@ class HipchatService < Service message << title if note - note = format_body(note) - message << note + message << format_body(Banzai::Filter::MarkdownFilter.renderer.render(note)) end message diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb index 26dd95bdfec..90066f01f6f 100644 --- a/spec/models/project_services/hipchat_service_spec.rb +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -117,7 +117,7 @@ describe HipchatService, models: true do end context 'issue events' do - let(:issue) { create(:issue, title: 'Awesome issue', description: 'please fix') } + let(:issue) { create(:issue, title: 'Awesome issue', description: '**please** fix') } let(:issue_service) { Issues::CreateService.new(project, user) } let(:issues_sample_data) { issue_service.hook_data(issue, 'open') } @@ -135,12 +135,12 @@ describe HipchatService, models: true do "issue ##{obj_attr["iid"]} in " \ "#{project_name}: " \ "Awesome issue" \ - "
please fix
") + "

please fix

\n
") end end context 'merge request events' do - let(:merge_request) { create(:merge_request, description: 'please fix', title: 'Awesome merge request', target_project: project, source_project: project) } + let(:merge_request) { create(:merge_request, description: '**please** fix', title: 'Awesome merge request', target_project: project, source_project: project) } let(:merge_service) { MergeRequests::CreateService.new(project, user) } let(:merge_sample_data) { merge_service.hook_data(merge_request, 'open') } @@ -159,7 +159,7 @@ describe HipchatService, models: true do "merge request !#{obj_attr["iid"]} in " \ "#{project_name}: " \ "Awesome merge request" \ - "
please fix
") + "

please fix

\n
") end end @@ -190,7 +190,7 @@ describe HipchatService, models: true do "commit #{commit_id} in " \ "#{project_name}: " \ "#{title}" \ - "
a comment on a commit
") + "

a comment on a commit

\n
") end end @@ -203,7 +203,7 @@ describe HipchatService, models: true do let(:merge_request_note) do create(:note_on_merge_request, noteable: merge_request, project: project, - note: "merge request note") + note: "merge request **note**") end it "calls Hipchat API for merge request comment events" do @@ -222,7 +222,7 @@ describe HipchatService, models: true do "merge request !#{merge_id} in " \ "#{project_name}: " \ "#{title}" \ - "
merge request note
") + "

merge request note

\n
") end end @@ -230,7 +230,7 @@ describe HipchatService, models: true do let(:issue) { create(:issue, project: project) } let(:issue_note) do create(:note_on_issue, noteable: issue, project: project, - note: "issue note") + note: "issue **note**") end it "calls Hipchat API for issue comment events" do @@ -247,7 +247,7 @@ describe HipchatService, models: true do "issue ##{issue_id} in " \ "#{project_name}: " \ "#{title}" \ - "
issue note
") + "

issue note

\n
") end end @@ -275,7 +275,7 @@ describe HipchatService, models: true do "snippet ##{snippet_id} in " \ "#{project_name}: " \ "#{title}" \ - "
snippet note
") + "

snippet note

\n
") end end end From 0090116d87585ab6e433ba7c04198271848c43c0 Mon Sep 17 00:00:00 2001 From: David Eisner Date: Tue, 4 Oct 2016 12:28:42 +0100 Subject: [PATCH 023/247] Full Banzai rendering for HipChat notifications --- app/models/project_services/hipchat_service.rb | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 98f0312d84e..f4edbbbceb2 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -121,14 +121,6 @@ class HipchatService < Service message end - def format_body(body) - if body - body = body.truncate(200, separator: ' ', omission: '...') - end - - "
#{body}
" - end - def create_issue_message(data) user_name = data[:user][:name] @@ -144,7 +136,7 @@ class HipchatService < Service message = "#{user_name} #{state} #{issue_link} in #{project_link}: #{title}" if description - message << format_body(Banzai::Filter::MarkdownFilter.renderer.render(description)) + message << Banzai.render(note, project: project) end message @@ -166,7 +158,7 @@ class HipchatService < Service "#{project_link}: #{title}" if description - message << format_body(Banzai::Filter::MarkdownFilter.renderer.render(description)) + message << Banzai.render(note, project: project) end message @@ -217,7 +209,7 @@ class HipchatService < Service message << title if note - message << format_body(Banzai::Filter::MarkdownFilter.renderer.render(note)) + message << Banzai.render(note, project: project) end message From ad28b3989dece0d3495e08cf545708caf9642cfc Mon Sep 17 00:00:00 2001 From: David Eisner Date: Tue, 4 Oct 2016 12:38:31 +0100 Subject: [PATCH 024/247] Also render commit titles in HipChat notifications --- app/models/project_services/hipchat_service.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index f4edbbbceb2..7d70452a70b 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -88,6 +88,10 @@ class HipchatService < Service end end + def render_line(text) + Banzai.render(text.lines.first.chomp, project: project, pipeline: :single_line) if text + end + def create_push_message(push) ref_type = Gitlab::Git.tag_ref?(push[:ref]) ? 'tag' : 'branch' ref = Gitlab::Git.ref_name(push[:ref]) @@ -110,7 +114,7 @@ class HipchatService < Service message << "(Compare changes)" push[:commits].take(MAX_COMMITS).each do |commit| - message << "
- #{commit[:message].lines.first} (#{commit[:id][0..5]})" + message << "
- #{render_line(commit[:message])} (#{commit[:id][0..5]})" end if push[:commits].count > MAX_COMMITS @@ -126,7 +130,7 @@ class HipchatService < Service obj_attr = data[:object_attributes] obj_attr = HashWithIndifferentAccess.new(obj_attr) - title = obj_attr[:title] + title = render_line(obj_attr[:title]) state = obj_attr[:state] issue_iid = obj_attr[:iid] issue_url = obj_attr[:url] @@ -150,7 +154,7 @@ class HipchatService < Service merge_request_id = obj_attr[:iid] state = obj_attr[:state] description = obj_attr[:description] - title = obj_attr[:title] + title = render_line(obj_attr[:title]) merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}" merge_request_link = "merge request !#{merge_request_id}" @@ -165,7 +169,7 @@ class HipchatService < Service end def format_title(title) - "" + title.lines.first.chomp + "" + "#{render_line(title)}" end def create_note_message(data) From 59b2770a035489db9995b8638792ed5c92242035 Mon Sep 17 00:00:00 2001 From: David Eisner Date: Tue, 4 Oct 2016 16:23:16 +0100 Subject: [PATCH 025/247] Absolute URLs for Banzai HTML for HipChat Using "pipeline: :email" gets "only_path: false" into the context to produce full URLs instead of /namespace/project/... --- .../project_services/hipchat_service.rb | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 7d70452a70b..9d52a1423b7 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -89,7 +89,7 @@ class HipchatService < Service end def render_line(text) - Banzai.render(text.lines.first.chomp, project: project, pipeline: :single_line) if text + markdown(text.lines.first.chomp, pipeline: :single_line) if text end def create_push_message(push) @@ -125,6 +125,20 @@ class HipchatService < Service message end + def markdown(text, context = {}) + if text + context = ({ + project: project, + pipeline: :email + }).merge(context) + + html = Banzai.render(text, context) + html = Banzai.post_process(html, context) + else + "" + end + end + def create_issue_message(data) user_name = data[:user][:name] @@ -139,9 +153,7 @@ class HipchatService < Service issue_link = "issue ##{issue_iid}" message = "#{user_name} #{state} #{issue_link} in #{project_link}: #{title}" - if description - message << Banzai.render(note, project: project) - end + message << markdown(description) message end @@ -161,9 +173,7 @@ class HipchatService < Service message = "#{user_name} #{state} #{merge_request_link} in " \ "#{project_link}: #{title}" - if description - message << Banzai.render(note, project: project) - end + message << markdown(description) message end @@ -180,11 +190,13 @@ class HipchatService < Service note = obj_attr[:note] note_url = obj_attr[:url] noteable_type = obj_attr[:noteable_type] + commit_id = nil case noteable_type when "Commit" commit_attr = HashWithIndifferentAccess.new(data[:commit]) - subject_desc = commit_attr[:id] + commit_id = commit_attr[:id] + subject_desc = commit_id subject_desc = Commit.truncate_sha(subject_desc) subject_type = "commit" title = format_title(commit_attr[:message]) @@ -212,9 +224,7 @@ class HipchatService < Service message = "#{user_name} commented on #{subject_html} in #{project_link}: " message << title - if note - message << Banzai.render(note, project: project) - end + message << markdown(note, ref: commit_id) message end From 73f13526d6ef3da1289074e2503bf2764b41b137 Mon Sep 17 00:00:00 2001 From: David Eisner Date: Tue, 4 Oct 2016 16:25:45 +0100 Subject: [PATCH 026/247] Ensure absolute URLs for single lines from Banzai for HipChat "pipeline: :single_line" leaves the protocol/host part out of the URLs and caches them that way. To avoid giving those out to HipChat, markdown is always rendered with "pipeline: :email" first. There must be a better way to do this, but I can't see how to avoid the link caching. --- app/models/project_services/hipchat_service.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 9d52a1423b7..ce4a2a96015 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -125,12 +125,16 @@ class HipchatService < Service message end - def markdown(text, context = {}) + def markdown(text, options = {}) if text - context = ({ + context = { project: project, pipeline: :email - }).merge(context) + } + + Banzai.render(text, context) + + context.merge!(options) html = Banzai.render(text, context) html = Banzai.post_process(html, context) From 551c74edf75e3fa89ea57a45b217a3a34f8c2fc1 Mon Sep 17 00:00:00 2001 From: David Eisner Date: Tue, 4 Oct 2016 16:27:40 +0100 Subject: [PATCH 027/247] Clean up Banzai HTML for HipChat The `class` and `data-*` attributes are meaningless in HipChat, and it would probably be better to limit the tags, too. For example, we could avoid block-level elements in `render_line`. --- app/models/project_services/hipchat_service.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index ce4a2a96015..8988a7b905e 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -1,4 +1,6 @@ class HipchatService < Service + include ActionView::Helpers::SanitizeHelper + MAX_COMMITS = 3 prop_accessor :token, :room, :server, :notify, :color, :api_version @@ -138,6 +140,7 @@ class HipchatService < Service html = Banzai.render(text, context) html = Banzai.post_process(html, context) + sanitize html, attributes: %w(href title alt) else "" end From f6a97e6c0bf4d0f699ded24983c6be1ca4b5d6cc Mon Sep 17 00:00:00 2001 From: David Eisner Date: Wed, 5 Oct 2016 13:38:08 +0100 Subject: [PATCH 028/247] Tests for markdown HipChat notifications --- spec/models/project_services/hipchat_service_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb index 90066f01f6f..1029b6d2459 100644 --- a/spec/models/project_services/hipchat_service_spec.rb +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -135,7 +135,7 @@ describe HipchatService, models: true do "issue ##{obj_attr["iid"]} in " \ "#{project_name}: " \ "Awesome issue" \ - "

please fix

\n
") + "

please fix

") end end @@ -159,7 +159,7 @@ describe HipchatService, models: true do "merge request !#{obj_attr["iid"]} in " \ "#{project_name}: " \ "Awesome merge request" \ - "

please fix

\n
") + "

please fix

") end end @@ -190,7 +190,7 @@ describe HipchatService, models: true do "commit #{commit_id} in " \ "#{project_name}: " \ "#{title}" \ - "

a comment on a commit

\n
") + "

a comment on a commit

") end end @@ -222,7 +222,7 @@ describe HipchatService, models: true do "merge request !#{merge_id} in " \ "#{project_name}: " \ "#{title}" \ - "

merge request note

\n
") + "

merge request note

") end end @@ -247,7 +247,7 @@ describe HipchatService, models: true do "issue ##{issue_id} in " \ "#{project_name}: " \ "#{title}" \ - "

issue note

\n
") + "

issue note

") end end @@ -275,7 +275,7 @@ describe HipchatService, models: true do "snippet ##{snippet_id} in " \ "#{project_name}: " \ "#{title}" \ - "

snippet note

\n
") + "

snippet note

") end end end From 1c7807925aaa3efcc85275273cf65c574985dd61 Mon Sep 17 00:00:00 2001 From: Airat Shigapov Date: Wed, 12 Oct 2016 09:51:02 +0300 Subject: [PATCH 029/247] Use guard clause instead of if-else statement --- .../project_services/hipchat_service.rb | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 8988a7b905e..e7a77070b9f 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -128,22 +128,21 @@ class HipchatService < Service end def markdown(text, options = {}) - if text - context = { - project: project, - pipeline: :email - } + return "" unless text - Banzai.render(text, context) + context = { + project: project, + pipeline: :email + } - context.merge!(options) + Banzai.render(text, context) - html = Banzai.render(text, context) - html = Banzai.post_process(html, context) - sanitize html, attributes: %w(href title alt) - else - "" - end + context.merge!(options) + + html = Banzai.render(text, context) + html = Banzai.post_process(html, context) + + sanitize html, attributes: %w(href title alt) end def create_issue_message(data) From 5d608ceb4f433a0d3f196a2a5cb11cf6a535baf2 Mon Sep 17 00:00:00 2001 From: Airat Shigapov Date: Wed, 19 Oct 2016 22:51:15 +0300 Subject: [PATCH 030/247] Return truncation for notification descriptions, fix minor bugs with rendering --- app/models/project_services/hipchat_service.rb | 17 +++++++++++------ .../project_services/hipchat_service_spec.rb | 12 ++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index e7a77070b9f..660a8ae3421 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -2,6 +2,11 @@ class HipchatService < Service include ActionView::Helpers::SanitizeHelper MAX_COMMITS = 3 + HIPCHAT_ALLOWED_TAGS = %w[ + a b i strong em br img pre code + table th tr td caption colgroup col thead tbody tfoot + ul ol li dl dt dd + ] prop_accessor :token, :room, :server, :notify, :color, :api_version boolean_accessor :notify_only_broken_builds @@ -139,10 +144,10 @@ class HipchatService < Service context.merge!(options) - html = Banzai.render(text, context) - html = Banzai.post_process(html, context) + html = Banzai.post_process(Banzai.render(text, context), context) + sanitized_html = sanitize(html, tags: HIPCHAT_ALLOWED_TAGS, attributes: %w[href title alt]) - sanitize html, attributes: %w(href title alt) + sanitized_html.truncate(200, separator: ' ', omission: '...') end def create_issue_message(data) @@ -159,7 +164,7 @@ class HipchatService < Service issue_link = "issue ##{issue_iid}" message = "#{user_name} #{state} #{issue_link} in #{project_link}: #{title}" - message << markdown(description) + message << "
#{markdown(description)}
" message end @@ -179,7 +184,7 @@ class HipchatService < Service message = "#{user_name} #{state} #{merge_request_link} in " \ "#{project_link}: #{title}" - message << markdown(description) + message << "
#{markdown(description)}
" message end @@ -230,7 +235,7 @@ class HipchatService < Service message = "#{user_name} commented on #{subject_html} in #{project_link}: " message << title - message << markdown(note, ref: commit_id) + message << "
#{markdown(note, ref: commit_id)}
" message end diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb index 1029b6d2459..2da3a9cb09f 100644 --- a/spec/models/project_services/hipchat_service_spec.rb +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -135,7 +135,7 @@ describe HipchatService, models: true do "issue ##{obj_attr["iid"]} in " \ "#{project_name}: " \ "Awesome issue" \ - "

please fix

") + "
please fix
") end end @@ -159,7 +159,7 @@ describe HipchatService, models: true do "merge request !#{obj_attr["iid"]} in " \ "#{project_name}: " \ "Awesome merge request" \ - "

please fix

") + "
please fix
") end end @@ -190,7 +190,7 @@ describe HipchatService, models: true do "commit #{commit_id} in " \ "#{project_name}: " \ "#{title}" \ - "

a comment on a commit

") + "
a comment on a commit
") end end @@ -222,7 +222,7 @@ describe HipchatService, models: true do "merge request !#{merge_id} in " \ "#{project_name}: " \ "#{title}" \ - "

merge request note

") + "
merge request note
") end end @@ -247,7 +247,7 @@ describe HipchatService, models: true do "issue ##{issue_id} in " \ "#{project_name}: " \ "#{title}" \ - "

issue note

") + "
issue note
") end end @@ -275,7 +275,7 @@ describe HipchatService, models: true do "snippet ##{snippet_id} in " \ "#{project_name}: " \ "#{title}" \ - "

snippet note

") + "
snippet note
") end end end From 435678d58828db76c3ef5f95643dac0e3ae979b3 Mon Sep 17 00:00:00 2001 From: Airat Shigapov Date: Thu, 20 Oct 2016 15:12:39 +0300 Subject: [PATCH 031/247] Add CHANGELOG.md entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f163f323e6..0bfdf23b959 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - Adds user project membership expired event to clarify why user was removed (Callum Dryden) + - Fix HipChat notifications rendering (airatshigapov, eisnerd) - Simpler arguments passed to named_route on toggle_award_url helper method ## 8.13.0 (2016-10-22) From ea704005c7bdca55e2782a2c24fe0c5e89cad179 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 19 Oct 2016 14:48:37 +0200 Subject: [PATCH 032/247] Update duration at the end of pipeline --- CHANGELOG.md | 1 + app/models/ci/pipeline.rb | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bfdf23b959..de24e08c52f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Add `/projects/visible` API endpoint (Ben Boeckel) - Fix centering of custom header logos (Ashley Dumaine) - Keep around commits only pipeline creation as pipeline data doesn't change over time + - Update duration at the end of pipeline - ExpireBuildArtifactsWorker query builds table without ordering enqueuing one job per build to cleanup - Add group level labels. (!6425) - Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index e84c91b417d..d5c1e03b461 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -59,9 +59,6 @@ module Ci before_transition any => [:success, :failed, :canceled] do |pipeline| pipeline.finished_at = Time.now - end - - before_transition do |pipeline| pipeline.update_duration end From 523ee4a5f4c28aab29310a742f4798bc77f20ccf Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 20 Oct 2016 16:16:57 +0800 Subject: [PATCH 033/247] Preserve note_type and position for notes from emails Closes #23208 --- .../email/handler/create_note_handler.rb | 4 +++- spec/fixtures/emails/commands_in_reply.eml | 2 -- spec/fixtures/emails/commands_only_reply.eml | 2 -- .../email/handler/create_note_handler_spec.rb | 24 ++++++++++--------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/gitlab/email/handler/create_note_handler.rb b/lib/gitlab/email/handler/create_note_handler.rb index 06dae31cc27..447c7a6a6b9 100644 --- a/lib/gitlab/email/handler/create_note_handler.rb +++ b/lib/gitlab/email/handler/create_note_handler.rb @@ -46,7 +46,9 @@ module Gitlab noteable_type: sent_notification.noteable_type, noteable_id: sent_notification.noteable_id, commit_id: sent_notification.commit_id, - line_code: sent_notification.line_code + line_code: sent_notification.line_code, + position: sent_notification.position, + type: sent_notification.note_type ).execute end end diff --git a/spec/fixtures/emails/commands_in_reply.eml b/spec/fixtures/emails/commands_in_reply.eml index 06bf60ab734..712f6f797b4 100644 --- a/spec/fixtures/emails/commands_in_reply.eml +++ b/spec/fixtures/emails/commands_in_reply.eml @@ -23,8 +23,6 @@ Cool! /close /todo -/due tomorrow - On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta wrote: diff --git a/spec/fixtures/emails/commands_only_reply.eml b/spec/fixtures/emails/commands_only_reply.eml index aed64224b06..2d2e2f94290 100644 --- a/spec/fixtures/emails/commands_only_reply.eml +++ b/spec/fixtures/emails/commands_only_reply.eml @@ -21,8 +21,6 @@ X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1 /close /todo -/due tomorrow - On Sun, Jun 9, 2013 at 1:39 PM, eviltrout via Discourse Meta wrote: diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb index 4909fed6b77..48660d1dd1b 100644 --- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb +++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb @@ -12,10 +12,13 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do let(:email_raw) { fixture_file('emails/valid_reply.eml') } let(:project) { create(:project, :public) } - let(:noteable) { create(:issue, project: project) } let(:user) { create(:user) } + let(:note) { create(:diff_note_on_merge_request, project: project) } + let(:noteable) { note.noteable } - let!(:sent_notification) { SentNotification.record(noteable, user.id, mail_key) } + let!(:sent_notification) do + SentNotification.record_note(note, user.id, mail_key) + end context "when the recipient address doesn't include a mail key" do let(:email_raw) { fixture_file('emails/valid_reply.eml').gsub(mail_key, "") } @@ -82,7 +85,6 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do expect { receiver.execute }.to change { noteable.notes.count }.by(1) expect(noteable.reload).to be_closed - expect(noteable.due_date).to eq(Date.tomorrow) expect(TodoService.new.todo_exist?(noteable, user)).to be_truthy end end @@ -100,7 +102,6 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do expect { receiver.execute }.to change { noteable.notes.count }.by(1) expect(noteable.reload).to be_open - expect(noteable.due_date).to be_nil expect(TodoService.new.todo_exist?(noteable, user)).to be_falsy end end @@ -117,7 +118,6 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do expect { receiver.execute }.to change { noteable.notes.count }.by(2) expect(noteable.reload).to be_closed - expect(noteable.due_date).to eq(Date.tomorrow) expect(TodoService.new.todo_exist?(noteable, user)).to be_truthy end end @@ -138,10 +138,11 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do it "creates a comment" do expect { receiver.execute }.to change { noteable.notes.count }.by(1) - note = noteable.notes.last + new_note = noteable.notes.last - expect(note.author).to eq(sent_notification.recipient) - expect(note.note).to include("I could not disagree more.") + expect(new_note.author).to eq(sent_notification.recipient) + expect(new_note.position).to eq(note.position) + expect(new_note.note).to include("I could not disagree more.") end it "adds all attachments" do @@ -160,10 +161,11 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do shared_examples 'an email that contains a mail key' do |header| it "fetches the mail key from the #{header} header and creates a comment" do expect { receiver.execute }.to change { noteable.notes.count }.by(1) - note = noteable.notes.last + new_note = noteable.notes.last - expect(note.author).to eq(sent_notification.recipient) - expect(note.note).to include('I could not disagree more.') + expect(new_note.author).to eq(sent_notification.recipient) + expect(new_note.position).to eq(note.position) + expect(new_note.note).to include('I could not disagree more.') end end From cbb65aae395821c596746d2b347fc3a7de1b3da8 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 20 Oct 2016 16:24:37 +0800 Subject: [PATCH 034/247] Add CHANGELOG entry [ci skip] --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de24e08c52f..98d95e275e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Please view this file on the master branch, on stable branches it's out of date. - Fix HipChat notifications rendering (airatshigapov, eisnerd) - Simpler arguments passed to named_route on toggle_award_url helper method + - Fix discussion thread from emails for merge requests. !7010 + ## 8.13.0 (2016-10-22) - Fix save button on project pipeline settings page. (!6955) From 25d00ea871a970fb82d79067d97c84fdcb5264c5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 20 Oct 2016 20:47:21 +0800 Subject: [PATCH 035/247] We want to release this in 8.13.0 --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98d95e275e2..73dc323e02c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,6 @@ Please view this file on the master branch, on stable branches it's out of date. - Fix HipChat notifications rendering (airatshigapov, eisnerd) - Simpler arguments passed to named_route on toggle_award_url helper method - - Fix discussion thread from emails for merge requests. !7010 - ## 8.13.0 (2016-10-22) - Fix save button on project pipeline settings page. (!6955) @@ -47,6 +45,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Speed-up group milestones show page - Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps) - Extract project#update_merge_requests and SystemHooks to its own worker from GitPushService + - Fix discussion thread from emails for merge requests. !7010 - Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs) - Add tag shortcut from the Commit page. !6543 - Keep refs for each deployment From 8979567e439c624145ffef7ebc255b7936b5d05e Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 19 Oct 2016 14:49:09 +0200 Subject: [PATCH 036/247] Use deployment IID when saving refs --- app/models/deployment.rb | 2 +- app/models/environment.rb | 4 ++-- spec/controllers/projects/merge_requests_controller_spec.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 1f8c5fb3d85..c843903877b 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -102,6 +102,6 @@ class Deployment < ActiveRecord::Base private def ref_path - File.join(environment.ref_path, 'deployments', id.to_s) + File.join(environment.ref_path, 'deployments', iid.to_s) end end diff --git a/app/models/environment.rb b/app/models/environment.rb index d575f1dc73a..73f415c0ef0 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -71,8 +71,8 @@ class Environment < ActiveRecord::Base return nil unless ref - deployment_id = ref.split('/').last - deployments.find(deployment_id) + deployment_iid = ref.split('/').last + deployments.find_by(iid: deployment_iid) end def ref_path diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index d6980471ea4..940d54f8686 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -913,7 +913,7 @@ describe Projects::MergeRequestsController do end describe 'GET ci_environments_status' do - context 'when the environment is from a forked project' do + context 'the environment is from a forked project' do let!(:forked) { create(:project) } let!(:environment) { create(:environment, project: forked) } let!(:deployment) { create(:deployment, environment: environment, sha: forked.commit.id, ref: 'master') } From 1cb75998992745216cb634537c281561559d1964 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 20 Oct 2016 14:21:40 +0200 Subject: [PATCH 037/247] Only create refs for new deployments This patch makes sure GitLab does not save the refs to the filesystem each time the deployment is updated. This will save some IO although I expect the impact to be minimal. --- app/models/deployment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deployment.rb b/app/models/deployment.rb index c843903877b..91d85c2279b 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -11,7 +11,7 @@ class Deployment < ActiveRecord::Base delegate :name, to: :environment, prefix: true - after_save :create_ref + after_create :create_ref def commit project.commit(sha) From 3974c2e9e18d80a9b5a49bd16ea3fc0d157dd919 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Fri, 14 Oct 2016 17:25:12 -0500 Subject: [PATCH 038/247] Create protected branches bundle --- .../protected_branch_access_dropdown.js.es6 | 0 .../{ => protected_branches}/protected_branch_create.js.es6 | 0 .../{ => protected_branches}/protected_branch_dropdown.js.es6 | 0 .../{ => protected_branches}/protected_branch_edit.js.es6 | 0 .../{ => protected_branches}/protected_branch_edit_list.js.es6 | 0 .../javascripts/protected_branches/protected_branches_bundle.js | 1 + app/views/projects/protected_branches/index.html.haml | 2 ++ config/application.rb | 1 + 8 files changed, 4 insertions(+) rename app/assets/javascripts/{ => protected_branches}/protected_branch_access_dropdown.js.es6 (100%) rename app/assets/javascripts/{ => protected_branches}/protected_branch_create.js.es6 (100%) rename app/assets/javascripts/{ => protected_branches}/protected_branch_dropdown.js.es6 (100%) rename app/assets/javascripts/{ => protected_branches}/protected_branch_edit.js.es6 (100%) rename app/assets/javascripts/{ => protected_branches}/protected_branch_edit_list.js.es6 (100%) create mode 100644 app/assets/javascripts/protected_branches/protected_branches_bundle.js diff --git a/app/assets/javascripts/protected_branch_access_dropdown.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6 similarity index 100% rename from app/assets/javascripts/protected_branch_access_dropdown.js.es6 rename to app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6 diff --git a/app/assets/javascripts/protected_branch_create.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_create.js.es6 similarity index 100% rename from app/assets/javascripts/protected_branch_create.js.es6 rename to app/assets/javascripts/protected_branches/protected_branch_create.js.es6 diff --git a/app/assets/javascripts/protected_branch_dropdown.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6 similarity index 100% rename from app/assets/javascripts/protected_branch_dropdown.js.es6 rename to app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6 diff --git a/app/assets/javascripts/protected_branch_edit.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_edit.js.es6 similarity index 100% rename from app/assets/javascripts/protected_branch_edit.js.es6 rename to app/assets/javascripts/protected_branches/protected_branch_edit.js.es6 diff --git a/app/assets/javascripts/protected_branch_edit_list.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6 similarity index 100% rename from app/assets/javascripts/protected_branch_edit_list.js.es6 rename to app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6 diff --git a/app/assets/javascripts/protected_branches/protected_branches_bundle.js b/app/assets/javascripts/protected_branches/protected_branches_bundle.js new file mode 100644 index 00000000000..15b3affd469 --- /dev/null +++ b/app/assets/javascripts/protected_branches/protected_branches_bundle.js @@ -0,0 +1 @@ +/*= require_tree . */ diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml index 49dcc9a6ba4..42e9bdbd30e 100644 --- a/app/views/projects/protected_branches/index.html.haml +++ b/app/views/projects/protected_branches/index.html.haml @@ -1,4 +1,6 @@ - page_title "Protected branches" +- content_for :page_specific_javascripts do + = page_specific_javascript_tag('protected_branches/protected_branches_bundle.js') .row.prepend-top-default.append-bottom-default .col-lg-3 diff --git a/config/application.rb b/config/application.rb index 8a9c539cb43..f3337b00dc6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -87,6 +87,7 @@ module Gitlab config.assets.precompile << "users/users_bundle.js" config.assets.precompile << "network/network_bundle.js" config.assets.precompile << "profile/profile_bundle.js" + config.assets.precompile << "protected_branches/protected_branches_bundle.js" config.assets.precompile << "diff_notes/diff_notes_bundle.js" config.assets.precompile << "boards/boards_bundle.js" config.assets.precompile << "merge_conflicts/merge_conflicts_bundle.js" From a2aa1abbc272b285dab12f03465f13e71fc91e15 Mon Sep 17 00:00:00 2001 From: Adam Niedzielski Date: Wed, 19 Oct 2016 15:35:38 +0200 Subject: [PATCH 039/247] Test GitLab project import for a user with only their default namespace. Refactor the spec file: - remove hardcoded record IDs - avoid top-level let if not used in all scenarios - prefer expect { ... }.to change { ... }.from(0).to(1) over checking that there are no records at the beginning of the test --- .../import_export/import_file_spec.rb | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index f32834801a0..3015576f6f8 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -3,13 +3,8 @@ require 'spec_helper' feature 'Import/Export - project import integration test', feature: true, js: true do include Select2Helper - let(:admin) { create(:admin) } - let(:normal_user) { create(:user) } - let!(:namespace) { create(:namespace, name: "asd", owner: admin) } let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') } let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } - let(:project) { Project.last } - let(:project_hook) { Gitlab::Git::Hook.new('post-receive', project.repository.path) } background do allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) @@ -19,41 +14,43 @@ feature 'Import/Export - project import integration test', feature: true, js: tr FileUtils.rm_rf(export_path, secure: true) end - context 'admin user' do + context 'when selecting the namespace' do + let(:user) { create(:admin) } + let!(:namespace) { create(:namespace, name: "asd", owner: user) } + before do - login_as(admin) + login_as(user) end scenario 'user imports an exported project successfully' do - expect(Project.all.count).to be_zero - visit new_project_path - select2('2', from: '#project_namespace_id') + select2(namespace.id, from: '#project_namespace_id') fill_in :project_path, with: 'test-project-path', visible: true click_link 'GitLab export' expect(page).to have_content('GitLab project export') - expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path') + expect(URI.parse(current_url).query).to eq("namespace_id=#{namespace.id}&path=test-project-path") attach_file('file', file) - click_on 'Import project' # import starts + expect { click_on 'Import project' }.to change { Project.count }.from(0).to(1) + project = Project.last expect(project).not_to be_nil expect(project.issues).not_to be_empty expect(project.merge_requests).not_to be_empty - expect(project_hook).to exist - expect(wiki_exists?).to be true + expect(project_hook_exists?(project)).to be true + expect(wiki_exists?(project)).to be true expect(project.import_status).to eq('finished') end scenario 'invalid project' do - project = create(:project, namespace_id: 2) + project = create(:project, namespace: namespace) visit new_project_path - select2('2', from: '#project_namespace_id') + select2(namespace.id, from: '#project_namespace_id') fill_in :project_path, with: project.name, visible: true click_link 'GitLab export' @@ -66,11 +63,11 @@ feature 'Import/Export - project import integration test', feature: true, js: tr end scenario 'project with no name' do - create(:project, namespace_id: 2) + create(:project, namespace: namespace) visit new_project_path - select2('2', from: '#project_namespace_id') + select2(namespace.id, from: '#project_namespace_id') # click on disabled element find(:link, 'GitLab export').trigger('click') @@ -81,24 +78,30 @@ feature 'Import/Export - project import integration test', feature: true, js: tr end end - context 'normal user' do + context 'when limited to the default user namespace' do + let(:user) { create(:user) } before do - login_as(normal_user) + login_as(user) end - scenario 'non-admin user is allowed to import a project' do - expect(Project.all.count).to be_zero - + scenario 'passes correct namespace ID in the URL' do visit new_project_path fill_in :project_path, with: 'test-project-path', visible: true - expect(page).to have_content('GitLab export') + click_link 'GitLab export' + + expect(page).to have_content('GitLab project export') + expect(URI.parse(current_url).query).to eq("namespace_id=#{user.namespace.id}&path=test-project-path") end end - def wiki_exists? + def wiki_exists?(project) wiki = ProjectWiki.new(project) File.exist?(wiki.repository.path_to_repo) && !wiki.repository.empty? end + + def project_hook_exists?(project) + Gitlab::Git::Hook.new('post-receive', project.repository.path).exists? + end end From beddc37478113771785385a645fecf50f743d2ec Mon Sep 17 00:00:00 2001 From: Adam Niedzielski Date: Wed, 19 Oct 2016 20:42:35 +0200 Subject: [PATCH 040/247] Fix GitLab project import when a user has access only to their default namespace. Render a hidden field with namespace ID so it can be read by JavaScript and passed to "/import/gitlab_project/new" screen. --- app/views/projects/new.html.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index cc8cb134fb8..399ccf15b7f 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -27,6 +27,7 @@ - else .input-group-addon.static-namespace #{root_url}#{current_user.username}/ + = f.hidden_field :namespace_id, value: current_user.namespace_id .form-group.col-xs-12.col-sm-6.project-path = f.label :namespace_id, class: 'label-light' do %span From 1bdda800b6a18237921dd0cdec60c36c0fa0153f Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 20 Oct 2016 14:15:39 -0200 Subject: [PATCH 041/247] [ci skip] Add a comment explaining validate_board_limit callback Callback associations are not common to see around. We want to make clear that the `before_add` callback uses the number before the addition, in this particular case 1. --- app/models/project.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/models/project.rb b/app/models/project.rb index 6685baab699..af117f0acb0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1339,6 +1339,13 @@ class Project < ActiveRecord::Base shared_projects.any? end + # Similar to the normal callbacks that hook into the life cycle of an + # Active Record object, you can also define callbacks that get triggered + # when you add an object to an association collection. If any of these + # callbacks throw an exception, the object will not be added to the + # collection. Before you add a new board to the boards collection if you + # already have 1, 2, or n it will fail, but it if you have 0 that is lower + # than the number of permitted boards per project it won't fail. def validate_board_limit(board) raise BoardLimitExceeded, 'Number of permitted boards exceeded' if boards.size >= NUMBER_OF_PERMITTED_BOARDS end From 327ae90c6bcbbc3cc08895ece2f6cc641983a84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 20 Oct 2016 18:51:03 +0200 Subject: [PATCH 042/247] Don't use Hash#slice since it's not supported in Ruby 2.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- lib/api/commit_statuses.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index f282a3b9cd6..f54d4f06627 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -67,9 +67,14 @@ module API pipeline = @project.ensure_pipeline(ref, commit.sha, current_user) status = GenericCommitStatus.running_or_pending.find_or_initialize_by( - project: @project, pipeline: pipeline, - user: current_user, name: name, ref: ref) - status.attributes = declared(params).slice(:target_url, :description) + project: @project, + pipeline: pipeline, + user: current_user, + name: name, + ref: ref, + target_url: params[:target_url], + description: params[:description] + ) begin case params[:state].to_s From 813286e5ea6712039fd868310160eef8acb1c012 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 21 Oct 2016 08:39:37 +1100 Subject: [PATCH 043/247] Added item to CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73dc323e02c..128f5dec039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - Adds user project membership expired event to clarify why user was removed (Callum Dryden) - Fix HipChat notifications rendering (airatshigapov, eisnerd) + - Add hover to trash icon in notes !7008 (blackst0ne) - Simpler arguments passed to named_route on toggle_award_url helper method ## 8.13.0 (2016-10-22) From 7f67b6c210b201c409176e2a59db771b5fe9b28d Mon Sep 17 00:00:00 2001 From: Tom Koole Date: Sun, 5 Feb 2017 22:39:20 -0500 Subject: [PATCH 044/247] fix new label errors not visible in dropdown for #27287, also humanize error key, improve testing hieararchy for reuse, remove duplicate test --- app/assets/javascripts/create_label.js.es6 | 6 +- .../27287-label-dropdown-error-messages.yml | 4 ++ spec/features/issues/issue_sidebar_spec.rb | 67 ++++++++++--------- 3 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 changelogs/unreleased/27287-label-dropdown-error-messages.yml diff --git a/app/assets/javascripts/create_label.js.es6 b/app/assets/javascripts/create_label.js.es6 index 947c129d5b5..85384d98126 100644 --- a/app/assets/javascripts/create_label.js.es6 +++ b/app/assets/javascripts/create_label.js.es6 @@ -107,9 +107,9 @@ if (typeof label.message === 'string') { errors = label.message; } else { - errors = label.message.map(function (value, key) { - return key + " " + value[0]; - }).join("
"); + errors = Object.keys(label.message).map(key => + `${gl.text.humanize(key)} ${label.message[key].join(', ')}` + ).join("
"); } this.$newLabelError diff --git a/changelogs/unreleased/27287-label-dropdown-error-messages.yml b/changelogs/unreleased/27287-label-dropdown-error-messages.yml new file mode 100644 index 00000000000..dfd4102c324 --- /dev/null +++ b/changelogs/unreleased/27287-label-dropdown-error-messages.yml @@ -0,0 +1,4 @@ +--- +title: Fix displaying error messages for create label dropdown +merge_request: 9058 +author: Tom Koole diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 1eb981942ea..7b9d4534ada 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -7,9 +7,9 @@ feature 'Issue Sidebar', feature: true do let(:project) { create(:project, :public) } let(:issue) { create(:issue, project: project) } let!(:user) { create(:user)} + let!(:label) { create(:label, project: project, title: 'bug') } before do - create(:label, project: project, title: 'bug') login_as(user) end @@ -50,16 +50,6 @@ feature 'Issue Sidebar', feature: true do visit_issue(project, issue) end - describe 'when clicking on edit labels', js: true do - it 'shows dropdown option to create a new label' do - find('.block.labels .edit-link').click - - page.within('.block.labels') do - expect(page).to have_content 'Create new' - end - end - end - context 'sidebar', js: true do it 'changes size when the screen size is smaller' do sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed' @@ -77,36 +67,53 @@ feature 'Issue Sidebar', feature: true do end end - context 'creating a new label', js: true do - it 'shows option to crate a new label is present' do + context 'editing issue labels', js: true do + before do page.within('.block.labels') do find('.edit-link').click + end + end + it 'shows option to create a new label' do + page.within('.block.labels') do expect(page).to have_content 'Create new' end end - it 'shows dropdown switches to "create label" section' do - page.within('.block.labels') do - find('.edit-link').click - click_link 'Create new' - - expect(page).to have_content 'Create new label' + context 'creating a new label', js: true do + before do + page.within('.block.labels') do + click_link 'Create new' + end end - end - it 'adds new label' do - page.within('.block.labels') do - find('.edit-link').click - sleep 1 - click_link 'Create new' + it 'shows dropdown switches to "create label" section' do + page.within('.block.labels') do + expect(page).to have_content 'Create new label' + end + end - fill_in 'new_label_name', with: 'wontfix' - page.find(".suggest-colors a", match: :first).click - click_button 'Create' + it 'adds new label' do + page.within('.block.labels') do + fill_in 'new_label_name', with: 'wontfix' + page.find(".suggest-colors a", match: :first).click + click_button 'Create' - page.within('.dropdown-page-one') do - expect(page).to have_content 'wontfix' + page.within('.dropdown-page-one') do + expect(page).to have_content 'wontfix' + end + end + end + + it 'shows error message if label title is taken' do + page.within('.block.labels') do + fill_in 'new_label_name', with: label.title + page.find('.suggest-colors a', match: :first).click + click_button 'Create' + + page.within('.dropdown-page-two') do + expect(page).to have_content 'Title has already been taken' + end end end end From e7e2562e4f82b10301e899ebb0e355df6beac0e6 Mon Sep 17 00:00:00 2001 From: Jared Deckard Date: Mon, 6 Feb 2017 16:25:30 -0600 Subject: [PATCH 045/247] Position task list checkbox to match the list indent --- app/assets/stylesheets/framework/lists.scss | 10 -------- app/assets/stylesheets/framework/mixins.scss | 7 ++++++ .../stylesheets/framework/typography.scss | 25 ++++++++++++++++++- .../unreleased/22466-task-list-alignment.yml | 4 +++ 4 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 changelogs/unreleased/22466-task-list-alignment.yml diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index 2bfdb9f9601..55ed4b7b06c 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -96,16 +96,6 @@ ul.unstyled-list > li { border-bottom: none; } -ul.task-list { - li.task-list-item { - list-style-type: none; - } - - ul:not(.task-list) { - padding-left: 1.3em; - } -} - // Generic content list ul.content-list { @include basic-list; diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 1acd06122a3..df78bbdea51 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -76,6 +76,13 @@ #{$property}: $value; } +/* http://phrappe.com/css/conditional-css-for-webkit-based-browsers/ */ +@mixin on-webkit-only { + @media screen and (-webkit-min-device-pixel-ratio:0) { + @content; + } +} + @mixin keyframes($animation-name) { @-webkit-keyframes #{$animation-name} { @content; diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 54958973f15..db5e2c51fe7 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -134,7 +134,7 @@ ul, ol { padding: 0; - margin: 3px 0 3px 28px !important; + margin: 3px 0 !important; } ul:dir(rtl), @@ -144,6 +144,29 @@ li { line-height: 1.6em; + margin-left: 25px; + padding-left: 3px; + + /* Normalize the bullet position on webkit. */ + @include on-webkit-only { + margin-left: 28px; + padding-left: 0; + } + } + + ul.task-list { + li.task-list-item { + list-style-type: none; + position: relative; + padding-left: 28px; + margin-left: 0 !important; + + input.task-list-item-checkbox { + position: absolute; + left: 8px; + top: 5px; + } + } } a[href*="/uploads/"], diff --git a/changelogs/unreleased/22466-task-list-alignment.yml b/changelogs/unreleased/22466-task-list-alignment.yml new file mode 100644 index 00000000000..6e6ccb873ec --- /dev/null +++ b/changelogs/unreleased/22466-task-list-alignment.yml @@ -0,0 +1,4 @@ +--- +title: Align task list checkboxes +merge_request: 6487 +author: Jared Deckard From 41d05fa85a4b73a3577912ffc4ebd66bc14f94ff Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 14 Feb 2017 14:08:20 +0000 Subject: [PATCH 046/247] Fixed alignment of snippet search results Also enabled syntaax highlight on the search results Closes #26832 --- .../search/results/_snippet_blob.html.haml | 55 ++++++++----------- changelogs/unreleased/snippets-search.yml | 4 ++ 2 files changed, 28 insertions(+), 31 deletions(-) create mode 100644 changelogs/unreleased/snippets-search.yml diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml index f7808ea6aff..69c218acdfb 100644 --- a/app/views/search/results/_snippet_blob.html.haml +++ b/app/views/search/results/_snippet_blob.html.haml @@ -12,41 +12,34 @@ %span.light= time_ago_with_tooltip(snippet.created_at) %h4.snippet-title - snippet_path = reliable_snippet_path(snippet) - = link_to snippet_path do - .file-holder - .js-file-title.file-title + .file-holder + .js-file-title.file-title + = link_to snippet_path do %i.fa.fa-file %strong= snippet.file_name - - if markup?(snippet.file_name) - .file-content.wiki + - if markup?(snippet.file_name) + .file-content.wiki + - snippet_chunks.each do |chunk| + - unless chunk[:data].empty? + = render_markup(snippet.file_name, chunk[:data]) + - else + .file-content.code + .nothing-here-block Empty file + - else + .file-content.code.js-syntax-highlight + .line-numbers - snippet_chunks.each do |chunk| - unless chunk[:data].empty? - = render_markup(snippet.file_name, chunk[:data]) + - Gitlab::Git::Util.count_lines(chunk[:data]).times do |index| + - offset = defined?(chunk[:start_line]) ? chunk[:start_line] : 1 + - i = index + offset + = link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}", class: "diff-line-num" do + %i.fa.fa-link + = i + .blob-content + - snippet_chunks.each do |chunk| + - unless chunk[:data].empty? + = highlight(snippet.file_name, chunk[:data], repository: nil, plain: snippet.no_highlighting?) - else .file-content.code .nothing-here-block Empty file - - else - .file-content.code.js-syntax-highlight - .line-numbers - - snippet_chunks.each do |chunk| - - unless chunk[:data].empty? - - Gitlab::Git::Util.count_lines(chunk[:data]).times do |index| - - offset = defined?(chunk[:start_line]) ? chunk[:start_line] : 1 - - i = index + offset - = link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}", class: "diff-line-num" do - %i.fa.fa-link - = i - - unless snippet == snippet_chunks.last - %a.diff-line-num - = "." - %pre.code - %code - - snippet_chunks.each do |chunk| - - unless chunk[:data].empty? - = chunk[:data] - - unless chunk == snippet_chunks.last - %a - = "..." - - else - .file-content.code - .nothing-here-block Empty file diff --git a/changelogs/unreleased/snippets-search.yml b/changelogs/unreleased/snippets-search.yml new file mode 100644 index 00000000000..00cf34f4a48 --- /dev/null +++ b/changelogs/unreleased/snippets-search.yml @@ -0,0 +1,4 @@ +--- +title: Fix snippets search result spacing +merge_request: +author: From 3894ae3bd07550bef632068f6d5296144099f619 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 16 Feb 2017 09:34:13 +0000 Subject: [PATCH 047/247] Added ability to change user permissions in group to owner Closes #28233 --- app/views/shared/members/_member.html.haml | 2 +- .../unreleased/group-memebrs-owner-level.yml | 4 ++++ spec/features/groups/members/list_spec.rb | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/group-memebrs-owner-level.yml diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml index 239387fc9fa..8e721c9c8dd 100644 --- a/app/views/shared/members/_member.html.haml +++ b/app/views/shared/members/_member.html.haml @@ -61,7 +61,7 @@ = dropdown_title("Change permissions") .dropdown-content %ul - - Gitlab::Access.options.each do |role, role_id| + - member.class.access_level_roles.each do |role, role_id| %li = link_to role, "javascript:void(0)", class: ("is-active" if member.access_level == role_id), diff --git a/changelogs/unreleased/group-memebrs-owner-level.yml b/changelogs/unreleased/group-memebrs-owner-level.yml new file mode 100644 index 00000000000..ba77f38eb6d --- /dev/null +++ b/changelogs/unreleased/group-memebrs-owner-level.yml @@ -0,0 +1,4 @@ +--- +title: Added option to update to owner for group members +merge_request: +author: diff --git a/spec/features/groups/members/list_spec.rb b/spec/features/groups/members/list_spec.rb index 109de39b2dd..14c193f7450 100644 --- a/spec/features/groups/members/list_spec.rb +++ b/spec/features/groups/members/list_spec.rb @@ -30,6 +30,21 @@ feature 'Groups members list', feature: true do expect(second_row).to be_blank end + it 'updates user to owner level', :js do + group.add_owner(user1) + group.add_developer(user2) + + visit group_group_members_path(group) + + page.within(second_row) do + click_button('Developer') + + click_link('Owner') + + expect(page).to have_button('Owner') + end + end + def first_row page.all('ul.content-list > li')[0] end From 905fdfba927dcfa32b99d649521a52445bc6838f Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 17 Feb 2017 07:03:42 +1100 Subject: [PATCH 048/247] Add merge request count to each issue on issues list --- .../images/icon-merge-request-unmerged.svg | 1 + app/assets/stylesheets/pages/issues.scss | 5 +++++ .../concerns/issuable_collections.rb | 20 +++++++++++++------ app/controllers/projects/issues_controller.rb | 2 +- .../projects/merge_requests_controller.rb | 2 +- app/models/concerns/issuable.rb | 4 ++-- app/models/merge_requests_closing_issues.rb | 8 ++++++++ .../shared/_issuable_meta_data.html.haml | 6 ++++++ .../unreleased/add_mr_info_to_issues_list.yml | 4 ++++ 9 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 app/assets/images/icon-merge-request-unmerged.svg create mode 100644 changelogs/unreleased/add_mr_info_to_issues_list.yml diff --git a/app/assets/images/icon-merge-request-unmerged.svg b/app/assets/images/icon-merge-request-unmerged.svg new file mode 100644 index 00000000000..c4d8e65122d --- /dev/null +++ b/app/assets/images/icon-merge-request-unmerged.svg @@ -0,0 +1 @@ + diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 80b0c9493d8..b595480561b 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -10,6 +10,11 @@ .issue-labels { display: inline-block; } + + .icon-merge-request-unmerged { + height: 13px; + margin-bottom: 3px; + } } } diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index a6e158ebae6..d7d781cbe72 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -9,24 +9,32 @@ module IssuableCollections private - def issuable_meta_data(issuable_collection) + def issuable_meta_data(issuable_collection, collection_type) # map has to be used here since using pluck or select will # throw an error when ordering issuables by priority which inserts # a new order into the collection. # We cannot use reorder to not mess up the paginated collection. - issuable_ids = issuable_collection.map(&:id) - issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) + issuable_ids = issuable_collection.map(&:id) + issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) issuable_votes_count = AwardEmoji.votes_for_collection(issuable_ids, @collection_type) + issuable_merge_requests_count = + if collection_type == 'Issue' + MergeRequestsClosingIssues.count_for_collection(issuable_ids) + else + [] + end issuable_ids.each_with_object({}) do |id, issuable_meta| downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? } - upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } - notes = issuable_note_count.find { |notes| notes.noteable_id == id } + upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } + notes = issuable_note_count.find { |notes| notes.noteable_id == id } + merge_requests = issuable_merge_requests_count.find { |mr| mr.issue_id == id } issuable_meta[id] = Issuable::IssuableMeta.new( upvotes.try(:count).to_i, downvotes.try(:count).to_i, - notes.try(:count).to_i + notes.try(:count).to_i, + merge_requests.try(:count).to_i ) end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 744a4af1c51..05056ad046a 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -26,7 +26,7 @@ class Projects::IssuesController < Projects::ApplicationController @collection_type = "Issue" @issues = issues_collection @issues = @issues.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@issues) + @issuable_meta_data = issuable_meta_data(@issues, @collection_type) if @issues.out_of_range? && @issues.total_pages != 0 return redirect_to url_for(params.merge(page: @issues.total_pages)) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index c3e1760f168..8a7aeeaa96f 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -39,7 +39,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController @collection_type = "MergeRequest" @merge_requests = merge_requests_collection @merge_requests = @merge_requests.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@merge_requests) + @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) if @merge_requests.out_of_range? && @merge_requests.total_pages != 0 return redirect_to url_for(params.merge(page: @merge_requests.total_pages)) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 5f53c48fc88..c9c6bd24d75 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -16,9 +16,9 @@ module Issuable include TimeTrackable # This object is used to gather issuable meta data for displaying - # upvotes, downvotes and notes count for issues and merge requests + # upvotes, downvotes, notes and closing merge requests count for issues and merge requests # lists avoiding n+1 queries and improving performance. - IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count) + IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count, :merge_requests_count) included do cache_markdown_field :title, pipeline: :single_line diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index ab597c37947..1ecdfd1dfdb 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -4,4 +4,12 @@ class MergeRequestsClosingIssues < ActiveRecord::Base validates :merge_request_id, uniqueness: { scope: :issue_id }, presence: true validates :issue_id, presence: true + + class << self + def count_for_collection(ids) + select('issue_id', 'COUNT(*) as count'). + group(:issue_id). + where(issue_id: ids) + end + end end diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml index 1264e524d86..66310da5cd6 100644 --- a/app/views/shared/_issuable_meta_data.html.haml +++ b/app/views/shared/_issuable_meta_data.html.haml @@ -2,6 +2,12 @@ - issue_votes = @issuable_meta_data[issuable.id] - upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes - issuable_url = @collection_type == "Issue" ? issue_path(issuable, anchor: 'notes') : merge_request_path(issuable, anchor: 'notes') +- issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count + +- if issuable_mr > 0 + %li + = image_tag('icon-merge-request-unmerged', class: 'icon-merge-request-unmerged') + = issuable_mr - if upvotes > 0 %li diff --git a/changelogs/unreleased/add_mr_info_to_issues_list.yml b/changelogs/unreleased/add_mr_info_to_issues_list.yml new file mode 100644 index 00000000000..8087aa6296c --- /dev/null +++ b/changelogs/unreleased/add_mr_info_to_issues_list.yml @@ -0,0 +1,4 @@ +--- +title: Add merge request count to each issue on issues list +merge_request: 9252 +author: blackst0ne From 204a0865e0e69d740abcaa85a689218140678a49 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 17 Feb 2017 07:09:24 +1100 Subject: [PATCH 049/247] Add merge request count to each issue on issues list --- .../images/icon-merge-request-unmerged.svg | 1 + app/assets/stylesheets/pages/issues.scss | 5 +++++ .../concerns/issuable_collections.rb | 20 +++++++++++++------ app/controllers/projects/issues_controller.rb | 2 +- .../projects/merge_requests_controller.rb | 2 +- app/models/concerns/issuable.rb | 4 ++-- app/models/merge_requests_closing_issues.rb | 8 ++++++++ .../shared/_issuable_meta_data.html.haml | 6 ++++++ .../unreleased/add_mr_info_to_issues_list.yml | 4 ++++ 9 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 app/assets/images/icon-merge-request-unmerged.svg create mode 100644 changelogs/unreleased/add_mr_info_to_issues_list.yml diff --git a/app/assets/images/icon-merge-request-unmerged.svg b/app/assets/images/icon-merge-request-unmerged.svg new file mode 100644 index 00000000000..c4d8e65122d --- /dev/null +++ b/app/assets/images/icon-merge-request-unmerged.svg @@ -0,0 +1 @@ + diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 80b0c9493d8..b595480561b 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -10,6 +10,11 @@ .issue-labels { display: inline-block; } + + .icon-merge-request-unmerged { + height: 13px; + margin-bottom: 3px; + } } } diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index a6e158ebae6..d7d781cbe72 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -9,24 +9,32 @@ module IssuableCollections private - def issuable_meta_data(issuable_collection) + def issuable_meta_data(issuable_collection, collection_type) # map has to be used here since using pluck or select will # throw an error when ordering issuables by priority which inserts # a new order into the collection. # We cannot use reorder to not mess up the paginated collection. - issuable_ids = issuable_collection.map(&:id) - issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) + issuable_ids = issuable_collection.map(&:id) + issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) issuable_votes_count = AwardEmoji.votes_for_collection(issuable_ids, @collection_type) + issuable_merge_requests_count = + if collection_type == 'Issue' + MergeRequestsClosingIssues.count_for_collection(issuable_ids) + else + [] + end issuable_ids.each_with_object({}) do |id, issuable_meta| downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? } - upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } - notes = issuable_note_count.find { |notes| notes.noteable_id == id } + upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } + notes = issuable_note_count.find { |notes| notes.noteable_id == id } + merge_requests = issuable_merge_requests_count.find { |mr| mr.issue_id == id } issuable_meta[id] = Issuable::IssuableMeta.new( upvotes.try(:count).to_i, downvotes.try(:count).to_i, - notes.try(:count).to_i + notes.try(:count).to_i, + merge_requests.try(:count).to_i ) end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 744a4af1c51..05056ad046a 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -26,7 +26,7 @@ class Projects::IssuesController < Projects::ApplicationController @collection_type = "Issue" @issues = issues_collection @issues = @issues.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@issues) + @issuable_meta_data = issuable_meta_data(@issues, @collection_type) if @issues.out_of_range? && @issues.total_pages != 0 return redirect_to url_for(params.merge(page: @issues.total_pages)) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 63b5bcbb586..1d286ca62e5 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -39,7 +39,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController @collection_type = "MergeRequest" @merge_requests = merge_requests_collection @merge_requests = @merge_requests.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@merge_requests) + @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) if @merge_requests.out_of_range? && @merge_requests.total_pages != 0 return redirect_to url_for(params.merge(page: @merge_requests.total_pages)) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 5f53c48fc88..c9c6bd24d75 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -16,9 +16,9 @@ module Issuable include TimeTrackable # This object is used to gather issuable meta data for displaying - # upvotes, downvotes and notes count for issues and merge requests + # upvotes, downvotes, notes and closing merge requests count for issues and merge requests # lists avoiding n+1 queries and improving performance. - IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count) + IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count, :merge_requests_count) included do cache_markdown_field :title, pipeline: :single_line diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index ab597c37947..1ecdfd1dfdb 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -4,4 +4,12 @@ class MergeRequestsClosingIssues < ActiveRecord::Base validates :merge_request_id, uniqueness: { scope: :issue_id }, presence: true validates :issue_id, presence: true + + class << self + def count_for_collection(ids) + select('issue_id', 'COUNT(*) as count'). + group(:issue_id). + where(issue_id: ids) + end + end end diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml index 1264e524d86..66310da5cd6 100644 --- a/app/views/shared/_issuable_meta_data.html.haml +++ b/app/views/shared/_issuable_meta_data.html.haml @@ -2,6 +2,12 @@ - issue_votes = @issuable_meta_data[issuable.id] - upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes - issuable_url = @collection_type == "Issue" ? issue_path(issuable, anchor: 'notes') : merge_request_path(issuable, anchor: 'notes') +- issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count + +- if issuable_mr > 0 + %li + = image_tag('icon-merge-request-unmerged', class: 'icon-merge-request-unmerged') + = issuable_mr - if upvotes > 0 %li diff --git a/changelogs/unreleased/add_mr_info_to_issues_list.yml b/changelogs/unreleased/add_mr_info_to_issues_list.yml new file mode 100644 index 00000000000..8087aa6296c --- /dev/null +++ b/changelogs/unreleased/add_mr_info_to_issues_list.yml @@ -0,0 +1,4 @@ +--- +title: Add merge request count to each issue on issues list +merge_request: 9252 +author: blackst0ne From ffd3583486f4772c8aec58b2750619d889d18d1b Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 17 Feb 2017 08:30:00 +1100 Subject: [PATCH 050/247] Added second parameter to @issuable_meta_data variables --- app/controllers/concerns/issues_action.rb | 2 +- app/controllers/concerns/merge_requests_action.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index fb5edb34370..b17c138d5c7 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -10,7 +10,7 @@ module IssuesAction .page(params[:page]) @collection_type = "Issue" - @issuable_meta_data = issuable_meta_data(@issues) + @issuable_meta_data = issuable_meta_data(@issues, @collection_type) respond_to do |format| format.html diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index 6229759dcf1..d3c8e4888bc 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -9,7 +9,7 @@ module MergeRequestsAction .page(params[:page]) @collection_type = "MergeRequest" - @issuable_meta_data = issuable_meta_data(@merge_requests) + @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) end private From 27ffc2817554902c380a1101db7a0feb5816955f Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Fri, 17 Feb 2017 08:33:09 +1100 Subject: [PATCH 051/247] Add merge request count to each issue on issues list --- .../images/icon-merge-request-unmerged.svg | 1 + app/assets/stylesheets/pages/issues.scss | 5 +++++ .../concerns/issuable_collections.rb | 20 +++++++++++++------ app/controllers/concerns/issues_action.rb | 2 +- .../concerns/merge_requests_action.rb | 2 +- app/controllers/projects/issues_controller.rb | 2 +- .../projects/merge_requests_controller.rb | 2 +- app/models/concerns/issuable.rb | 4 ++-- app/models/merge_requests_closing_issues.rb | 8 ++++++++ .../shared/_issuable_meta_data.html.haml | 6 ++++++ .../unreleased/add_mr_info_to_issues_list.yml | 4 ++++ 11 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 app/assets/images/icon-merge-request-unmerged.svg create mode 100644 changelogs/unreleased/add_mr_info_to_issues_list.yml diff --git a/app/assets/images/icon-merge-request-unmerged.svg b/app/assets/images/icon-merge-request-unmerged.svg new file mode 100644 index 00000000000..c4d8e65122d --- /dev/null +++ b/app/assets/images/icon-merge-request-unmerged.svg @@ -0,0 +1 @@ + diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 80b0c9493d8..b595480561b 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -10,6 +10,11 @@ .issue-labels { display: inline-block; } + + .icon-merge-request-unmerged { + height: 13px; + margin-bottom: 3px; + } } } diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index a6e158ebae6..d7d781cbe72 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -9,24 +9,32 @@ module IssuableCollections private - def issuable_meta_data(issuable_collection) + def issuable_meta_data(issuable_collection, collection_type) # map has to be used here since using pluck or select will # throw an error when ordering issuables by priority which inserts # a new order into the collection. # We cannot use reorder to not mess up the paginated collection. - issuable_ids = issuable_collection.map(&:id) - issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) + issuable_ids = issuable_collection.map(&:id) + issuable_note_count = Note.count_for_collection(issuable_ids, @collection_type) issuable_votes_count = AwardEmoji.votes_for_collection(issuable_ids, @collection_type) + issuable_merge_requests_count = + if collection_type == 'Issue' + MergeRequestsClosingIssues.count_for_collection(issuable_ids) + else + [] + end issuable_ids.each_with_object({}) do |id, issuable_meta| downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? } - upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } - notes = issuable_note_count.find { |notes| notes.noteable_id == id } + upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } + notes = issuable_note_count.find { |notes| notes.noteable_id == id } + merge_requests = issuable_merge_requests_count.find { |mr| mr.issue_id == id } issuable_meta[id] = Issuable::IssuableMeta.new( upvotes.try(:count).to_i, downvotes.try(:count).to_i, - notes.try(:count).to_i + notes.try(:count).to_i, + merge_requests.try(:count).to_i ) end end diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index fb5edb34370..b17c138d5c7 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -10,7 +10,7 @@ module IssuesAction .page(params[:page]) @collection_type = "Issue" - @issuable_meta_data = issuable_meta_data(@issues) + @issuable_meta_data = issuable_meta_data(@issues, @collection_type) respond_to do |format| format.html diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index 6229759dcf1..d3c8e4888bc 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -9,7 +9,7 @@ module MergeRequestsAction .page(params[:page]) @collection_type = "MergeRequest" - @issuable_meta_data = issuable_meta_data(@merge_requests) + @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) end private diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 744a4af1c51..05056ad046a 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -26,7 +26,7 @@ class Projects::IssuesController < Projects::ApplicationController @collection_type = "Issue" @issues = issues_collection @issues = @issues.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@issues) + @issuable_meta_data = issuable_meta_data(@issues, @collection_type) if @issues.out_of_range? && @issues.total_pages != 0 return redirect_to url_for(params.merge(page: @issues.total_pages)) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 63b5bcbb586..1d286ca62e5 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -39,7 +39,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController @collection_type = "MergeRequest" @merge_requests = merge_requests_collection @merge_requests = @merge_requests.page(params[:page]) - @issuable_meta_data = issuable_meta_data(@merge_requests) + @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) if @merge_requests.out_of_range? && @merge_requests.total_pages != 0 return redirect_to url_for(params.merge(page: @merge_requests.total_pages)) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 5f53c48fc88..c9c6bd24d75 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -16,9 +16,9 @@ module Issuable include TimeTrackable # This object is used to gather issuable meta data for displaying - # upvotes, downvotes and notes count for issues and merge requests + # upvotes, downvotes, notes and closing merge requests count for issues and merge requests # lists avoiding n+1 queries and improving performance. - IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count) + IssuableMeta = Struct.new(:upvotes, :downvotes, :notes_count, :merge_requests_count) included do cache_markdown_field :title, pipeline: :single_line diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index ab597c37947..1ecdfd1dfdb 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -4,4 +4,12 @@ class MergeRequestsClosingIssues < ActiveRecord::Base validates :merge_request_id, uniqueness: { scope: :issue_id }, presence: true validates :issue_id, presence: true + + class << self + def count_for_collection(ids) + select('issue_id', 'COUNT(*) as count'). + group(:issue_id). + where(issue_id: ids) + end + end end diff --git a/app/views/shared/_issuable_meta_data.html.haml b/app/views/shared/_issuable_meta_data.html.haml index 1264e524d86..66310da5cd6 100644 --- a/app/views/shared/_issuable_meta_data.html.haml +++ b/app/views/shared/_issuable_meta_data.html.haml @@ -2,6 +2,12 @@ - issue_votes = @issuable_meta_data[issuable.id] - upvotes, downvotes = issue_votes.upvotes, issue_votes.downvotes - issuable_url = @collection_type == "Issue" ? issue_path(issuable, anchor: 'notes') : merge_request_path(issuable, anchor: 'notes') +- issuable_mr = @issuable_meta_data[issuable.id].merge_requests_count + +- if issuable_mr > 0 + %li + = image_tag('icon-merge-request-unmerged', class: 'icon-merge-request-unmerged') + = issuable_mr - if upvotes > 0 %li diff --git a/changelogs/unreleased/add_mr_info_to_issues_list.yml b/changelogs/unreleased/add_mr_info_to_issues_list.yml new file mode 100644 index 00000000000..8087aa6296c --- /dev/null +++ b/changelogs/unreleased/add_mr_info_to_issues_list.yml @@ -0,0 +1,4 @@ +--- +title: Add merge request count to each issue on issues list +merge_request: 9252 +author: blackst0ne From 0f36cfd7f58977becea9d3ecf410d3669440fbe9 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Wed, 15 Feb 2017 14:06:00 +0000 Subject: [PATCH 052/247] Adds Pending and Finished tabs to pipelines page Fix broken test --- .../vue_pipelines_index/pipelines.js.es6 | 2 +- .../projects/pipelines_controller.rb | 12 +++++-- app/finders/pipelines_finder.rb | 6 +++- app/views/projects/pipelines/index.html.haml | 22 +++++++++--- .../unreleased/26900-pipelines-tabs.yml | 4 +++ .../projects/pipelines_controller_spec.rb | 4 ++- .../projects/pipelines/pipelines_spec.rb | 35 +++++++++++++++++++ spec/finders/pipelines_finder_spec.rb | 4 +-- 8 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 changelogs/unreleased/26900-pipelines-tabs.yml diff --git a/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 index dac364977d5..83e045c6d3d 100644 --- a/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 +++ b/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 @@ -23,7 +23,7 @@ const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_s apiScope: 'all', pageInfo: {}, pagenum: 1, - count: { all: 0, running_or_pending: 0 }, + count: {}, pageRequest: false, }; }, diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 84451257b98..8657bc4dfdc 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -13,9 +13,15 @@ class Projects::PipelinesController < Projects::ApplicationController .page(params[:page]) .per(30) - @running_or_pending_count = PipelinesFinder + @running_count = PipelinesFinder .new(project).execute(scope: 'running').count + @pending_count = PipelinesFinder + .new(project).execute(scope: 'pending').count + + @finished_count = PipelinesFinder + .new(project).execute(scope: 'finished').count + @pipelines_count = PipelinesFinder .new(project).execute.count @@ -29,7 +35,9 @@ class Projects::PipelinesController < Projects::ApplicationController .represent(@pipelines), count: { all: @pipelines_count, - running_or_pending: @running_or_pending_count + running: @running_count, + pending: @pending_count, + finished: @finished_count, } } end diff --git a/app/finders/pipelines_finder.rb b/app/finders/pipelines_finder.rb index 32aea75486d..a9172f6767f 100644 --- a/app/finders/pipelines_finder.rb +++ b/app/finders/pipelines_finder.rb @@ -10,7 +10,11 @@ class PipelinesFinder scoped_pipelines = case scope when 'running' - pipelines.running_or_pending + pipelines.running + when 'pending' + pipelines.pending + when 'finished' + pipelines.finished when 'branches' from_ids(ids_for_ref(branches)) when 'tags' diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml index 6e0428e2a31..4147a617d95 100644 --- a/app/views/projects/pipelines/index.html.haml +++ b/app/views/projects/pipelines/index.html.haml @@ -5,23 +5,35 @@ %div{ class: container_class } .top-area %ul.nav-links - %li{ class: active_when(@scope.nil?) }> + %li.js-pipelines-tab-all{ class: active_when(@scope.nil?) }> = link_to project_pipelines_path(@project) do All %span.badge.js-totalbuilds-count = number_with_delimiter(@pipelines_count) - %li{ class: active_when(@scope == 'running') }> + %li.js-pipelines-tab-pending{ class: active_when(@scope == 'pending') }> + = link_to project_pipelines_path(@project, scope: :pending) do + Pending + %span.badge + = number_with_delimiter(@pending_count) + + %li.js-pipelines-tab-running{ class: active_when(@scope == 'running') }> = link_to project_pipelines_path(@project, scope: :running) do Running %span.badge.js-running-count - = number_with_delimiter(@running_or_pending_count) + = number_with_delimiter(@running_count) - %li{ class: active_when(@scope == 'branches') }> + %li.js-pipelines-tab-finished{ class: active_when(@scope == 'finished') }> + = link_to project_pipelines_path(@project, scope: :finished) do + Finished + %span.badge + = number_with_delimiter(@finished_count) + + %li.js-pipelines-tab-branches{ class: active_when(@scope == 'branches') }> = link_to project_pipelines_path(@project, scope: :branches) do Branches - %li{ class: active_when(@scope == 'tags') }> + %li.js-pipelines-tab-tags{ class: active_when(@scope == 'tags') }> = link_to project_pipelines_path(@project, scope: :tags) do Tags diff --git a/changelogs/unreleased/26900-pipelines-tabs.yml b/changelogs/unreleased/26900-pipelines-tabs.yml new file mode 100644 index 00000000000..f08514c621f --- /dev/null +++ b/changelogs/unreleased/26900-pipelines-tabs.yml @@ -0,0 +1,4 @@ +--- +title: Adds Pending and Finished tabs to pipelines page +merge_request: +author: diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 1ed2ee3ab4a..242cf18c42b 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -25,7 +25,9 @@ describe Projects::PipelinesController do expect(json_response).to include('pipelines') expect(json_response['pipelines'].count).to eq 2 expect(json_response['count']['all']).to eq 2 - expect(json_response['count']['running_or_pending']).to eq 2 + expect(json_response['count']['running']).to eq 0 + expect(json_response['count']['pending']).to eq 2 + expect(json_response['count']['finished']).to eq 0 end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index b56be499264..8f4317181df 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -42,6 +42,41 @@ describe 'Pipelines', :feature, :js do end end + context 'header tabs' do + before do + visit namespace_project_pipelines_path(project.namespace, project) + wait_for_vue_resource + end + + it 'shows a tab for All pipelines and count' do + expect(page.find('.js-pipelines-tab-all a').text).to include('All') + expect(page.find('.js-pipelines-tab-all .badge').text).to include('1') + end + + it 'shows a tab for Pending pipelines and count' do + expect(page.find('.js-pipelines-tab-pending a').text).to include('Pending') + expect(page.find('.js-pipelines-tab-pending .badge').text).to include('0') + end + + it 'shows a tab for Running pipelines and count' do + expect(page.find('.js-pipelines-tab-running a').text).to include('Running') + expect(page.find('.js-pipelines-tab-running .badge').text).to include('1') + end + + it 'shows a tab for Finished pipelines and count' do + expect(page.find('.js-pipelines-tab-finished a').text).to include('Finished') + expect(page.find('.js-pipelines-tab-finished .badge').text).to include('0') + end + + it 'shows a tab for Branches' do + expect(page.find('.js-pipelines-tab-branches a').text).to include('Branches') + end + + it 'shows a tab for Tags' do + expect(page.find('.js-pipelines-tab-tags a').text).to include('Tags') + end + end + context 'when pipeline is cancelable' do let!(:build) do create(:ci_build, pipeline: pipeline, diff --git a/spec/finders/pipelines_finder_spec.rb b/spec/finders/pipelines_finder_spec.rb index fdc8215aa47..6bada7b3eb9 100644 --- a/spec/finders/pipelines_finder_spec.rb +++ b/spec/finders/pipelines_finder_spec.rb @@ -39,8 +39,8 @@ describe PipelinesFinder do end end - # Scoping to running will speed up the test as it doesn't hit the FS - let(:params) { { scope: 'running' } } + # Scoping to pending will speed up the test as it doesn't hit the FS + let(:params) { { scope: 'pending' } } it 'orders in descending order on ID' do feature_pipeline = create(:ci_pipeline, project: project, ref: 'feature') From 32b59a1fa7f439cccbf0de29094c3fab3ec518a8 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Sat, 18 Feb 2017 11:47:56 +1100 Subject: [PATCH 053/247] Added specs --- spec/features/issuables/issuable_list_spec.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index e31bc40adc3..13ea9ce853c 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -30,6 +30,12 @@ describe 'issuable list', feature: true do end end + it "counts merge requests closing issues icons for each issue" do + visit_issuable_list(:issue) + + expect(first('.icon-merge-request-unmerged').find(:xpath, '..')).to have_content(1) + end + def visit_issuable_list(issuable_type) if issuable_type == :issue visit namespace_project_issues_path(project.namespace, project) @@ -42,6 +48,13 @@ describe 'issuable list', feature: true do 3.times do if issuable_type == :issue issuable = create(:issue, project: project, author: user) + merge_request = create(:merge_request, + title: FFaker::Lorem.sentence, + description: "Closes #{issuable.to_reference}", + source_project: project, + source_branch: FFaker::Name.name) + + MergeRequestsClosingIssues.create!(issue: issuable, merge_request: merge_request) else issuable = create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) end From c21df05066a3a9351db649ebc3f00f4bee63cce8 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Sat, 18 Feb 2017 11:49:13 +1100 Subject: [PATCH 054/247] Remove empty line in note --- app/views/projects/notes/_note.html.haml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index a68a09baf4f..1b08165c14c 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -63,7 +63,6 @@ = icon('pencil', class: 'link-highlight') = link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button js-note-delete danger' do = icon('trash-o', class: 'danger-highlight') - .note-body{ class: note_editable ? 'js-task-list-container' : '' } .note-text.md = preserve do From 24ba7585e6da5ee8881ff8b4db53558940cb0c23 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Sat, 18 Feb 2017 12:58:24 +1100 Subject: [PATCH 055/247] Fixed rubocop offenses --- spec/features/issuables/issuable_list_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index 13ea9ce853c..ce4dca1175f 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -30,11 +30,11 @@ describe 'issuable list', feature: true do end end - it "counts merge requests closing issues icons for each issue" do - visit_issuable_list(:issue) + it "counts merge requests closing issues icons for each issue" do + visit_issuable_list(:issue) - expect(first('.icon-merge-request-unmerged').find(:xpath, '..')).to have_content(1) - end + expect(first('.icon-merge-request-unmerged').find(:xpath, '..')).to have_content(1) + end def visit_issuable_list(issuable_type) if issuable_type == :issue From d38fb942e188021d7def5eb577a73c82b8e5e66d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Feb 2017 21:08:47 +0800 Subject: [PATCH 056/247] Optimize Ci::Pipeline.latest query Since we already know which ref we want, we could filter it out first. Feedback: https://gitlab.com/gitlab-org/gitlab-ce/issues/26570#note_23423376 Closes #26570 --- app/models/ci/pipeline.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index dc4590a9923..2a987bfa87b 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -91,6 +91,7 @@ module Ci scope :latest, ->(ref = nil) do max_id = unscope(:select) .select("max(#{quoted_table_name}.id)") + .where(ref: ref) .group(:ref, :sha) relation = ref ? where(ref: ref) : self From 3750b06b8cdc02bc87eba27dd8e4ab5f1f24802f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Feb 2017 22:17:42 +0800 Subject: [PATCH 057/247] Consider the case where we don't specify ref for pipeline --- app/models/ci/pipeline.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 2a987bfa87b..6e89b18aee5 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -91,11 +91,13 @@ module Ci scope :latest, ->(ref = nil) do max_id = unscope(:select) .select("max(#{quoted_table_name}.id)") - .where(ref: ref) .group(:ref, :sha) - relation = ref ? where(ref: ref) : self - relation.where(id: max_id) + if ref + where(ref: ref, id: max_id.where(ref: ref)) + else + where(id: max_id) + end end def self.latest_status(ref = nil) From 22d6f96cf982765fa9b957905248a573c6e3c498 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Feb 2017 22:19:24 +0800 Subject: [PATCH 058/247] Add index for ci_commits for gl_project_id, ref, status and remove the old one which we don't really need. --- ...6135621_add_index_for_latest_successful_pipeline.rb | 10 ++++++++++ ...70216141440_drop_index_for_builds_project_status.rb | 8 ++++++++ db/schema.rb | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb create mode 100644 db/migrate/20170216141440_drop_index_for_builds_project_status.rb diff --git a/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb b/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb new file mode 100644 index 00000000000..7b1e687977b --- /dev/null +++ b/db/migrate/20170216135621_add_index_for_latest_successful_pipeline.rb @@ -0,0 +1,10 @@ +class AddIndexForLatestSuccessfulPipeline < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + DOWNTIME = false + + disable_ddl_transaction! + + def change + add_concurrent_index(:ci_commits, [:gl_project_id, :ref, :status]) + end +end diff --git a/db/migrate/20170216141440_drop_index_for_builds_project_status.rb b/db/migrate/20170216141440_drop_index_for_builds_project_status.rb new file mode 100644 index 00000000000..906711b9f3f --- /dev/null +++ b/db/migrate/20170216141440_drop_index_for_builds_project_status.rb @@ -0,0 +1,8 @@ +class DropIndexForBuildsProjectStatus < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + DOWNTIME = false + + def change + remove_index(:ci_commits, [:gl_project_id, :status]) + end +end diff --git a/db/schema.rb b/db/schema.rb index e0208dab3d3..6be017e66b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170215200045) do +ActiveRecord::Schema.define(version: 20170216141440) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -251,8 +251,8 @@ ActiveRecord::Schema.define(version: 20170215200045) do t.integer "lock_version" end + add_index "ci_commits", ["gl_project_id", "ref", "status"], name: "index_ci_commits_on_gl_project_id_and_ref_and_status", using: :btree add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree - add_index "ci_commits", ["gl_project_id", "status"], name: "index_ci_commits_on_gl_project_id_and_status", using: :btree add_index "ci_commits", ["gl_project_id"], name: "index_ci_commits_on_gl_project_id", using: :btree add_index "ci_commits", ["status"], name: "index_ci_commits_on_status", using: :btree add_index "ci_commits", ["user_id"], name: "index_ci_commits_on_user_id", using: :btree From b2f1c2b8be610695cf0523ae93524a1f53831c44 Mon Sep 17 00:00:00 2001 From: Rudi Kramer Date: Mon, 20 Feb 2017 11:14:40 +0000 Subject: [PATCH 059/247] Update two_factor_authentication.md by correcting FreeOTP link. --- doc/user/profile/account/two_factor_authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md index a23ad79ae1d..eaa39a0c4ea 100644 --- a/doc/user/profile/account/two_factor_authentication.md +++ b/doc/user/profile/account/two_factor_authentication.md @@ -213,5 +213,5 @@ your GitLab server's time is synchronized via a service like NTP. Otherwise, you may have cases where authorization always fails because of time differences. [Google Authenticator]: https://support.google.com/accounts/answer/1066447?hl=en -[FreeOTP]: https://fedorahosted.org/freeotp/ +[FreeOTP]: https://freeotp.github.io/ [YubiKey]: https://www.yubico.com/products/yubikey-hardware/ From cd04235efe4dd20accc9c7e1567fe5ccf95f7780 Mon Sep 17 00:00:00 2001 From: dimitrieh Date: Mon, 20 Feb 2017 12:20:49 +0100 Subject: [PATCH 060/247] Rename retry failed button on pipeline page to just retry --- app/views/projects/pipelines/_info.html.haml | 2 +- .../unreleased/rename-retry-failed-pipeline-to-retry.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index e0c972aa2fb..59e50d25460 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -8,7 +8,7 @@ .header-action-buttons - if can?(current_user, :update_pipeline, @pipeline.project) - if @pipeline.retryable? - = link_to "Retry failed", retry_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), class: 'btn btn-inverted-secondary', method: :post + = link_to "Retry", retry_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), class: 'btn btn-inverted-secondary', method: :post - if @pipeline.cancelable? = link_to "Cancel running", cancel_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post diff --git a/changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml b/changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml new file mode 100644 index 00000000000..b813127b1e6 --- /dev/null +++ b/changelogs/unreleased/rename-retry-failed-pipeline-to-retry.yml @@ -0,0 +1,4 @@ +--- +title: Rename retry failed button on pipeline page to just retry +merge_request: +author: From 8cbf27af2b1efaf5bbe605c846ecc16b72ab7536 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 17 Feb 2017 16:50:58 +0000 Subject: [PATCH 061/247] Changes when loading indicator is added to dropdown Previously it was added when you started typing. But there is actually a delay before sending any requests which meant the loading icon was visible but it wasn't actually loading anything --- app/assets/javascripts/gl_dropdown.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index bf3da8528f0..f18711557bd 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -47,9 +47,10 @@ } // Only filter asynchronously only if option remote is set if (this.options.remote) { - $inputContainer.parent().addClass('is-loading'); clearTimeout(timeout); return timeout = setTimeout(function() { + $inputContainer.parent().addClass('is-loading'); + return this.options.query(this.input.val(), function(data) { $inputContainer.parent().removeClass('is-loading'); return this.options.callback(data); From e4067c57ab6b835cbb077b2d9651b071ff45c886 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Feb 2017 10:28:45 +0000 Subject: [PATCH 062/247] Fixed ref switcher tests --- spec/features/projects/ref_switcher_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb index 4eafac1acd8..3b8f0b2d3f8 100644 --- a/spec/features/projects/ref_switcher_spec.rb +++ b/spec/features/projects/ref_switcher_spec.rb @@ -20,6 +20,8 @@ feature 'Ref switcher', feature: true, js: true do input.set 'binary' wait_for_ajax + expect(find('.dropdown-content ul')).to have_selector('li', count: 6) + page.within '.dropdown-content ul' do input.native.send_keys :enter end From a308e60757ee0e504ea7c2cacba77c3af1055b13 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 20 Feb 2017 08:13:37 -0500 Subject: [PATCH 063/247] Truncate long title text on Todo items --- app/assets/stylesheets/pages/todos.scss | 44 ++++++++++++++++--- app/views/dashboard/todos/_todo.html.haml | 17 ++++--- ...group-names-overflow-out-of-todos-view.yml | 4 ++ 3 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index 551a66fbf3a..bac831ec315 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -43,6 +43,12 @@ } } + .todo-avatar, + .todo-actions { + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + } + .todo-actions { display: -webkit-flex; display: flex; @@ -55,8 +61,9 @@ } .todo-item { - -webkit-flex: auto; - flex: auto; + -webkit-flex: 0 1 100%; + flex: 0 1 100%; + min-width: 0; } } @@ -74,8 +81,29 @@ .todo-item { .todo-title { - @include str-truncated(calc(100% - 174px)); - overflow: visible; + display: flex; + + & > .title-item { + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + margin: 0 2px; + + &:first-child { + margin-left: 0; + } + + &:last-child { + margin-right: 0; + } + } + + .todo-label { + -webkit-flex: 0 1 auto; + flex: 0 1 auto; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } } .status-box { @@ -154,10 +182,12 @@ .todo-item { .todo-title { - white-space: normal; - overflow: visible; - max-width: 100%; + flex-flow: row wrap; margin-bottom: 10px; + + .todo-label { + white-space: normal; + } } .todo-body { diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index dc2d924f212..a3993d5ef16 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -1,28 +1,33 @@ %li{ class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo), data: { url: todo_target_path(todo) } } - = author_avatar(todo, size: 40) + .todo-avatar + = author_avatar(todo, size: 40) .todo-item.todo-block .todo-title.title - unless todo.build_failed? || todo.unmergeable? = todo_target_state_pill(todo) - %span.author-name + .title-item.author-name - if todo.author = link_to_author(todo) - else (removed) - %span.action-name + .title-item.action-name = todo_action_name(todo) - %span.todo-label + .title-item.todo-label - if todo.target = todo_target_link(todo) - else (removed) - · #{time_ago_with_tooltip(todo.created_at)} - = todo_due_date(todo) + .title-item + · + + .title-item + #{time_ago_with_tooltip(todo.created_at)} + = todo_due_date(todo) .todo-body .todo-note diff --git a/changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml b/changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml new file mode 100644 index 00000000000..3bcf0e06d08 --- /dev/null +++ b/changelogs/unreleased/28186-long-group-names-overflow-out-of-todos-view.yml @@ -0,0 +1,4 @@ +--- +title: Truncate long Todo titles for non-mobile screens +merge_request: 9311 +author: From 95ed01749e0ffe55a979acb246ca8e0ae663bffb Mon Sep 17 00:00:00 2001 From: Jan Christophersen Date: Sat, 11 Feb 2017 20:15:01 +0100 Subject: [PATCH 064/247] Add AsciiDoc snippet for CI/CD Badges This commit adds CI/CD Badges Snippets for AsciiDoc as requested in #26087. I've however run into an issue in highlighting the snippet, it seems as if AsciiDoc is currently not being highlighted properly (displayed as plaintext) Add testcase for to_asciidoc Update test case for Badges list --- app/views/projects/pipelines_settings/_badge.html.haml | 7 +++++++ .../unreleased/26087-asciidoc-cicd-badges-snippet.yml | 4 ++++ lib/gitlab/badge/metadata.rb | 4 ++++ spec/features/projects/badges/list_spec.rb | 6 ++++-- spec/lib/gitlab/badge/shared/metadata.rb | 10 ++++++++++ 5 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml diff --git a/app/views/projects/pipelines_settings/_badge.html.haml b/app/views/projects/pipelines_settings/_badge.html.haml index 22a3b884520..43bbd735059 100644 --- a/app/views/projects/pipelines_settings/_badge.html.haml +++ b/app/views/projects/pipelines_settings/_badge.html.haml @@ -25,3 +25,10 @@ HTML .col-md-10.code.js-syntax-highlight = highlight('.html', badge.to_html) + .row + %hr + .row + .col-md-2.text-center + AsciiDoc + .col-md-10.code.js-syntax-highlight + = highlight('.adoc', badge.to_asciidoc) diff --git a/changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml b/changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml new file mode 100644 index 00000000000..799c5277207 --- /dev/null +++ b/changelogs/unreleased/26087-asciidoc-cicd-badges-snippet.yml @@ -0,0 +1,4 @@ +--- +title: Added AsciiDoc Snippet to CI/CD Badges +merge_request: 9164 +author: Jan Christophersen diff --git a/lib/gitlab/badge/metadata.rb b/lib/gitlab/badge/metadata.rb index 548f85b78bb..4a049ef758d 100644 --- a/lib/gitlab/badge/metadata.rb +++ b/lib/gitlab/badge/metadata.rb @@ -20,6 +20,10 @@ module Gitlab "[![#{title}](#{image_url})](#{link_url})" end + def to_asciidoc + "image:#{image_url}[link=\"#{link_url}\",title=\"#{title}\"]" + end + def title raise NotImplementedError end diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb index 67a4a5d1ab1..ae9db0c0d6e 100644 --- a/spec/features/projects/badges/list_spec.rb +++ b/spec/features/projects/badges/list_spec.rb @@ -14,7 +14,8 @@ feature 'list of badges' do expect(page).to have_content 'build status' expect(page).to have_content 'Markdown' expect(page).to have_content 'HTML' - expect(page).to have_css('.highlight', count: 2) + expect(page).to have_content 'AsciiDoc' + expect(page).to have_css('.highlight', count: 3) expect(page).to have_xpath("//img[@alt='build status']") page.within('.highlight', match: :first) do @@ -28,7 +29,8 @@ feature 'list of badges' do expect(page).to have_content 'coverage report' expect(page).to have_content 'Markdown' expect(page).to have_content 'HTML' - expect(page).to have_css('.highlight', count: 2) + expect(page).to have_content 'AsciiDoc' + expect(page).to have_css('.highlight', count: 3) expect(page).to have_xpath("//img[@alt='coverage report']") page.within('.highlight', match: :first) do diff --git a/spec/lib/gitlab/badge/shared/metadata.rb b/spec/lib/gitlab/badge/shared/metadata.rb index 0cf18514251..63c7ca5a915 100644 --- a/spec/lib/gitlab/badge/shared/metadata.rb +++ b/spec/lib/gitlab/badge/shared/metadata.rb @@ -18,4 +18,14 @@ shared_examples 'badge metadata' do it { is_expected.to include metadata.image_url } it { is_expected.to include metadata.link_url } end + + describe '#to_asciidoc' do + subject { metadata.to_asciidoc } + + it { is_expected.to include metadata.image_url } + it { is_expected.to include metadata.link_url } + it { is_expected.to include 'image:' } + it { is_expected.to include 'link=' } + it { is_expected.to include 'title=' } + end end From b86640fee90a7bc7b752b0d66ac7310dd9673b23 Mon Sep 17 00:00:00 2001 From: dimitrieh Date: Mon, 20 Feb 2017 17:08:29 +0100 Subject: [PATCH 065/247] fixed specs + docs --- app/views/projects/commit/_pipeline.html.haml | 2 +- doc/api/pipelines.md | 2 +- lib/api/pipelines.rb | 4 ++-- spec/features/commits_spec.rb | 4 ++-- spec/features/projects/pipelines/pipeline_spec.rb | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 6abff6aaf95..754bcb95ddb 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -3,7 +3,7 @@ .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) - = link_to "Retry failed", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post + = link_to "Retry", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post - if pipeline.builds.running_or_pending.any? = link_to "Cancel running", cancel_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md index 82351ae688f..f3c9827f742 100644 --- a/doc/api/pipelines.md +++ b/doc/api/pipelines.md @@ -163,7 +163,7 @@ Example of response } ``` -## Retry failed builds in a pipeline +## Retry builds in a pipeline > [Introduced][ce-5837] in GitLab 8.11 diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index b634b1d0222..f59f7959173 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -23,7 +23,7 @@ module API pipelines = PipelinesFinder.new(user_project).execute(scope: params[:scope]) present paginate(pipelines), with: Entities::Pipeline end - + desc 'Create a new pipeline' do detail 'This feature was introduced in GitLab 8.14' success Entities::Pipeline @@ -58,7 +58,7 @@ module API present pipeline, with: Entities::Pipeline end - desc 'Retry failed builds in the pipeline' do + desc 'Retry builds in the pipeline' do detail 'This feature was introduced in GitLab 8.11.' success Entities::Pipeline end diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index 8f561c8f90b..324ede798fe 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -153,7 +153,7 @@ describe 'Commits' do expect(page).to have_content pipeline.git_author_name expect(page).to have_link('Download artifacts') expect(page).not_to have_link('Cancel running') - expect(page).not_to have_link('Retry failed') + expect(page).not_to have_link('Retry') end end @@ -172,7 +172,7 @@ describe 'Commits' do expect(page).to have_content pipeline.git_author_name expect(page).not_to have_link('Download artifacts') expect(page).not_to have_link('Cancel running') - expect(page).not_to have_link('Retry failed') + expect(page).not_to have_link('Retry') end end end diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 0b5ccc8c515..e457a935d91 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -54,7 +54,7 @@ describe 'Pipeline', :feature, :js do expect(page).to have_content('Build') expect(page).to have_content('Test') expect(page).to have_content('Deploy') - expect(page).to have_content('Retry failed') + expect(page).to have_content('Retry') expect(page).to have_content('Cancel running') end @@ -164,9 +164,9 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { click_on 'Retry failed' } + before { click_on 'Retry' } - it { expect(page).not_to have_content('Retry failed') } + it { expect(page).not_to have_content('Retry') } end end @@ -198,7 +198,7 @@ describe 'Pipeline', :feature, :js do expect(page).to have_content(build_failed.id) expect(page).to have_content(build_running.id) expect(page).to have_content(build_external.id) - expect(page).to have_content('Retry failed') + expect(page).to have_content('Retry') expect(page).to have_content('Cancel running') expect(page).to have_link('Play') end @@ -226,9 +226,9 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { click_on 'Retry failed' } + before { click_on 'Retry' } - it { expect(page).not_to have_content('Retry failed') } + it { expect(page).not_to have_content('Retry') } it { expect(page).to have_selector('.retried') } end end From e23c803769955d6728ed048112f8ca21e9b58a47 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 4 Feb 2017 00:14:17 -0800 Subject: [PATCH 066/247] Add user deletion permission check in `Users::DestroyService` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We saw from a recent incident that the `Users::DestroyService` would attempt to delete a user over and over. Revoking the permissions from the current user did not help. We should ensure that the current user does, in fact, have permissions to delete the user. Signed-off-by: Rémy Coutable --- app/services/users/destroy_service.rb | 4 +++ app/workers/delete_user_worker.rb | 2 ++ .../sh-delete-user-permission-check.yml | 4 +++ spec/services/users/destroy_spec.rb | 31 ++++++++++++++++--- 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/sh-delete-user-permission-check.yml diff --git a/app/services/users/destroy_service.rb b/app/services/users/destroy_service.rb index 2d11305be13..bc0653cb634 100644 --- a/app/services/users/destroy_service.rb +++ b/app/services/users/destroy_service.rb @@ -7,6 +7,10 @@ module Users end def execute(user, options = {}) + unless current_user.admin? || current_user == user + raise Gitlab::Access::AccessDeniedError, "#{current_user} tried to destroy user #{user}!" + end + if !options[:delete_solo_owned_groups] && user.solo_owned_groups.present? user.errors[:base] << 'You must transfer ownership or delete groups before you can remove user' return user diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb index 5483bbb210b..3340a7be4fe 100644 --- a/app/workers/delete_user_worker.rb +++ b/app/workers/delete_user_worker.rb @@ -7,5 +7,7 @@ class DeleteUserWorker current_user = User.find(current_user_id) Users::DestroyService.new(current_user).execute(delete_user, options.symbolize_keys) + rescue Gitlab::Access::AccessDeniedError => e + Rails.logger.warn("User could not be destroyed: #{e}") end end diff --git a/changelogs/unreleased/sh-delete-user-permission-check.yml b/changelogs/unreleased/sh-delete-user-permission-check.yml new file mode 100644 index 00000000000..c0e79aae2a8 --- /dev/null +++ b/changelogs/unreleased/sh-delete-user-permission-check.yml @@ -0,0 +1,4 @@ +--- +title: Add user deletion permission check in `Users::DestroyService` +merge_request: +author: diff --git a/spec/services/users/destroy_spec.rb b/spec/services/users/destroy_spec.rb index 46e58393218..c0bf27c698c 100644 --- a/spec/services/users/destroy_spec.rb +++ b/spec/services/users/destroy_spec.rb @@ -2,11 +2,11 @@ require 'spec_helper' describe Users::DestroyService, services: true do describe "Deletes a user and all their personal projects" do - let!(:user) { create(:user) } - let!(:current_user) { create(:user) } - let!(:namespace) { create(:namespace, owner: user) } - let!(:project) { create(:project, namespace: namespace) } - let(:service) { described_class.new(current_user) } + let!(:user) { create(:user) } + let!(:admin) { create(:admin) } + let!(:namespace) { create(:namespace, owner: user) } + let!(:project) { create(:project, namespace: namespace) } + let(:service) { described_class.new(admin) } context 'no options are given' do it 'deletes the user' do @@ -57,5 +57,26 @@ describe Users::DestroyService, services: true do expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound) end end + + context "deletion permission checks" do + it 'does not delete the user when user is not an admin' do + other_user = create(:user) + + expect { described_class.new(other_user).execute(user) }.to raise_error(Gitlab::Access::AccessDeniedError) + expect(User.exists?(user.id)).to be(true) + end + + it 'allows admins to delete anyone' do + described_class.new(admin).execute(user) + + expect(User.exists?(user.id)).to be(false) + end + + it 'allows users to delete their own account' do + described_class.new(user).execute(user) + + expect(User.exists?(user.id)).to be(false) + end + end end end From e49d55e96116deebcd757c5d833b679918a38127 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Mon, 20 Feb 2017 17:37:50 +0100 Subject: [PATCH 067/247] Use newer mail_room to get `require_relative` support --- Gemfile | 2 +- Gemfile.lock | 4 ++-- config/mail_room.yml | 5 +---- spec/config/mail_room_spec.rb | 4 ++-- spec/fixtures/{ => config}/mail_room_disabled.yml | 0 spec/fixtures/{ => config}/mail_room_enabled.yml | 0 6 files changed, 6 insertions(+), 9 deletions(-) rename spec/fixtures/{ => config}/mail_room_disabled.yml (100%) rename spec/fixtures/{ => config}/mail_room_enabled.yml (100%) diff --git a/Gemfile b/Gemfile index 0060f122512..4ad8d63512f 100644 --- a/Gemfile +++ b/Gemfile @@ -333,7 +333,7 @@ gem 'newrelic_rpm', '~> 3.16' gem 'octokit', '~> 4.6.2' -gem 'mail_room', '~> 0.9.0' +gem 'mail_room', '~> 0.9.1' gem 'email_reply_trimmer', '~> 0.1' gem 'html2text' diff --git a/Gemfile.lock b/Gemfile.lock index a3c2fad41ba..da6bc7388e9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -409,7 +409,7 @@ GEM nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) - mail_room (0.9.0) + mail_room (0.9.1) memoist (0.15.0) method_source (0.8.2) mime-types (2.99.3) @@ -912,7 +912,7 @@ DEPENDENCIES license_finder (~> 2.1.0) licensee (~> 8.0.0) loofah (~> 2.0.3) - mail_room (~> 0.9.0) + mail_room (~> 0.9.1) method_source (~> 0.8) minitest (~> 5.7.0) mousetrap-rails (~> 1.4.6) diff --git a/config/mail_room.yml b/config/mail_room.yml index 774c5350a45..88d93d4bc6b 100644 --- a/config/mail_room.yml +++ b/config/mail_room.yml @@ -1,9 +1,6 @@ -# If you change this file in a Merge Request, please also create -# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests -# :mailboxes: <% - require_relative "lib/gitlab/mail_room" unless defined?(Gitlab::MailRoom) + require_relative "../lib/gitlab/mail_room" unless defined?(Gitlab::MailRoom) config = Gitlab::MailRoom.config if Gitlab::MailRoom.enabled? diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb index 294fae95752..0b8ff006d22 100644 --- a/spec/config/mail_room_spec.rb +++ b/spec/config/mail_room_spec.rb @@ -8,7 +8,7 @@ describe 'mail_room.yml' do context 'when incoming email is disabled' do before do - ENV['MAIL_ROOM_GITLAB_CONFIG_FILE'] = Rails.root.join('spec/fixtures/mail_room_disabled.yml').to_s + ENV['MAIL_ROOM_GITLAB_CONFIG_FILE'] = Rails.root.join('spec/fixtures/config/mail_room_disabled.yml').to_s Gitlab::MailRoom.reset_config! end @@ -26,7 +26,7 @@ describe 'mail_room.yml' do let(:gitlab_redis) { Gitlab::Redis.new(Rails.env) } before do - ENV['MAIL_ROOM_GITLAB_CONFIG_FILE'] = Rails.root.join('spec/fixtures/mail_room_enabled.yml').to_s + ENV['MAIL_ROOM_GITLAB_CONFIG_FILE'] = Rails.root.join('spec/fixtures/config/mail_room_enabled.yml').to_s Gitlab::MailRoom.reset_config! end diff --git a/spec/fixtures/mail_room_disabled.yml b/spec/fixtures/config/mail_room_disabled.yml similarity index 100% rename from spec/fixtures/mail_room_disabled.yml rename to spec/fixtures/config/mail_room_disabled.yml diff --git a/spec/fixtures/mail_room_enabled.yml b/spec/fixtures/config/mail_room_enabled.yml similarity index 100% rename from spec/fixtures/mail_room_enabled.yml rename to spec/fixtures/config/mail_room_enabled.yml From 3c20a6478c5b2586ccc5f0fd23fac578a89bc37f Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Feb 2017 16:38:52 +0000 Subject: [PATCH 068/247] Fixed eslint error --- app/assets/javascripts/gl_dropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index f18711557bd..a01662e2f9e 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -50,7 +50,7 @@ clearTimeout(timeout); return timeout = setTimeout(function() { $inputContainer.parent().addClass('is-loading'); - + return this.options.query(this.input.val(), function(data) { $inputContainer.parent().removeClass('is-loading'); return this.options.callback(data); From 9d7615d04e0e4fc2fd8da69be482877dd9cd7349 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Mon, 20 Feb 2017 17:47:29 +0100 Subject: [PATCH 069/247] Changelog --- changelogs/unreleased/1363-redo-mailroom-support.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/unreleased/1363-redo-mailroom-support.yml diff --git a/changelogs/unreleased/1363-redo-mailroom-support.yml b/changelogs/unreleased/1363-redo-mailroom-support.yml new file mode 100644 index 00000000000..8ed206f4fdb --- /dev/null +++ b/changelogs/unreleased/1363-redo-mailroom-support.yml @@ -0,0 +1,4 @@ +--- +title: Redo internals of Incoming Mail Support +merge_request: 9385 +author: From 6c373e718161da77fa1ec02065307641f6e55003 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 15:19:19 -0300 Subject: [PATCH 070/247] add index file to Pages docs --- doc/pages/index.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 doc/pages/index.md diff --git a/doc/pages/index.md b/doc/pages/index.md new file mode 100644 index 00000000000..3590cf5cfb1 --- /dev/null +++ b/doc/pages/index.md @@ -0,0 +1,39 @@ +# All you need to know about GitLab Pages + +## Product + +- [Product Webpage](https://pages.gitlab.io) +- [We're Bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/) +- [Pages Group - Templates](https://gitlab.com/pages) + +## Getting Started + +- Comprehensive Step-by-Step Guide: [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) +- GitLab Pages from A to Z + - [Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](https://gitlab.com/marcia/drafts/blob/master/pages/pages_part-1.md) + - [Part 2: Quick Start Guide - Setting Up GitLab Pages](https://gitlab.com/marcia/drafts/blob/master/pages/pages_part-2.md) + - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from a forked project](#LINK) + - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from scratch](#LINK) + - [Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](#LINK) +- Secure GitLab Pages Custom Domain with SSL/TLS Certificates + - [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) + - [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) + - [StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/) +- Static Site Generators - Blog Posts Series + - [SSGs Part 1: Static vs Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) + - [SSGs Part 2: Modern Static Site Generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) + - [SSGs Part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) +- [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/) + +## Advanced Use + +- Blog Posts: + - [GitLab CI: Run jobs Sequentially, in Parallel, or Build a Custom Pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/) + - [GitLab CI: Deployment & Environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/) + - [Building a new GitLab Docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) + - [Publish Code Coverage Report with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/) + +## General Documentation + +- [User docs](../user/project/pages/) +- [Admin docs](administration.html) From a2b7f8d1410bf97772a03c38df1396cce795b983 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 16:14:48 -0300 Subject: [PATCH 071/247] add pages guide part 1 - static sites, domains, DNS, SSL/TLS --- doc/pages/index.md | 2 +- ...omains_dns_records_ssl_tls_certificates.md | 159 ++++++++++++++++++ 2 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md diff --git a/doc/pages/index.md b/doc/pages/index.md index 3590cf5cfb1..c3dd08b46a7 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -10,7 +10,7 @@ - Comprehensive Step-by-Step Guide: [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) - GitLab Pages from A to Z - - [Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](https://gitlab.com/marcia/drafts/blob/master/pages/pages_part-1.md) + - [Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html) - [Part 2: Quick Start Guide - Setting Up GitLab Pages](https://gitlab.com/marcia/drafts/blob/master/pages/pages_part-2.md) - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from a forked project](#LINK) - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from scratch](#LINK) diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md new file mode 100644 index 00000000000..f76e02471e9 --- /dev/null +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -0,0 +1,159 @@ +# GitLab Pages from A to Z + +> Type: user guide +> +> Level: beginner + +- **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates** +- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ +- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ + +---- + +This is a comprehensive guide, made for those who want to publish a website with GitLab Pages but aren't familiar with the entire process involved. + +To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), or watch this [video tutorial](#LINK). + +> For this guide, we assume you already have GitLab Pages server up and running for your GitLab instance. + +## What you need to know before getting started + +Before we begin, let's understand a few concepts first. + +### Static Sites + +GitLab Pages only supports static websites, meaning, your output files must be HTML, CSS, and JavaScript only. + +To create your static site, you can either hardcode in HTML, CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/) to simplify your code and build the static site for you, which is highly recommendable and much faster than hardcoding. + +#### Further Reading + +- Read through this technical overview on [Static versus Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) +- Understand [how modern Static Site Generators work](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) and what you can add to your static site +- You can use [any SSG with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) +- Fork an [example project](https://gitlab.com/pages) to build your website based upon + +### GitLab Pages Domain + +If you set up a GitLab Pages project on GitLab.com, it will automatically be accessible under a [subdomain of `.pages.io`](https://docs.gitlab.com/ce/user/project/pages/). The `` is defined by your username on GitLab.com, or the group name you created this project under. + +> Note: If you use your own GitLab instance to deploy your site with GitLab Pages, check with your sysadmin what's your Pages wildcard domain. This guide is valid for any GitLab instance, you just need to replace Pages wildcard domain on GitLab.com (`*.gitlab.io`) with your own. + +#### Practical examples + +**Project Websites:** + +- You created a project called `blog` under your username `john`, therefore your project URL is `https://gitlab.com/john/blog/`. Once you enable GitLab Pages for this project, and build your site, it will be available under `https://john.gitlab.io/blog/`. +- You created a group for all your websites called `websites`, and a project within this group is called `blog`. Your project URL is `https://gitlab.com/websites/blog/`. Once you enable GitLab Pages for this project, the site will live under `https://websites.gitlab.io/blog/`. + +**User and Group Websites:** + +- Under your username, `john`, you created a project called `john.gitlab.io`. Your project URL will be `https://gitlab.com/john/john.gitlab.io`. Once you enable GitLab Pages for your project, your website will be published under `https://john.gitlab.io`. +- Under your group `websites`, you created a project called `websites.gitlab.io`. your project's URL will be `https://gitlab.com/websites/websites.gitlab.io`. Once you enable GitLab Pages for your project, your website will be published under `https://websites.gitlab.io`. + +**General example:** + +- On GitLab.com, a project site will always be available under `https://namespace.gitlab.io/project-name` +- On GitLab.com, a user or group website will be available under `https://namespace.gitlab.io/` +- On your GitLab instance, replace `gitlab.io` above with your Pages server domain. Ask your sysadmin for this information. + +### DNS Records + +A Domain Name System (DNS) web service routes visitors to websites by translating domain names (such as `www.example.com`) into the numeric IP addresses (such as `192.0.2.1`) that computers use to connect to each other. + +A DNS record is created to point a (sub)domain to a certain location, which can be an IP address or another domain. In case you want to use GitLab Pages with your own (sub)domain, you need to access your domain's registrar control panel to add a DNS record pointing it back to your GitLab Pages site. + +Note that **how to** add DNS records depends on which server your domain is hosted on. Every control panel has its own place to do it. If you are not an admin of your domain, and don't have access to your registrar, you'll need to ask for the technical support of your hosting service to do it for you. + +To help you out, we've gathered some instructions on how to do that for the most popular hosting services: + +- [Amazon](http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-configure-route53.html) +- [Bluehost](https://my.bluehost.com/cgi/help/559) +- [CloudFlare](https://support.cloudflare.com/hc/en-us/articles/200169096-How-do-I-add-A-records-) +- [cPanel](https://documentation.cpanel.net/display/ALD/Edit+DNS+Zone) +- [DreamHost](https://help.dreamhost.com/hc/en-us/articles/215414867-How-do-I-add-custom-DNS-records-) +- [Go Daddy](https://www.godaddy.com/help/add-an-a-record-19238) +- [Hostgator](http://support.hostgator.com/articles/changing-dns-records) +- [Inmotion hosting](https://my.bluehost.com/cgi/help/559) +- [Media Temple](https://mediatemple.net/community/products/dv/204403794/how-can-i-change-the-dns-records-for-my-domain) +- [Microsoft](https://msdn.microsoft.com/en-us/library/bb727018.aspx) + +If your hosting service is not listed above, you can just try to search the web for "how to add dns record on ". + +#### DNS A record + +In case you want to point a root domain (`example.com`) to your GitLab Pages site, deployed to `namespace.gitlab.io`, you need to log into your domain's admin control panel and add a DNS `A` record pointing your domain to Pages' server IP address. For projects on GitLab.com, this IP is `104.208.235.32`. For projects leaving in other GitLab instances (CE or EE), please contact your sysadmin asking for this information (which IP address is Pages server running on your instance). + +**Practical Example:** + +![DNS A record pointing to GitLab.com Pages server]() + +#### DNS CNAME record + +In case you want to point a subdomain (`hello-world.example.com`) to your GitLab Pages site initially deployed to `namespace.gitlab.io`, you need to log into your domain's admin control panel and add a DNS `CNAME` record pointing your subdomain to your website URL (`namespace.gitlab.io`) address. + +Notice that, despite it's a user or project website, the `CNAME` should point to your Pages domain (`namespace.gitlab.io`), without any `/project-name`. + +**Practical Example:** + +![DNS CNAME record pointing to GitLab.com project]() + +#### TL;DR + +| From | DNS Record | To | +| ---- | ---------- | -- | +| domain.com | A | 104.208.235.32 | +| subdomain.domain.com | CNAME | namespace.gitlab.io | + +> **Notes**: +> +> - **Do not** use a CNAME record if you want to point your `domain.com` to your GitLab Pages site. Use an `A` record instead. +> - **Do not** add any special chars after the default Pages domain. E.g., **do not** point your `subdomain.domain.com` to `namespace.gitlab.io.` or `namespace.gitlab.io/`. + +### SSL/TLS Certificates + +Every GitLab Pages project on GitLab.com will be available under HTTPS for the default Pages domain (`*.gitlab.io`). Once you set up your Pages project with your custom (sub)domain, if you want it secured by HTTPS, you will have to issue a certificate for that (sub)domain and install it on your project. + +> Note: certificates are NOT required to add to your custom (sub)domain on your GitLab Pages project, though they are highly recommendable. + +The importance of having any website securely served under HTTPS is explained on the introductory section of the blog post [Secure GitLab Pages with StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/#https-a-quick-overview). + +The reason why certificates are so important is that they encrypt the connection between the **client** (you, me, your visitors) and the **server** (where you site lives), through a keychain of authentications and validations. + +### Issuing Certificates + +GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by [Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority) and self-signed certificates. Of course, [you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate), for security reasons and for having browsers trusting your site's certificate. + +There are several different kinds of certificates, each one with certain security level. A static personal website will not require the same security level as an online banking web app, for instance. There are a couple Certificate Authorities that offer free certificates, aiming to make the internet more secure to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/), which issues certificates trusted by most of browsers, it's open source, and free to use. Please read through this tutorial to understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/). + +With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/), which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/). Their certs are valid up to 15 years. Read through the tutorial on [how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/). + +### Adding certificates to your project + +Regardless the CA you choose, the steps to add your certificate to your Pages project are the same. + +#### What do you need + +1. A PEM certificate +1. An intermediary certificate +1. A public key + +![Pages project - adding certificates]() + +These fields are found under your **Project**'s **Settings** > **Pages** > **New Domain**. + +#### What's what? + +- A PEM certificate is the certificate generated by the CA, which needs to be added to the field **Certificate (PEM)**. +- An [intermediary certificate][] (aka "root certificate") is the part of the encryption keychain that identifies the CA. Usually it's combined with the PEM certificate, but there are some cases in which you need to add them manually. [CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) are one of these cases. +- A public key is an encrypted key which validates your PEM against your domain. + +#### Now what? + +Now that you hopefully understand why you need all of this, it's simple: + +- Your PEM certificate needs to be added to the first field +- If your certificate is missing its intermediary, copy and paste the root certificate (usually available from your CA website) and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/), just jumping a line between them. +- Copy your public key and paste it in the last field + +> Note: **do not** open certificates or encryption keys in regular text editors. Always use code editors (such as Sublime Text, Atom, Dreamweaver, Brackets, etc). From abb668f1e4ad82cd44d0d6c175a9dbee23e98f64 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 20 Feb 2017 13:54:29 -0600 Subject: [PATCH 072/247] remove require.context from boards_bundle --- .../javascripts/boards/boards_bundle.js.es6 | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6 index 878ad1b6031..f6b75ac6196 100644 --- a/app/assets/javascripts/boards/boards_bundle.js.es6 +++ b/app/assets/javascripts/boards/boards_bundle.js.es6 @@ -2,15 +2,19 @@ /* global Vue */ /* global BoardService */ -function requireAll(context) { return context.keys().map(context); } - window.Vue = require('vue'); window.Vue.use(require('vue-resource')); -requireAll(require.context('./models', true, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./stores', true, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./services', true, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./mixins', true, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./filters', true, /^\.\/.*\.(js|es6)$/)); +require('./models/issue'); +require('./models/label'); +require('./models/list'); +require('./models/milestone'); +require('./models/user'); +require('./stores/boards_store'); +require('./stores/modal_store'); +require('./services/board_service'); +require('./mixins/modal_mixins'); +require('./mixins/sortable_default_options'); +require('./filters/due_date_filters'); require('./components/board'); require('./components/board_sidebar'); require('./components/new_list_dropdown'); From 6d9edfa60bf3f3fbf0aa7cb8c4dd9755effcdeef Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 17:03:22 -0300 Subject: [PATCH 073/247] add closing section: further reading --- ...tatic_sites_domains_dns_records_ssl_tls_certificates.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index f76e02471e9..797e7d28469 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -1,4 +1,4 @@ -# GitLab Pages from A to Z +# GitLab Pages from A to Z: Part 1 > Type: user guide > @@ -157,3 +157,8 @@ Now that you hopefully understand why you need all of this, it's simple: - Copy your public key and paste it in the last field > Note: **do not** open certificates or encryption keys in regular text editors. Always use code editors (such as Sublime Text, Atom, Dreamweaver, Brackets, etc). + +## Further Reading + +- Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ +- Read through GitLab Pages from A to Z _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ From 41e36f2c0fc21a63bdc51383bbc3be03cb3497cf Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 20 Feb 2017 14:04:02 -0600 Subject: [PATCH 074/247] remove require.context from cycle_analytics_bundle --- .../cycle_analytics_bundle.js.es6 | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 index 1ac715aab77..411ac7b24b2 100644 --- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 +++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 @@ -4,10 +4,20 @@ window.Vue = require('vue'); window.Cookies = require('js-cookie'); - -function requireAll(context) { return context.keys().map(context); } -requireAll(require.context('./svg', false, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('.', true, /^\.\/(?!cycle_analytics_bundle).*\.(js|es6)$/)); +require('./svg/icon_branch'); +require('./svg/icon_build_status'); +require('./svg/icon_commit'); +require('./components/stage_code_component'); +require('./components/stage_issue_component'); +require('./components/stage_plan_component'); +require('./components/stage_production_component'); +require('./components/stage_review_component'); +require('./components/stage_staging_component'); +require('./components/stage_test_component'); +require('./components/total_time_component'); +require('./cycle_analytics_service'); +require('./cycle_analytics_store'); +require('./default_event_objects'); $(() => { const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed'; From dec96c248d44b8f6f5615b7bcdb2ce9ad63ff32a Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 20 Feb 2017 14:11:43 -0600 Subject: [PATCH 075/247] remove unneeded eslint exceptions --- app/assets/javascripts/boards/boards_bundle.js.es6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6 index f6b75ac6196..0c5177ced2f 100644 --- a/app/assets/javascripts/boards/boards_bundle.js.es6 +++ b/app/assets/javascripts/boards/boards_bundle.js.es6 @@ -1,4 +1,4 @@ -/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren, import/newline-after-import, no-multi-spaces, max-len */ +/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren */ /* global Vue */ /* global BoardService */ From 0aa685658319d837c090def9604cc2fba1dd5cf5 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 17:13:45 -0300 Subject: [PATCH 076/247] add part 2: quick start guide --- doc/pages/pages_quick_start_guide.md | 112 +++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 doc/pages/pages_quick_start_guide.md diff --git a/doc/pages/pages_quick_start_guide.md b/doc/pages/pages_quick_start_guide.md new file mode 100644 index 00000000000..804b34a8e75 --- /dev/null +++ b/doc/pages/pages_quick_start_guide.md @@ -0,0 +1,112 @@ +# GitLab Pages from A to Z: Part 2 + +> Type: user guide +> +> Level: beginner + +- **Part 2: Quick Start Guide - Setting Up GitLab Pages** +- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ +- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ + +---- + +## Setting Up GitLab Pages + +For a complete step-by-step tutorial, please read the blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain what do you need and why do you need them. + + + +### What You Need to Get Started + +1. A project +1. A configuration file (`.gitlab-ci.yml`) to deploy your site +1. A specific `job` called `pages` in the configuration file that will make GitLab aware that you are deploying a GitLab Pages website + +#### Optional Features + +1. A custom domain or subdomain +1. A DNS pointing your (sub)domain to your Pages site + 1. **Optional**: an SSL/TLS certificate so your custom domain is accessible under HTTPS. + +### Project + +Your GitLab Pages project is a regular project created the same way you do for the other ones. To get started with GitLab Pages, you have two ways: + +- Fork one of the templates from Page Examples, or +- Create a new project from scratch + +Let's go over both options. + +#### Fork a Project to Get Started From + +To make things easy for you, we've created this [group](https://gitlab.com/pages) of default projects containing the most popular SSGs templates. + +Watch the [video tutorial](#LINK) we've created for the steps below. + +1. Choose your SSG template +1. Fork a project from the [Pages group](https://gitlab.com/pages) +1. Remove the fork relationship by navigating to your **Project**'s **Settings** > **Edit Project** + + ![remove fork relashionship]() + +1. Enable Shared Runners for your fork: navigate to your **Project**'s **Settings** > **CI/CD Pipelines** +1. Trigger a build (push a change to any file) +1. As soon as the build passes, your website will have been deployed with GitLab Pages. Your website URL will be available under your **Project**'s **Settings** > **Pages** + +To turn a **project website** forked from the Pages group into a **user/group** website, you'll need to: + +- Rename it to `namespace.gitlab.io`: navigate to **Project**'s **Settings** > **Edit Project** > **Rename repository** +- Adjust your SSG's [base URL](#urls-and-baseurls) to from `"project-name"` to `""`. This setting will be at a different place for each SSG, as each of them have their own structure and file tree. Most likelly, it will be in the SSG's config file. + +> **Notes:** +> +>1. Why do I need to remove the fork relationship? +> +> Unless you want to contribute to the original project, you won't need it connected to the upstream. A [fork](https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/#fork) is useful for submitting merge requests to the upstream. +> +> 2. Why do I need to enable Shared Runners? +> +> Shared Runners will run the script set by your GitLab CI configuration file. They're enabled by default to new projects, but not to forks. + +#### Create a Project from Scratch + +1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, click **New project**, and name it considering the [examples above](#practical-examples). +1. Clone it to your local computer, add your website files to your project, add, commit and push to GitLab. +1. From the your **Project**'s page, click **Set up CI**: + + ![add new file]() + +1. Choose one of the templates from the dropbox menu. Pick up the template corresponding to the SSG you're using (or plain HTML). + + ![gitlab-ci templates]() + +Once you have both site files and `.gitlab-ci.yml` in your project's root, GitLab CI will build your site and deploy it with Pages. Once the first build passes, you see your site is live by navigating to your **Project**'s **Settings** > **Pages**, where you'll find its default URL. + +> **Notes:** +> +> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but, if you don't find yours among the templates, you'll need to configure your own `.gitlab-ci.yml`. Do do that, please read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html). New SSGs are very welcome among the [example projects](https://gitlab.com/pages). If you set up a new one, please [contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md) to our examples. +> +> - The second step _"Clone it to your local computer"_, can be done differently, achieving the same results: instead of cloning the bare repository to you local computer and moving your site files into it, you can run `git init` in your local website directory, add the remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`, then add, commit, and push. + +### URLs and Baseurls + + + +Every Static Site Generator (SSG) default configuration expects to find your website under a (sub)domain (`example.com`), not in a subdirectory of that domain (`example.com/subdir`). Therefore, whenever you publish a project website (`namespace.gitlab.io/project-name`), you'll have to look for this configuration (base URL) on your SSG's documentation and set it up to reflect this pattern. + +For example, for a Jekyll site, the `baseurl` is defined in the Jekyll configuration file, `_config.yml`. If your website URL is `https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`: + +```yaml +baseurl: "/blog" +``` + +On the contrary, if you deploy your website after forking one of our [default examples](https://gitlab.com/pages), the baseurl will already be configured this way, as all examples there are project websites. If you decide to make yours a user or group website, you'll have to remove this configuration from your project. For the Jekyll example we've just mentioned, you'd have to change Jekyll's `_config.yml` to: + +```yaml +baseurl: "" +``` + +## Further Reading + +- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ +- Read through _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ From 8ba08213a16aaa9d00b5d7df308212550d90d28e Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 20 Feb 2017 14:29:09 -0600 Subject: [PATCH 077/247] remove require.context from diff_notes_bundle --- .../diff_notes/diff_notes_bundle.js.es6 | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 b/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 index 190461451d5..cadf8b96b87 100644 --- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 +++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 @@ -1,14 +1,18 @@ -/* eslint-disable func-names, comma-dangle, new-cap, no-new, import/newline-after-import, no-multi-spaces, max-len */ +/* eslint-disable func-names, comma-dangle, new-cap, no-new, max-len */ /* global Vue */ /* global ResolveCount */ -function requireAll(context) { return context.keys().map(context); } const Vue = require('vue'); -requireAll(require.context('./models', false, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./stores', false, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./services', false, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./mixins', false, /^\.\/.*\.(js|es6)$/)); -requireAll(require.context('./components', false, /^\.\/.*\.(js|es6)$/)); +require('./models/discussion'); +require('./models/note'); +require('./stores/comments'); +require('./services/resolve'); +require('./mixins/discussion'); +require('./components/comment_resolve_btn'); +require('./components/jump_to_discussion'); +require('./components/resolve_btn'); +require('./components/resolve_count'); +require('./components/resolve_discussion_btn'); $(() => { const projectPath = document.querySelector('.merge-request').dataset.projectPath; From 2a7e2a6447842a0ab152a791b93fe7b980bc7973 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 17:34:54 -0300 Subject: [PATCH 078/247] fix links --- doc/pages/pages_quick_start_guide.md | 4 ++-- ...s_static_sites_domains_dns_records_ssl_tls_certificates.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/pages/pages_quick_start_guide.md b/doc/pages/pages_quick_start_guide.md index 804b34a8e75..f7b0c3c9520 100644 --- a/doc/pages/pages_quick_start_guide.md +++ b/doc/pages/pages_quick_start_guide.md @@ -6,7 +6,7 @@ - **Part 2: Quick Start Guide - Setting Up GitLab Pages** - _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ -- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ +- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ ---- @@ -109,4 +109,4 @@ baseurl: "" ## Further Reading - Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ -- Read through _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ +- Read through _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index 797e7d28469..bb6268bacb9 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -6,7 +6,7 @@ - **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates** - _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ -- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ +- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ ---- @@ -161,4 +161,4 @@ Now that you hopefully understand why you need all of this, it's simple: ## Further Reading - Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ -- Read through GitLab Pages from A to Z _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html)_ +- Read through GitLab Pages from A to Z _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ From 0b1636daf69fc5eea8dfc5f9cd6426c84ee5e3db Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 17:35:31 -0300 Subject: [PATCH 079/247] add part 3: creating and tweaking CI for Pages --- doc/pages/index.md | 4 +- .../pages_creating_and_tweaking_gitlab-ci.md | 279 ++++++++++++++++++ 2 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 doc/pages/pages_creating_and_tweaking_gitlab-ci.md diff --git a/doc/pages/index.md b/doc/pages/index.md index c3dd08b46a7..047fe0477cf 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -11,10 +11,10 @@ - Comprehensive Step-by-Step Guide: [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) - GitLab Pages from A to Z - [Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html) - - [Part 2: Quick Start Guide - Setting Up GitLab Pages](https://gitlab.com/marcia/drafts/blob/master/pages/pages_part-2.md) + - [Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html) - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from a forked project](#LINK) - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from scratch](#LINK) - - [Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](#LINK) + - [Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html) - Secure GitLab Pages Custom Domain with SSL/TLS Certificates - [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) - [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) diff --git a/doc/pages/pages_creating_and_tweaking_gitlab-ci.md b/doc/pages/pages_creating_and_tweaking_gitlab-ci.md new file mode 100644 index 00000000000..8e1877c4981 --- /dev/null +++ b/doc/pages/pages_creating_and_tweaking_gitlab-ci.md @@ -0,0 +1,279 @@ +# GitLab Pages from A to Z: Part 3 + +> Type: user guide +> +> Level: intermediate + +- **Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages** +- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ +- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ + +---- + +### Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages + +[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves inumerous purposes, to build, test, and deploy your app from GitLab through [Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) methods. You will need it to build your website with GitLab Pages, and deploy it to the Pages server. + +What this file actually does is telling the [GitLab Runner](https://docs.gitlab.com/runner/) to run scripts as you would do from the command line. The Runner acts as your terminal. GitLab CI tells the Runner which commands to run. Both are built-in in GitLab, and you don't need to set up anything for them to work. + +Explaining [every detail of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) and GitLab Runner is out of the scope of this guide, but we'll need to understand just a few things to be able to write our own `.gitlab-ci.yml` or tweak an existing one. It's an [Yaml](http://docs.ansible.com/ansible/YAMLSyntax.html) file, with its own syntax. You can always check your CI syntax with the [GitLab CI Lint Tool](https://gitlab.com/ci/lint). + +**Practical Example:** + +Let's consider you have a [Jekyll](https://jekyllrb.com/) site. To build it locally, you would open your terminal, and run `jekyll build`. Of course, before building it, you had to install Jekyll in your computer. For that, you had to open your terminal and run `gem install jekyll`. Right? GitLab CI + GitLab Runner do the same thing. But you need to write in the `.gitlab-ci.yml` the script you want to run so the GitLab Runner will do it for you. It looks more complicated then it is. What you need to tell the Runner: + +``` +$ gem install jekyll +$ jekyll build +``` + +#### Script + +To transpose this script to Yaml, it would be like this: + +```yaml +script: + - gem install jekyll + - jekyll build +``` + +#### Job + +So far so good. Now, each `script`, in GitLab is organized by a `job`, which is a bunch of scripts and settings you want to apply to that specific task. + +```yaml +job: + script: + - gem install jekyll + - jekyll build +``` + +For GitLab Pages, this `job` has a specific name, called `pages`, which tells the Runner you want that task to deploy your website with GitLab Pages: + +```yaml +pages: + script: + - gem install jekyll + - jekyll build +``` + +#### `public` Dir + +We also need to tell Jekyll where do you want the website to build, and GitLab Pages will only consider files in a directory called `public`. To do that with Jekyll, we need to add a flag specifying the [destination (`-d`)](https://jekyllrb.com/docs/usage/) of the built website: `jekyll build -d public`. Of course, we need to tell this to our Runner: + +```yaml +pages: + script: + - gem install jekyll + - jekyll build -d public +``` + +#### Artifacts + +We also need to tell the Runner that this _job_ generates _artifacts_, which is the site built by Jekyll. Where are these artifacts stored? In the `public` directory: + +```yaml +pages: + script: + - gem install jekyll + - jekyll build -d public + artifacts: + paths: + - public +``` + +The script above would be enough to build your Jekyll site with GitLab Pages. But, from Jekyll 3.4.0 on, its default template originated by `jekyll new project` requires [Bundler](http://bundler.io/) to install Jekyll dependencies and the default theme. To adjust our script to meet these new requirements, we only need to install and build Jekyll with Bundler: + +```yaml +pages: + script: + - bundle install + - bundle exec jekyll build -d public + artifacts: + paths: + - public +``` + +That's it! A `.gitlab-ci.yml` with the content above would deploy your Jekyll 3.4.0 site with GitLab Pages. This is the minimum configuration for our example. On the steps below, we'll refine the script by adding extra options to our GitLab CI. + +#### Image + +At this point, you probably ask yourself: "okay, but to install Jekyll I need Ruby. Where is Ruby on that script?". The answer is simple: the first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a [Docker](https://www.docker.com/) image specifying what do you need in your container to run that script: + +```yaml +image: ruby:2.3 + +pages: + script: + - bundle install + - bundle exec jekyll build -d public + artifacts: + paths: + - public +``` + +In this case, you're telling the Runner to pull this image, which contains Ruby 2.3 as part of its file system. When you don't specify this image in your configuration, the Runner will use a default image, which is Ruby 2.1. + +If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll need to specify which image you want to use, and this image should contain NodeJS as part of its file system. E.g., for a [Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`. + +> Note: we're not trying to explain what a Docker image is, we just need to introduce the concept with a minimum viable explanation. To know more about Docker images, please visit their website or take a look at a [summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here. + +Let's go a little further. + +#### Branching + +If you use GitLab as a version control platform, you will have your branching strategy to work on your project. Meaning, you will have other branches in your project, but you'll want only pushes to the default branch (usually `master`) to be deployed to your website. To do that, we need to add another line to our CI, telling the Runner to only perform that _job_ called `pages` on the `master` branch `only`: + +```yaml +image: ruby:2.3 + +pages: + script: + - bundle install + - bundle exec jekyll build -d public + artifacts: + paths: + - public + only: + - master +``` + +#### Stages + +Another interesting concept to keep in mind are build stages. Your web app can pass through a lot of tests and other tasks until it's deployed to staging or production environments. There are three default stages on GitLab CI: build, test, and deploy. To specify which stage your _job_ is running, simply add another line to your CI: + +```yaml +image: ruby:2.3 + +pages: + stage: deploy + script: + - bundle install + - bundle exec jekyll build -d public + artifacts: + paths: + - public + only: + - master +``` + +You might ask yourself: "why should I bother with stages at all?" Well, let's say you want to be able to test your script and check the built site before deploying your site to production. You want to run the test exactly as your script will do when you push to `master`. It's simple, let's add another task (_job_) to our CI, telling it to test every push to other branches, `except` the `master` branch: + +```yaml +image: ruby:2.3 + +pages: + stage: deploy + script: + - bundle install + - bundle exec jekyll build -d public + artifacts: + paths: + - public + only: + - master + +test: + stage: test + script: + - bundle install + - bundle exec jekyll build -d test + artifacts: + paths: + - test + except: + - master +``` + +The `test` job is running on the stage `test`, Jekyll will build the site in a directory called `test`, and this job will affect all the branches except `master`. + +The best benefit of applying _stages_ to different _jobs_ is that every job in the same stage builds in parallel. So, if your web app needs more than one test before being deployed, you can run all your test at the same time, it's not necessary to wait on test to finish to run the other. Of course, this is just a brief introduction of GitLab CI and GitLab Runner, which are tools much more powerful than that. This is what you need to be able to create and tweak your builds for your GitLab Pages site. + +#### Before Script + +To avoid running the same script multiple times across your _jobs_, you can add the parameter `before_script`, in which you specify which commands you want to run for every single _job_. In our example, notice that we run `bundle install` for both jobs, `pages` and `test`. We don't need to repeat it: + +```yaml +image: ruby:2.3 + +before_script: + - bundle install + +pages: + stage: deploy + script: + - bundle exec jekyll build -d public + artifacts: + paths: + - public + only: + - master + +test: + stage: test + script: + - bundle exec jekyll build -d test + artifacts: + paths: + - test + except: + - master +``` + +#### Caching Dependencies + +If you want to cache the installation files for your projects dependencies, for building faster, you can use the parameter `cache`. For this example, we'll cache Jekyll dependencies in a `vendor` directory when we run `bundle install`: + +```yaml +image: ruby:2.3 + +cache: + paths: + - vendor/ + +before_script: + - bundle install --path vendor + +pages: + stage: deploy + script: + - bundle exec jekyll build -d public + artifacts: + paths: + - public + only: + - master + +test: + stage: test + script: + - bundle exec jekyll build -d test + artifacts: + paths: + - test + except: + - master +``` + +For this specific case, we need to exclude `/vendor` from Jekyll `_config.yml` file, otherwise Jekyll will understand it as a regular directory to build together with the site: + +```yml +exclude: + - vendor +``` + +There we go! Now our GitLab CI not only builds our website, but also **continuously test** pushes to feature-branches, **caches** dependencies installed with Bundler, and **continuously deploy** every push to the `master` branch. + +### Advanced GitLab CI for GitLab Pages + +What you can do with GitLab CI is pretty much up to your creativity. Once you get used to it, you start creating awesome scripts that automate most of tasks you'd do manually in the past. Read through the [documentation of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) to understand how to go even further on your scripts. + +- On this blog post, understand the concept of [using GitLab CI `environments` to deploy your web app to staging and production](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/). +- On this post, learn [how to run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/) +- On this blog post, we go through the process of [pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) to deploy this website you're looking at, docs.gitlab.com. +- On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/). + +## Further Reading + +- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ +- Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ From 625fc65b98a7c346afa7aa689566af33c02ff799 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 19:01:05 -0300 Subject: [PATCH 080/247] add link to Matija's video --- ...ges_static_sites_domains_dns_records_ssl_tls_certificates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index bb6268bacb9..56ad4805eda 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -12,7 +12,7 @@ This is a comprehensive guide, made for those who want to publish a website with GitLab Pages but aren't familiar with the entire process involved. -To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), or watch this [video tutorial](#LINK). +To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), or watch this [video tutorial](https://youtu.be/b_qjiabYhmQ). > For this guide, we assume you already have GitLab Pages server up and running for your GitLab instance. From cac59408a58a8c6d2c3ce4fa5a27161a186b5ed5 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 20 Feb 2017 15:01:56 -0600 Subject: [PATCH 081/247] add production asset compile step to CI config --- .gitlab-ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 433b3119fba..becf2db85fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -240,6 +240,18 @@ rake db:seed_fu: paths: - log/development.log +rake gitlab:assets:compile: + stage: test + <<: *dedicated-runner + dependencies: [] + variables: + NODE_ENV: "production" + RAILS_ENV: "production" + SETUP_DB: "false" + USE_DB: "false" + SKIP_STORAGE_VALIDATION: "true" + script: bundle exec rake yarn:install gitlab:assets:compile + rake karma: cache: paths: From 9e631b6a9116ed40084d1a0a733cb43efc85251f Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Tue, 21 Feb 2017 00:57:23 +0000 Subject: [PATCH 082/247] Update GitLab CE/EE comparison & subscribe links in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f85fac4a56..09e08adbb73 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ We're hiring developers, support people, and production engineers all the time, There are two editions of GitLab: - GitLab Community Edition (CE) is available freely under the MIT Expat license. -- GitLab Enterprise Edition (EE) includes [extra features](https://about.gitlab.com/features/#compare) that are more useful for organizations with more than 100 users. To use EE and get official support please [become a subscriber](https://about.gitlab.com/pricing/). +- GitLab Enterprise Edition (EE) includes [extra features](https://about.gitlab.com/products/#compare-options) that are more useful for organizations with more than 100 users. To use EE and get official support please [become a subscriber](https://about.gitlab.com/products/). ## Website From 2a12cbe6d6d5c7c78c6fac64e7d5a6af6742462a Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Tue, 21 Feb 2017 12:07:50 +1100 Subject: [PATCH 083/247] Improved specs --- spec/features/issuables/issuable_list_spec.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index ce4dca1175f..4ea801cd1ac 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -33,6 +33,7 @@ describe 'issuable list', feature: true do it "counts merge requests closing issues icons for each issue" do visit_issuable_list(:issue) + expect(page).to have_selector('.icon-merge-request-unmerged', count: 1) expect(first('.icon-merge-request-unmerged').find(:xpath, '..')).to have_content(1) end @@ -48,13 +49,6 @@ describe 'issuable list', feature: true do 3.times do if issuable_type == :issue issuable = create(:issue, project: project, author: user) - merge_request = create(:merge_request, - title: FFaker::Lorem.sentence, - description: "Closes #{issuable.to_reference}", - source_project: project, - source_branch: FFaker::Name.name) - - MergeRequestsClosingIssues.create!(issue: issuable, merge_request: merge_request) else issuable = create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) end @@ -65,6 +59,16 @@ describe 'issuable list', feature: true do create(:award_emoji, :downvote, awardable: issuable) create(:award_emoji, :upvote, awardable: issuable) + + if issuable_type == :issue + issue = Issue.reorder(:iid).first + merge_request = create(:merge_request, + title: FFaker::Lorem.sentence, + source_project: project, + source_branch: FFaker::Name.name) + + MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) if MergeRequestsClosingIssues.count.zero? + end end end end From 1eb72a71f54da310b2277e5890dce27c15e11036 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Tue, 21 Feb 2017 12:45:08 +1100 Subject: [PATCH 084/247] Refactored count_for_collection() for using pluck instead of select --- app/controllers/concerns/issuable_collections.rb | 4 ++-- app/models/merge_requests_closing_issues.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index d7d781cbe72..85ae4985e58 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -28,13 +28,13 @@ module IssuableCollections downvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.downvote? } upvotes = issuable_votes_count.find { |votes| votes.awardable_id == id && votes.upvote? } notes = issuable_note_count.find { |notes| notes.noteable_id == id } - merge_requests = issuable_merge_requests_count.find { |mr| mr.issue_id == id } + merge_requests = issuable_merge_requests_count.find { |mr| mr.first == id } issuable_meta[id] = Issuable::IssuableMeta.new( upvotes.try(:count).to_i, downvotes.try(:count).to_i, notes.try(:count).to_i, - merge_requests.try(:count).to_i + merge_requests.try(:last).to_i ) end end diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index 1ecdfd1dfdb..97210900bd5 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -7,9 +7,9 @@ class MergeRequestsClosingIssues < ActiveRecord::Base class << self def count_for_collection(ids) - select('issue_id', 'COUNT(*) as count'). - group(:issue_id). - where(issue_id: ids) + group(:issue_id). + where(issue_id: ids). + pluck('issue_id', 'COUNT(*) as count') end end end From 2807cafe41de14d343f1c97edecd2e531e0f1fd2 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 23:05:52 -0300 Subject: [PATCH 085/247] add video tutorial - Pages admin --- doc/pages/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/pages/index.md b/doc/pages/index.md index 047fe0477cf..11b2582841f 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -37,3 +37,4 @@ - [User docs](../user/project/pages/) - [Admin docs](administration.html) + - Video tutorial - [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s) From b90a1656e486deddb29dbc4bbfce3f663f7484bc Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Mon, 20 Feb 2017 23:06:00 -0300 Subject: [PATCH 086/247] update link --- ...ges_static_sites_domains_dns_records_ssl_tls_certificates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index 56ad4805eda..1a4e798df66 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -12,7 +12,7 @@ This is a comprehensive guide, made for those who want to publish a website with GitLab Pages but aren't familiar with the entire process involved. -To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), or watch this [video tutorial](https://youtu.be/b_qjiabYhmQ). +To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s). > For this guide, we assume you already have GitLab Pages server up and running for your GitLab instance. From 7e648110ed09bd12e1d405fbeba8dcb0590de602 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 10 Feb 2017 16:13:13 +0000 Subject: [PATCH 087/247] Added tooltip to add issues button on issue boards Closes #27985 --- .../javascripts/boards/boards_bundle.js.es6 | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6 index 878ad1b6031..d194dc9b188 100644 --- a/app/assets/javascripts/boards/boards_bundle.js.es6 +++ b/app/assets/javascripts/boards/boards_bundle.js.es6 @@ -93,17 +93,53 @@ $(() => { modal: ModalStore.store, store: Store.state, }, + watch: { + disabled() { + this.updateTooltip(); + }, + }, computed: { disabled() { return !this.store.lists.filter(list => list.type !== 'blank' && list.type !== 'done').length; }, + tooltipTitle() { + if (this.disabled) { + return 'Please add a list to your board first'; + } + + return ''; + }, + }, + methods: { + updateTooltip() { + const $tooltip = $(this.$el); + + this.$nextTick(() => { + if (this.disabled) { + $tooltip.tooltip(); + } else { + $tooltip.tooltip('destroy'); + } + }); + }, + openModal() { + if (!this.disabled) { + this.toggleModal(true); + } + }, + }, + mounted() { + this.updateTooltip(); }, template: ` `, From 216d3ad7cba15016ffd038645fe0db0d91ce84f3 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 10 Feb 2017 16:19:00 +0000 Subject: [PATCH 088/247] Added CHANGELOG --- changelogs/unreleased/add-issues-tooltip.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/unreleased/add-issues-tooltip.yml diff --git a/changelogs/unreleased/add-issues-tooltip.yml b/changelogs/unreleased/add-issues-tooltip.yml new file mode 100644 index 00000000000..58adb6c6b5a --- /dev/null +++ b/changelogs/unreleased/add-issues-tooltip.yml @@ -0,0 +1,4 @@ +--- +title: Disabled tooltip on add issues button in usse boards +merge_request: +author: From 8ed25c80003b327b359079d600f7207db46846b4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 10 Feb 2017 16:38:11 +0000 Subject: [PATCH 089/247] Added tests --- spec/features/boards/add_issues_modal_spec.rb | 6 ++++++ spec/features/boards/boards_spec.rb | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index 2875fc1e533..a3e24bb5ffa 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -49,6 +49,12 @@ describe 'Issue Boards add issue modal', :feature, :js do expect(page).not_to have_selector('.add-issues-modal') end + + it 'does not show tooltip on add issues button' do + button = page.find('.issue-boards-search button', text: 'Add issues') + + expect(button[:title]).not_to eq("Please add a list to your board first") + end end context 'issues list' do diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 1b25b51cfb2..e247bfa2980 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -28,10 +28,10 @@ describe 'Issue Boards', feature: true, js: true do expect(page).to have_content('Welcome to your Issue Board!') end - it 'disables add issues button by default' do + it 'shows tooltip on add issues button' do button = page.find('.issue-boards-search button', text: 'Add issues') - expect(button[:disabled]).to eq true + expect(button[:"data-original-title"]).to eq("Please add a list to your board first") end it 'hides the blank state when clicking nevermind button' do From 0d29b08ca747439483336d24346425947903a523 Mon Sep 17 00:00:00 2001 From: dimitrieh Date: Tue, 21 Feb 2017 09:45:19 +0100 Subject: [PATCH 090/247] Changed coverage reg expression placeholder text to be more like a placeholder --- app/views/projects/pipelines_settings/_show.html.haml | 2 +- .../28389-ux-problem-with-pipeline-coverage-placeholder.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 8024fb8979d..9aef600dbaf 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -60,7 +60,7 @@ = f.label :build_coverage_regex, "Test coverage parsing", class: 'label-light' .input-group %span.input-group-addon / - = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered' + = f.text_field :build_coverage_regex, class: 'form-control', placeholder: 'REGULAR_EXPRESSION' %span.input-group-addon / %p.help-block A regular expression that will be used to find the test coverage diff --git a/changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml b/changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml new file mode 100644 index 00000000000..ed357d86fe3 --- /dev/null +++ b/changelogs/unreleased/28389-ux-problem-with-pipeline-coverage-placeholder.yml @@ -0,0 +1,4 @@ +--- +title: Changed coverage reg expression placeholder text to be more like a placeholder +merge_request: +author: From 1eb238901b4e3e2f1f9dd1c841e29846630b1278 Mon Sep 17 00:00:00 2001 From: dimitrieh Date: Tue, 21 Feb 2017 10:00:27 +0100 Subject: [PATCH 091/247] changed changelog text to be normal case --- app/views/projects/pipelines_settings/_show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 9aef600dbaf..132f6372e40 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -60,7 +60,7 @@ = f.label :build_coverage_regex, "Test coverage parsing", class: 'label-light' .input-group %span.input-group-addon / - = f.text_field :build_coverage_regex, class: 'form-control', placeholder: 'REGULAR_EXPRESSION' + = f.text_field :build_coverage_regex, class: 'form-control', placeholder: 'Regular expression' %span.input-group-addon / %p.help-block A regular expression that will be used to find the test coverage From 1f244284284607946b2758c4e9ef26559cd8d71c Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 21 Feb 2017 17:08:35 +0800 Subject: [PATCH 092/247] Fix build attributes test, see: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9021#note_23782188 This is discovered by https://gitlab.com/gitlab-org/gitlab-ce/builds/10815456 I removed `gl_project_id` and this is failing. I took some look, realizing that: * `trace` is duplicated in `attributes` * `tag_list` is not included in `build.attributes` * `artifacts_expire_at` is missing in `attributes` So we need to: * Remove duplicated `trace` in `attributes` (40 -> 39) * Remove `tag_list` in `attributes` (39 -> 38) * Add `artifacts_expire_at` to `attributes` (38 -> 39) * Add `gl_project_id` to `attributes` (39 -> 40) --- app/services/ci/retry_build_service.rb | 7 ++++--- spec/services/ci/retry_build_service_spec.rb | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index 4b47ee489cf..4ce9cabeda3 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -1,16 +1,17 @@ module Ci class RetryBuildService < ::BaseService - CLONE_ATTRIBUTES = %i[pipeline ref tag options commands tag_list name + CLONE_ATTRIBUTES = %i[pipeline ref tag options commands name allow_failure stage stage_idx trigger_request yaml_variables when environment coverage_regex] .freeze REJECT_ATTRIBUTES = %i[id status user token coverage trace runner - artifacts_file artifacts_metadata artifacts_size + artifacts_expire_at artifacts_file + artifacts_metadata artifacts_size created_at updated_at started_at finished_at queued_at erased_by erased_at].freeze - IGNORE_ATTRIBUTES = %i[trace type lock_version project target_url + IGNORE_ATTRIBUTES = %i[type lock_version project gl_project_id target_url deploy job_id description].freeze def execute(build) diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index 93147870afe..d03f7505eac 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -12,7 +12,7 @@ describe Ci::RetryBuildService, :services do shared_examples 'build duplication' do let(:build) do - create(:ci_build, :failed, :artifacts, :erased, :trace, + create(:ci_build, :failed, :artifacts_expired, :erased, :trace, :queued, :coverage, pipeline: pipeline) end @@ -38,7 +38,7 @@ describe Ci::RetryBuildService, :services do described_class::IGNORE_ATTRIBUTES + described_class::REJECT_ATTRIBUTES - expect(attributes.size).to eq build.attributes.size + expect(build.attributes.size).to eq(attributes.size) end end From 9caefa50e7d22d8d1c4fb8726f0cd81db6ef1da1 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 21 Feb 2017 10:11:53 +0000 Subject: [PATCH 093/247] Fix the commit search UI Closes https://gitlab.com/gitlab-org/gitlab-ee/issues/1765 --- app/views/search/_results.html.haml | 2 +- changelogs/unreleased/commit-search-ui-fix.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/commit-search-ui-fix.yml diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 7fe2bce3e7c..22004ecacbc 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -11,7 +11,7 @@ .results.prepend-top-10 - if @scope == 'commits' - %ul.list-unstyled + %ul.content-list.commit-list.table-list.table-wide = render partial: "search/results/commit", collection: @search_objects - else .search-results diff --git a/changelogs/unreleased/commit-search-ui-fix.yml b/changelogs/unreleased/commit-search-ui-fix.yml new file mode 100644 index 00000000000..4a5c2cf6090 --- /dev/null +++ b/changelogs/unreleased/commit-search-ui-fix.yml @@ -0,0 +1,4 @@ +--- +title: Fixed commit search UI +merge_request: +author: From 9e6b2c5dd4a1a58ca62650b6f529213bc730f64f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 21 Feb 2017 18:36:50 +0800 Subject: [PATCH 094/247] We actually want to clone project and remove gl_project_id in the future. Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9409#note_23859361 --- app/services/ci/retry_build_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index 4ce9cabeda3..38ef323f6e5 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -1,6 +1,6 @@ module Ci class RetryBuildService < ::BaseService - CLONE_ATTRIBUTES = %i[pipeline ref tag options commands name + CLONE_ATTRIBUTES = %i[pipeline project ref tag options commands name allow_failure stage stage_idx trigger_request yaml_variables when environment coverage_regex] .freeze @@ -11,7 +11,7 @@ module Ci created_at updated_at started_at finished_at queued_at erased_by erased_at].freeze - IGNORE_ATTRIBUTES = %i[type lock_version project gl_project_id target_url + IGNORE_ATTRIBUTES = %i[type lock_version gl_project_id target_url deploy job_id description].freeze def execute(build) From 1ef911f0e086badcb717c68cd1817c68ed8b4d8d Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 21 Feb 2017 10:00:33 +0100 Subject: [PATCH 095/247] API: Use POST requests to mark todos as done --- changelogs/unreleased/api-todos-restful.yml | 4 +++ doc/api/todos.md | 15 ++++-------- doc/api/v3_to_v4.md | 2 +- lib/api/todos.rb | 6 +++-- spec/requests/api/todos_spec.rb | 27 +++++++++++---------- 5 files changed, 28 insertions(+), 26 deletions(-) create mode 100644 changelogs/unreleased/api-todos-restful.yml diff --git a/changelogs/unreleased/api-todos-restful.yml b/changelogs/unreleased/api-todos-restful.yml new file mode 100644 index 00000000000..dba1350a495 --- /dev/null +++ b/changelogs/unreleased/api-todos-restful.yml @@ -0,0 +1,4 @@ +--- +title: 'API: Use POST requests to mark todos as done' +merge_request: 9410 +author: Robert Schilling diff --git a/doc/api/todos.md b/doc/api/todos.md index a5e81801024..a2fbbc7e1f8 100644 --- a/doc/api/todos.md +++ b/doc/api/todos.md @@ -184,7 +184,7 @@ Marks a single pending todo given by its ID for the current user as done. The todo marked as done is returned in the response. ``` -DELETE /todos/:id +POST /todos/:id/mark_as_done ``` Parameters: @@ -194,7 +194,7 @@ Parameters: | `id` | integer | yes | The ID of a todo | ```bash -curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/todos/130 +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/todos/130/mark_as_done ``` Example Response: @@ -277,20 +277,15 @@ Example Response: ## Mark all todos as done -Marks all pending todos for the current user as done. It returns the number of marked todos. +Marks all pending todos for the current user as done. It returns the HTTP status code `204` with an empty response. ``` -DELETE /todos +POST /todos/mark_as_done ``` ```bash -curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/todos +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/todos/donmark_as_donee ``` -Example Response: - -```json -3 -``` [ce-3188]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3188 diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index 3f58c098b43..1af124c56b1 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -24,9 +24,9 @@ changes are in V4: - `/gitlab_ci_ymls/:key` - `/dockerfiles/:key` - Moved `/projects/fork/:id` to `/projects/:id/fork` +- Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` - Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters - Return pagination headers for all endpoints that return an array - Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead - Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` - Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) - diff --git a/lib/api/todos.rb b/lib/api/todos.rb index 9bd077263a7..0b9650b296c 100644 --- a/lib/api/todos.rb +++ b/lib/api/todos.rb @@ -58,7 +58,7 @@ module API params do requires :id, type: Integer, desc: 'The ID of the todo being marked as done' end - delete ':id' do + post ':id/mark_as_done' do todo = current_user.todos.find(params[:id]) TodoService.new.mark_todos_as_done([todo], current_user) @@ -66,9 +66,11 @@ module API end desc 'Mark all todos as done' - delete do + post '/mark_as_done' do todos = find_todos TodoService.new.mark_todos_as_done(todos, current_user) + + no_content! end end end diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb index 2069d2a7c75..f35e963a14b 100644 --- a/spec/requests/api/todos_spec.rb +++ b/spec/requests/api/todos_spec.rb @@ -107,46 +107,47 @@ describe API::Todos, api: true do end end - describe 'DELETE /todos/:id' do + describe 'POST /todos/:id/mark_as_done' do context 'when unauthenticated' do it 'returns authentication error' do - delete api("/todos/#{pending_1.id}") + post api("/todos/#{pending_1.id}/mark_as_done") - expect(response.status).to eq(401) + expect(response).to have_http_status(401) end end context 'when authenticated' do it 'marks a todo as done' do - delete api("/todos/#{pending_1.id}", john_doe) + post api("/todos/#{pending_1.id}/mark_as_done", john_doe) - expect(response.status).to eq(200) + expect(response).to have_http_status(201) + expect(json_response['id']).to eq(pending_1.id) + expect(json_response['state']).to eq('done') expect(pending_1.reload).to be_done end it 'updates todos cache' do expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original - delete api("/todos/#{pending_1.id}", john_doe) + post api("/todos/#{pending_1.id}/mark_as_done", john_doe) end end end - describe 'DELETE /todos' do + describe 'POST /mark_as_done' do context 'when unauthenticated' do it 'returns authentication error' do - delete api('/todos') + post api('/todos/mark_as_done') - expect(response.status).to eq(401) + expect(response).to have_http_status(401) end end context 'when authenticated' do it 'marks all todos as done' do - delete api('/todos', john_doe) + post api('/todos/mark_as_done', john_doe) - expect(response.status).to eq(200) - expect(response.body).to eq('3') + expect(response).to have_http_status(204) expect(pending_1.reload).to be_done expect(pending_2.reload).to be_done expect(pending_3.reload).to be_done @@ -155,7 +156,7 @@ describe API::Todos, api: true do it 'updates todos cache' do expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original - delete api("/todos", john_doe) + post api("/todos/mark_as_done", john_doe) end end end From 32691ffd4a87e3492fa2d24d904602683bcf8ffb Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Tue, 21 Feb 2017 10:23:15 +0100 Subject: [PATCH 096/247] Backport Todos API to V3 --- lib/api/api.rb | 1 + lib/api/v3/todos.rb | 28 ++++++++++++ spec/requests/api/v3/todos_spec.rb | 73 ++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 lib/api/v3/todos.rb create mode 100644 spec/requests/api/v3/todos_spec.rb diff --git a/lib/api/api.rb b/lib/api/api.rb index dbb7271ccbd..e729c07f8c3 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -19,6 +19,7 @@ module API mount ::API::V3::Repositories mount ::API::V3::SystemHooks mount ::API::V3::Tags + mount ::API::V3::Todos mount ::API::V3::Templates mount ::API::V3::Users end diff --git a/lib/api/v3/todos.rb b/lib/api/v3/todos.rb new file mode 100644 index 00000000000..4f9b5fe72a6 --- /dev/null +++ b/lib/api/v3/todos.rb @@ -0,0 +1,28 @@ +module API + module V3 + class Todos < Grape::API + before { authenticate! } + + resource :todos do + desc 'Mark a todo as done' do + success ::API::Entities::Todo + end + params do + requires :id, type: Integer, desc: 'The ID of the todo being marked as done' + end + delete ':id' do + todo = current_user.todos.find(params[:id]) + TodoService.new.mark_todos_as_done([todo], current_user) + + present todo.reload, with: ::API::Entities::Todo, current_user: current_user + end + + desc 'Mark all todos as done' + delete do + todos = TodosFinder.new(current_user, params).execute + TodoService.new.mark_todos_as_done(todos, current_user) + end + end + end + end +end diff --git a/spec/requests/api/v3/todos_spec.rb b/spec/requests/api/v3/todos_spec.rb new file mode 100644 index 00000000000..80fa697e949 --- /dev/null +++ b/spec/requests/api/v3/todos_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe API::V3::Todos, api: true do + include ApiHelpers + + let(:project_1) { create(:empty_project) } + let(:project_2) { create(:empty_project) } + let(:author_1) { create(:user) } + let(:author_2) { create(:user) } + let(:john_doe) { create(:user, username: 'john_doe') } + let!(:pending_1) { create(:todo, :mentioned, project: project_1, author: author_1, user: john_doe) } + let!(:pending_2) { create(:todo, project: project_2, author: author_2, user: john_doe) } + let!(:pending_3) { create(:todo, project: project_1, author: author_2, user: john_doe) } + let!(:done) { create(:todo, :done, project: project_1, author: author_1, user: john_doe) } + + before do + project_1.team << [john_doe, :developer] + project_2.team << [john_doe, :developer] + end + + describe 'DELETE /todos/:id' do + context 'when unauthenticated' do + it 'returns authentication error' do + delete v3_api("/todos/#{pending_1.id}") + + expect(response.status).to eq(401) + end + end + + context 'when authenticated' do + it 'marks a todo as done' do + delete v3_api("/todos/#{pending_1.id}", john_doe) + + expect(response.status).to eq(200) + expect(pending_1.reload).to be_done + end + + it 'updates todos cache' do + expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original + + delete v3_api("/todos/#{pending_1.id}", john_doe) + end + end + end + + describe 'DELETE /todos' do + context 'when unauthenticated' do + it 'returns authentication error' do + delete v3_api('/todos') + + expect(response.status).to eq(401) + end + end + + context 'when authenticated' do + it 'marks all todos as done' do + delete v3_api('/todos', john_doe) + + expect(response.status).to eq(200) + expect(response.body).to eq('3') + expect(pending_1.reload).to be_done + expect(pending_2.reload).to be_done + expect(pending_3.reload).to be_done + end + + it 'updates todos cache' do + expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original + + delete v3_api("/todos", john_doe) + end + end + end +end From 8b14e164a67387a465a701b10322c0c2a5053e83 Mon Sep 17 00:00:00 2001 From: dimitrieh Date: Tue, 21 Feb 2017 13:25:42 +0100 Subject: [PATCH 097/247] fix more tests --- app/views/projects/commit/_pipeline.html.haml | 2 +- spec/features/projects/pipelines/pipeline_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 754bcb95ddb..c2b32a22170 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -3,7 +3,7 @@ .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) - = link_to "Retry", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post + = link_to "Retry", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'js-retry-button btn btn-grouped btn-primary', method: :post - if pipeline.builds.running_or_pending.any? = link_to "Cancel running", cancel_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index e457a935d91..a8f557bd07d 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -164,7 +164,7 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { click_on 'Retry' } + before { click_link('Retry', class: 'js-retry-button') } it { expect(page).not_to have_content('Retry') } end @@ -226,7 +226,7 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { click_on 'Retry' } + before { click_link('Retry', class: 'js-retry-button') } it { expect(page).not_to have_content('Retry') } it { expect(page).to have_selector('.retried') } From 63bd79f594272d98ce022685f26a47ce0afae9d4 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Tue, 21 Feb 2017 09:53:44 +0100 Subject: [PATCH 098/247] Chat slash commands show labels correctly --- .../unreleased/zj-fix-slash-command-labels.yml | 4 ++++ lib/gitlab/chat_commands/presenters/issue_base.rb | 2 +- .../chat_commands/presenters/issue_show_spec.rb | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/zj-fix-slash-command-labels.yml diff --git a/changelogs/unreleased/zj-fix-slash-command-labels.yml b/changelogs/unreleased/zj-fix-slash-command-labels.yml new file mode 100644 index 00000000000..93b7194dd4e --- /dev/null +++ b/changelogs/unreleased/zj-fix-slash-command-labels.yml @@ -0,0 +1,4 @@ +--- +title: Chat slash commands show labels correctly +merge_request: +author: diff --git a/lib/gitlab/chat_commands/presenters/issue_base.rb b/lib/gitlab/chat_commands/presenters/issue_base.rb index a0058407fb2..054f7f4be0c 100644 --- a/lib/gitlab/chat_commands/presenters/issue_base.rb +++ b/lib/gitlab/chat_commands/presenters/issue_base.rb @@ -32,7 +32,7 @@ module Gitlab }, { title: "Labels", - value: @resource.labels.any? ? @resource.label_names : "_None_", + value: @resource.labels.any? ? @resource.label_names.join(', ') : "_None_", short: true } ] diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb index 5b678d31fce..3916fc704a4 100644 --- a/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb +++ b/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb @@ -26,6 +26,21 @@ describe Gitlab::ChatCommands::Presenters::IssueShow do end end + context 'with labels' do + let(:label) { create(:label, project: project, title: 'mep') } + let(:label1) { create(:label, project: project, title: 'mop') } + + before do + issue.labels << [label, label1] + end + + it 'shows the labels' do + labels = attachment[:fields].find { |f| f[:title] == 'Labels' } + + expect(labels[:value]).to eq("mep, mop") + end + end + context 'confidential issue' do let(:issue) { create(:issue, project: project) } From 71270f80dd42e524a904a3c19f23217e8766e282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nov=C3=BD?= Date: Thu, 25 Aug 2016 21:56:32 +0000 Subject: [PATCH 099/247] UI: Allow a project variable to be set to an empty value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- app/views/projects/variables/_form.html.haml | 2 +- .../lnovy-gitlab-ce-empty-variables.yml | 4 ++ spec/features/variables_spec.rb | 44 ++++++++++++++++--- 3 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml diff --git a/app/views/projects/variables/_form.html.haml b/app/views/projects/variables/_form.html.haml index a5bae83e0ce..1ae86d258af 100644 --- a/app/views/projects/variables/_form.html.haml +++ b/app/views/projects/variables/_form.html.haml @@ -6,5 +6,5 @@ = f.text_field :key, class: "form-control", placeholder: "PROJECT_VARIABLE", required: true .form-group = f.label :value, "Value", class: "label-light" - = f.text_area :value, class: "form-control", placeholder: "PROJECT_VARIABLE", required: true + = f.text_area :value, class: "form-control", placeholder: "PROJECT_VARIABLE" = f.submit btn_text, class: "btn btn-save" diff --git a/changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml b/changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml new file mode 100644 index 00000000000..bd5db5ac7af --- /dev/null +++ b/changelogs/unreleased/lnovy-gitlab-ce-empty-variables.yml @@ -0,0 +1,4 @@ +--- +title: 'UI: Allow a project variable to be set to an empty value' +merge_request: 6044 +author: Lukáš Nový diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb index 9a4bc027004..a07eba2f01e 100644 --- a/spec/features/variables_spec.rb +++ b/spec/features/variables_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'Project variables', js: true do let(:user) { create(:user) } let(:project) { create(:project) } - let(:variable) { create(:ci_variable, key: 'test') } + let(:variable) { create(:ci_variable, key: 'test_key', value: 'test value') } before do login_as(user) @@ -16,16 +16,28 @@ describe 'Project variables', js: true do it 'shows list of variables' do page.within('.variables-table') do expect(page).to have_content(variable.key) + expect(page).to have_content(variable.value) end end it 'adds new variable' do - fill_in('variable_key', with: 'key') - fill_in('variable_value', with: 'key value') + fill_in('variable_key', with: 'new_key') + fill_in('variable_value', with: 'new value') click_button('Add new variable') page.within('.variables-table') do - expect(page).to have_content('key') + expect(page).to have_content('new_key') + expect(page).to have_content('new value') + end + end + + it 'adds empty variable' do + fill_in('variable_key', with: 'new_key') + fill_in('variable_value', with: '') + click_button('Add new variable') + + page.within('.variables-table') do + expect(page).to have_content('new_key') end end @@ -68,12 +80,30 @@ describe 'Project variables', js: true do end expect(page).to have_content('Update variable') - fill_in('variable_key', with: 'key') - fill_in('variable_value', with: 'key value') + fill_in('variable_key', with: 'new_key') + fill_in('variable_value', with: 'new value') click_button('Save variable') page.within('.variables-table') do - expect(page).to have_content('key') + expect(page).not_to have_content(variable.key) + expect(page).not_to have_content(variable.value) + expect(page).to have_content('new_key') + expect(page).to have_content('new value') + end + end + + it 'edits variable with empty value' do + page.within('.variables-table') do + find('.btn-variable-edit').click + end + + expect(page).to have_content('Update variable') + fill_in('variable_value', with: '') + click_button('Save variable') + + page.within('.variables-table') do + expect(page).to have_content(variable.key) + expect(page).not_to have_content(variable.value) end end end From 79696f5b7aaf260176355026e91af05d40d92d0c Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 21 Feb 2017 15:07:02 +0100 Subject: [PATCH 100/247] Hash concurrent foreign key names similar to Rails This was initially not implemented simply because I forgot about the size limit of constraint names in PostgreSQL (63 bytes). Using the old technique we can't add foreign keys for certain tables. For example, adding a foreign key on protected_branch_merge_access_levels.protected_branch_id would lead to the following key name: fk_protected_branch_merge_access_levels_protected_branches_protected_branch_id This key is 78 bytes long, thus violating the PostgreSQL size requirements. The hashing strategy is copied from Rails' foreign_key_name() method, which unfortunately is private and subject to change without notice. --- lib/gitlab/database/migration_helpers.rb | 11 ++++++++++- spec/lib/gitlab/database/migration_helpers_spec.rb | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 4800a509b37..fc445ab9483 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -54,7 +54,7 @@ module Gitlab disable_statement_timeout - key_name = "fk_#{source}_#{target}_#{column}" + key_name = concurrent_foreign_key_name(source, column) # Using NOT VALID allows us to create a key without immediately # validating it. This means we keep the ALTER TABLE lock only for a @@ -74,6 +74,15 @@ module Gitlab execute("ALTER TABLE #{source} VALIDATE CONSTRAINT #{key_name};") end + # Returns the name for a concurrent foreign key. + # + # PostgreSQL constraint names have a limit of 63 bytes. The logic used + # here is based on Rails' foreign_key_name() method, which unfortunately + # is private so we can't rely on it directly. + def concurrent_foreign_key_name(table, column) + "fk_#{Digest::SHA256.hexdigest("#{table}_#{column}_fk").first(10)}" + end + # Long-running migrations may take more than the timeout allowed by # the database. Disable the session's statement timeout to ensure # migrations don't get killed prematurely. (PostgreSQL only) diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index e94ca4fcfd2..e007044868c 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -101,6 +101,16 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end end + describe '#concurrent_foreign_key_name' do + it 'returns the name for a foreign key' do + name = model.concurrent_foreign_key_name(:this_is_a_very_long_table_name, + :with_a_very_long_column_name) + + expect(name).to be_an_instance_of(String) + expect(name.length).to eq(13) + end + end + describe '#disable_statement_timeout' do context 'using PostgreSQL' do it 'disables statement timeouts' do From 3f7b7a3b0f2199c56b9f5acab07539610ae10c7c Mon Sep 17 00:00:00 2001 From: David Piegza Date: Mon, 20 Feb 2017 18:01:37 +0100 Subject: [PATCH 101/247] Fix preselected namespace when creating a project --- app/helpers/namespaces_helper.rb | 4 ++ app/views/projects/new.html.haml | 2 +- spec/features/projects/new_project_spec.rb | 45 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb index 0676767d910..dc5ae8edbb2 100644 --- a/app/helpers/namespaces_helper.rb +++ b/app/helpers/namespaces_helper.rb @@ -1,4 +1,8 @@ module NamespacesHelper + def namespace_id_from(params) + params.dig(:project, :namespace_id) || params[:namespace_id] + end + def namespaces_options(selected = :current_user, display_path: false, extra_group: nil) groups = current_user.owned_groups + current_user.masters_groups diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index a07885537b9..2a98bba05ee 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -22,7 +22,7 @@ - if current_user.can_select_namespace? .input-group-addon = root_url - = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user, display_path: true), {}, {class: 'select2 js-select-namespace', tabindex: 1} + = f.select :namespace_id, namespaces_options(namespace_id_from(params) || :current_user, display_path: true), {}, {class: 'select2 js-select-namespace', tabindex: 1} - else .input-group-addon.static-namespace diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index b56e562b2b6..45185f2dd1f 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -19,6 +19,51 @@ feature "New project", feature: true do end end + context "Namespace selector" do + context "with user namespace" do + before do + visit new_project_path + end + + it "selects the user namespace" do + namespace = find("#project_namespace_id") + + expect(namespace.text).to eq user.username + end + end + + context "with group namespace" do + let(:group) { create(:group, :private, owner: user) } + + before do + group.add_owner(user) + visit new_project_path(namespace_id: group.id) + end + + it "selects the group namespace" do + namespace = find("#project_namespace_id option[selected]") + + expect(namespace.text).to eq group.name + end + + context "on validation error" do + before do + fill_in('project_path', with: 'private-group-project') + choose('Internal') + click_button('Create project') + + expect(page).to have_css '.project-edit-errors .alert.alert-danger' + end + + it "selects the group namespace" do + namespace = find("#project_namespace_id option[selected]") + + expect(namespace.text).to eq group.name + end + end + end + end + context 'Import project options' do before do visit new_project_path From 420797f654c5a82de081b9e5777a0fe8c609b664 Mon Sep 17 00:00:00 2001 From: Adam Boseley Date: Mon, 2 Jan 2017 03:11:03 +0000 Subject: [PATCH 102/247] Update using_docker_images.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- doc/ci/docker/using_docker_images.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md index 9dee61bfa1f..00787323b6b 100644 --- a/doc/ci/docker/using_docker_images.md +++ b/doc/ci/docker/using_docker_images.md @@ -39,13 +39,15 @@ accessible during the build process. ## What is an image -The `image` keyword is the name of the docker image that is present in the -local Docker Engine (list all images with `docker images`) or any image that -can be found at [Docker Hub][hub]. For more information about images and Docker -Hub please read the [Docker Fundamentals][] documentation. +The `image` keyword is the name of the docker image the docker executor +will run to perform the CI tasks. -In short, with `image` we refer to the docker image, which will be used to -create a container on which your job will run. +By default the executor will only pull images from [Docker Hub][hub], +but this can be configured in the `gitlab-runner/config.toml` by setting +the [docker pull policy][] to allow using local images. + +For more information about images and Docker Hub please read +the [Docker Fundamentals][] documentation. ## What is a service @@ -271,6 +273,7 @@ containers as well as all volumes (`-v`) that were created with the container creation. [Docker Fundamentals]: https://docs.docker.com/engine/understanding-docker/ +[docker pull policy]: https://docs.gitlab.com/runner/executors/docker.html#how-pull-policies-work [hub]: https://hub.docker.com/ [linking-containers]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ [tutum/wordpress]: https://hub.docker.com/r/tutum/wordpress/ From 3f7c1686790b3c54925be0aabc74c0d22b09e752 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Tue, 21 Feb 2017 14:54:36 +0000 Subject: [PATCH 103/247] Fix broken test --- spec/features/projects/pipelines/pipeline_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index a8f557bd07d..9cae000388f 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -164,7 +164,7 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { click_link('Retry', class: 'js-retry-button') } + before { find('.js-retry-button').trigger('click') } it { expect(page).not_to have_content('Retry') } end @@ -226,7 +226,7 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { click_link('Retry', class: 'js-retry-button') } + before { find('js-retry-button').trigger('click') } it { expect(page).not_to have_content('Retry') } it { expect(page).to have_selector('.retried') } From 2ace39f2420abf018ceef6aaad52e4917bcbab7d Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Tue, 14 Feb 2017 17:07:11 -0200 Subject: [PATCH 104/247] Spam check and reCAPTCHA improvements --- app/controllers/concerns/spammable_actions.rb | 30 ++- app/controllers/projects/issues_controller.rb | 34 +--- .../projects/snippets_controller.rb | 21 +- app/controllers/snippets_controller.rb | 13 +- app/models/concerns/spammable.rb | 2 +- app/models/project_snippet.rb | 4 - app/services/create_snippet_service.rb | 10 +- app/services/issuable_base_service.rb | 32 +-- app/services/issues/create_service.rb | 21 +- app/services/issues/update_service.rb | 8 + app/services/spam_check_service.rb | 24 +++ app/services/spam_service.rb | 31 ++- app/services/update_snippet_service.rb | 10 +- .../layouts/_recaptcha_verification.html.haml | 23 +++ app/views/projects/issues/verify.html.haml | 22 +- app/views/projects/snippets/verify.html.haml | 4 + app/views/snippets/verify.html.haml | 4 + ...3-snippet-and-issue-spam-check-on-edit.yml | 4 + lib/api/helpers.rb | 4 + lib/api/issues.rb | 6 +- lib/api/project_snippets.rb | 8 +- lib/api/snippets.rb | 7 +- lib/api/v3/issues.rb | 10 +- lib/api/v3/project_snippets.rb | 8 +- .../projects/issues_controller_spec.rb | 111 ++++++++++- .../projects/snippets_controller_spec.rb | 188 ++++++++++++++++-- spec/controllers/snippets_controller_spec.rb | 159 ++++++++++++++- spec/models/concerns/spammable_spec.rb | 1 + spec/requests/api/issues_spec.rb | 27 +++ spec/requests/api/project_snippets_spec.rb | 92 ++++++--- spec/requests/api/snippets_spec.rb | 66 +++++- spec/requests/api/v3/issues_spec.rb | 27 +++ spec/requests/api/v3/project_snippets_spec.rb | 92 ++++++--- spec/services/issues/create_service_spec.rb | 10 - spec/services/spam_service_spec.rb | 83 ++++---- 35 files changed, 942 insertions(+), 254 deletions(-) create mode 100644 app/services/spam_check_service.rb create mode 100644 app/views/layouts/_recaptcha_verification.html.haml create mode 100644 app/views/projects/snippets/verify.html.haml create mode 100644 app/views/snippets/verify.html.haml create mode 100644 changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb index a6891149bfa..da225d8f1c7 100644 --- a/app/controllers/concerns/spammable_actions.rb +++ b/app/controllers/concerns/spammable_actions.rb @@ -17,13 +17,31 @@ module SpammableActions private - def recaptcha_params - return {} unless params[:recaptcha_verification] && Gitlab::Recaptcha.load_configurations! && verify_recaptcha + def recaptcha_check_with_fallback(&fallback) + if spammable.valid? + redirect_to spammable + elsif render_recaptcha? + if params[:recaptcha_verification] + flash[:alert] = 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.' + end - { - recaptcha_verified: true, - spam_log_id: params[:spam_log_id] - } + render :verify + else + fallback.call + end + end + + def spammable_params + default_params = { request: request } + + recaptcha_check = params[:recaptcha_verification] && + Gitlab::Recaptcha.load_configurations! && + verify_recaptcha + + return default_params unless recaptcha_check + + { recaptcha_verified: true, + spam_log_id: params[:spam_log_id] }.merge(default_params) end def spammable diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 744a4af1c51..6ef36771ac1 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -94,15 +94,15 @@ class Projects::IssuesController < Projects::ApplicationController end def create - extra_params = { request: request, - merge_request_for_resolving_discussions: merge_request_for_resolving_discussions } - extra_params.merge!(recaptcha_params) + create_params = issue_params + .merge(merge_request_for_resolving_discussions: merge_request_for_resolving_discussions) + .merge(spammable_params) - @issue = Issues::CreateService.new(project, current_user, issue_params.merge(extra_params)).execute + @issue = Issues::CreateService.new(project, current_user, create_params).execute respond_to do |format| format.html do - html_response_create + recaptcha_check_with_fallback { render :new } end format.js do @link = @issue.attachment.url.to_js @@ -111,7 +111,9 @@ class Projects::IssuesController < Projects::ApplicationController end def update - @issue = Issues::UpdateService.new(project, current_user, issue_params).execute(issue) + update_params = issue_params.merge(spammable_params) + + @issue = Issues::UpdateService.new(project, current_user, update_params).execute(issue) if params[:move_to_project_id].to_i > 0 new_project = Project.find(params[:move_to_project_id]) @@ -123,11 +125,7 @@ class Projects::IssuesController < Projects::ApplicationController respond_to do |format| format.html do - if @issue.valid? - redirect_to issue_path(@issue) - else - render :edit - end + recaptcha_check_with_fallback { render :edit } end format.json do @@ -179,20 +177,6 @@ class Projects::IssuesController < Projects::ApplicationController protected - def html_response_create - if @issue.valid? - redirect_to issue_path(@issue) - elsif render_recaptcha? - if params[:recaptcha_verification] - flash[:alert] = 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.' - end - - render :verify - else - render :new - end - end - def issue # The Sortable default scope causes performance issues when used with find_by @noteable = @issue ||= @project.issues.where(iid: params[:id]).reorder(nil).take || redirect_old diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index ef5d3d242eb..ea1a97b7cf0 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -38,24 +38,19 @@ class Projects::SnippetsController < Projects::ApplicationController end def create - create_params = snippet_params.merge(request: request) + create_params = snippet_params.merge(spammable_params) + @snippet = CreateSnippetService.new(@project, current_user, create_params).execute - if @snippet.valid? - respond_with(@snippet, - location: namespace_project_snippet_path(@project.namespace, - @project, @snippet)) - else - render :new - end + recaptcha_check_with_fallback { render :new } end def update - UpdateSnippetService.new(project, current_user, @snippet, - snippet_params).execute - respond_with(@snippet, - location: namespace_project_snippet_path(@project.namespace, - @project, @snippet)) + update_params = snippet_params.merge(spammable_params) + + UpdateSnippetService.new(project, current_user, @snippet, update_params).execute + + recaptcha_check_with_fallback { render :edit } end def show diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 366804ab17e..a632c36cfb8 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -42,16 +42,19 @@ class SnippetsController < ApplicationController end def create - create_params = snippet_params.merge(request: request) + create_params = snippet_params.merge(spammable_params) + @snippet = CreateSnippetService.new(nil, current_user, create_params).execute - respond_with @snippet.becomes(Snippet) + recaptcha_check_with_fallback { render :new } end def update - UpdateSnippetService.new(nil, current_user, @snippet, - snippet_params).execute - respond_with @snippet.becomes(Snippet) + update_params = snippet_params.merge(spammable_params) + + UpdateSnippetService.new(nil, current_user, @snippet, update_params).execute + + recaptcha_check_with_fallback { render :edit } end def show diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb index 79adc77c9e4..107e6764ba2 100644 --- a/app/models/concerns/spammable.rb +++ b/app/models/concerns/spammable.rb @@ -13,7 +13,7 @@ module Spammable attr_accessor :spam attr_accessor :spam_log - after_validation :check_for_spam, on: :create + after_validation :check_for_spam, on: [:create, :update] cattr_accessor :spammable_attrs, instance_accessor: false do [] diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb index 9bb456eee24..25b5d777641 100644 --- a/app/models/project_snippet.rb +++ b/app/models/project_snippet.rb @@ -9,8 +9,4 @@ class ProjectSnippet < Snippet participant :author participant :notes_with_associations - - def check_for_spam? - super && project.public? - end end diff --git a/app/services/create_snippet_service.rb b/app/services/create_snippet_service.rb index 14f5ba064ff..40286dbf3bf 100644 --- a/app/services/create_snippet_service.rb +++ b/app/services/create_snippet_service.rb @@ -1,7 +1,8 @@ class CreateSnippetService < BaseService + include SpamCheckService + def execute - request = params.delete(:request) - api = params.delete(:api) + filter_spam_check_params snippet = if project project.snippets.build(params) @@ -15,10 +16,11 @@ class CreateSnippetService < BaseService end snippet.author = current_user - snippet.spam = SpamService.new(snippet, request).check(api) + + spam_check(snippet, current_user) if snippet.save - UserAgentDetailService.new(snippet, request).create + UserAgentDetailService.new(snippet, @request).create end snippet diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 5f3ced49665..9500faf2862 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -191,14 +191,12 @@ class IssuableBaseService < BaseService # To be overridden by subclasses end - def after_update(issuable) + def before_update(issuable) # To be overridden by subclasses end - def update_issuable(issuable, attributes) - issuable.with_transaction_returning_status do - issuable.update(attributes.merge(updated_by: current_user)) - end + def after_update(issuable) + # To be overridden by subclasses end def update(issuable) @@ -212,16 +210,22 @@ class IssuableBaseService < BaseService label_ids = process_label_ids(params, existing_label_ids: issuable.label_ids) params[:label_ids] = label_ids if labels_changing?(issuable.label_ids, label_ids) - if params.present? && update_issuable(issuable, params) - # We do not touch as it will affect a update on updated_at field - ActiveRecord::Base.no_touching do - handle_common_system_notes(issuable, old_labels: old_labels) - end + if params.present? + issuable.assign_attributes(params.merge(updated_by: current_user)) - handle_changes(issuable, old_labels: old_labels, old_mentioned_users: old_mentioned_users) - after_update(issuable) - issuable.create_new_cross_references!(current_user) - execute_hooks(issuable, 'update') + before_update(issuable) + + if issuable.with_transaction_returning_status { issuable.save } + # We do not touch as it will affect a update on updated_at field + ActiveRecord::Base.no_touching do + handle_common_system_notes(issuable, old_labels: old_labels) + end + + handle_changes(issuable, old_labels: old_labels, old_mentioned_users: old_mentioned_users) + after_update(issuable) + issuable.create_new_cross_references!(current_user) + execute_hooks(issuable, 'update') + end end issuable diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb index 961605a1005..366b3572738 100644 --- a/app/services/issues/create_service.rb +++ b/app/services/issues/create_service.rb @@ -1,10 +1,9 @@ module Issues class CreateService < Issues::BaseService + include SpamCheckService + def execute - @request = params.delete(:request) - @api = params.delete(:api) - @recaptcha_verified = params.delete(:recaptcha_verified) - @spam_log_id = params.delete(:spam_log_id) + filter_spam_check_params issue_attributes = params.merge(merge_request_for_resolving_discussions: merge_request_for_resolving_discussions) @issue = BuildService.new(project, current_user, issue_attributes).execute @@ -12,14 +11,8 @@ module Issues create(@issue) end - def before_create(issuable) - if @recaptcha_verified - spam_log = current_user.spam_logs.find_by(id: @spam_log_id, title: issuable.title) - spam_log&.update!(recaptcha_verified: true) - else - issuable.spam = spam_service.check(@api) - issuable.spam_log = spam_service.spam_log - end + def before_create(issue) + spam_check(issue, current_user) end def after_create(issuable) @@ -42,10 +35,6 @@ module Issues private - def spam_service - @spam_service ||= SpamService.new(@issue, @request) - end - def user_agent_detail_service UserAgentDetailService.new(@issue, @request) end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 78cbf94ec69..22e32b13259 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -1,9 +1,17 @@ module Issues class UpdateService < Issues::BaseService + include SpamCheckService + def execute(issue) + filter_spam_check_params + update(issue) end + def before_update(issue) + spam_check(issue, current_user) + end + def handle_changes(issue, old_labels: [], old_mentioned_users: []) if has_changes?(issue, old_labels: old_labels) todo_service.mark_pending_todos_as_done(issue, current_user) diff --git a/app/services/spam_check_service.rb b/app/services/spam_check_service.rb new file mode 100644 index 00000000000..023e0824e85 --- /dev/null +++ b/app/services/spam_check_service.rb @@ -0,0 +1,24 @@ +# SpamCheckService +# +# Provide helper methods for checking if a given spammable object has +# potential spam data. +# +# Dependencies: +# - params with :request +# +module SpamCheckService + def filter_spam_check_params + @request = params.delete(:request) + @api = params.delete(:api) + @recaptcha_verified = params.delete(:recaptcha_verified) + @spam_log_id = params.delete(:spam_log_id) + end + + def spam_check(spammable, user) + spam_service = SpamService.new(spammable, @request) + + spam_service.when_recaptcha_verified(@recaptcha_verified, @api) do + user.spam_logs.find_by(id: @spam_log_id)&.update!(recaptcha_verified: true) + end + end +end diff --git a/app/services/spam_service.rb b/app/services/spam_service.rb index 024a7c19d33..3e65b7d31a3 100644 --- a/app/services/spam_service.rb +++ b/app/services/spam_service.rb @@ -17,15 +17,6 @@ class SpamService end end - def check(api = false) - return false unless request && check_for_spam? - - return false unless akismet.is_spam? - - create_spam_log(api) - true - end - def mark_as_spam! return false unless spammable.submittable_as_spam? @@ -36,8 +27,30 @@ class SpamService end end + def when_recaptcha_verified(recaptcha_verified, api = false) + # In case it's a request which is already verified through recaptcha, yield + # block. + if recaptcha_verified + yield + else + # Otherwise, it goes to Akismet and check if it's a spam. If that's the + # case, it assigns spammable record as "spam" and create a SpamLog record. + spammable.spam = check(api) + spammable.spam_log = spam_log + end + end + private + def check(api) + return false unless request && check_for_spam? + + return false unless akismet.is_spam? + + create_spam_log(api) + true + end + def akismet @akismet ||= AkismetService.new( spammable_owner, diff --git a/app/services/update_snippet_service.rb b/app/services/update_snippet_service.rb index a6bb36821c3..358bca73aec 100644 --- a/app/services/update_snippet_service.rb +++ b/app/services/update_snippet_service.rb @@ -1,4 +1,6 @@ class UpdateSnippetService < BaseService + include SpamCheckService + attr_accessor :snippet def initialize(project, user, snippet, params) @@ -9,7 +11,7 @@ class UpdateSnippetService < BaseService def execute # check that user is allowed to set specified visibility_level new_visibility = params[:visibility_level] - + if new_visibility && new_visibility.to_i != snippet.visibility_level unless Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility) deny_visibility_level(snippet, new_visibility) @@ -17,6 +19,10 @@ class UpdateSnippetService < BaseService end end - snippet.update_attributes(params) + filter_spam_check_params + snippet.assign_attributes(params) + spam_check(snippet, current_user) + + snippet.save end end diff --git a/app/views/layouts/_recaptcha_verification.html.haml b/app/views/layouts/_recaptcha_verification.html.haml new file mode 100644 index 00000000000..77c77dc6754 --- /dev/null +++ b/app/views/layouts/_recaptcha_verification.html.haml @@ -0,0 +1,23 @@ +- humanized_resource_name = spammable.class.model_name.human.downcase +- resource_name = spammable.class.model_name.singular + +%h3.page-title + Anti-spam verification +%hr + +%p + #{"We detected potential spam in the #{humanized_resource_name}. Please solve the reCAPTCHA to proceed."} + += form_for form do |f| + .recaptcha + - params[resource_name].each do |field, value| + = hidden_field(resource_name, field, value: value) + = hidden_field_tag(:spam_log_id, spammable.spam_log.id) + = hidden_field_tag(:recaptcha_verification, true) + = recaptcha_tags + + -# Yields a block with given extra params. + = yield + + .row-content-block.footer-block + = f.submit "Submit #{humanized_resource_name}", class: 'btn btn-create' diff --git a/app/views/projects/issues/verify.html.haml b/app/views/projects/issues/verify.html.haml index 1934b18c086..09aa401e44a 100644 --- a/app/views/projects/issues/verify.html.haml +++ b/app/views/projects/issues/verify.html.haml @@ -1,20 +1,4 @@ -- page_title "Anti-spam verification" +- form = [@project.namespace.becomes(Namespace), @project, @issue] -%h3.page-title - Anti-spam verification -%hr - -%p - We detected potential spam in the issue description. Please verify that you are not a robot to submit the issue. - -= form_for [@project.namespace.becomes(Namespace), @project, @issue] do |f| - .recaptcha - - params[:issue].each do |field, value| - = hidden_field(:issue, field, value: value) - = hidden_field_tag(:merge_request_for_resolving_discussions, params[:merge_request_for_resolving_discussions]) - = hidden_field_tag(:spam_log_id, @issue.spam_log.id) - = hidden_field_tag(:recaptcha_verification, true) - = recaptcha_tags - - .row-content-block.footer-block - = f.submit "Submit #{@issue.class.model_name.human.downcase}", class: 'btn btn-create' += render layout: 'layouts/recaptcha_verification', locals: { spammable: @issue, form: form } do + = hidden_field_tag(:merge_request_for_resolving_discussions, params[:merge_request_for_resolving_discussions]) diff --git a/app/views/projects/snippets/verify.html.haml b/app/views/projects/snippets/verify.html.haml new file mode 100644 index 00000000000..eb56f03b3f4 --- /dev/null +++ b/app/views/projects/snippets/verify.html.haml @@ -0,0 +1,4 @@ +- form = [@project.namespace.becomes(Namespace), @project, @snippet.becomes(Snippet)] + += render 'layouts/recaptcha_verification', spammable: @snippet, form: form + diff --git a/app/views/snippets/verify.html.haml b/app/views/snippets/verify.html.haml new file mode 100644 index 00000000000..cb623ccab57 --- /dev/null +++ b/app/views/snippets/verify.html.haml @@ -0,0 +1,4 @@ +- form = [@snippet.becomes(Snippet)] + += render 'layouts/recaptcha_verification', spammable: @snippet, form: form + diff --git a/changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml b/changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml new file mode 100644 index 00000000000..d70b5ef8fd5 --- /dev/null +++ b/changelogs/unreleased/28093-snippet-and-issue-spam-check-on-edit.yml @@ -0,0 +1,4 @@ +--- +title: Spam check and reCAPTCHA improvements +merge_request: +author: diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 7b6fae866eb..32692f19fcd 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -215,6 +215,10 @@ module API end end + def render_spam_error! + render_api_error!({ error: 'Spam detected' }, 400) + end + def render_api_error!(message, status) error!({ 'message' => message }, status, header) end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 2b946bfd349..6d30c5d81b1 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -169,9 +169,13 @@ module API params.delete(:updated_at) end + update_params = declared_params(include_missing: false).merge(request: request, api: true) + issue = ::Issues::UpdateService.new(user_project, current_user, - declared_params(include_missing: false)).execute(issue) + update_params).execute(issue) + + render_spam_error! if issue.spam? if issue.valid? present issue, with: Entities::Issue, current_user: current_user, project: user_project diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index dcc0c82ee27..2a1cce73f3f 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -63,6 +63,8 @@ module API snippet = CreateSnippetService.new(user_project, current_user, snippet_params).execute + render_spam_error! if snippet.spam? + if snippet.persisted? present snippet, with: Entities::ProjectSnippet else @@ -92,12 +94,16 @@ module API authorize! :update_project_snippet, snippet snippet_params = declared_params(include_missing: false) + .merge(request: request, api: true) + snippet_params[:content] = snippet_params.delete(:code) if snippet_params[:code].present? UpdateSnippetService.new(user_project, current_user, snippet, snippet_params).execute - if snippet.persisted? + render_spam_error! if snippet.spam? + + if snippet.valid? present snippet, with: Entities::ProjectSnippet else render_validation_error!(snippet) diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb index eb9ece49e7f..ac03fbd2a3d 100644 --- a/lib/api/snippets.rb +++ b/lib/api/snippets.rb @@ -67,6 +67,8 @@ module API attrs = declared_params(include_missing: false).merge(request: request, api: true) snippet = CreateSnippetService.new(nil, current_user, attrs).execute + render_spam_error! if snippet.spam? + if snippet.persisted? present snippet, with: Entities::PersonalSnippet else @@ -93,9 +95,12 @@ module API return not_found!('Snippet') unless snippet authorize! :update_personal_snippet, snippet - attrs = declared_params(include_missing: false) + attrs = declared_params(include_missing: false).merge(request: request, api: true) UpdateSnippetService.new(nil, current_user, snippet, attrs).execute + + render_spam_error! if snippet.spam? + if snippet.persisted? present snippet, with: Entities::PersonalSnippet else diff --git a/lib/api/v3/issues.rb b/lib/api/v3/issues.rb index ba5b6fdbe52..d0af09f0e1e 100644 --- a/lib/api/v3/issues.rb +++ b/lib/api/v3/issues.rb @@ -149,9 +149,7 @@ module API issue = ::Issues::CreateService.new(user_project, current_user, issue_params.merge(request: request, api: true)).execute - if issue.spam? - render_api_error!({ error: 'Spam detected' }, 400) - end + render_spam_error! if issue.spam? if issue.valid? present issue, with: ::API::Entities::Issue, current_user: current_user, project: user_project @@ -182,9 +180,13 @@ module API params.delete(:updated_at) end + update_params = declared_params(include_missing: false).merge(request: request, api: true) + issue = ::Issues::UpdateService.new(user_project, current_user, - declared_params(include_missing: false)).execute(issue) + update_params).execute(issue) + + render_spam_error! if issue.spam? if issue.valid? present issue, with: ::API::Entities::Issue, current_user: current_user, project: user_project diff --git a/lib/api/v3/project_snippets.rb b/lib/api/v3/project_snippets.rb index 9f95d4395fa..e03e941d30b 100644 --- a/lib/api/v3/project_snippets.rb +++ b/lib/api/v3/project_snippets.rb @@ -64,6 +64,8 @@ module API snippet = CreateSnippetService.new(user_project, current_user, snippet_params).execute + render_spam_error! if snippet.spam? + if snippet.persisted? present snippet, with: ::API::V3::Entities::ProjectSnippet else @@ -93,12 +95,16 @@ module API authorize! :update_project_snippet, snippet snippet_params = declared_params(include_missing: false) + .merge(request: request, api: true) + snippet_params[:content] = snippet_params.delete(:code) if snippet_params[:code].present? UpdateSnippetService.new(user_project, current_user, snippet, snippet_params).execute - if snippet.persisted? + render_spam_error! if snippet.spam? + + if snippet.valid? present snippet, with: ::API::V3::Entities::ProjectSnippet else render_validation_error!(snippet) diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index e576bf9ef79..7871b6a9e10 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -152,6 +152,113 @@ describe Projects::IssuesController do end end + context 'Akismet is enabled' do + let(:project) { create(:project_empty_repo, :public) } + + before do + stub_application_setting(recaptcha_enabled: true) + allow_any_instance_of(SpamService).to receive(:check_for_spam?).and_return(true) + end + + context 'when an issue is not identified as spam' do + before do + allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false) + allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(false) + end + + it 'normally updates the issue' do + expect { update_issue(title: 'Foo') }.to change { issue.reload.title }.to('Foo') + end + end + + context 'when an issue is identified as spam' do + before { allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) } + + context 'when captcha is not verified' do + def update_spam_issue + update_issue(title: 'Spam Title', description: 'Spam lives here') + end + + before { allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false) } + + it 'rejects an issue recognized as a spam' do + expect { update_spam_issue }.not_to change{ issue.reload.title } + end + + it 'rejects an issue recognized as a spam when recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + expect { update_spam_issue }.not_to change{ issue.reload.title } + end + + it 'creates a spam log' do + update_spam_issue + + spam_logs = SpamLog.all + + expect(spam_logs.count).to eq(1) + expect(spam_logs.first.title).to eq('Spam Title') + expect(spam_logs.first.recaptcha_verified).to be_falsey + end + + it 'renders verify template' do + update_spam_issue + + expect(response).to render_template(:verify) + end + end + + context 'when captcha is verified' do + let(:spammy_title) { 'Whatever' } + let!(:spam_logs) { create_list(:spam_log, 2, user: user, title: spammy_title) } + + def update_verified_issue + update_issue({ title: spammy_title }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + end + + before do + allow_any_instance_of(described_class).to receive(:verify_recaptcha) + .and_return(true) + end + + it 'redirect to issue page' do + update_verified_issue + + expect(response). + to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + end + + it 'accepts an issue after recaptcha is verified' do + expect{ update_verified_issue }.to change{ issue.reload.title }.to(spammy_title) + end + + it 'marks spam log as recaptcha_verified' do + expect { update_verified_issue }.to change { SpamLog.last.recaptcha_verified }.from(false).to(true) + end + + it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do + spam_log = create(:spam_log) + + expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) }. + not_to change { SpamLog.last.recaptcha_verified } + end + end + end + end + + def update_issue(issue_params = {}, additional_params = {}) + params = { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: issue.iid, + issue: issue_params + }.merge(additional_params) + + put :update, params + end + def move_issue put :update, namespace_id: project.namespace.to_param, @@ -384,7 +491,7 @@ describe Projects::IssuesController do allow_any_instance_of(SpamService).to receive(:check_for_spam?).and_return(true) end - context 'when an issue is not identified as a spam' do + context 'when an issue is not identified as spam' do before do allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false) allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(false) @@ -395,7 +502,7 @@ describe Projects::IssuesController do end end - context 'when an issue is identified as a spam' do + context 'when an issue is identified as spam' do before { allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) } context 'when captcha is not verified' do diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 77ee10a1e15..8bab094a79e 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -70,7 +70,7 @@ describe Projects::SnippetsController do end describe 'POST #create' do - def create_snippet(project, snippet_params = {}) + def create_snippet(project, snippet_params = {}, additional_params = {}) sign_in(user) project.add_developer(user) @@ -79,7 +79,7 @@ describe Projects::SnippetsController do namespace_id: project.namespace.to_param, project_id: project.to_param, project_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params) - } + }.merge(additional_params) end context 'when the snippet is spam' do @@ -87,35 +87,179 @@ describe Projects::SnippetsController do allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) end - context 'when the project is private' do - let(:private_project) { create(:project_empty_repo, :private) } + context 'when the snippet is private' do + it 'creates the snippet' do + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) + end + end - context 'when the snippet is public' do - it 'creates the snippet' do - expect { create_snippet(private_project, visibility_level: Snippet::PUBLIC) }. - to change { Snippet.count }.by(1) + context 'when the snippet is public' do + it 'rejects the shippet' do + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } + expect(response).to render_template(:new) + end + + it 'creates a spam log' do + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) + end + + it 'renders :new with recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + create_snippet(project, visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:new) + end + + context 'recaptcha enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + end + + it 'renders :verify with recaptcha enabled' do + create_snippet(project, visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:verify) + end + + it 'renders snippet page when recaptcha verified' do + spammy_title = 'Whatever' + + spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title) + create_snippet(project, + { visibility_level: Snippet::PUBLIC }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + + expect(response).to redirect_to(Snippet.last) + end + end + end + end + end + + describe 'PUT #update' do + let(:project) { create :project, :public } + let(:snippet) { create :project_snippet, author: user, project: project, visibility_level: visibility_level } + + def update_snippet(snippet_params = {}, additional_params = {}) + sign_in(user) + + project.add_developer(user) + + put :update, { + namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: snippet.id, + project_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params) + }.merge(additional_params) + + snippet.reload + end + + context 'when the snippet is spam' do + before do + allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) + end + + context 'when the snippet is private' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'updates the snippet' do + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') + end + end + + context 'when the snippet is public' do + let(:visibility_level) { Snippet::PUBLIC } + + it 'rejects the shippet' do + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) + end + + it 'renders :edit with recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + update_snippet(title: 'Foo') + + expect(response).to render_template(:edit) + end + + context 'recaptcha enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + end + + it 'renders :verify with recaptcha enabled' do + update_snippet(title: 'Foo') + + expect(response).to render_template(:verify) + end + + it 'renders snippet page when recaptcha verified' do + spammy_title = 'Whatever' + + spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title) + snippet = update_snippet({ title: spammy_title }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + + expect(response).to redirect_to(snippet) end end end - context 'when the project is public' do - context 'when the snippet is private' do - it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) - end + context 'when the private snippet is made public' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'rejects the shippet' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } end - context 'when the snippet is public' do - it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } - expect(response).to render_template(:new) + it 'creates a spam log' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) + end + + it 'renders :edit with recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:edit) + end + + context 'recaptcha enabled' do + before do + stub_application_setting(recaptcha_enabled: true) end - it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + it 'renders :verify with recaptcha enabled' do + update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:verify) + end + + it 'renders snippet page when recaptcha verified' do + spammy_title = 'Whatever' + + spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title) + snippet = update_snippet({ title: spammy_title, visibility_level: Snippet::PUBLIC }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + + expect(response).to redirect_to(snippet) end end end diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index f90c0d76ceb..5de3b9890ef 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -139,12 +139,14 @@ describe SnippetsController do end describe 'POST #create' do - def create_snippet(snippet_params = {}) + def create_snippet(snippet_params = {}, additional_params = {}) sign_in(user) post :create, { personal_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params) - } + }.merge(additional_params) + + Snippet.last end context 'when the snippet is spam' do @@ -163,13 +165,164 @@ describe SnippetsController do it 'rejects the shippet' do expect { create_snippet(visibility_level: Snippet::PUBLIC) }. not_to change { Snippet.count } - expect(response).to render_template(:new) end it 'creates a spam log' do expect { create_snippet(visibility_level: Snippet::PUBLIC) }. to change { SpamLog.count }.by(1) end + + it 'renders :new with recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + create_snippet(visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:new) + end + + context 'recaptcha enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + end + + it 'renders :verify with recaptcha enabled' do + create_snippet(visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:verify) + end + + it 'renders snippet page when recaptcha verified' do + spammy_title = 'Whatever' + + spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title) + snippet = create_snippet({ title: spammy_title }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + + expect(response).to redirect_to(snippet_path(snippet)) + end + end + end + end + end + + describe 'PUT #update' do + let(:project) { create :project } + let(:snippet) { create :personal_snippet, author: user, project: project, visibility_level: visibility_level } + + def update_snippet(snippet_params = {}, additional_params = {}) + sign_in(user) + + put :update, { + id: snippet.id, + personal_snippet: { title: 'Title', content: 'Content' }.merge(snippet_params) + }.merge(additional_params) + + snippet.reload + end + + context 'when the snippet is spam' do + before do + allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) + end + + context 'when the snippet is private' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'updates the snippet' do + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') + end + end + + context 'when a private snippet is made public' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'rejects the snippet' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) + end + + it 'renders :edit with recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:edit) + end + + context 'recaptcha enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + end + + it 'renders :verify with recaptcha enabled' do + update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) + + expect(response).to render_template(:verify) + end + + it 'renders snippet page when recaptcha verified' do + spammy_title = 'Whatever' + + spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title) + snippet = update_snippet({ title: spammy_title, visibility_level: Snippet::PUBLIC }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + + expect(response).to redirect_to(snippet) + end + end + end + + context 'when the snippet is public' do + let(:visibility_level) { Snippet::PUBLIC } + + it 'rejects the shippet' do + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) + end + + it 'renders :edit with recaptcha disabled' do + stub_application_setting(recaptcha_enabled: false) + + update_snippet(title: 'Foo') + + expect(response).to render_template(:edit) + end + + context 'recaptcha enabled' do + before do + stub_application_setting(recaptcha_enabled: true) + end + + it 'renders :verify with recaptcha enabled' do + update_snippet(title: 'Foo') + + expect(response).to render_template(:verify) + end + + it 'renders snippet page when recaptcha verified' do + spammy_title = 'Whatever' + + spam_logs = create_list(:spam_log, 2, user: user, title: spammy_title) + snippet = update_snippet({ title: spammy_title }, + { spam_log_id: spam_logs.last.id, + recaptcha_verification: true }) + + expect(response).to redirect_to(snippet_path(snippet)) + end + end end end end diff --git a/spec/models/concerns/spammable_spec.rb b/spec/models/concerns/spammable_spec.rb index b6e5c95d18a..fd3b8307571 100644 --- a/spec/models/concerns/spammable_spec.rb +++ b/spec/models/concerns/spammable_spec.rb @@ -23,6 +23,7 @@ describe Issue, 'Spammable' do describe '#check_for_spam?' do it 'returns true for public project' do issue.project.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC) + expect(issue.check_for_spam?).to eq(true) end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index ece1b43567d..7a0bd5f9721 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -1028,6 +1028,33 @@ describe API::Issues, api: true do end end + describe 'PUT /projects/:id/issues/:issue_id with spam filtering' do + let(:params) do + { + title: 'updated title', + description: 'content here', + labels: 'label, label2' + } + end + + it "does not create a new project issue" do + allow_any_instance_of(SpamService).to receive_messages(check_for_spam?: true) + allow_any_instance_of(AkismetService).to receive_messages(is_spam?: true) + + put api("/projects/#{project.id}/issues/#{issue.id}", user), params + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) + + spam_logs = SpamLog.all + expect(spam_logs.count).to eq(1) + expect(spam_logs[0].title).to eq('updated title') + expect(spam_logs[0].description).to eq('content here') + expect(spam_logs[0].user).to eq(user) + expect(spam_logs[0].noteable_type).to eq('Issue') + end + end + describe 'PUT /projects/:id/issues/:issue_id to update labels' do let!(:label) { create(:label, title: 'dummy', project: project) } let!(:label_link) { create(:label_link, label: label, target: issue) } diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index f56876bcf54..da9df56401b 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -78,43 +78,33 @@ describe API::ProjectSnippets, api: true do allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) end - context 'when the project is private' do - let(:private_project) { create(:project_empty_repo, :private) } - - context 'when the snippet is public' do - it 'creates the snippet' do - expect { create_snippet(private_project, visibility_level: Snippet::PUBLIC) }. - to change { Snippet.count }.by(1) - end + context 'when the snippet is private' do + it 'creates the snippet' do + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end - context 'when the project is public' do - context 'when the snippet is private' do - it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) - end + context 'when the snippet is public' do + it 'rejects the shippet' do + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) end - context 'when the snippet is public' do - it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } - expect(response).to have_http_status(400) - end - - it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) - end + it 'creates a spam log' do + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end end describe 'PUT /projects/:project_id/snippets/:id/' do - let(:snippet) { create(:project_snippet, author: admin) } + let(:visibility_level) { Snippet::PUBLIC } + let(:snippet) { create(:project_snippet, author: admin, visibility_level: visibility_level) } it 'updates snippet' do new_content = 'New content' @@ -138,6 +128,56 @@ describe API::ProjectSnippets, api: true do expect(response).to have_http_status(400) end + + context 'when the snippet is spam' do + def update_snippet(snippet_params = {}) + put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), snippet_params + end + + before do + allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) + end + + context 'when the snippet is private' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'creates the snippet' do + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') + end + end + + context 'when the snippet is public' do + let(:visibility_level) { Snippet::PUBLIC } + + it 'rejects the snippet' do + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) + end + end + + context 'when the private snippet is made public' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'rejects the snippet' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) + end + end + end end describe 'DELETE /projects/:project_id/snippets/:id/' do diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index 1ef92930b3c..41def7cd1d4 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -129,7 +129,9 @@ describe API::Snippets, api: true do it 'rejects the shippet' do expect { create_snippet(visibility_level: Snippet::PUBLIC) }. not_to change { Snippet.count } + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do @@ -141,16 +143,20 @@ describe API::Snippets, api: true do end describe 'PUT /snippets/:id' do + let(:visibility_level) { Snippet::PUBLIC } let(:other_user) { create(:user) } - let(:public_snippet) { create(:personal_snippet, :public, author: user) } + let(:snippet) do + create(:personal_snippet, author: user, visibility_level: visibility_level) + end + it 'updates snippet' do new_content = 'New content' - put api("/snippets/#{public_snippet.id}", user), content: new_content + put api("/snippets/#{snippet.id}", user), content: new_content expect(response).to have_http_status(200) - public_snippet.reload - expect(public_snippet.content).to eq(new_content) + snippet.reload + expect(snippet.content).to eq(new_content) end it 'returns 404 for invalid snippet id' do @@ -161,7 +167,7 @@ describe API::Snippets, api: true do end it "returns 404 for another user's snippet" do - put api("/snippets/#{public_snippet.id}", other_user), title: 'fubar' + put api("/snippets/#{snippet.id}", other_user), title: 'fubar' expect(response).to have_http_status(404) expect(json_response['message']).to eq('404 Snippet Not Found') @@ -172,6 +178,56 @@ describe API::Snippets, api: true do expect(response).to have_http_status(400) end + + context 'when the snippet is spam' do + def update_snippet(snippet_params = {}) + put api("/snippets/#{snippet.id}", user), snippet_params + end + + before do + allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) + end + + context 'when the snippet is private' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'updates the snippet' do + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') + end + end + + context 'when the snippet is public' do + let(:visibility_level) { Snippet::PUBLIC } + + it 'rejects the shippet' do + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) + end + end + + context 'when a private snippet is made public' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'rejects the snippet' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) + end + end + end end describe 'DELETE /snippets/:id' do diff --git a/spec/requests/api/v3/issues_spec.rb b/spec/requests/api/v3/issues_spec.rb index 33a127de98a..8e6732fe23e 100644 --- a/spec/requests/api/v3/issues_spec.rb +++ b/spec/requests/api/v3/issues_spec.rb @@ -986,6 +986,33 @@ describe API::V3::Issues, api: true do end end + describe 'PUT /projects/:id/issues/:issue_id with spam filtering' do + let(:params) do + { + title: 'updated title', + description: 'content here', + labels: 'label, label2' + } + end + + it "does not create a new project issue" do + allow_any_instance_of(SpamService).to receive_messages(check_for_spam?: true) + allow_any_instance_of(AkismetService).to receive_messages(is_spam?: true) + + put v3_api("/projects/#{project.id}/issues/#{issue.id}", user), params + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) + + spam_logs = SpamLog.all + expect(spam_logs.count).to eq(1) + expect(spam_logs[0].title).to eq('updated title') + expect(spam_logs[0].description).to eq('content here') + expect(spam_logs[0].user).to eq(user) + expect(spam_logs[0].noteable_type).to eq('Issue') + end + end + describe 'PUT /projects/:id/issues/:issue_id to update labels' do let!(:label) { create(:label, title: 'dummy', project: project) } let!(:label_link) { create(:label_link, label: label, target: issue) } diff --git a/spec/requests/api/v3/project_snippets_spec.rb b/spec/requests/api/v3/project_snippets_spec.rb index 3700477f0db..957a3bf97ef 100644 --- a/spec/requests/api/v3/project_snippets_spec.rb +++ b/spec/requests/api/v3/project_snippets_spec.rb @@ -85,43 +85,33 @@ describe API::ProjectSnippets, api: true do allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) end - context 'when the project is private' do - let(:private_project) { create(:project_empty_repo, :private) } - - context 'when the snippet is public' do - it 'creates the snippet' do - expect { create_snippet(private_project, visibility_level: Snippet::PUBLIC) }. - to change { Snippet.count }.by(1) - end + context 'when the snippet is private' do + it 'creates the snippet' do + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end - context 'when the project is public' do - context 'when the snippet is private' do - it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) - end + context 'when the snippet is public' do + it 'rejects the shippet' do + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) end - context 'when the snippet is public' do - it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } - expect(response).to have_http_status(400) - end - - it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) - end + it 'creates a spam log' do + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end end describe 'PUT /projects/:project_id/snippets/:id/' do - let(:snippet) { create(:project_snippet, author: admin) } + let(:visibility_level) { Snippet::PUBLIC } + let(:snippet) { create(:project_snippet, author: admin, visibility_level: visibility_level) } it 'updates snippet' do new_content = 'New content' @@ -145,6 +135,56 @@ describe API::ProjectSnippets, api: true do expect(response).to have_http_status(400) end + + context 'when the snippet is spam' do + def update_snippet(snippet_params = {}) + put v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), snippet_params + end + + before do + allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) + end + + context 'when the snippet is private' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'creates the snippet' do + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') + end + end + + context 'when the snippet is public' do + let(:visibility_level) { Snippet::PUBLIC } + + it 'rejects the snippet' do + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) + end + end + + context 'when the private snippet is made public' do + let(:visibility_level) { Snippet::PRIVATE } + + it 'rejects the snippet' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq({ "error" => "Spam detected" }) + end + + it 'creates a spam log' do + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) + end + end + end end describe 'DELETE /projects/:project_id/snippets/:id/' do diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb index e1feeed8a67..6045d00ff09 100644 --- a/spec/services/issues/create_service_spec.rb +++ b/spec/services/issues/create_service_spec.rb @@ -230,16 +230,6 @@ describe Issues::CreateService, services: true do expect { issue }.not_to change{SpamLog.last.recaptcha_verified} end end - - context 'when spam log title does not match the issue title' do - before do - opts[:title] = 'Another issue' - end - - it 'does not mark spam_log as recaptcha_verified' do - expect { issue }.not_to change{SpamLog.last.recaptcha_verified} - end - end end context 'when recaptcha was not verified' do diff --git a/spec/services/spam_service_spec.rb b/spec/services/spam_service_spec.rb index 271c17dd8c0..4ce3b95aa87 100644 --- a/spec/services/spam_service_spec.rb +++ b/spec/services/spam_service_spec.rb @@ -1,46 +1,61 @@ require 'spec_helper' describe SpamService, services: true do - describe '#check' do - let(:project) { create(:project, :public) } - let(:issue) { create(:issue, project: project) } - let(:request) { double(:request, env: {}) } - - def check_spam(issue, request) - described_class.new(issue, request).check - end - - context 'when indicated as spam by akismet' do - before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: true)) } - - it 'returns false when request is missing' do - expect(check_spam(issue, nil)).to be_falsey - end - - it 'returns false when issue is not public' do - issue = create(:issue, project: create(:project, :private)) - - expect(check_spam(issue, request)).to be_falsey - end - - it 'returns true' do - expect(check_spam(issue, request)).to be_truthy - end - - it 'creates a spam log' do - expect { check_spam(issue, request) }.to change { SpamLog.count }.from(0).to(1) + describe '#when_recaptcha_verified' do + def check_spam(issue, request, recaptcha_verified) + described_class.new(issue, request).when_recaptcha_verified(recaptcha_verified) do + 'yielded' end end - context 'when not indicated as spam by akismet' do - before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: false)) } + it 'yields block when recaptcha was already verified' do + issue = build_stubbed(:issue) - it 'returns false' do - expect(check_spam(issue, request)).to be_falsey + expect(check_spam(issue, nil, true)).to eql('yielded') + end + + context 'when recaptcha was not verified' do + let(:project) { create(:project, :public) } + let(:issue) { create(:issue, project: project) } + let(:request) { double(:request, env: {}) } + + context 'when indicated as spam by akismet' do + before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: true)) } + + it 'doesnt check as spam when request is missing' do + check_spam(issue, nil, false) + + expect(issue.spam).to be_falsey + end + + it 'checks as spam' do + check_spam(issue, request, false) + + expect(issue.spam).to be_truthy + end + + it 'creates a spam log' do + expect { check_spam(issue, request, false) } + .to change { SpamLog.count }.from(0).to(1) + end + + it 'doesnt yield block' do + expect(check_spam(issue, request, false)) + .to eql(SpamLog.last) + end end - it 'does not create a spam log' do - expect { check_spam(issue, request) }.not_to change { SpamLog.count } + context 'when not indicated as spam by akismet' do + before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: false)) } + + it 'returns false' do + expect(check_spam(issue, request, false)).to be_falsey + end + + it 'does not create a spam log' do + expect { check_spam(issue, request, false) } + .not_to change { SpamLog.count } + end end end end From 55f2425a678b61178d46e50f2b5a2da929228f52 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 17 Feb 2017 10:45:05 +0100 Subject: [PATCH 105/247] API: Make subscription API more RESTfuL --- .../unreleased/api-subscription-restful.yml | 4 + doc/api/v3_to_v4.md | 1 + lib/api/api.rb | 1 + lib/api/subscriptions.rb | 4 +- lib/api/v3/subscriptions.rb | 53 ++++++++++++ spec/requests/api/issues_spec.rb | 22 ++--- spec/requests/api/labels_spec.rb | 24 +++--- spec/requests/api/merge_requests_spec.rb | 22 ++--- spec/requests/api/v3/labels_spec.rb | 82 +++++++++++++++++++ 9 files changed, 177 insertions(+), 36 deletions(-) create mode 100644 changelogs/unreleased/api-subscription-restful.yml create mode 100644 lib/api/v3/subscriptions.rb diff --git a/changelogs/unreleased/api-subscription-restful.yml b/changelogs/unreleased/api-subscription-restful.yml new file mode 100644 index 00000000000..95db470e6c9 --- /dev/null +++ b/changelogs/unreleased/api-subscription-restful.yml @@ -0,0 +1,4 @@ +--- +title: 'API: - Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource.' +merge_request: 9325 +author: Robert Schilling diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index 1af124c56b1..e24ee0da204 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -29,4 +29,5 @@ changes are in V4: - Return pagination headers for all endpoints that return an array - Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead - Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` +- Make subscription API more RESTful. Use `post ":id/#{type}/:subscribable_id/subscribe"` to subscribe and `post ":id/#{type}/:subscribable_id/unsubscribe"` to unsubscribe from a resource. - Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) diff --git a/lib/api/api.rb b/lib/api/api.rb index e729c07f8c3..2e51be9fff3 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -17,6 +17,7 @@ module API mount ::API::V3::Projects mount ::API::V3::ProjectSnippets mount ::API::V3::Repositories + mount ::API::V3::Subscriptions mount ::API::V3::SystemHooks mount ::API::V3::Tags mount ::API::V3::Todos diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb index e11d7537cc9..acf11dbdf26 100644 --- a/lib/api/subscriptions.rb +++ b/lib/api/subscriptions.rb @@ -21,7 +21,7 @@ module API desc 'Subscribe to a resource' do success entity_class end - post ":id/#{type}/:subscribable_id/subscription" do + post ":id/#{type}/:subscribable_id/subscribe" do resource = instance_exec(params[:subscribable_id], &finder) if resource.subscribed?(current_user, user_project) @@ -35,7 +35,7 @@ module API desc 'Unsubscribe from a resource' do success entity_class end - delete ":id/#{type}/:subscribable_id/subscription" do + post ":id/#{type}/:subscribable_id/unsubscribe" do resource = instance_exec(params[:subscribable_id], &finder) if !resource.subscribed?(current_user, user_project) diff --git a/lib/api/v3/subscriptions.rb b/lib/api/v3/subscriptions.rb new file mode 100644 index 00000000000..02a4157c26e --- /dev/null +++ b/lib/api/v3/subscriptions.rb @@ -0,0 +1,53 @@ +module API + module V3 + class Subscriptions < Grape::API + before { authenticate! } + + subscribable_types = { + 'merge_request' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, + 'merge_requests' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, + 'issues' => proc { |id| find_project_issue(id) }, + 'labels' => proc { |id| find_project_label(id) }, + } + + params do + requires :id, type: String, desc: 'The ID of a project' + requires :subscribable_id, type: String, desc: 'The ID of a resource' + end + resource :projects do + subscribable_types.each do |type, finder| + type_singularized = type.singularize + entity_class = ::API::Entities.const_get(type_singularized.camelcase) + + desc 'Subscribe to a resource' do + success entity_class + end + post ":id/#{type}/:subscribable_id/subscription" do + resource = instance_exec(params[:subscribable_id], &finder) + + if resource.subscribed?(current_user, user_project) + not_modified! + else + resource.subscribe(current_user, user_project) + present resource, with: entity_class, current_user: current_user, project: user_project + end + end + + desc 'Unsubscribe from a resource' do + success entity_class + end + delete ":id/#{type}/:subscribable_id/subscription" do + resource = instance_exec(params[:subscribable_id], &finder) + + if !resource.subscribed?(current_user, user_project) + not_modified! + else + resource.unsubscribe(current_user, user_project) + present resource, with: entity_class, current_user: current_user, project: user_project + end + end + end + end + end + end +end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index ece1b43567d..774a8a1946f 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -1232,55 +1232,55 @@ describe API::Issues, api: true do end end - describe 'POST :id/issues/:issue_id/subscription' do + describe 'POST :id/issues/:issue_id/subscribe' do it 'subscribes to an issue' do - post api("/projects/#{project.id}/issues/#{issue.id}/subscription", user2) + post api("/projects/#{project.id}/issues/#{issue.id}/subscribe", user2) expect(response).to have_http_status(201) expect(json_response['subscribed']).to eq(true) end it 'returns 304 if already subscribed' do - post api("/projects/#{project.id}/issues/#{issue.id}/subscription", user) + post api("/projects/#{project.id}/issues/#{issue.id}/subscribe", user) expect(response).to have_http_status(304) end it 'returns 404 if the issue is not found' do - post api("/projects/#{project.id}/issues/123/subscription", user) + post api("/projects/#{project.id}/issues/123/subscribe", user) expect(response).to have_http_status(404) end it 'returns 404 if the issue is confidential' do - post api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscription", non_member) + post api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscribe", non_member) expect(response).to have_http_status(404) end end - describe 'DELETE :id/issues/:issue_id/subscription' do + describe 'POST :id/issues/:issue_id/unsubscribe' do it 'unsubscribes from an issue' do - delete api("/projects/#{project.id}/issues/#{issue.id}/subscription", user) + post api("/projects/#{project.id}/issues/#{issue.id}/unsubscribe", user) - expect(response).to have_http_status(200) + expect(response).to have_http_status(201) expect(json_response['subscribed']).to eq(false) end it 'returns 304 if not subscribed' do - delete api("/projects/#{project.id}/issues/#{issue.id}/subscription", user2) + post api("/projects/#{project.id}/issues/#{issue.id}/unsubscribe", user2) expect(response).to have_http_status(304) end it 'returns 404 if the issue is not found' do - delete api("/projects/#{project.id}/issues/123/subscription", user) + post api("/projects/#{project.id}/issues/123/unsubscribe", user) expect(response).to have_http_status(404) end it 'returns 404 if the issue is confidential' do - delete api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscription", non_member) + post api("/projects/#{project.id}/issues/#{confidential_issue.id}/unsubscribe", non_member) expect(response).to have_http_status(404) end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index 5d7a76cf3be..566d11bba57 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -318,10 +318,10 @@ describe API::Labels, api: true do end end - describe "POST /projects/:id/labels/:label_id/subscription" do + describe "POST /projects/:id/labels/:label_id/subscribe" do context "when label_id is a label title" do it "subscribes to the label" do - post api("/projects/#{project.id}/labels/#{label1.title}/subscription", user) + post api("/projects/#{project.id}/labels/#{label1.title}/subscribe", user) expect(response).to have_http_status(201) expect(json_response["name"]).to eq(label1.title) @@ -331,7 +331,7 @@ describe API::Labels, api: true do context "when label_id is a label ID" do it "subscribes to the label" do - post api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + post api("/projects/#{project.id}/labels/#{label1.id}/subscribe", user) expect(response).to have_http_status(201) expect(json_response["name"]).to eq(label1.title) @@ -343,7 +343,7 @@ describe API::Labels, api: true do before { label1.subscribe(user, project) } it "returns 304" do - post api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + post api("/projects/#{project.id}/labels/#{label1.id}/subscribe", user) expect(response).to have_http_status(304) end @@ -351,21 +351,21 @@ describe API::Labels, api: true do context "when label ID is not found" do it "returns 404 error" do - post api("/projects/#{project.id}/labels/1234/subscription", user) + post api("/projects/#{project.id}/labels/1234/subscribe", user) expect(response).to have_http_status(404) end end end - describe "DELETE /projects/:id/labels/:label_id/subscription" do + describe "POST /projects/:id/labels/:label_id/unsubscribe" do before { label1.subscribe(user, project) } context "when label_id is a label title" do it "unsubscribes from the label" do - delete api("/projects/#{project.id}/labels/#{label1.title}/subscription", user) + post api("/projects/#{project.id}/labels/#{label1.title}/unsubscribe", user) - expect(response).to have_http_status(200) + expect(response).to have_http_status(201) expect(json_response["name"]).to eq(label1.title) expect(json_response["subscribed"]).to be_falsey end @@ -373,9 +373,9 @@ describe API::Labels, api: true do context "when label_id is a label ID" do it "unsubscribes from the label" do - delete api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + post api("/projects/#{project.id}/labels/#{label1.id}/unsubscribe", user) - expect(response).to have_http_status(200) + expect(response).to have_http_status(201) expect(json_response["name"]).to eq(label1.title) expect(json_response["subscribed"]).to be_falsey end @@ -385,7 +385,7 @@ describe API::Labels, api: true do before { label1.unsubscribe(user, project) } it "returns 304" do - delete api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + post api("/projects/#{project.id}/labels/#{label1.id}/unsubscribe", user) expect(response).to have_http_status(304) end @@ -393,7 +393,7 @@ describe API::Labels, api: true do context "when label ID is not found" do it "returns 404 error" do - delete api("/projects/#{project.id}/labels/1234/subscription", user) + post api("/projects/#{project.id}/labels/1234/unsubscribe", user) expect(response).to have_http_status(404) end diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index f4dee4a4ca1..c125df8b90b 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -662,22 +662,22 @@ describe API::MergeRequests, api: true do end end - describe 'POST :id/merge_requests/:merge_request_id/subscription' do + describe 'POST :id/merge_requests/:merge_request_id/subscribe' do it 'subscribes to a merge request' do - post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", admin) + post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscribe", admin) expect(response).to have_http_status(201) expect(json_response['subscribed']).to eq(true) end it 'returns 304 if already subscribed' do - post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", user) + post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscribe", user) expect(response).to have_http_status(304) end it 'returns 404 if the merge request is not found' do - post api("/projects/#{project.id}/merge_requests/123/subscription", user) + post api("/projects/#{project.id}/merge_requests/123/subscribe", user) expect(response).to have_http_status(404) end @@ -686,28 +686,28 @@ describe API::MergeRequests, api: true do guest = create(:user) project.team << [guest, :guest] - post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest) + post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscribe", guest) expect(response).to have_http_status(403) end end - describe 'DELETE :id/merge_requests/:merge_request_id/subscription' do + describe 'POST :id/merge_requests/:merge_request_id/unsubscribe' do it 'unsubscribes from a merge request' do - delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", user) + post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/unsubscribe", user) - expect(response).to have_http_status(200) + expect(response).to have_http_status(201) expect(json_response['subscribed']).to eq(false) end it 'returns 304 if not subscribed' do - delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", admin) + post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/unsubscribe", admin) expect(response).to have_http_status(304) end it 'returns 404 if the merge request is not found' do - post api("/projects/#{project.id}/merge_requests/123/subscription", user) + post api("/projects/#{project.id}/merge_requests/123/unsubscribe", user) expect(response).to have_http_status(404) end @@ -716,7 +716,7 @@ describe API::MergeRequests, api: true do guest = create(:user) project.team << [guest, :guest] - delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest) + post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/unsubscribe", guest) expect(response).to have_http_status(403) end diff --git a/spec/requests/api/v3/labels_spec.rb b/spec/requests/api/v3/labels_spec.rb index 18e2c0d40c8..bcb0c6b9449 100644 --- a/spec/requests/api/v3/labels_spec.rb +++ b/spec/requests/api/v3/labels_spec.rb @@ -67,4 +67,86 @@ describe API::V3::Labels, api: true do expect(priority_label_response['subscribed']).to be_falsey end end + + describe "POST /projects/:id/labels/:label_id/subscription" do + context "when label_id is a label title" do + it "subscribes to the label" do + post v3_api("/projects/#{project.id}/labels/#{label1.title}/subscription", user) + + expect(response).to have_http_status(201) + expect(json_response["name"]).to eq(label1.title) + expect(json_response["subscribed"]).to be_truthy + end + end + + context "when label_id is a label ID" do + it "subscribes to the label" do + post v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + + expect(response).to have_http_status(201) + expect(json_response["name"]).to eq(label1.title) + expect(json_response["subscribed"]).to be_truthy + end + end + + context "when user is already subscribed to label" do + before { label1.subscribe(user, project) } + + it "returns 304" do + post v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + + expect(response).to have_http_status(304) + end + end + + context "when label ID is not found" do + it "returns 404 error" do + post v3_api("/projects/#{project.id}/labels/1234/subscription", user) + + expect(response).to have_http_status(404) + end + end + end + + describe "DELETE /projects/:id/labels/:label_id/subscription" do + before { label1.subscribe(user, project) } + + context "when label_id is a label title" do + it "unsubscribes from the label" do + delete v3_api("/projects/#{project.id}/labels/#{label1.title}/subscription", user) + + expect(response).to have_http_status(200) + expect(json_response["name"]).to eq(label1.title) + expect(json_response["subscribed"]).to be_falsey + end + end + + context "when label_id is a label ID" do + it "unsubscribes from the label" do + delete v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + + expect(response).to have_http_status(200) + expect(json_response["name"]).to eq(label1.title) + expect(json_response["subscribed"]).to be_falsey + end + end + + context "when user is already unsubscribed from label" do + before { label1.unsubscribe(user, project) } + + it "returns 304" do + delete v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user) + + expect(response).to have_http_status(304) + end + end + + context "when label ID is not found" do + it "returns 404 error" do + delete v3_api("/projects/#{project.id}/labels/1234/subscription", user) + + expect(response).to have_http_status(404) + end + end + end end From 4ad2fbc35ced9d42186606e426b66857f9a7d54f Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Tue, 21 Feb 2017 16:50:21 +0000 Subject: [PATCH 106/247] Fix broken test --- app/views/projects/pipelines/_info.html.haml | 2 +- spec/features/projects/pipelines/pipeline_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 59e50d25460..0605af4fcd3 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -8,7 +8,7 @@ .header-action-buttons - if can?(current_user, :update_pipeline, @pipeline.project) - if @pipeline.retryable? - = link_to "Retry", retry_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), class: 'btn btn-inverted-secondary', method: :post + = link_to "Retry", retry_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), class: 'js-retry-button btn btn-inverted-secondary', method: :post - if @pipeline.cancelable? = link_to "Cancel running", cancel_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 9cae000388f..9f06e52ab55 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -226,7 +226,7 @@ describe 'Pipeline', :feature, :js do it { expect(page).not_to have_content('retried') } context 'when retrying' do - before { find('js-retry-button').trigger('click') } + before { find('.js-retry-button').trigger('click') } it { expect(page).not_to have_content('Retry') } it { expect(page).to have_selector('.retried') } From 2707cfc1e0734478a9ef6c56912315cfb69dbb7a Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Tue, 21 Feb 2017 18:01:53 +0100 Subject: [PATCH 107/247] Upgrade Rails to 4.2.8 --- Gemfile | 2 +- Gemfile.lock | 87 +++++++++++++++++++++++++--------------------------- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/Gemfile b/Gemfile index ccbbb11c5d9..f0cb92cfae2 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails', '4.2.7.1' +gem 'rails', '4.2.8' gem 'rails-deprecated_sanitizer', '~> 1.0.3' # Responders respond_to and respond_with diff --git a/Gemfile.lock b/Gemfile.lock index 4f98dc9d085..e0c600f64c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,40 +3,39 @@ GEM specs: RedCloth (4.3.2) ace-rails-ap (4.1.0) - actionmailer (4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) + actionmailer (4.2.8) + actionpack (= 4.2.8) + actionview (= 4.2.8) + activejob (= 4.2.8) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.7.1) - actionview (= 4.2.7.1) - activesupport (= 4.2.7.1) + actionpack (4.2.8) + actionview (= 4.2.8) + activesupport (= 4.2.8) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.7.1) - activesupport (= 4.2.7.1) + actionview (4.2.8) + activesupport (= 4.2.8) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - activejob (4.2.7.1) - activesupport (= 4.2.7.1) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (4.2.8) + activesupport (= 4.2.8) globalid (>= 0.3.0) - activemodel (4.2.7.1) - activesupport (= 4.2.7.1) + activemodel (4.2.8) + activesupport (= 4.2.8) builder (~> 3.1) - activerecord (4.2.7.1) - activemodel (= 4.2.7.1) - activesupport (= 4.2.7.1) + activerecord (4.2.8) + activemodel (= 4.2.8) + activesupport (= 4.2.8) arel (~> 6.0) activerecord_sane_schema_dumper (0.2) rails (>= 4, < 5) - activesupport (4.2.7.1) + activesupport (4.2.8) i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) @@ -47,7 +46,7 @@ GEM activerecord (>= 3.0) akismet (2.0.0) allocations (1.0.5) - arel (6.0.3) + arel (6.0.4) asana (0.4.0) faraday (~> 0.9) faraday_middleware (~> 0.9) @@ -86,7 +85,7 @@ GEM sass (>= 3.3.4) brakeman (3.4.1) browser (2.2.0) - builder (3.2.2) + builder (3.2.3) bullet (5.2.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.10.0) @@ -127,7 +126,7 @@ GEM execjs coffee-script-source (1.10.0) colorize (0.7.7) - concurrent-ruby (1.0.2) + concurrent-ruby (1.0.4) connection_pool (2.2.1) crack (0.4.3) safe_yaml (~> 1.0.0) @@ -354,7 +353,7 @@ GEM json (~> 1.8) multi_xml (>= 0.5.2) httpclient (2.8.2) - i18n (0.7.0) + i18n (0.8.0) ice_nine (0.11.1) influxdb (0.2.3) cause @@ -370,7 +369,7 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.5) railties (>= 3.2.16) - json (1.8.3) + json (1.8.6) json-schema (2.6.2) addressable (~> 2.3.8) jwt (1.5.6) @@ -429,9 +428,8 @@ GEM net-ssh (3.0.1) netrc (0.11.0) newrelic_rpm (3.16.0.318) - nokogiri (1.6.8) + nokogiri (1.6.8.1) mini_portile2 (~> 2.1.0) - pkg-config (~> 1.1.7) numerizer (0.1.1) oauth (0.5.1) oauth2 (1.2.0) @@ -506,7 +504,6 @@ GEM parser (2.3.1.4) ast (~> 2.2) pg (0.18.4) - pkg-config (1.1.7) poltergeist (1.9.0) capybara (~> 2.1) cliver (~> 0.3.1) @@ -548,28 +545,28 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) - rails (4.2.7.1) - actionmailer (= 4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) - activemodel (= 4.2.7.1) - activerecord (= 4.2.7.1) - activesupport (= 4.2.7.1) + rails (4.2.8) + actionmailer (= 4.2.8) + actionpack (= 4.2.8) + actionview (= 4.2.8) + activejob (= 4.2.8) + activemodel (= 4.2.8) + activerecord (= 4.2.8) + activesupport (= 4.2.8) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.7.1) + railties (= 4.2.8) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.7) + rails-dom-testing (1.0.8) activesupport (>= 4.2.0.beta, < 5.0) - nokogiri (~> 1.6.0) + nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (4.2.7.1) - actionpack (= 4.2.7.1) - activesupport (= 4.2.7.1) + railties (4.2.8) + actionpack (= 4.2.8) + activesupport (= 4.2.8) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.1.0) @@ -733,10 +730,10 @@ GEM spring (>= 0.9.1) spring-commands-spinach (1.1.0) spring (>= 0.9.1) - sprockets (3.7.0) + sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.1.1) + sprockets-rails (3.2.0) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) @@ -760,7 +757,7 @@ GEM daemons (~> 1.0, >= 1.0.9) eventmachine (~> 1.0, >= 1.0.4) rack (>= 1, < 3) - thor (0.19.1) + thor (0.19.4) thread_safe (0.3.5) tilt (2.0.5) timecop (0.8.1) @@ -949,7 +946,7 @@ DEPENDENCIES rack-cors (~> 0.4.0) rack-oauth2 (~> 1.2.1) rack-proxy (~> 0.6.0) - rails (= 4.2.7.1) + rails (= 4.2.8) rails-deprecated_sanitizer (~> 1.0.3) rainbow (~> 2.1.0) rblineprof (~> 0.3.6) From 4f115a090a931c3999f6b51d9fa027165b96b618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Tue, 21 Feb 2017 18:48:22 +0100 Subject: [PATCH 108/247] Fix specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/features/variables_spec.rb | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb index a07eba2f01e..a362d6fd3b6 100644 --- a/spec/features/variables_spec.rb +++ b/spec/features/variables_spec.rb @@ -16,18 +16,17 @@ describe 'Project variables', js: true do it 'shows list of variables' do page.within('.variables-table') do expect(page).to have_content(variable.key) - expect(page).to have_content(variable.value) end end it 'adds new variable' do - fill_in('variable_key', with: 'new_key') - fill_in('variable_value', with: 'new value') + fill_in('variable_key', with: 'key') + fill_in('variable_value', with: 'key value') click_button('Add new variable') + expect(page).to have_content('Variables were successfully updated.') page.within('.variables-table') do - expect(page).to have_content('new_key') - expect(page).to have_content('new value') + expect(page).to have_content('key') end end @@ -36,6 +35,7 @@ describe 'Project variables', js: true do fill_in('variable_value', with: '') click_button('Add new variable') + expect(page).to have_content('Variables were successfully updated.') page.within('.variables-table') do expect(page).to have_content('new_key') end @@ -80,16 +80,12 @@ describe 'Project variables', js: true do end expect(page).to have_content('Update variable') - fill_in('variable_key', with: 'new_key') - fill_in('variable_value', with: 'new value') + fill_in('variable_key', with: 'key') + fill_in('variable_value', with: 'key value') click_button('Save variable') - page.within('.variables-table') do - expect(page).not_to have_content(variable.key) - expect(page).not_to have_content(variable.value) - expect(page).to have_content('new_key') - expect(page).to have_content('new value') - end + expect(page).to have_content('Variable was successfully updated.') + expect(project.variables.first.value).to eq('key value') end it 'edits variable with empty value' do @@ -101,9 +97,7 @@ describe 'Project variables', js: true do fill_in('variable_value', with: '') click_button('Save variable') - page.within('.variables-table') do - expect(page).to have_content(variable.key) - expect(page).not_to have_content(variable.value) - end + expect(page).to have_content('Variable was successfully updated.') + expect(project.variables.first.value).to eq('') end end From 649a1fcf15a239c08911040e355da112a33a2f31 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Tue, 21 Feb 2017 18:50:28 +0100 Subject: [PATCH 109/247] Fix incomming email check task to use same patch we did in mail_room --- lib/tasks/gitlab/check.rake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 35c4194e87c..6102517e730 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -724,8 +724,11 @@ namespace :gitlab do def check_imap_authentication print "IMAP server credentials are correct? ... " - config_path = Rails.root.join('config', 'mail_room.yml') - config_file = YAML.load(ERB.new(File.read(config_path)).result) + config_path = Rails.root.join('config', 'mail_room.yml').to_s + erb = ERB.new(File.read(config_path)) + erb.filename = config_path + config_file = YAML.load(erb.result) + config = config_file[:mailboxes].first if config From 649c095a671f9fcf6f09449c96b145761a2d6817 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Wed, 15 Feb 2017 16:13:53 -0600 Subject: [PATCH 110/247] Add filtered search to MR page --- app/assets/javascripts/dispatcher.js.es6 | 2 +- .../filtered_search/dropdown_hint.js.es6 | 29 +- .../filtered_search_dropdown.js.es6 | 27 +- .../filtered_search_dropdown_manager.js.es6 | 6 +- .../filtered_search_manager.js.es6 | 15 +- .../javascripts/search_autocomplete.js.es6 | 4 +- .../projects/merge_requests_controller.rb | 11 + .../projects/merge_requests/index.html.haml | 7 +- .../shared/issuable/_search_bar.html.haml | 8 +- .../unreleased/add-filtered-search-to-mr.yml | 4 + features/project/merge_requests.feature | 7 - .../filtered_search/dropdown_label_spec.rb | 8 +- .../filtered_search/filter_issues_spec.rb | 14 +- .../merge_requests/filter_by_labels_spec.rb | 84 ++---- .../filter_by_milestone_spec.rb | 35 ++- .../filter_merge_requests_spec.rb | 281 +++++++----------- .../merge_requests/reset_filters_spec.rb | 29 +- spec/features/search_spec.rb | 4 +- spec/javascripts/search_autocomplete_spec.js | 4 +- spec/support/filtered_search_helpers.rb | 37 +++ spec/support/merge_request_helpers.rb | 9 + 21 files changed, 281 insertions(+), 344 deletions(-) create mode 100644 changelogs/unreleased/add-filtered-search-to-mr.yml create mode 100644 spec/support/filtered_search_helpers.rb diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 index 45aa6050aed..f55db02f0fd 100644 --- a/app/assets/javascripts/dispatcher.js.es6 +++ b/app/assets/javascripts/dispatcher.js.es6 @@ -74,7 +74,7 @@ const ShortcutsBlob = require('./shortcuts_blob'); case 'projects:merge_requests:index': case 'projects:issues:index': if (gl.FilteredSearchManager) { - new gl.FilteredSearchManager(); + new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests'); } Issuable.init(); new gl.IssuableBulkActions({ diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 index 572c221929a..9e92d544bef 100644 --- a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 @@ -37,23 +37,18 @@ require('./filtered_search_dropdown'); } renderContent() { - const dropdownData = [{ - icon: 'fa-pencil', - hint: 'author:', - tag: '<@author>', - }, { - icon: 'fa-user', - hint: 'assignee:', - tag: '<@assignee>', - }, { - icon: 'fa-clock-o', - hint: 'milestone:', - tag: '<%milestone>', - }, { - icon: 'fa-tag', - hint: 'label:', - tag: '<~label>', - }]; + const dropdownData = []; + + [].forEach.call(this.input.parentElement.querySelectorAll('.dropdown-menu'), (dropdownMenu) => { + const { icon, hint, tag } = dropdownMenu.dataset; + if (icon && hint && tag) { + dropdownData.push({ + icon: `fa-${icon}`, + hint, + tag: `<${tag}>`, + }); + } + }); this.droplab.changeHookList(this.hookId, this.dropdown, [droplabFilter], this.config); this.droplab.setData(this.hookId, dropdownData); diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 index e8c2df03a46..fbc72a3001a 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 @@ -52,8 +52,9 @@ } renderContent(forceShowList = false) { - if (forceShowList && this.getCurrentHook().list.hidden) { - this.getCurrentHook().list.show(); + const currentHook = this.getCurrentHook(); + if (forceShowList && currentHook && currentHook.list.hidden) { + currentHook.list.show(); } } @@ -92,18 +93,24 @@ } hideDropdown() { - this.getCurrentHook().list.hide(); + const currentHook = this.getCurrentHook(); + if (currentHook) { + currentHook.list.hide(); + } } resetFilters() { const hook = this.getCurrentHook(); - const data = hook.list.data; - const results = data.map((o) => { - const updated = o; - updated.droplab_hidden = false; - return updated; - }); - hook.list.render(results); + + if (hook) { + const data = hook.list.data; + const results = data.map((o) => { + const updated = o; + updated.droplab_hidden = false; + return updated; + }); + hook.list.render(results); + } } } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 8ce4cf4fc36..cecd3518ce3 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -2,10 +2,12 @@ (() => { class FilteredSearchDropdownManager { - constructor(baseEndpoint = '') { + constructor(baseEndpoint = '', page) { this.baseEndpoint = baseEndpoint.replace(/\/$/, ''); this.tokenizer = gl.FilteredSearchTokenizer; + this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeys; this.filteredSearchInput = document.querySelector('.filtered-search'); + this.page = page; this.setupMapping(); @@ -150,7 +152,7 @@ this.droplab = new DropLab(); } - const match = gl.FilteredSearchTokenKeys.searchByKey(dropdownName.toLowerCase()); + const match = this.filteredSearchTokenKeys.searchByKey(dropdownName.toLowerCase()); const shouldOpenFilterDropdown = match && this.currentDropdown !== match.key && this.mapping[match.key]; const shouldOpenHintDropdown = !match && this.currentDropdown !== 'hint'; diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 index 13a9bf59246..bbafead0305 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -1,12 +1,13 @@ (() => { class FilteredSearchManager { - constructor() { + constructor(page) { this.filteredSearchInput = document.querySelector('.filtered-search'); this.clearSearchButton = document.querySelector('.clear-search'); + this.filteredSearchTokenKeys = gl.FilteredSearchTokenKeys; if (this.filteredSearchInput) { this.tokenizer = gl.FilteredSearchTokenizer; - this.dropdownManager = new gl.FilteredSearchDropdownManager(this.filteredSearchInput.getAttribute('data-base-endpoint') || ''); + this.dropdownManager = new gl.FilteredSearchDropdownManager(this.filteredSearchInput.getAttribute('data-base-endpoint') || '', page); this.bindEvents(); this.loadSearchParamsFromURL(); @@ -117,8 +118,8 @@ const keyParam = decodeURIComponent(split[0]); const value = split[1]; - // Check if it matches edge conditions listed in gl.FilteredSearchTokenKeys - const condition = gl.FilteredSearchTokenKeys.searchByConditionUrl(p); + // Check if it matches edge conditions listed in this.filteredSearchTokenKeys + const condition = this.filteredSearchTokenKeys.searchByConditionUrl(p); if (condition) { inputValues.push(`${condition.tokenKey}:${condition.value}`); @@ -126,7 +127,7 @@ // Sanitize value since URL converts spaces into + // Replace before decode so that we know what was originally + versus the encoded + const sanitizedValue = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : value; - const match = gl.FilteredSearchTokenKeys.searchByKeyParam(keyParam); + const match = this.filteredSearchTokenKeys.searchByKeyParam(keyParam); if (match) { const indexOf = keyParam.indexOf('_'); @@ -171,9 +172,9 @@ paths.push(`state=${currentState}`); tokens.forEach((token) => { - const condition = gl.FilteredSearchTokenKeys + const condition = this.filteredSearchTokenKeys .searchByConditionKeyValue(token.key, token.value.toLowerCase()); - const { param } = gl.FilteredSearchTokenKeys.searchByKey(token.key) || {}; + const { param } = this.filteredSearchTokenKeys.searchByKey(token.key) || {}; const keyParam = param ? `${token.key}_${param}` : token.key; let tokenPath = ''; diff --git a/app/assets/javascripts/search_autocomplete.js.es6 b/app/assets/javascripts/search_autocomplete.js.es6 index 6250e75d407..6fd5345a0a6 100644 --- a/app/assets/javascripts/search_autocomplete.js.es6 +++ b/app/assets/javascripts/search_autocomplete.js.es6 @@ -169,10 +169,10 @@ url: issuesPath + "/?author_username=" + userName }, 'separator', { text: 'Merge requests assigned to me', - url: mrPath + "/?assignee_id=" + userId + url: mrPath + "/?assignee_username=" + userName }, { text: "Merge requests I've created", - url: mrPath + "/?author_id=" + userId + url: mrPath + "/?author_username=" + userName } ]; if (!name) { diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 2bf3542d089..75971faa93e 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -50,6 +50,17 @@ class Projects::MergeRequestsController < Projects::ApplicationController @labels = LabelsFinder.new(current_user, labels_params).execute end + @users = [] + if params[:assignee_id].present? + assignee = User.find_by_id(params[:assignee_id]) + @users.push(assignee) if assignee + end + + if params[:author_id].present? + author = User.find_by_id(params[:author_id]) + @users.push(author) if author + end + respond_to do |format| format.html format.json do diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index 144b3a9c8c8..83e6c026ba7 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -5,18 +5,19 @@ = render "projects/issues/head" = render 'projects/last_push' +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag('filtered_search') + %div{ class: container_class } .top-area = render 'shared/issuable/nav', type: :merge_requests .nav-controls - = render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project) - - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project)) - if merge_project = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do New Merge Request - = render 'shared/issuable/filter', type: :merge_requests + = render 'shared/issuable/search_bar', type: :merge_requests .merge-requests-holder = render 'merge_requests' diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index 6e417aa2251..8e04b50bb8a 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -32,7 +32,7 @@ {{hint}} %span.js-filter-tag.dropdown-light-content {{tag}} - #js-dropdown-author.dropdown-menu + #js-dropdown-author.dropdown-menu{ data: { icon: 'pencil', hint: 'author', tag: '@author' } } %ul.filter-dropdown{ 'data-dynamic' => true, 'data-dropdown' => true } %li.filter-dropdown-item %button.btn.btn-link.dropdown-user @@ -42,7 +42,7 @@ {{name}} %span.dropdown-light-content @{{username}} - #js-dropdown-assignee.dropdown-menu + #js-dropdown-assignee.dropdown-menu{ data: { icon: 'user', hint: 'assignee', tag: '@assignee' } } %ul{ 'data-dropdown' => true } %li.filter-dropdown-item{ 'data-value' => 'none' } %button.btn.btn-link @@ -57,7 +57,7 @@ {{name}} %span.dropdown-light-content @{{username}} - #js-dropdown-milestone.dropdown-menu{ 'data-dropdown' => true } + #js-dropdown-milestone.dropdown-menu{ data: { icon: 'clock-o', hint: 'milestone', tag: '%milestone' } } %ul{ 'data-dropdown' => true } %li.filter-dropdown-item{ 'data-value' => 'none' } %button.btn.btn-link @@ -70,7 +70,7 @@ %li.filter-dropdown-item %button.btn.btn-link.js-data-value {{title}} - #js-dropdown-label.dropdown-menu{ 'data-dropdown' => true } + #js-dropdown-label.dropdown-menu{ data: { icon: 'tag', hint: 'label', tag: '~label' } } %ul{ 'data-dropdown' => true } %li.filter-dropdown-item{ 'data-value' => 'none' } %button.btn.btn-link diff --git a/changelogs/unreleased/add-filtered-search-to-mr.yml b/changelogs/unreleased/add-filtered-search-to-mr.yml new file mode 100644 index 00000000000..e3577e2aec7 --- /dev/null +++ b/changelogs/unreleased/add-filtered-search-to-mr.yml @@ -0,0 +1,4 @@ +--- +title: Add filtered search to MR page +merge_request: +author: diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index 5aa592e9067..bcde497553b 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -293,13 +293,6 @@ Feature: Project Merge Requests And I preview a description text like "Bug fixed :smile:" Then I should see the Markdown write tab - @javascript - Scenario: I search merge request - Given I click link "All" - When I fill in merge request search with "Fe" - Then I should see "Feature NS-03" in merge requests - And I should not see "Bug NS-04" in merge requests - @javascript Scenario: I can unsubscribe from merge request Given I visit merge request page "Bug NS-04" diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index c6a88e1b7b0..ab3b868fd3a 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' describe 'Dropdown label', js: true, feature: true do + include FilteredSearchHelpers + let(:project) { create(:empty_project) } let(:user) { create(:user) } let(:filtered_search) { find('.filtered-search') } @@ -17,12 +19,6 @@ describe 'Dropdown label', js: true, feature: true do let!(:long_label) { create(:label, project: project, title: 'this is a very long title this is a very long title this is a very long title this is a very long title this is a very long title') } end - def init_label_search - filtered_search.set('label:') - # This ensures the dropdown is shown - expect(find(js_dropdown_label)).not_to have_css('.filter-dropdown-loading') - end - def search_for_label(label) init_label_search filtered_search.send_keys(label) diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 64f448a83b7..0420e64d42c 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' describe 'Filter issues', js: true, feature: true do + include FilteredSearchHelpers include WaitForAjax let!(:group) { create(:group) } @@ -17,19 +18,6 @@ describe 'Filter issues', js: true, feature: true do let!(:multiple_words_label) { create(:label, project: project, title: "Two words") } let!(:closed_issue) { create(:issue, title: 'bug that is closed', project: project, state: :closed) } - let(:filtered_search) { find('.filtered-search') } - - def input_filtered_search(search_term, submit: true) - filtered_search.set(search_term) - - if submit - filtered_search.send_keys(:enter) - end - end - - def expect_filtered_search_input(input) - expect(find('.filtered-search').value).to eq(input) - end def expect_no_issues_list page.within '.issues-list' do diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb index 4c60329865c..55f3c1863ff 100644 --- a/spec/features/merge_requests/filter_by_labels_spec.rb +++ b/spec/features/merge_requests/filter_by_labels_spec.rb @@ -1,6 +1,8 @@ require 'rails_helper' feature 'Issue filtering by Labels', feature: true, js: true do + include FilteredSearchHelpers + include MergeRequestHelpers include WaitForAjax let(:project) { create(:project, :public) } @@ -32,123 +34,77 @@ feature 'Issue filtering by Labels', feature: true, js: true do context 'filter by label bug' do before do - select_labels('bug') + input_filtered_search('label:~bug') end it 'apply the filter' do expect(page).to have_content "Bugfix1" expect(page).to have_content "Bugfix2" expect(page).not_to have_content "Feature1" - expect(find('.filtered-labels')).to have_content "bug" - expect(find('.filtered-labels')).not_to have_content "feature" - expect(find('.filtered-labels')).not_to have_content "enhancement" - - find('.js-label-filter-remove').click - wait_for_ajax - expect(find('.filtered-labels', visible: false)).to have_no_content "bug" end end context 'filter by label feature' do before do - select_labels('feature') + input_filtered_search('label:~feature') end it 'applies the filter' do expect(page).to have_content "Feature1" expect(page).not_to have_content "Bugfix2" expect(page).not_to have_content "Bugfix1" - expect(find('.filtered-labels')).to have_content "feature" - expect(find('.filtered-labels')).not_to have_content "bug" - expect(find('.filtered-labels')).not_to have_content "enhancement" end end context 'filter by label enhancement' do before do - select_labels('enhancement') + input_filtered_search('label:~enhancement') end it 'applies the filter' do expect(page).to have_content "Bugfix2" expect(page).not_to have_content "Feature1" expect(page).not_to have_content "Bugfix1" - expect(find('.filtered-labels')).to have_content "enhancement" - expect(find('.filtered-labels')).not_to have_content "bug" - expect(find('.filtered-labels')).not_to have_content "feature" end end context 'filter by label enhancement and bug in issues list' do before do - select_labels('bug', 'enhancement') + input_filtered_search('label:~bug label:~enhancement') end it 'applies the filters' do expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) expect(page).to have_content "Bugfix2" expect(page).not_to have_content "Feature1" - expect(find('.filtered-labels')).to have_content "bug" - expect(find('.filtered-labels')).to have_content "enhancement" - expect(find('.filtered-labels')).not_to have_content "feature" - - find('.js-label-filter-remove', match: :first).click - wait_for_ajax - - expect(page).to have_content "Bugfix2" - expect(page).not_to have_content "Feature1" - expect(page).not_to have_content "Bugfix1" - expect(find('.filtered-labels')).not_to have_content "bug" - expect(find('.filtered-labels')).to have_content "enhancement" - expect(find('.filtered-labels')).not_to have_content "feature" end end - context 'remove filtered labels' do + context 'clear button' do before do - page.within '.labels-filter' do - click_button 'Label' - wait_for_ajax - click_link 'bug' - find('.dropdown-menu-close').click - end - - page.within '.filtered-labels' do - expect(page).to have_content 'bug' - end + input_filtered_search('label:~bug') end it 'allows user to remove filtered labels' do - first('.js-label-filter-remove').click - wait_for_ajax + first('.clear-search').click + filtered_search.send_keys(:enter) - expect(find('.filtered-labels', visible: false)).not_to have_content 'bug' - expect(find('.labels-filter')).not_to have_content 'bug' + expect(page).to have_issuable_counts(open: 3, closed: 0, all: 3) + expect(page).to have_content "Bugfix2" + expect(page).to have_content "Feature1" + expect(page).to have_content "Bugfix1" end end - context 'dropdown filtering' do + context 'filter dropdown' do it 'filters by label name' do - page.within '.labels-filter' do - click_button 'Label' - wait_for_ajax - find('.dropdown-input input').set 'bug' + init_label_search + filtered_search.send_keys('~bug') - page.within '.dropdown-content' do - expect(page).not_to have_content 'enhancement' - expect(page).to have_content 'bug' - end + page.within '.filter-dropdown' do + expect(page).not_to have_content 'enhancement' + expect(page).to have_content 'bug' end end end - - def select_labels(*labels) - page.find('.js-label-select').click - wait_for_ajax - labels.each do |label| - execute_script("$('.dropdown-menu-labels li:contains(\"#{label}\") a').click()") - end - page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click - wait_for_ajax - end end diff --git a/spec/features/merge_requests/filter_by_milestone_spec.rb b/spec/features/merge_requests/filter_by_milestone_spec.rb index f6e9230c8da..5608cda28f8 100644 --- a/spec/features/merge_requests/filter_by_milestone_spec.rb +++ b/spec/features/merge_requests/filter_by_milestone_spec.rb @@ -1,10 +1,18 @@ require 'rails_helper' feature 'Merge Request filtering by Milestone', feature: true do + include FilteredSearchHelpers + include MergeRequestHelpers + let(:project) { create(:project, :public) } let!(:user) { create(:user)} let(:milestone) { create(:milestone, project: project) } + def filter_by_milestone(title) + find(".js-milestone-select").click + find(".milestone-filter a", text: title).click + end + before do project.team << [user, :master] login_as(user) @@ -15,42 +23,42 @@ feature 'Merge Request filtering by Milestone', feature: true do create(:merge_request, :simple, source_project: project, milestone: milestone) visit_merge_requests(project) - filter_by_milestone(Milestone::None.title) + input_filtered_search('milestone:none') expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) expect(page).to have_css('.merge-request', count: 1) end context 'filters by upcoming milestone', js: true do - it 'does not show issues with no expiry' do + it 'does not show merge requests with no expiry' do create(:merge_request, :with_diffs, source_project: project) create(:merge_request, :simple, source_project: project, milestone: milestone) visit_merge_requests(project) - filter_by_milestone(Milestone::Upcoming.title) + input_filtered_search('milestone:upcoming') expect(page).to have_css('.merge-request', count: 0) end - it 'shows issues in future' do + it 'shows merge requests in future' do milestone = create(:milestone, project: project, due_date: Date.tomorrow) create(:merge_request, :with_diffs, source_project: project) create(:merge_request, :simple, source_project: project, milestone: milestone) visit_merge_requests(project) - filter_by_milestone(Milestone::Upcoming.title) + input_filtered_search('milestone:upcoming') expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) expect(page).to have_css('.merge-request', count: 1) end - it 'does not show issues in past' do + it 'does not show merge requests in past' do milestone = create(:milestone, project: project, due_date: Date.yesterday) create(:merge_request, :with_diffs, source_project: project) create(:merge_request, :simple, source_project: project, milestone: milestone) visit_merge_requests(project) - filter_by_milestone(Milestone::Upcoming.title) + input_filtered_search('milestone:upcoming') expect(page).to have_css('.merge-request', count: 0) end @@ -61,7 +69,7 @@ feature 'Merge Request filtering by Milestone', feature: true do create(:merge_request, :simple, source_project: project) visit_merge_requests(project) - filter_by_milestone(milestone.title) + input_filtered_search("milestone:%'#{milestone.title}'") expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) expect(page).to have_css('.merge-request', count: 1) @@ -77,19 +85,10 @@ feature 'Merge Request filtering by Milestone', feature: true do create(:merge_request, :simple, source_project: project) visit_merge_requests(project) - filter_by_milestone(milestone.title) + input_filtered_search("milestone:%\"#{milestone.title}\"") expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) expect(page).to have_css('.merge-request', count: 1) end end - - def visit_merge_requests(project) - visit namespace_project_merge_requests_path(project.namespace, project) - end - - def filter_by_milestone(title) - find(".js-milestone-select").click - find(".milestone-filter a", text: title).click - end end diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb index 4642b5a530d..6579a88d4ab 100644 --- a/spec/features/merge_requests/filter_merge_requests_spec.rb +++ b/spec/features/merge_requests/filter_merge_requests_spec.rb @@ -1,11 +1,13 @@ require 'rails_helper' describe 'Filter merge requests', feature: true do + include FilteredSearchHelpers + include MergeRequestHelpers include WaitForAjax let!(:project) { create(:project) } let!(:group) { create(:group) } - let!(:user) { create(:user)} + let!(:user) { create(:user) } let!(:milestone) { create(:milestone, project: project) } let!(:label) { create(:label, project: project) } let!(:wontfix) { create(:label, project: project, title: "Won't fix") } @@ -15,183 +17,134 @@ describe 'Filter merge requests', feature: true do group.add_developer(user) login_as(user) create(:merge_request, source_project: project, target_project: project) + + visit namespace_project_merge_requests_path(project.namespace, project) end describe 'for assignee from mr#index' do + let(:search_query) { "assignee:@#{user.username}" } + before do - visit namespace_project_merge_requests_path(project.namespace, project) + input_filtered_search(search_query) - find('.js-assignee-search').click - - find('.dropdown-menu-user-link', text: user.username).click - - wait_for_ajax + expect_mr_list_count(0) end context 'assignee', js: true do it 'updates to current user' do - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) + expect_filtered_search_input(search_query) end it 'does not change when closed link is clicked' do find('.issues-state-filters a', text: "Closed").click - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) + expect_filtered_search_input(search_query) end it 'does not change when all link is clicked' do find('.issues-state-filters a', text: "All").click - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) + expect_filtered_search_input(search_query) end end end describe 'for milestone from mr#index' do + let(:search_query) { "milestone:%#{milestone.title}" } + before do - visit namespace_project_merge_requests_path(project.namespace, project) + input_filtered_search(search_query) - find('.js-milestone-select').click - - find('.milestone-filter .dropdown-content a', text: milestone.title).click - - wait_for_ajax + expect_mr_list_count(0) end context 'milestone', js: true do it 'updates to current milestone' do - expect(find('.js-milestone-select .dropdown-toggle-text')).to have_content(milestone.title) + expect_filtered_search_input(search_query) end it 'does not change when closed link is clicked' do find('.issues-state-filters a', text: "Closed").click - expect(find('.js-milestone-select .dropdown-toggle-text')).to have_content(milestone.title) + expect_filtered_search_input(search_query) end it 'does not change when all link is clicked' do find('.issues-state-filters a', text: "All").click - expect(find('.js-milestone-select .dropdown-toggle-text')).to have_content(milestone.title) + expect_filtered_search_input(search_query) end end end describe 'for label from mr#index', js: true do - before do - visit namespace_project_merge_requests_path(project.namespace, project) - find('.js-label-select').click - wait_for_ajax - end - - it 'filters by any label' do - find('.dropdown-menu-labels a', text: 'Any Label').click - page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click - wait_for_ajax - - expect(find('.labels-filter')).to have_content 'Label' - end - it 'filters by no label' do - find('.dropdown-menu-labels a', text: 'No Label').click - page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click - wait_for_ajax + input_filtered_search('label:none') - page.within '.labels-filter' do - expect(page).to have_content 'Labels' - end - expect(find('.js-label-select .dropdown-toggle-text')).to have_content('Labels') + expect_mr_list_count(1) + expect_filtered_search_input('label:none') end it 'filters by a label' do - find('.dropdown-menu-labels a', text: label.title).click - page.within '.labels-filter' do - expect(page).to have_content label.title - end - expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title) + input_filtered_search("label:~#{label.title}") + + expect_mr_list_count(0) + expect_filtered_search_input("label:~#{label.title}") end it "filters by `won't fix` and another label" do - page.within '.labels-filter' do - click_link wontfix.title - expect(page).to have_content wontfix.title - click_link label.title - end + input_filtered_search("label:~\"#{wontfix.title}\" label:~#{label.title}") - expect(find('.js-label-select .dropdown-toggle-text')).to have_content("#{wontfix.title} +1 more") + expect_mr_list_count(0) + expect_filtered_search_input("label:~\"#{wontfix.title}\" label:~#{label.title}") end it "filters by `won't fix` label followed by another label after page load" do - page.within '.labels-filter' do - click_link wontfix.title - expect(page).to have_content wontfix.title - end + input_filtered_search("label:~\"#{wontfix.title}\"") - find('body').click + expect_mr_list_count(0) + expect_filtered_search_input("label:~\"#{wontfix.title}\"") - expect(find('.filtered-labels')).to have_content(wontfix.title) + input_filtered_search_keys(" label:~#{label.title}") - find('.js-label-select').click - wait_for_ajax - find('.dropdown-menu-labels a', text: label.title).click + expect_filtered_search_input("label:~\"#{wontfix.title}\" label:~#{label.title}") - find('body').click - - expect(find('.filtered-labels')).to have_content(wontfix.title) - expect(find('.filtered-labels')).to have_content(label.title) - - find('.js-label-select').click - wait_for_ajax - - expect(find('.dropdown-menu-labels li', text: wontfix.title)).to have_css('.is-active') - expect(find('.dropdown-menu-labels li', text: label.title)).to have_css('.is-active') - end - - it "selects and unselects `won't fix`" do - find('.dropdown-menu-labels a', text: wontfix.title).click - find('.dropdown-menu-labels a', text: wontfix.title).click - # Close label dropdown to load - find('body').click - expect(page).not_to have_css('.filtered-labels') + expect_mr_list_count(0) + expect_filtered_search_input("label:~\"#{wontfix.title}\" label:~#{label.title}") end end describe 'for assignee and label from issues#index' do + let(:search_query) { "assignee:@#{user.username} label:~#{label.title}" } + before do - visit namespace_project_merge_requests_path(project.namespace, project) + input_filtered_search("assignee:@#{user.username}") - find('.js-assignee-search').click + expect_mr_list_count(1) + expect_filtered_search_input("assignee:@#{user.username}") - find('.dropdown-menu-user-link', text: user.username).click + input_filtered_search_keys(" label:~#{label.title}") - expect(page).not_to have_selector('.mr-list .merge-request') + expect_mr_list_count(1) - find('.js-label-select').click - - find('.dropdown-menu-labels .dropdown-content a', text: label.title).click - page.first('.labels-filter .dropdown-title .dropdown-menu-close-icon').click - - wait_for_ajax + find("#state-opened[href=\"#{URI.parse(current_url).path}?assignee_username=#{user.username}&label_name%5B%5D=#{label.title}&scope=all&state=opened\"]") end context 'assignee and label', js: true do it 'updates to current assignee and label' do - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) - expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title) + expect_filtered_search_input(search_query) end it 'does not change when closed link is clicked' do find('.issues-state-filters a', text: "Closed").click - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) - expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title) + expect_filtered_search_input(search_query) end it 'does not change when all link is clicked' do find('.issues-state-filters a', text: "All").click - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) - expect(find('.js-label-select .dropdown-toggle-text')).to have_content(label.title) + expect_filtered_search_input(search_query) end end end @@ -203,11 +156,11 @@ describe 'Filter merge requests', feature: true do bug_label = create(:label, project: project, title: 'bug') milestone = create(:milestone, title: "8", project: project) - mr = create(:merge_request, - title: "Bug 2", - source_project: project, - target_project: project, - source_branch: "bug2", + mr = create(:merge_request, + title: "Bug 2", + source_project: project, + target_project: project, + source_branch: "bug2", milestone: milestone, author: user, assignee: user) @@ -218,15 +171,13 @@ describe 'Filter merge requests', feature: true do context 'only text', js: true do it 'filters merge requests by searched text' do - fill_in 'issuable_search', with: 'Bug' + input_filtered_search('bug') - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 2) - end + expect_mr_list_count(2) end it 'does not show any merge requests' do - fill_in 'issuable_search', with: 'testing' + input_filtered_search('testing') page.within '.mr-list' do expect(page).not_to have_selector('.merge-request') @@ -234,82 +185,49 @@ describe 'Filter merge requests', feature: true do end end - context 'text and dropdown options', js: true do + context 'filters and searches', js: true do it 'filters by text and label' do - fill_in 'issuable_search', with: 'Bug' + input_filtered_search('Bug') - expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 2) - end + expect_mr_list_count(2) + expect_filtered_search_input('Bug') - click_button 'Label' - page.within '.labels-filter' do - click_link 'bug' - end - find('.dropdown-menu-close-icon').click + input_filtered_search_keys(' label:~bug') - expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 1) - end + expect_mr_list_count(1) end it 'filters by text and milestone' do - fill_in 'issuable_search', with: 'Bug' + input_filtered_search('Bug') - expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 2) - end + expect_mr_list_count(2) + expect_filtered_search_input('Bug') - click_button 'Milestone' - page.within '.milestone-filter' do - click_link '8' - end + input_filtered_search_keys(' milestone:%8') - expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 1) - end + expect_mr_list_count(1) end it 'filters by text and assignee' do - fill_in 'issuable_search', with: 'Bug' + input_filtered_search('Bug') - expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 2) - end + expect_mr_list_count(2) + expect_filtered_search_input('Bug') - click_button 'Assignee' - page.within '.dropdown-menu-assignee' do - click_link user.name - end + input_filtered_search_keys(" assignee:@#{user.username}") - expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 1) - end + expect_mr_list_count(1) end it 'filters by text and author' do - fill_in 'issuable_search', with: 'Bug' + input_filtered_search('Bug') - expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 2) - end + expect_mr_list_count(2) + expect_filtered_search_input('Bug') - click_button 'Author' - page.within '.dropdown-menu-author' do - click_link user.name - end + input_filtered_search_keys(" author:@#{user.username}") - expect(page).to have_issuable_counts(open: 1, closed: 0, all: 1) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 1) - end + expect_mr_list_count(1) end end end @@ -328,18 +246,9 @@ describe 'Filter merge requests', feature: true do end it 'is able to filter and sort merge requests' do - click_button 'Label' - wait_for_ajax - page.within '.labels-filter' do - click_link 'bug' - end - find('.dropdown-menu-close-icon').click - wait_for_ajax + input_filtered_search('label:~bug') - expect(page).to have_issuable_counts(open: 2, closed: 0, all: 2) - page.within '.mr-list' do - expect(page).to have_selector('.merge-request', count: 2) - end + expect_mr_list_count(2) click_button 'Last created' page.within '.dropdown-menu-sort' do @@ -352,4 +261,38 @@ describe 'Filter merge requests', feature: true do end end end + + describe 'filter by assignee id', js: true do + it 'filter by current user' do + visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: user.id) + + expect_filtered_search_input("assignee:@#{user.username}") + end + + it 'filter by new user' do + new_user = create(:user) + project.add_developer(new_user) + + visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: new_user.id) + + expect_filtered_search_input("assignee:@#{new_user.username}") + end + end + + describe 'filter by author id', js: true do + it 'filter by current user' do + visit namespace_project_merge_requests_path(project.namespace, project, author_id: user.id) + + expect_filtered_search_input("author:@#{user.username}") + end + + it 'filter by new user' do + new_user = create(:user) + project.add_developer(new_user) + + visit namespace_project_merge_requests_path(project.namespace, project, author_id: new_user.id) + + expect_filtered_search_input("author:@#{new_user.username}") + end + end end diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb index 3a7ece7e1d6..58f11499e3f 100644 --- a/spec/features/merge_requests/reset_filters_spec.rb +++ b/spec/features/merge_requests/reset_filters_spec.rb @@ -1,17 +1,20 @@ require 'rails_helper' feature 'Issues filter reset button', feature: true, js: true do + include FilteredSearchHelpers + include MergeRequestHelpers include WaitForAjax include IssueHelpers - let!(:project) { create(:project, :public) } - let!(:user) { create(:user)} - let!(:milestone) { create(:milestone, project: project) } - let!(:bug) { create(:label, project: project, name: 'bug')} + let!(:project) { create(:project, :public) } + let!(:user) { create(:user) } + let!(:milestone) { create(:milestone, project: project) } + let!(:bug) { create(:label, project: project, name: 'bug')} let!(:mr1) { create(:merge_request, title: "Feature", source_project: project, target_project: project, source_branch: "Feature", milestone: milestone, author: user, assignee: user) } let!(:mr2) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "Bugfix1") } - let(:merge_request_css) { '.merge-request' } + let(:merge_request_css) { '.merge-request' } + let(:clear_search_css) { '.filtered-search-input-container .clear-search' } before do mr2.labels << bug @@ -50,7 +53,7 @@ feature 'Issues filter reset button', feature: true, js: true do context 'when author filter has been applied' do it 'resets the author filter' do - visit_merge_requests(project, author_id: user.id) + visit_merge_requests(project, author_username: user.username) expect(page).to have_css(merge_request_css, count: 1) reset_filters @@ -60,7 +63,7 @@ feature 'Issues filter reset button', feature: true, js: true do context 'when assignee filter has been applied' do it 'resets the assignee filter' do - visit_merge_requests(project, assignee_id: user.id) + visit_merge_requests(project, assignee_username: user.username) expect(page).to have_css(merge_request_css, count: 1) reset_filters @@ -70,7 +73,7 @@ feature 'Issues filter reset button', feature: true, js: true do context 'when all filters have been applied' do it 'resets all filters' do - visit_merge_requests(project, assignee_id: user.id, author_id: user.id, milestone_title: milestone.title, label_name: bug.name, search: 'Bug') + visit_merge_requests(project, assignee_username: user.username, author_username: user.username, milestone_title: milestone.title, label_name: bug.name, search: 'Bug') expect(page).to have_css(merge_request_css, count: 0) reset_filters @@ -82,15 +85,7 @@ feature 'Issues filter reset button', feature: true, js: true do it 'the reset link should not be visible' do visit_merge_requests(project) expect(page).to have_css(merge_request_css, count: 2) - expect(page).not_to have_css '.reset_filters' + expect(page).not_to have_css(clear_search_css) end end - - def visit_merge_requests(project, opts = {}) - visit namespace_project_merge_requests_path project.namespace, project, opts - end - - def reset_filters - find('.reset-filters').click - end end diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index 0fe5a897565..7da05defa81 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -186,7 +186,7 @@ describe "Search", feature: true do sleep 2 expect(page).to have_selector('.merge-requests-holder') - expect(find('.js-assignee-search .dropdown-toggle-text')).to have_content(user.name) + expect(find('.filtered-search').value).to eq("assignee:@#{user.username}") end it 'takes user to her MR page when MR authored is clicked' do @@ -194,7 +194,7 @@ describe "Search", feature: true do sleep 2 expect(page).to have_selector('.merge-requests-holder') - expect(find('.js-author-search .dropdown-toggle-text')).to have_content(user.name) + expect(find('.filtered-search').value).to eq("author:@#{user.username}") end end diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js index cb8754581c0..aaf058bd755 100644 --- a/spec/javascripts/search_autocomplete_spec.js +++ b/spec/javascripts/search_autocomplete_spec.js @@ -89,8 +89,8 @@ require('vendor/fuzzaldrin-plus'); var a1, a2, a3, a4, issuesAssignedToMeLink, issuesIHaveCreatedLink, mrsAssignedToMeLink, mrsIHaveCreatedLink; issuesAssignedToMeLink = issuesPath + "/?assignee_username=" + userName; issuesIHaveCreatedLink = issuesPath + "/?author_username=" + userName; - mrsAssignedToMeLink = mrsPath + "/?assignee_id=" + userId; - mrsIHaveCreatedLink = mrsPath + "/?author_id=" + userId; + mrsAssignedToMeLink = mrsPath + "/?assignee_username=" + userName; + mrsIHaveCreatedLink = mrsPath + "/?author_username=" + userName; a1 = "a[href='" + issuesAssignedToMeLink + "']"; a2 = "a[href='" + issuesIHaveCreatedLink + "']"; a3 = "a[href='" + mrsAssignedToMeLink + "']"; diff --git a/spec/support/filtered_search_helpers.rb b/spec/support/filtered_search_helpers.rb new file mode 100644 index 00000000000..58f6636e680 --- /dev/null +++ b/spec/support/filtered_search_helpers.rb @@ -0,0 +1,37 @@ +module FilteredSearchHelpers + def filtered_search + page.find('.filtered-search') + end + + def input_filtered_search(search_term, submit: true) + filtered_search.set(search_term) + + if submit + filtered_search.send_keys(:enter) + end + end + + def input_filtered_search_keys(search_term) + filtered_search.send_keys(search_term) + filtered_search.send_keys(:enter) + end + + def expect_filtered_search_input(input) + expect(find('.filtered-search').value).to eq(input) + end + + def clear_search_field + find('.filtered-search-input-container .clear-search').click + end + + def reset_filters + clear_search_field + filtered_search.send_keys(:enter) + end + + def init_label_search + filtered_search.set('label:') + # This ensures the dropdown is shown + expect(find('#js-dropdown-label')).not_to have_css('.filter-dropdown-loading') + end +end diff --git a/spec/support/merge_request_helpers.rb b/spec/support/merge_request_helpers.rb index d5801c8272f..326b85eabd0 100644 --- a/spec/support/merge_request_helpers.rb +++ b/spec/support/merge_request_helpers.rb @@ -10,4 +10,13 @@ module MergeRequestHelpers def last_merge_request page.all('ul.mr-list > li').last.text end + + def expect_mr_list_count(open_count, closed_count = 0) + all_count = open_count + closed_count + + expect(page).to have_issuable_counts(open: open_count, closed: closed_count, all: all_count) + page.within '.mr-list' do + expect(page).to have_selector('.merge-request', count: open_count) + end + end end From c468ad75f4dba1833b139e7949dc0fa0c75c74dc Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Tue, 21 Feb 2017 13:20:38 -0600 Subject: [PATCH 111/247] Keep right padding the same whether sidebar is open or not --- app/assets/stylesheets/framework/sidebar.scss | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index d09b1c9d7f5..040a7ce0c16 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -29,14 +29,16 @@ } } +@media (min-width: $screen-sm-min) { + .content-wrapper { + padding-right: $gutter_collapsed_width; + } +} + .right-sidebar-collapsed { padding-right: 0; @media (min-width: $screen-sm-min) { - .content-wrapper { - padding-right: $gutter_collapsed_width; - } - .merge-request-tabs-holder.affix { right: $gutter_collapsed_width; } @@ -54,12 +56,6 @@ .right-sidebar-expanded { padding-right: 0; - @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { - &:not(.build-sidebar):not(.wiki-sidebar) { - padding-right: $gutter_collapsed_width; - } - } - @media (min-width: $screen-md-min) { .content-wrapper { padding-right: $gutter_width; From 0a53a3d9664187cbd8c72c24666a8ff03f3dccec Mon Sep 17 00:00:00 2001 From: mhasbini Date: Tue, 21 Feb 2017 21:21:49 +0200 Subject: [PATCH 112/247] change todos counter position & format ( for large counts ) --- app/assets/javascripts/header.js | 2 +- .../javascripts/lib/utils/text_utility.js | 3 +++ app/assets/stylesheets/pages/todos.scss | 2 ++ app/controllers/dashboard/todos_controller.rb | 5 ++++ app/helpers/todos_helper.rb | 4 ++++ app/views/layouts/header/_default.html.haml | 2 +- changelogs/unreleased/26703-todos-count.yml | 4 ++++ doc/workflow/todos.md | 3 ++- spec/features/todos/todos_spec.rb | 23 +++++++++++++++++++ spec/javascripts/header_spec.js | 4 ++-- .../lib/utils/text_utility_spec.js.es6 | 11 +++++++++ 11 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/26703-todos-count.yml diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js index fa85f9a6c86..a853c3aeb1f 100644 --- a/app/assets/javascripts/header.js +++ b/app/assets/javascripts/header.js @@ -2,7 +2,7 @@ (function() { $(document).on('todo:toggle', function(e, count) { var $todoPendingCount = $('.todos-pending-count'); - $todoPendingCount.text(gl.text.addDelimiter(count)); + $todoPendingCount.text(gl.text.highCountTrim(count)); $todoPendingCount.toggleClass('hidden', count === 0); }); })(); diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js index f755d212b3c..579d322e3fb 100644 --- a/app/assets/javascripts/lib/utils/text_utility.js +++ b/app/assets/javascripts/lib/utils/text_utility.js @@ -14,6 +14,9 @@ require('vendor/latinise'); gl.text.addDelimiter = function(text) { return text ? text.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : text; }; + gl.text.highCountTrim = function(count) { + return count > 99 ? '99+' : count; + }; gl.text.randomString = function() { return Math.random().toString(36).substring(7); }; diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index 551a66fbf3a..3258692ae2b 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -6,6 +6,8 @@ .navbar-nav { li { .badge.todos-pending-count { + position: inherit; + top: -6px; margin-top: -5px; font-weight: normal; background: $todo-alert-blue; diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 4e61b0886d8..ee2358b986d 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -35,6 +35,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController render json: todos_counts end + # Used in TodosHelper also + def self.todos_count_format(count) + count >= 100 ? '99+' : count + end + private def find_todos diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 845f1a0e840..c52afd6db1c 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -3,6 +3,10 @@ module TodosHelper @todos_pending_count ||= current_user.todos_pending_count end + def todos_count_format(count) + count > 99 ? '99+' : count + end + def todos_done_count @todos_done_count ||= current_user.todos_done_count end diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 60b9b8bdbc4..f8986893776 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -35,7 +35,7 @@ = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('bell fw') %span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) } - = todos_pending_count + = todos_count_format(todos_pending_count) - if Gitlab::Sherlock.enabled? %li = link_to sherlock_transactions_path, title: 'Sherlock Transactions', diff --git a/changelogs/unreleased/26703-todos-count.yml b/changelogs/unreleased/26703-todos-count.yml new file mode 100644 index 00000000000..24fd0c406e2 --- /dev/null +++ b/changelogs/unreleased/26703-todos-count.yml @@ -0,0 +1,4 @@ +--- +title: show 99+ for large count in todos notification bell +merge_request: 9171 +author: mhasbini diff --git a/doc/workflow/todos.md b/doc/workflow/todos.md index 6eb457fde3f..4b0fba842e9 100644 --- a/doc/workflow/todos.md +++ b/doc/workflow/todos.md @@ -16,7 +16,8 @@ in a simple dashboard. You can quickly access the Todos dashboard using the bell icon next to the search bar in the upper right corner. The number in blue is the number of Todos -you still have open. +you still have open if the count is < 100, else it's 99+. The exact number +will still be shown in the body of the _To do_ tab. ![Todos icon](img/todos_icon.png) diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb index fb19dac1d6a..3495091a0d5 100644 --- a/spec/features/todos/todos_spec.rb +++ b/spec/features/todos/todos_spec.rb @@ -171,6 +171,29 @@ describe 'Dashboard Todos', feature: true do end end + context 'User have large number of todos' do + before do + create_list(:todo, 101, :mentioned, user: user, project: project, target: issue, author: author) + + login_as(user) + visit dashboard_todos_path + end + + it 'shows 99+ for count >= 100 in notification' do + expect(page).to have_selector('.todos-pending-count', text: '99+') + end + + it 'shows exact number in To do tab' do + expect(page).to have_selector('.todos-pending .badge', text: '101') + end + + it 'shows exact number for count < 100' do + 3.times { first('.js-done-todo').click } + + expect(page).to have_selector('.todos-pending-count', text: '98') + end + end + context 'User has a Build Failed todo' do let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: author) } diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js index 576b6cfefdc..46a27b8c98f 100644 --- a/spec/javascripts/header_spec.js +++ b/spec/javascripts/header_spec.js @@ -45,8 +45,8 @@ require('~/lib/utils/text_utility'); expect(isTodosCountHidden()).toEqual(false); }); - it('should add delimiter to todos-pending-count', function() { - expect($(todosPendingCount).text()).toEqual('1,000'); + it('should show 99+ for todos-pending-count', function() { + expect($(todosPendingCount).text()).toEqual('99+'); }); }); }); diff --git a/spec/javascripts/lib/utils/text_utility_spec.js.es6 b/spec/javascripts/lib/utils/text_utility_spec.js.es6 index 86ade66ec29..06b69b8ac17 100644 --- a/spec/javascripts/lib/utils/text_utility_spec.js.es6 +++ b/spec/javascripts/lib/utils/text_utility_spec.js.es6 @@ -35,5 +35,16 @@ require('~/lib/utils/text_utility'); expect(gl.text.pluralize('test', 1)).toBe('test'); }); }); + + describe('gl.text.highCountTrim', () => { + it('returns 99+ for count >= 100', () => { + expect(gl.text.highCountTrim(105)).toBe('99+'); + expect(gl.text.highCountTrim(100)).toBe('99+'); + }); + + it('returns exact number for count < 100', () => { + expect(gl.text.highCountTrim(45)).toBe(45); + }); + }); }); })(); From 0b2fc0557f00753a552600da6e5c13d5617afaee Mon Sep 17 00:00:00 2001 From: Dmitriy Volkov Date: Sat, 11 Feb 2017 16:56:53 +0300 Subject: [PATCH 113/247] docs(ci/docker_build): Add example of variable use --- doc/ci/docker/using_docker_build.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md index 28141cced3b..174fa8393e4 100644 --- a/doc/ci/docker/using_docker_build.md +++ b/doc/ci/docker/using_docker_build.md @@ -298,6 +298,30 @@ push to the Registry connected to your project. Its password is provided in the `$CI_BUILD_TOKEN` variable. This allows you to automate building and deployment of your Docker images. +You can also make use of [other variables](../variables/README.md) to avoid hardcoding: + +```yaml +services: + - docker:dind + +variables: + IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME + +before_script: + - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY + +build: + stage: build + script: + - docker build -t $IMAGE_TAG . + - docker push $IMAGE_TAG +``` + +Here, `$CI_REGISTRY_IMAGE` would be resolved to the address of the registry tied +to this project, and `$CI_BUILD_REF_NAME` would be resolved to the branch or +tag name for this particular job. We also declare our own variable, `$IMAGE_TAG`, +combining the two to save us some typing in the `script` section. + Here's a more elaborate example that splits up the tasks into 4 pipeline stages, including two tests that run in parallel. The build is stored in the container registry and used by subsequent stages, downloading the image From c79bbe26ab1e16facddaf159d4d074937586d742 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Thu, 2 Feb 2017 12:24:30 -0200 Subject: [PATCH 114/247] Change branch_name param to branch throughout V4 API --- app/services/files/multi_service.rb | 8 +- ...32-rename-branch-name-params-to-branch.yml | 4 + doc/api/branches.md | 4 +- doc/api/commits.md | 4 +- doc/api/repository_files.md | 24 +- doc/api/v3_to_v4.md | 6 + lib/api/api.rb | 2 + lib/api/branches.rb | 6 +- lib/api/commits.rb | 7 +- lib/api/files.rb | 8 +- lib/api/v3/commits.rb | 205 +++++++ lib/api/v3/files.rb | 138 +++++ spec/requests/api/branches_spec.rb | 16 +- spec/requests/api/commits_spec.rb | 20 +- spec/requests/api/files_spec.rb | 8 +- spec/requests/api/v3/commits_spec.rb | 578 ++++++++++++++++++ spec/requests/api/v3/files_spec.rb | 270 ++++++++ 17 files changed, 1255 insertions(+), 53 deletions(-) create mode 100644 changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml create mode 100644 lib/api/v3/commits.rb create mode 100644 lib/api/v3/files.rb create mode 100644 spec/requests/api/v3/commits_spec.rb create mode 100644 spec/requests/api/v3/files_spec.rb diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb index 6ba868df04d..af6da5b9d56 100644 --- a/app/services/files/multi_service.rb +++ b/app/services/files/multi_service.rb @@ -55,7 +55,7 @@ module Files file_path = action[:file_path] file_path = action[:previous_path] if action[:action] == :move - blob = repository.blob_at_branch(params[:branch_name], file_path) + blob = repository.blob_at_branch(params[:branch], file_path) unless blob raise_error("File to be #{action[:action]}d `#{file_path}` does not exist.") @@ -89,7 +89,7 @@ module Files def validate_create(action) return if project.empty_repo? - if repository.blob_at_branch(params[:branch_name], action[:file_path]) + if repository.blob_at_branch(params[:branch], action[:file_path]) raise_error("Your changes could not be committed because a file with the name `#{action[:file_path]}` already exists.") end end @@ -102,14 +102,14 @@ module Files raise_error("You must supply the original file path when moving file `#{action[:file_path]}`.") end - blob = repository.blob_at_branch(params[:branch_name], action[:file_path]) + blob = repository.blob_at_branch(params[:branch], action[:file_path]) if blob raise_error("Move destination `#{action[:file_path]}` already exists.") end if action[:content].nil? - blob = repository.blob_at_branch(params[:branch_name], action[:previous_path]) + blob = repository.blob_at_branch(params[:branch], action[:previous_path]) blob.load_all_data!(repository) if blob.truncated? params[:actions][index][:content] = blob.data end diff --git a/changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml b/changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml new file mode 100644 index 00000000000..028923b83cf --- /dev/null +++ b/changelogs/unreleased/22132-rename-branch-name-params-to-branch.yml @@ -0,0 +1,4 @@ +--- +title: Standardize branch name params as branch on V4 API +merge_request: 8936 +author: diff --git a/doc/api/branches.md b/doc/api/branches.md index 5eaa8d2e920..765ca439720 100644 --- a/doc/api/branches.md +++ b/doc/api/branches.md @@ -193,11 +193,11 @@ POST /projects/:id/repository/branches | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `branch_name` | string | yes | The name of the branch | +| `branch` | string | yes | The name of the branch | | `ref` | string | yes | The branch name or commit SHA to create branch from | ```bash -curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/branches?branch_name=newbranch&ref=master" +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/branches?branch=newbranch&ref=master" ``` Example response: diff --git a/doc/api/commits.md b/doc/api/commits.md index eaab3e0df3d..18bc2873678 100644 --- a/doc/api/commits.md +++ b/doc/api/commits.md @@ -69,7 +69,7 @@ POST /projects/:id/repository/commits | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME | -| `branch_name` | string | yes | The name of a branch | +| `branch` | string | yes | The name of a branch | | `commit_message` | string | yes | Commit message | | `actions[]` | array | yes | An array of action hashes to commit as a batch. See the next table for what attributes it can take. | | `author_email` | string | no | Specify the commit author's email address | @@ -87,7 +87,7 @@ POST /projects/:id/repository/commits ```bash PAYLOAD=$(cat << 'JSON' { - "branch_name": "master", + "branch": "master", "commit_message": "some commit message", "actions": [ { diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md index dbb3c1113e8..677e209ccd9 100644 --- a/doc/api/repository_files.md +++ b/doc/api/repository_files.md @@ -46,22 +46,22 @@ POST /projects/:id/repository/files ``` ```bash -curl --request POST --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch_name=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20content&commit_message=create%20a%20new%20file' +curl --request POST --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20content&commit_message=create%20a%20new%20file' ``` Example response: ```json { - "file_path": "app/project.rb", - "branch_name": "master" + "file_name": "app/project.rb", + "branch": "master" } ``` Parameters: - `file_path` (required) - Full path to new file. Ex. lib/class.rb -- `branch_name` (required) - The name of branch +- `branch` (required) - The name of branch - `encoding` (optional) - Change encoding to 'base64'. Default is text. - `author_email` (optional) - Specify the commit author's email address - `author_name` (optional) - Specify the commit author's name @@ -75,22 +75,22 @@ PUT /projects/:id/repository/files ``` ```bash -curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch_name=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20other%20content&commit_message=update%20file' +curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20other%20content&commit_message=update%20file' ``` Example response: ```json { - "file_path": "app/project.rb", - "branch_name": "master" + "file_name": "app/project.rb", + "branch": "master" } ``` Parameters: - `file_path` (required) - Full path to file. Ex. lib/class.rb -- `branch_name` (required) - The name of branch +- `branch` (required) - The name of branch - `encoding` (optional) - Change encoding to 'base64'. Default is text. - `author_email` (optional) - Specify the commit author's email address - `author_name` (optional) - Specify the commit author's name @@ -113,22 +113,22 @@ DELETE /projects/:id/repository/files ``` ```bash -curl --request DELETE --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch_name=master&author_email=author%40example.com&author_name=Firstname%20Lastname&commit_message=delete%20file' +curl --request DELETE --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&commit_message=delete%20file' ``` Example response: ```json { - "file_path": "app/project.rb", - "branch_name": "master" + "file_name": "app/project.rb", + "branch": "master" } ``` Parameters: - `file_path` (required) - Full path to file. Ex. lib/class.rb -- `branch_name` (required) - The name of branch +- `branch` (required) - The name of branch - `author_email` (optional) - Specify the commit author's email address - `author_name` (optional) - Specify the commit author's name - `commit_message` (required) - Commit message diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index 1af124c56b1..b72d9325bb4 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -30,3 +30,9 @@ changes are in V4: - Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead - Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` - Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) +- Renamed param `branch_name` to `branch` on the following endpoints + - POST `:id/repository/branches` + - POST `:id/repository/commits` + - POST/PUT/DELETE `:id/repository/files` +- Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response + diff --git a/lib/api/api.rb b/lib/api/api.rb index e729c07f8c3..98692408204 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -7,7 +7,9 @@ module API version 'v3', using: :path do mount ::API::V3::Boards mount ::API::V3::Branches + mount ::API::V3::Commits mount ::API::V3::DeployKeys + mount ::API::V3::Files mount ::API::V3::Issues mount ::API::V3::Labels mount ::API::V3::Members diff --git a/lib/api/branches.rb b/lib/api/branches.rb index 9d1f5a28ef6..c65de90cca2 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -97,13 +97,13 @@ module API success Entities::RepoBranch end params do - requires :branch_name, type: String, desc: 'The name of the branch' + requires :branch, type: String, desc: 'The name of the branch' requires :ref, type: String, desc: 'Create branch from commit sha or existing branch' end post ":id/repository/branches" do authorize_push_project result = CreateBranchService.new(user_project, current_user). - execute(params[:branch_name], params[:ref]) + execute(params[:branch], params[:ref]) if result[:status] == :success present result[:branch], @@ -126,7 +126,7 @@ module API if result[:status] == :success { - branch_name: params[:branch] + branch: params[:branch] } else render_api_error!(result[:message], result[:return_code]) diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 3b314c89c6e..0cd817f9352 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -41,7 +41,7 @@ module API detail 'This feature was introduced in GitLab 8.13' end params do - requires :branch_name, type: String, desc: 'The name of branch' + requires :branch, type: String, desc: 'The name of branch' requires :commit_message, type: String, desc: 'Commit message' requires :actions, type: Array[Hash], desc: 'Actions to perform in commit' optional :author_email, type: String, desc: 'Author email for commit' @@ -50,9 +50,8 @@ module API post ":id/repository/commits" do authorize! :push_code, user_project - attrs = declared_params - attrs[:start_branch] = attrs[:branch_name] - attrs[:target_branch] = attrs[:branch_name] + attrs = declared_params.merge(start_branch: declared_params[:branch], target_branch: declared_params[:branch]) + attrs[:actions].map! do |action| action[:action] = action[:action].to_sym action[:file_path].slice!(0) if action[:file_path] && action[:file_path].start_with?('/') diff --git a/lib/api/files.rb b/lib/api/files.rb index 6e16ccd2fd8..500f9d3c787 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -4,8 +4,8 @@ module API def commit_params(attrs) { file_path: attrs[:file_path], - start_branch: attrs[:branch_name], - target_branch: attrs[:branch_name], + start_branch: attrs[:branch], + target_branch: attrs[:branch], commit_message: attrs[:commit_message], file_content: attrs[:content], file_content_encoding: attrs[:encoding], @@ -17,13 +17,13 @@ module API def commit_response(attrs) { file_path: attrs[:file_path], - branch_name: attrs[:branch_name] + branch: attrs[:branch] } end params :simple_file_params do requires :file_path, type: String, desc: 'The path to new file. Ex. lib/class.rb' - requires :branch_name, type: String, desc: 'The name of branch' + requires :branch, type: String, desc: 'The name of branch' requires :commit_message, type: String, desc: 'Commit Message' optional :author_email, type: String, desc: 'The email of the author' optional :author_name, type: String, desc: 'The name of the author' diff --git a/lib/api/v3/commits.rb b/lib/api/v3/commits.rb new file mode 100644 index 00000000000..477e22fd25e --- /dev/null +++ b/lib/api/v3/commits.rb @@ -0,0 +1,205 @@ +require 'mime/types' + +module API + module V3 + class Commits < Grape::API + include PaginationParams + + before { authenticate! } + before { authorize! :download_code, user_project } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + desc 'Get a project repository commits' do + success ::API::Entities::RepoCommit + end + params do + optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used' + optional :since, type: DateTime, desc: 'Only commits after or in this date will be returned' + optional :until, type: DateTime, desc: 'Only commits before or in this date will be returned' + optional :page, type: Integer, default: 0, desc: 'The page for pagination' + optional :per_page, type: Integer, default: 20, desc: 'The number of results per page' + optional :path, type: String, desc: 'The file path' + end + get ":id/repository/commits" do + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' + offset = params[:page] * params[:per_page] + + commits = user_project.repository.commits(ref, + path: params[:path], + limit: params[:per_page], + offset: offset, + after: params[:since], + before: params[:until]) + + present commits, with: ::API::Entities::RepoCommit + end + + desc 'Commit multiple file changes as one commit' do + success ::API::Entities::RepoCommitDetail + detail 'This feature was introduced in GitLab 8.13' + end + params do + requires :branch_name, type: String, desc: 'The name of branch' + requires :commit_message, type: String, desc: 'Commit message' + requires :actions, type: Array[Hash], desc: 'Actions to perform in commit' + optional :author_email, type: String, desc: 'Author email for commit' + optional :author_name, type: String, desc: 'Author name for commit' + end + post ":id/repository/commits" do + authorize! :push_code, user_project + + attrs = declared_params.dup + branch = attrs.delete(:branch_name) + attrs.merge!(branch: branch, start_branch: branch, target_branch: branch) + + attrs[:actions].map! do |action| + action[:action] = action[:action].to_sym + action[:file_path].slice!(0) if action[:file_path] && action[:file_path].start_with?('/') + action[:previous_path].slice!(0) if action[:previous_path] && action[:previous_path].start_with?('/') + action + end + + result = ::Files::MultiService.new(user_project, current_user, attrs).execute + + if result[:status] == :success + commit_detail = user_project.repository.commits(result[:result], limit: 1).first + present commit_detail, with: ::API::Entities::RepoCommitDetail + else + render_api_error!(result[:message], 400) + end + end + + desc 'Get a specific commit of a project' do + success ::API::Entities::RepoCommitDetail + failure [[404, 'Not Found']] + end + params do + requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' + end + get ":id/repository/commits/:sha" do + commit = user_project.commit(params[:sha]) + + not_found! "Commit" unless commit + + present commit, with: ::API::Entities::RepoCommitDetail + end + + desc 'Get the diff for a specific commit of a project' do + failure [[404, 'Not Found']] + end + params do + requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' + end + get ":id/repository/commits/:sha/diff" do + commit = user_project.commit(params[:sha]) + + not_found! "Commit" unless commit + + commit.raw_diffs.to_a + end + + desc "Get a commit's comments" do + success ::API::Entities::CommitNote + failure [[404, 'Not Found']] + end + params do + use :pagination + requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag' + end + get ':id/repository/commits/:sha/comments' do + commit = user_project.commit(params[:sha]) + + not_found! 'Commit' unless commit + notes = Note.where(commit_id: commit.id).order(:created_at) + + present paginate(notes), with: ::API::Entities::CommitNote + end + + desc 'Cherry pick commit into a branch' do + detail 'This feature was introduced in GitLab 8.15' + success ::API::Entities::RepoCommit + end + params do + requires :sha, type: String, desc: 'A commit sha to be cherry picked' + requires :branch, type: String, desc: 'The name of the branch' + end + post ':id/repository/commits/:sha/cherry_pick' do + authorize! :push_code, user_project + + commit = user_project.commit(params[:sha]) + not_found!('Commit') unless commit + + branch = user_project.repository.find_branch(params[:branch]) + not_found!('Branch') unless branch + + commit_params = { + commit: commit, + create_merge_request: false, + source_project: user_project, + source_branch: commit.cherry_pick_branch_name, + target_branch: params[:branch] + } + + result = ::Commits::CherryPickService.new(user_project, current_user, commit_params).execute + + if result[:status] == :success + branch = user_project.repository.find_branch(params[:branch]) + present user_project.repository.commit(branch.dereferenced_target), with: ::API::Entities::RepoCommit + else + render_api_error!(result[:message], 400) + end + end + + desc 'Post comment to commit' do + success ::API::Entities::CommitNote + end + params do + requires :sha, type: String, regexp: /\A\h{6,40}\z/, desc: "The commit's SHA" + requires :note, type: String, desc: 'The text of the comment' + optional :path, type: String, desc: 'The file path' + given :path do + requires :line, type: Integer, desc: 'The line number' + requires :line_type, type: String, values: ['new', 'old'], default: 'new', desc: 'The type of the line' + end + end + post ':id/repository/commits/:sha/comments' do + commit = user_project.commit(params[:sha]) + not_found! 'Commit' unless commit + + opts = { + note: params[:note], + noteable_type: 'Commit', + commit_id: commit.id + } + + if params[:path] + commit.raw_diffs(all_diffs: true).each do |diff| + next unless diff.new_path == params[:path] + lines = Gitlab::Diff::Parser.new.parse(diff.diff.each_line) + + lines.each do |line| + next unless line.new_pos == params[:line] && line.type == params[:line_type] + break opts[:line_code] = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos) + end + + break if opts[:line_code] + end + + opts[:type] = LegacyDiffNote.name if opts[:line_code] + end + + note = ::Notes::CreateService.new(user_project, current_user, opts).execute + + if note.save + present note, with: ::API::Entities::CommitNote + else + render_api_error!("Failed to save note #{note.errors.messages}", 400) + end + end + end + end + end +end diff --git a/lib/api/v3/files.rb b/lib/api/v3/files.rb new file mode 100644 index 00000000000..4f8d58d37c8 --- /dev/null +++ b/lib/api/v3/files.rb @@ -0,0 +1,138 @@ +module API + module V3 + class Files < Grape::API + helpers do + def commit_params(attrs) + { + file_path: attrs[:file_path], + start_branch: attrs[:branch], + target_branch: attrs[:branch], + commit_message: attrs[:commit_message], + file_content: attrs[:content], + file_content_encoding: attrs[:encoding], + author_email: attrs[:author_email], + author_name: attrs[:author_name] + } + end + + def commit_response(attrs) + { + file_path: attrs[:file_path], + branch: attrs[:branch] + } + end + + params :simple_file_params do + requires :file_path, type: String, desc: 'The path to new file. Ex. lib/class.rb' + requires :branch_name, type: String, desc: 'The name of branch' + requires :commit_message, type: String, desc: 'Commit Message' + optional :author_email, type: String, desc: 'The email of the author' + optional :author_name, type: String, desc: 'The name of the author' + end + + params :extended_file_params do + use :simple_file_params + requires :content, type: String, desc: 'File content' + optional :encoding, type: String, values: %w[base64], desc: 'File encoding' + end + end + + params do + requires :id, type: String, desc: 'The project ID' + end + resource :projects do + desc 'Get a file from repository' + params do + requires :file_path, type: String, desc: 'The path to the file. Ex. lib/class.rb' + requires :ref, type: String, desc: 'The name of branch, tag, or commit' + end + get ":id/repository/files" do + authorize! :download_code, user_project + + commit = user_project.commit(params[:ref]) + not_found!('Commit') unless commit + + repo = user_project.repository + blob = repo.blob_at(commit.sha, params[:file_path]) + not_found!('File') unless blob + + blob.load_all_data!(repo) + status(200) + + { + file_name: blob.name, + file_path: blob.path, + size: blob.size, + encoding: "base64", + content: Base64.strict_encode64(blob.data), + ref: params[:ref], + blob_id: blob.id, + commit_id: commit.id, + last_commit_id: repo.last_commit_id_for_path(commit.sha, params[:file_path]) + } + end + + desc 'Create new file in repository' + params do + use :extended_file_params + end + post ":id/repository/files" do + authorize! :push_code, user_project + + file_params = declared_params(include_missing: false) + file_params[:branch] = file_params.delete(:branch_name) + + result = ::Files::CreateService.new(user_project, current_user, commit_params(file_params)).execute + + if result[:status] == :success + status(201) + commit_response(file_params) + else + render_api_error!(result[:message], 400) + end + end + + desc 'Update existing file in repository' + params do + use :extended_file_params + end + put ":id/repository/files" do + authorize! :push_code, user_project + + file_params = declared_params(include_missing: false) + file_params[:branch] = file_params.delete(:branch_name) + + result = ::Files::UpdateService.new(user_project, current_user, commit_params(file_params)).execute + + if result[:status] == :success + status(200) + commit_response(file_params) + else + http_status = result[:http_status] || 400 + render_api_error!(result[:message], http_status) + end + end + + desc 'Delete an existing file in repository' + params do + use :simple_file_params + end + delete ":id/repository/files" do + authorize! :push_code, user_project + + file_params = declared_params(include_missing: false) + file_params[:branch] = file_params.delete(:branch_name) + + result = ::Files::DestroyService.new(user_project, current_user, commit_params(file_params)).execute + + if result[:status] == :success + status(200) + commit_response(file_params) + else + render_api_error!(result[:message], 400) + end + end + end + end + end +end diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb index 2e6db0f43c6..5571f6cc107 100644 --- a/spec/requests/api/branches_spec.rb +++ b/spec/requests/api/branches_spec.rb @@ -272,7 +272,7 @@ describe API::Branches, api: true do describe "POST /projects/:id/repository/branches" do it "creates a new branch" do post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'feature1', + branch: 'feature1', ref: branch_sha expect(response).to have_http_status(201) @@ -283,14 +283,14 @@ describe API::Branches, api: true do it "denies for user without push access" do post api("/projects/#{project.id}/repository/branches", user2), - branch_name: branch_name, + branch: branch_name, ref: branch_sha expect(response).to have_http_status(403) end it 'returns 400 if branch name is invalid' do post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new design', + branch: 'new design', ref: branch_sha expect(response).to have_http_status(400) expect(json_response['message']).to eq('Branch name is invalid') @@ -298,12 +298,12 @@ describe API::Branches, api: true do it 'returns 400 if branch already exists' do post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new_design1', + branch: 'new_design1', ref: branch_sha expect(response).to have_http_status(201) post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new_design1', + branch: 'new_design1', ref: branch_sha expect(response).to have_http_status(400) expect(json_response['message']).to eq('Branch already exists') @@ -311,7 +311,7 @@ describe API::Branches, api: true do it 'returns 400 if ref name is invalid' do post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new_design3', + branch: 'new_design3', ref: 'foo' expect(response).to have_http_status(400) expect(json_response['message']).to eq('Invalid reference name') @@ -326,14 +326,14 @@ describe API::Branches, api: true do it "removes branch" do delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user) expect(response).to have_http_status(200) - expect(json_response['branch_name']).to eq(branch_name) + expect(json_response['branch']).to eq(branch_name) end it "removes a branch with dots in the branch name" do delete api("/projects/#{project.id}/repository/branches/with.1.2.3", user) expect(response).to have_http_status(200) - expect(json_response['branch_name']).to eq("with.1.2.3") + expect(json_response['branch']).to eq("with.1.2.3") end it 'returns 404 if branch not exists' do diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index ecc6a597869..8b3dfedc5a9 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -107,7 +107,7 @@ describe API::Commits, api: true do let(:message) { 'Created file' } let!(:invalid_c_params) do { - branch_name: 'master', + branch: 'master', commit_message: message, actions: [ { @@ -120,7 +120,7 @@ describe API::Commits, api: true do end let!(:valid_c_params) do { - branch_name: 'master', + branch: 'master', commit_message: message, actions: [ { @@ -162,7 +162,7 @@ describe API::Commits, api: true do let(:message) { 'Deleted file' } let!(:invalid_d_params) do { - branch_name: 'markdown', + branch: 'markdown', commit_message: message, actions: [ { @@ -174,7 +174,7 @@ describe API::Commits, api: true do end let!(:valid_d_params) do { - branch_name: 'markdown', + branch: 'markdown', commit_message: message, actions: [ { @@ -203,7 +203,7 @@ describe API::Commits, api: true do let(:message) { 'Moved file' } let!(:invalid_m_params) do { - branch_name: 'feature', + branch: 'feature', commit_message: message, actions: [ { @@ -217,7 +217,7 @@ describe API::Commits, api: true do end let!(:valid_m_params) do { - branch_name: 'feature', + branch: 'feature', commit_message: message, actions: [ { @@ -248,7 +248,7 @@ describe API::Commits, api: true do let(:message) { 'Updated file' } let!(:invalid_u_params) do { - branch_name: 'master', + branch: 'master', commit_message: message, actions: [ { @@ -261,7 +261,7 @@ describe API::Commits, api: true do end let!(:valid_u_params) do { - branch_name: 'master', + branch: 'master', commit_message: message, actions: [ { @@ -291,7 +291,7 @@ describe API::Commits, api: true do let(:message) { 'Multiple actions' } let!(:invalid_mo_params) do { - branch_name: 'master', + branch: 'master', commit_message: message, actions: [ { @@ -319,7 +319,7 @@ describe API::Commits, api: true do end let!(:valid_mo_params) do { - branch_name: 'master', + branch: 'master', commit_message: message, actions: [ { diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index 5e26e779366..a8ce0430401 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -104,7 +104,7 @@ describe API::Files, api: true do let(:valid_params) do { file_path: 'newfile.rb', - branch_name: 'master', + branch: 'master', content: 'puts 8', commit_message: 'Added newfile' } @@ -153,7 +153,7 @@ describe API::Files, api: true do let(:valid_params) do { file_path: file_path, - branch_name: 'master', + branch: 'master', content: 'puts 8', commit_message: 'Changed file' } @@ -193,7 +193,7 @@ describe API::Files, api: true do let(:valid_params) do { file_path: file_path, - branch_name: 'master', + branch: 'master', commit_message: 'Changed file' } end @@ -241,7 +241,7 @@ describe API::Files, api: true do let(:put_params) do { file_path: file_path, - branch_name: 'master', + branch: 'master', content: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=', commit_message: 'Binary file with a \n should not be touched', encoding: 'base64' diff --git a/spec/requests/api/v3/commits_spec.rb b/spec/requests/api/v3/commits_spec.rb new file mode 100644 index 00000000000..2d7584c3e59 --- /dev/null +++ b/spec/requests/api/v3/commits_spec.rb @@ -0,0 +1,578 @@ +require 'spec_helper' +require 'mime/types' + +describe API::V3::Commits, api: true do + include ApiHelpers + let(:user) { create(:user) } + let(:user2) { create(:user) } + let!(:project) { create(:project, :repository, creator: user, namespace: user.namespace) } + let!(:master) { create(:project_member, :master, user: user, project: project) } + let!(:guest) { create(:project_member, :guest, user: user2, project: project) } + let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') } + let!(:another_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'another comment on a commit') } + + before { project.team << [user, :reporter] } + + describe "List repository commits" do + context "authorized user" do + before { project.team << [user2, :reporter] } + + it "returns project commits" do + commit = project.repository.commit + get v3_api("/projects/#{project.id}/repository/commits", user) + + expect(response).to have_http_status(200) + expect(json_response).to be_an Array + expect(json_response.first['id']).to eq(commit.id) + expect(json_response.first['committer_name']).to eq(commit.committer_name) + expect(json_response.first['committer_email']).to eq(commit.committer_email) + end + end + + context "unauthorized user" do + it "does not return project commits" do + get v3_api("/projects/#{project.id}/repository/commits") + expect(response).to have_http_status(401) + end + end + + context "since optional parameter" do + it "returns project commits since provided parameter" do + commits = project.repository.commits("master") + since = commits.second.created_at + + get v3_api("/projects/#{project.id}/repository/commits?since=#{since.utc.iso8601}", user) + + expect(json_response.size).to eq 2 + expect(json_response.first["id"]).to eq(commits.first.id) + expect(json_response.second["id"]).to eq(commits.second.id) + end + end + + context "until optional parameter" do + it "returns project commits until provided parameter" do + commits = project.repository.commits("master") + before = commits.second.created_at + + get v3_api("/projects/#{project.id}/repository/commits?until=#{before.utc.iso8601}", user) + + if commits.size >= 20 + expect(json_response.size).to eq(20) + else + expect(json_response.size).to eq(commits.size - 1) + end + + expect(json_response.first["id"]).to eq(commits.second.id) + expect(json_response.second["id"]).to eq(commits.third.id) + end + end + + context "invalid xmlschema date parameters" do + it "returns an invalid parameter error message" do + get v3_api("/projects/#{project.id}/repository/commits?since=invalid-date", user) + + expect(response).to have_http_status(400) + expect(json_response['error']).to eq('since is invalid') + end + end + + context "path optional parameter" do + it "returns project commits matching provided path parameter" do + path = 'files/ruby/popen.rb' + + get v3_api("/projects/#{project.id}/repository/commits?path=#{path}", user) + + expect(json_response.size).to eq(3) + expect(json_response.first["id"]).to eq("570e7b2abdd848b95f2f578043fc23bd6f6fd24d") + end + end + end + + describe "Create a commit with multiple files and actions" do + let!(:url) { "/projects/#{project.id}/repository/commits" } + + it 'returns a 403 unauthorized for user without permissions' do + post v3_api(url, user2) + + expect(response).to have_http_status(403) + end + + it 'returns a 400 bad request if no params are given' do + post v3_api(url, user) + + expect(response).to have_http_status(400) + end + + context :create do + let(:message) { 'Created file' } + let!(:invalid_c_params) do + { + branch_name: 'master', + commit_message: message, + actions: [ + { + action: 'create', + file_path: 'files/ruby/popen.rb', + content: 'puts 8' + } + ] + } + end + let!(:valid_c_params) do + { + branch_name: 'master', + commit_message: message, + actions: [ + { + action: 'create', + file_path: 'foo/bar/baz.txt', + content: 'puts 8' + } + ] + } + end + + it 'a new file in project repo' do + post v3_api(url, user), valid_c_params + + expect(response).to have_http_status(201) + expect(json_response['title']).to eq(message) + expect(json_response['committer_name']).to eq(user.name) + expect(json_response['committer_email']).to eq(user.email) + end + + it 'returns a 400 bad request if file exists' do + post v3_api(url, user), invalid_c_params + + expect(response).to have_http_status(400) + end + + context 'with project path in URL' do + let(:url) { "/projects/#{project.namespace.path}%2F#{project.path}/repository/commits" } + + it 'a new file in project repo' do + post v3_api(url, user), valid_c_params + + expect(response).to have_http_status(201) + end + end + end + + context :delete do + let(:message) { 'Deleted file' } + let!(:invalid_d_params) do + { + branch_name: 'markdown', + commit_message: message, + actions: [ + { + action: 'delete', + file_path: 'doc/api/projects.md' + } + ] + } + end + let!(:valid_d_params) do + { + branch_name: 'markdown', + commit_message: message, + actions: [ + { + action: 'delete', + file_path: 'doc/api/users.md' + } + ] + } + end + + it 'an existing file in project repo' do + post v3_api(url, user), valid_d_params + + expect(response).to have_http_status(201) + expect(json_response['title']).to eq(message) + end + + it 'returns a 400 bad request if file does not exist' do + post v3_api(url, user), invalid_d_params + + expect(response).to have_http_status(400) + end + end + + context :move do + let(:message) { 'Moved file' } + let!(:invalid_m_params) do + { + branch_name: 'feature', + commit_message: message, + actions: [ + { + action: 'move', + file_path: 'CHANGELOG', + previous_path: 'VERSION', + content: '6.7.0.pre' + } + ] + } + end + let!(:valid_m_params) do + { + branch_name: 'feature', + commit_message: message, + actions: [ + { + action: 'move', + file_path: 'VERSION.txt', + previous_path: 'VERSION', + content: '6.7.0.pre' + } + ] + } + end + + it 'an existing file in project repo' do + post v3_api(url, user), valid_m_params + + expect(response).to have_http_status(201) + expect(json_response['title']).to eq(message) + end + + it 'returns a 400 bad request if file does not exist' do + post v3_api(url, user), invalid_m_params + + expect(response).to have_http_status(400) + end + end + + context :update do + let(:message) { 'Updated file' } + let!(:invalid_u_params) do + { + branch_name: 'master', + commit_message: message, + actions: [ + { + action: 'update', + file_path: 'foo/bar.baz', + content: 'puts 8' + } + ] + } + end + let!(:valid_u_params) do + { + branch_name: 'master', + commit_message: message, + actions: [ + { + action: 'update', + file_path: 'files/ruby/popen.rb', + content: 'puts 8' + } + ] + } + end + + it 'an existing file in project repo' do + post v3_api(url, user), valid_u_params + + expect(response).to have_http_status(201) + expect(json_response['title']).to eq(message) + end + + it 'returns a 400 bad request if file does not exist' do + post v3_api(url, user), invalid_u_params + + expect(response).to have_http_status(400) + end + end + + context "multiple operations" do + let(:message) { 'Multiple actions' } + let!(:invalid_mo_params) do + { + branch_name: 'master', + commit_message: message, + actions: [ + { + action: 'create', + file_path: 'files/ruby/popen.rb', + content: 'puts 8' + }, + { + action: 'delete', + file_path: 'doc/v3_api/projects.md' + }, + { + action: 'move', + file_path: 'CHANGELOG', + previous_path: 'VERSION', + content: '6.7.0.pre' + }, + { + action: 'update', + file_path: 'foo/bar.baz', + content: 'puts 8' + } + ] + } + end + let!(:valid_mo_params) do + { + branch_name: 'master', + commit_message: message, + actions: [ + { + action: 'create', + file_path: 'foo/bar/baz.txt', + content: 'puts 8' + }, + { + action: 'delete', + file_path: 'Gemfile.zip' + }, + { + action: 'move', + file_path: 'VERSION.txt', + previous_path: 'VERSION', + content: '6.7.0.pre' + }, + { + action: 'update', + file_path: 'files/ruby/popen.rb', + content: 'puts 8' + } + ] + } + end + + it 'are commited as one in project repo' do + post v3_api(url, user), valid_mo_params + + expect(response).to have_http_status(201) + expect(json_response['title']).to eq(message) + end + + it 'return a 400 bad request if there are any issues' do + post v3_api(url, user), invalid_mo_params + + expect(response).to have_http_status(400) + end + end + end + + describe "Get a single commit" do + context "authorized user" do + it "returns a commit by sha" do + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['id']).to eq(project.repository.commit.id) + expect(json_response['title']).to eq(project.repository.commit.title) + expect(json_response['stats']['additions']).to eq(project.repository.commit.stats.additions) + expect(json_response['stats']['deletions']).to eq(project.repository.commit.stats.deletions) + expect(json_response['stats']['total']).to eq(project.repository.commit.stats.total) + end + + it "returns a 404 error if not found" do + get v3_api("/projects/#{project.id}/repository/commits/invalid_sha", user) + expect(response).to have_http_status(404) + end + + it "returns nil for commit without CI" do + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['status']).to be_nil + end + + it "returns status for CI" do + pipeline = project.ensure_pipeline('master', project.repository.commit.sha) + pipeline.update(status: 'success') + + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['status']).to eq(pipeline.status) + end + + it "returns status for CI when pipeline is created" do + project.ensure_pipeline('master', project.repository.commit.sha) + + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['status']).to eq("created") + end + end + + context "unauthorized user" do + it "does not return the selected commit" do + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}") + expect(response).to have_http_status(401) + end + end + end + + describe "Get the diff of a commit" do + context "authorized user" do + before { project.team << [user2, :reporter] } + + it "returns the diff of the selected commit" do + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user) + expect(response).to have_http_status(200) + + expect(json_response).to be_an Array + expect(json_response.length).to be >= 1 + expect(json_response.first.keys).to include "diff" + end + + it "returns a 404 error if invalid commit" do + get v3_api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user) + expect(response).to have_http_status(404) + end + end + + context "unauthorized user" do + it "does not return the diff of the selected commit" do + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff") + expect(response).to have_http_status(401) + end + end + end + + describe 'Get the comments of a commit' do + context 'authorized user' do + it 'returns merge_request comments' do + get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user) + expect(response).to have_http_status(200) + expect(json_response).to be_an Array + expect(json_response.length).to eq(2) + expect(json_response.first['note']).to eq('a comment on a commit') + expect(json_response.first['author']['id']).to eq(user.id) + end + + it 'returns a 404 error if merge_request_id not found' do + get v3_api("/projects/#{project.id}/repository/commits/1234ab/comments", user) + expect(response).to have_http_status(404) + end + end + + context 'unauthorized user' do + it 'does not return the diff of the selected commit' do + get v3_api("/projects/#{project.id}/repository/commits/1234ab/comments") + expect(response).to have_http_status(401) + end + end + end + + describe 'POST :id/repository/commits/:sha/cherry_pick' do + let(:master_pickable_commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') } + + context 'authorized user' do + it 'cherry picks a commit' do + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'master' + + expect(response).to have_http_status(201) + expect(json_response['title']).to eq(master_pickable_commit.title) + expect(json_response['message']).to eq(master_pickable_commit.message) + expect(json_response['author_name']).to eq(master_pickable_commit.author_name) + expect(json_response['committer_name']).to eq(user.name) + end + + it 'returns 400 if commit is already included in the target branch' do + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'markdown' + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq('Sorry, we cannot cherry-pick this commit automatically. + A cherry-pick may have already been performed with this commit, or a more recent commit may have updated some of its content.') + end + + it 'returns 400 if you are not allowed to push to the target branch' do + project.team << [user2, :developer] + protected_branch = create(:protected_branch, project: project, name: 'feature') + + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user2), branch: protected_branch.name + + expect(response).to have_http_status(400) + expect(json_response['message']).to eq('You are not allowed to push into this branch') + end + + it 'returns 400 for missing parameters' do + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user) + + expect(response).to have_http_status(400) + expect(json_response['error']).to eq('branch is missing') + end + + it 'returns 404 if commit is not found' do + post v3_api("/projects/#{project.id}/repository/commits/abcd0123/cherry_pick", user), branch: 'master' + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 Commit Not Found') + end + + it 'returns 404 if branch is not found' do + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'foo' + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 Branch Not Found') + end + + it 'returns 400 for missing parameters' do + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user) + + expect(response).to have_http_status(400) + expect(json_response['error']).to eq('branch is missing') + end + end + + context 'unauthorized user' do + it 'does not cherry pick the commit' do + post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick"), branch: 'master' + + expect(response).to have_http_status(401) + end + end + end + + describe 'Post comment to commit' do + context 'authorized user' do + it 'returns comment' do + post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment' + expect(response).to have_http_status(201) + expect(json_response['note']).to eq('My comment') + expect(json_response['path']).to be_nil + expect(json_response['line']).to be_nil + expect(json_response['line_type']).to be_nil + end + + it 'returns the inline comment' do + post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new' + + expect(response).to have_http_status(201) + expect(json_response['note']).to eq('My comment') + expect(json_response['path']).to eq(project.repository.commit.raw_diffs.first.new_path) + expect(json_response['line']).to eq(1) + expect(json_response['line_type']).to eq('new') + end + + it 'returns 400 if note is missing' do + post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user) + expect(response).to have_http_status(400) + end + + it 'returns 404 if note is attached to non existent commit' do + post v3_api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment' + expect(response).to have_http_status(404) + end + end + + context 'unauthorized user' do + it 'does not return the diff of the selected commit' do + post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments") + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb new file mode 100644 index 00000000000..4af05605ec6 --- /dev/null +++ b/spec/requests/api/v3/files_spec.rb @@ -0,0 +1,270 @@ +require 'spec_helper' + +describe API::V3::Files, api: true do + include ApiHelpers + let(:user) { create(:user) } + let!(:project) { create(:project, :repository, namespace: user.namespace ) } + let(:guest) { create(:user) { |u| project.add_guest(u) } } + let(:file_path) { 'files/ruby/popen.rb' } + let(:params) do + { + file_path: file_path, + ref: 'master' + } + end + let(:author_email) { FFaker::Internet.email } + + # I have to remove periods from the end of the name + # This happened when the user's name had a suffix (i.e. "Sr.") + # This seems to be what git does under the hood. For example, this commit: + # + # $ git commit --author='Foo Sr. ' -m 'Where's my trailing period?' + # + # results in this: + # + # $ git show --pretty + # ... + # Author: Foo Sr + # ... + let(:author_name) { FFaker::Name.name.chomp("\.") } + + before { project.team << [user, :developer] } + + describe "GET /projects/:id/repository/files" do + let(:route) { "/projects/#{project.id}/repository/files" } + + shared_examples_for 'repository files' do + it "returns file info" do + get v3_api(route, current_user), params + + expect(response).to have_http_status(200) + expect(json_response['file_path']).to eq(file_path) + expect(json_response['file_name']).to eq('popen.rb') + expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') + expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n") + end + + context 'when no params are given' do + it_behaves_like '400 response' do + let(:request) { get v3_api(route, current_user) } + end + end + + context 'when file_path does not exist' do + let(:params) do + { + file_path: 'app/models/application.rb', + ref: 'master', + } + end + + it_behaves_like '404 response' do + let(:request) { get v3_api(route, current_user), params } + let(:message) { '404 File Not Found' } + end + end + + context 'when repository is disabled' do + include_context 'disabled repository' + + it_behaves_like '403 response' do + let(:request) { get v3_api(route, current_user), params } + end + end + end + + context 'when unauthenticated', 'and project is public' do + it_behaves_like 'repository files' do + let(:project) { create(:project, :public) } + let(:current_user) { nil } + end + end + + context 'when unauthenticated', 'and project is private' do + it_behaves_like '404 response' do + let(:request) { get v3_api(route), params } + let(:message) { '404 Project Not Found' } + end + end + + context 'when authenticated', 'as a developer' do + it_behaves_like 'repository files' do + let(:current_user) { user } + end + end + + context 'when authenticated', 'as a guest' do + it_behaves_like '403 response' do + let(:request) { get v3_api(route, guest), params } + end + end + end + + describe "POST /projects/:id/repository/files" do + let(:valid_params) do + { + file_path: 'newfile.rb', + branch_name: 'master', + content: 'puts 8', + commit_message: 'Added newfile' + } + end + + it "creates a new file in project repo" do + post v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(201) + expect(json_response['file_path']).to eq('newfile.rb') + last_commit = project.repository.commit.raw + expect(last_commit.author_email).to eq(user.email) + expect(last_commit.author_name).to eq(user.name) + end + + it "returns a 400 bad request if no params given" do + post v3_api("/projects/#{project.id}/repository/files", user) + + expect(response).to have_http_status(400) + end + + it "returns a 400 if editor fails to create file" do + allow_any_instance_of(Repository).to receive(:commit_file). + and_return(false) + + post v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(400) + end + + context "when specifying an author" do + it "creates a new file with the specified author" do + valid_params.merge!(author_email: author_email, author_name: author_name) + + post v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(201) + last_commit = project.repository.commit.raw + expect(last_commit.author_email).to eq(author_email) + expect(last_commit.author_name).to eq(author_name) + end + end + end + + describe "PUT /projects/:id/repository/files" do + let(:valid_params) do + { + file_path: file_path, + branch_name: 'master', + content: 'puts 8', + commit_message: 'Changed file' + } + end + + it "updates existing file in project repo" do + put v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(200) + expect(json_response['file_path']).to eq(file_path) + last_commit = project.repository.commit.raw + expect(last_commit.author_email).to eq(user.email) + expect(last_commit.author_name).to eq(user.name) + end + + it "returns a 400 bad request if no params given" do + put v3_api("/projects/#{project.id}/repository/files", user) + + expect(response).to have_http_status(400) + end + + context "when specifying an author" do + it "updates a file with the specified author" do + valid_params.merge!(author_email: author_email, author_name: author_name, content: "New content") + + put v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(200) + last_commit = project.repository.commit.raw + expect(last_commit.author_email).to eq(author_email) + expect(last_commit.author_name).to eq(author_name) + end + end + end + + describe "DELETE /projects/:id/repository/files" do + let(:valid_params) do + { + file_path: file_path, + branch_name: 'master', + commit_message: 'Changed file' + } + end + + it "deletes existing file in project repo" do + delete v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(200) + expect(json_response['file_path']).to eq(file_path) + last_commit = project.repository.commit.raw + expect(last_commit.author_email).to eq(user.email) + expect(last_commit.author_name).to eq(user.name) + end + + it "returns a 400 bad request if no params given" do + delete v3_api("/projects/#{project.id}/repository/files", user) + + expect(response).to have_http_status(400) + end + + it "returns a 400 if fails to create file" do + allow_any_instance_of(Repository).to receive(:remove_file).and_return(false) + + delete v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(400) + end + + context "when specifying an author" do + it "removes a file with the specified author" do + valid_params.merge!(author_email: author_email, author_name: author_name) + + delete v3_api("/projects/#{project.id}/repository/files", user), valid_params + + expect(response).to have_http_status(200) + last_commit = project.repository.commit.raw + expect(last_commit.author_email).to eq(author_email) + expect(last_commit.author_name).to eq(author_name) + end + end + end + + describe "POST /projects/:id/repository/files with binary file" do + let(:file_path) { 'test.bin' } + let(:put_params) do + { + file_path: file_path, + branch_name: 'master', + content: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=', + commit_message: 'Binary file with a \n should not be touched', + encoding: 'base64' + } + end + let(:get_params) do + { + file_path: file_path, + ref: 'master', + } + end + + before do + post v3_api("/projects/#{project.id}/repository/files", user), put_params + end + + it "remains unchanged" do + get v3_api("/projects/#{project.id}/repository/files", user), get_params + + expect(response).to have_http_status(200) + expect(json_response['file_path']).to eq(file_path) + expect(json_response['file_name']).to eq(file_path) + expect(json_response['content']).to eq(put_params[:content]) + end + end +end From 53312250054a28fc5e5a7df6ef971995c20697dd Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Tue, 21 Feb 2017 19:35:08 +0000 Subject: [PATCH 115/247] Revert "Merge branch '27934-left-align-nav' into 'master'" This reverts merge request !9338 --- app/assets/stylesheets/framework/header.scss | 26 +++- app/assets/stylesheets/framework/nav.scss | 10 +- app/assets/stylesheets/pages/projects.scss | 30 +++-- app/views/layouts/_page.html.haml | 2 +- app/views/layouts/header/_default.html.haml | 4 +- app/views/projects/show.html.haml | 113 +++++++++--------- .../unreleased/27934-left-align-nav.yml | 4 - 7 files changed, 105 insertions(+), 84 deletions(-) delete mode 100644 changelogs/unreleased/27934-left-align-nav.yml diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 78434b99b62..3945a789c82 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -148,11 +148,16 @@ header { } .header-logo { - display: inline-block; - margin: 0 8px 0 3px; - position: relative; + position: absolute; + left: 50%; top: 7px; transition-duration: .3s; + z-index: 999; + + #logo { + position: relative; + left: -50%; + } svg, img { @@ -162,6 +167,15 @@ header { &:hover { cursor: pointer; } + + @media (max-width: $screen-xs-max) { + right: 20px; + left: auto; + + #logo { + left: auto; + } + } } .title { @@ -169,7 +183,7 @@ header { padding-right: 20px; margin: 0; font-size: 18px; - max-width: 450px; + max-width: 385px; display: inline-block; line-height: $header-height; font-weight: normal; @@ -179,6 +193,10 @@ header { vertical-align: top; white-space: nowrap; + @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { + max-width: 300px; + } + @media (max-width: $screen-xs-max) { max-width: 190px; } diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index 7d4a814a36c..674d3bb45aa 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -1,7 +1,7 @@ @mixin fade($gradient-direction, $gradient-color) { visibility: hidden; opacity: 0; - z-index: 1; + z-index: 2; position: absolute; bottom: 12px; width: 43px; @@ -18,7 +18,7 @@ .fa { position: relative; - top: 6px; + top: 5px; font-size: 18px; } } @@ -79,6 +79,7 @@ } &.sub-nav { + text-align: center; background-color: $gray-normal; .container-fluid { @@ -286,6 +287,7 @@ background: $gray-light; border-bottom: 1px solid $border-color; transition: padding $sidebar-transition-duration; + text-align: center; .container-fluid { position: relative; @@ -351,7 +353,7 @@ right: -5px; .fa { - right: -28px; + right: -7px; } } @@ -381,7 +383,7 @@ left: 0; .fa { - left: -4px; + left: 10px; } } } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 8c0de314420..67110813abb 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -652,23 +652,29 @@ pre.light-well { } } -.container-fluid.project-stats-container { - @media (max-width: $screen-xs-max) { - padding: 12px 0; - } -} - .project-last-commit { - background-color: $gray-light; - padding: 12px $gl-padding; - border: 1px solid $border-color; - @media (min-width: $screen-sm-min) { margin-top: $gl-padding; } - @media (min-width: $screen-sm-min) { - border-radius: $border-radius-base; + &.container-fluid { + padding-top: 12px; + padding-bottom: 12px; + background-color: $gray-light; + border: 1px solid $border-color; + border-right-width: 0; + border-left-width: 0; + + @media (min-width: $screen-sm-min) { + border-right-width: 1px; + border-left-width: 1px; + } + } + + &.container-limited { + @media (min-width: 1281px) { + border-radius: $border-radius-base; + } } .ci-status { diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 1717ed6b365..a35a918d501 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -1,7 +1,7 @@ .page-with-sidebar{ class: page_gutter_class } - if defined?(nav) && nav .layout-nav - %div{ class: container_class } + .container-fluid = render "layouts/nav/#{nav}" .content-wrapper{ class: "#{layout_nav_class}" } = yield :sub_nav diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 60b9b8bdbc4..ddf50d6667f 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -61,12 +61,12 @@ %div = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success' + %h1.title= title + .header-logo = link_to root_path, class: 'home', title: 'Dashboard', id: 'logo' do = brand_header_logo - %h1.title= title - = yield :header_content = render 'shared/outdated_browser' diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index f7419728719..80d4081dd7b 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -13,70 +13,69 @@ = render "home_panel" - if current_user && can?(current_user, :download_code, @project) - .project-stats-container{ class: container_class } - %nav.project-stats - %ul.nav + %nav.project-stats{ class: container_class } + %ul.nav + %li + = link_to project_files_path(@project) do + Files (#{storage_counter(@project.statistics.total_repository_size)}) + %li + = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do + #{'Commit'.pluralize(@project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)}) + %li + = link_to namespace_project_branches_path(@project.namespace, @project) do + #{'Branch'.pluralize(@repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)}) + %li + = link_to namespace_project_tags_path(@project.namespace, @project) do + #{'Tag'.pluralize(@repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)}) + + - if default_project_view != 'readme' && @repository.readme %li - = link_to project_files_path(@project) do - Files (#{storage_counter(@project.statistics.total_repository_size)}) + = link_to 'Readme', readme_path(@project) + + - if @repository.changelog %li - = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do - #{'Commit'.pluralize(@project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)}) + = link_to 'Changelog', changelog_path(@project) + + - if @repository.license_blob %li - = link_to namespace_project_branches_path(@project.namespace, @project) do - #{'Branch'.pluralize(@repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)}) + = link_to license_short_name(@project), license_path(@project) + + - if @repository.contribution_guide %li - = link_to namespace_project_tags_path(@project.namespace, @project) do - #{'Tag'.pluralize(@repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)}) + = link_to 'Contribution guide', contribution_guide_path(@project) - - if default_project_view != 'readme' && @repository.readme - %li - = link_to 'Readme', readme_path(@project) + - if @repository.gitlab_ci_yml + %li + = link_to 'CI configuration', ci_configuration_path(@project) - - if @repository.changelog - %li - = link_to 'Changelog', changelog_path(@project) + - if current_user && can_push_branch?(@project, @project.default_branch) + - unless @repository.changelog + %li.missing + = link_to add_special_file_path(@project, file_name: 'CHANGELOG') do + Add Changelog + - unless @repository.license_blob + %li.missing + = link_to add_special_file_path(@project, file_name: 'LICENSE') do + Add License + - unless @repository.contribution_guide + %li.missing + = link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do + Add Contribution guide + - unless @repository.gitlab_ci_yml + %li.missing + = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do + Set up CI + - if koding_enabled? && @repository.koding_yml.blank? + %li.missing + = link_to 'Set up Koding', add_koding_stack_path(@project) + - if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present? + %li.missing + = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', target_branch: 'auto-deploy', context: 'autodeploy') do + Set up auto deploy - - if @repository.license_blob - %li - = link_to license_short_name(@project), license_path(@project) - - - if @repository.contribution_guide - %li - = link_to 'Contribution guide', contribution_guide_path(@project) - - - if @repository.gitlab_ci_yml - %li - = link_to 'CI configuration', ci_configuration_path(@project) - - - if current_user && can_push_branch?(@project, @project.default_branch) - - unless @repository.changelog - %li.missing - = link_to add_special_file_path(@project, file_name: 'CHANGELOG') do - Add Changelog - - unless @repository.license_blob - %li.missing - = link_to add_special_file_path(@project, file_name: 'LICENSE') do - Add License - - unless @repository.contribution_guide - %li.missing - = link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do - Add Contribution guide - - unless @repository.gitlab_ci_yml - %li.missing - = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do - Set up CI - - if koding_enabled? && @repository.koding_yml.blank? - %li.missing - = link_to 'Set up Koding', add_koding_stack_path(@project) - - if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present? - %li.missing - = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', target_branch: 'auto-deploy', context: 'autodeploy') do - Set up auto deploy - - - if @repository.commit - .project-last-commit - = render 'projects/last_commit', commit: @repository.commit, ref: current_ref, project: @project + - if @repository.commit + .project-last-commit{ class: container_class } + = render 'projects/last_commit', commit: @repository.commit, ref: current_ref, project: @project %div{ class: container_class } - if @project.archived? diff --git a/changelogs/unreleased/27934-left-align-nav.yml b/changelogs/unreleased/27934-left-align-nav.yml deleted file mode 100644 index 6c45e4ce175..00000000000 --- a/changelogs/unreleased/27934-left-align-nav.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Left align navigation -merge_request: -author: From 334f3283f53905c11b9eafc6b3de8f12f661adaf Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 21 Feb 2017 16:42:12 -0300 Subject: [PATCH 116/247] add link to video: pages quick start from forked repo --- doc/pages/index.md | 2 +- doc/pages/pages_quick_start_guide.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/pages/index.md b/doc/pages/index.md index 11b2582841f..54a951f0a2a 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -12,7 +12,7 @@ - GitLab Pages from A to Z - [Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html) - [Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html) - - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from a forked project](#LINK) + - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg) - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from scratch](#LINK) - [Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html) - Secure GitLab Pages Custom Domain with SSL/TLS Certificates diff --git a/doc/pages/pages_quick_start_guide.md b/doc/pages/pages_quick_start_guide.md index f7b0c3c9520..945e350e235 100644 --- a/doc/pages/pages_quick_start_guide.md +++ b/doc/pages/pages_quick_start_guide.md @@ -41,7 +41,7 @@ Let's go over both options. To make things easy for you, we've created this [group](https://gitlab.com/pages) of default projects containing the most popular SSGs templates. -Watch the [video tutorial](#LINK) we've created for the steps below. +Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've created for the steps below. 1. Choose your SSG template 1. Fork a project from the [Pages group](https://gitlab.com/pages) From 69b2bc4d5987fea42da13db5f7d6b1e89d44ebf6 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 21 Feb 2017 16:46:00 -0300 Subject: [PATCH 117/247] minor change [ci skip] --- ...ges_static_sites_domains_dns_records_ssl_tls_certificates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index 1a4e798df66..d32c8b76558 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -12,7 +12,7 @@ This is a comprehensive guide, made for those who want to publish a website with GitLab Pages but aren't familiar with the entire process involved. -To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s). +To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s). > For this guide, we assume you already have GitLab Pages server up and running for your GitLab instance. From 601b5adf5768b548a5810ffe890b38f7f4980d89 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Tue, 21 Feb 2017 19:34:03 +0000 Subject: [PATCH 118/247] Use a btn-group to group all action buttons --- .../components/environment_actions.js.es6 | 38 +++++++++---------- .../components/environment_item.js.es6 | 25 +++--------- .../stylesheets/pages/environments.scss | 18 ++++++++- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/app/assets/javascripts/environments/components/environment_actions.js.es6 b/app/assets/javascripts/environments/components/environment_actions.js.es6 index c5a714d9673..978d4dd8b6b 100644 --- a/app/assets/javascripts/environments/components/environment_actions.js.es6 +++ b/app/assets/javascripts/environments/components/environment_actions.js.es6 @@ -15,29 +15,29 @@ module.exports = Vue.component('actions-component', { }, template: ` -
- + + {{action.name}} + + + + + +
`, }); diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js.es6 index 24fd58a301a..ad9d1d21a79 100644 --- a/app/assets/javascripts/environments/components/environment_item.js.es6 +++ b/app/assets/javascripts/environments/components/environment_item.js.es6 @@ -505,39 +505,26 @@ module.exports = Vue.component('environment-item', {
-
- + -
-
- -
-
- -
-
- -
-
- diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index 181dcb7721f..f789ae1ccd3 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -35,7 +35,6 @@ display: table-cell; } - .environments-name, .environments-commit, .environments-actions { width: 20%; @@ -45,6 +44,7 @@ width: 10%; } + .environments-name, .environments-deploy, .environments-build { width: 15%; @@ -62,6 +62,22 @@ } } + .btn-group { + + > a { + color: $gl-text-color-secondary; + } + + svg path { + fill: $gl-text-color-secondary; + } + + .dropdown { + outline: none; + } + } + + .commit-title { margin: 0; } From 1e73657e5b2f07fc5a904f24f979be244a054f97 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 21 Feb 2017 16:58:09 -0300 Subject: [PATCH 119/247] add video to admin docs --- doc/administration/pages/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md index 8de0cc5af5c..1c444cf0d50 100644 --- a/doc/administration/pages/index.md +++ b/doc/administration/pages/index.md @@ -102,6 +102,8 @@ The Pages daemon doesn't listen to the outside world. 1. [Reconfigure GitLab][reconfigure] +Watch the [video tutorial][video-admin] for this configuration. + ### Wildcard domains with TLS support >**Requirements:** @@ -270,3 +272,4 @@ latest previous version. [reconfigure]: ../restart_gitlab.md#omnibus-gitlab-reconfigure [restart]: ../restart_gitlab.md#installations-from-source [gitlab-pages]: https://gitlab.com/gitlab-org/gitlab-pages/tree/v0.2.4 +[video-admin]: https://youtu.be/dD8c7WNcc6s From e27da0ffd7afe535a7b421885560b9f6f2e2cfc6 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 21 Feb 2017 17:07:08 -0300 Subject: [PATCH 120/247] link index-guide to pages user doc --- doc/user/project/pages/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index 4c4f15aad40..ff42e383880 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -14,6 +14,8 @@ deploy static pages for your individual projects, your user or your group. Read [GitLab Pages on GitLab.com](#gitlab-pages-on-gitlab-com) for specific information, if you are using GitLab.com to host your website. +Read through [All you Need to Know About GitLab Pages][pages-index-guide] for a list of all learning materials we have prepared for GitLab Pages (webpages, articles, guides, blog posts, video tutorials). + ## Getting started with GitLab Pages > **Note:** @@ -435,3 +437,4 @@ For a list of known issues, visit GitLab's [public issue tracker]. [public issue tracker]: https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name=Pages [ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605 [quick start guide]: ../../../ci/quick_start/README.md +[pages-index-guide]: ../../../pages/ From 31409030d67858d21281fc72b654246b32f7c6eb Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Wed, 15 Feb 2017 13:01:07 -0200 Subject: [PATCH 121/247] Create compare object with default branch when target branch is missing --- app/services/merge_requests/build_service.rb | 26 +++++++++++-------- changelogs/unreleased/issue_28051_2.yml | 4 +++ .../merge_requests/build_service_spec.rb | 13 +++++----- 3 files changed, 25 insertions(+), 18 deletions(-) create mode 100644 changelogs/unreleased/issue_28051_2.yml diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index f4d52e3ebbd..9d4739e37bb 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -2,18 +2,14 @@ module MergeRequests class BuildService < MergeRequests::BaseService def execute self.merge_request = MergeRequest.new(params) - merge_request.can_be_created = true merge_request.compare_commits = [] merge_request.source_project = find_source_project merge_request.target_project = find_target_project merge_request.target_branch = find_target_branch + merge_request.can_be_created = branches_valid? && source_branch_specified? && target_branch_specified? - if branches_specified? && branches_valid? - compare_branches - assign_title_and_description - else - merge_request.can_be_created = false - end + compare_branches if branches_present? + assign_title_and_description if merge_request.can_be_created merge_request end @@ -37,11 +33,17 @@ module MergeRequests target_branch || target_project.default_branch end - def branches_specified? - params[:source_branch] && params[:target_branch] + def source_branch_specified? + params[:source_branch].present? + end + + def target_branch_specified? + params[:target_branch].present? end def branches_valid? + return false unless source_branch_specified? || target_branch_specified? + validate_branches errors.blank? end @@ -55,8 +57,10 @@ module MergeRequests target_branch ) - merge_request.compare_commits = compare.commits - merge_request.compare = compare + if compare + merge_request.compare_commits = compare.commits + merge_request.compare = compare + end end def validate_branches diff --git a/changelogs/unreleased/issue_28051_2.yml b/changelogs/unreleased/issue_28051_2.yml new file mode 100644 index 00000000000..8cc32ad8493 --- /dev/null +++ b/changelogs/unreleased/issue_28051_2.yml @@ -0,0 +1,4 @@ +--- +title: Use default branch as target_branch when parameter is missing +merge_request: +author: diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index dc945ca4868..0768f644036 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -44,15 +44,14 @@ describe MergeRequests::BuildService, services: true do end end - context 'missing target branch' do - let(:target_branch) { '' } + context 'when target branch is missing' do + let(:target_branch) { nil } + let(:commits) { Commit.decorate([commit_1], project) } - it 'forbids the merge request from being created' do + it 'creates compare object with target branch as default branch' do expect(merge_request.can_be_created).to eq(false) - end - - it 'adds an error message to the merge request' do - expect(merge_request.errors).to contain_exactly('You must select source and target branch') + expect(merge_request.compare).to be_present + expect(merge_request.target_branch).to eq(project.default_branch) end end From 4d6d5ce64fd5bce8fa3db6dcb14deb930589a008 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 21 Feb 2017 17:14:18 -0300 Subject: [PATCH 122/247] add quick start section to user docs --- doc/user/project/pages/index.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index ff42e383880..e07b7e83f81 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -98,6 +98,13 @@ The steps to create a project page for a user or a group are identical: A user's project will be served under `http(s)://username.example.io/projectname` whereas a group's project under `http(s)://groupname.example.io/projectname`. +## Quick Start + +Read through [GitLab Pages Quick Start Guide][pages-quick] or watch the video tutorial on +[how to publish a website with GitLab Pages on GitLab.com from a forked project][video-pages-fork]. + +See also [All you Need to Know About GitLab Pages][pages-index-guide] for a list with all the resources we have for GitLab Pages. + ### Explore the contents of `.gitlab-ci.yml` The key thing about GitLab Pages is the `.gitlab-ci.yml` file, something that @@ -438,3 +445,5 @@ For a list of known issues, visit GitLab's [public issue tracker]. [ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605 [quick start guide]: ../../../ci/quick_start/README.md [pages-index-guide]: ../../../pages/ +[pages-quick]: ../../../pages/pages_quick_start_guide.html +[video-pages-fork]: https://youtu.be/TWqh9MtT4Bg From dde136ad8ec02e7a61d1197cbb209117b252dd8f Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Tue, 21 Feb 2017 18:24:08 -0300 Subject: [PATCH 123/247] add images --- doc/pages/images/add_certificate_to_pages.png | Bin 0 -> 58581 bytes doc/pages/images/choose_ci_template.png | Bin 0 -> 75580 bytes doc/pages/images/dns_a_record_example.png | Bin 0 -> 10681 bytes doc/pages/images/dns_cname_record_example.png | Bin 0 -> 11972 bytes doc/pages/images/remove_fork_relashionship.png | Bin 0 -> 39941 bytes doc/pages/images/setup_ci.png | Bin 0 -> 27380 bytes doc/pages/pages_quick_start_guide.md | 6 +++--- ..._domains_dns_records_ssl_tls_certificates.md | 6 +++--- 8 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 doc/pages/images/add_certificate_to_pages.png create mode 100644 doc/pages/images/choose_ci_template.png create mode 100644 doc/pages/images/dns_a_record_example.png create mode 100644 doc/pages/images/dns_cname_record_example.png create mode 100644 doc/pages/images/remove_fork_relashionship.png create mode 100644 doc/pages/images/setup_ci.png diff --git a/doc/pages/images/add_certificate_to_pages.png b/doc/pages/images/add_certificate_to_pages.png new file mode 100644 index 0000000000000000000000000000000000000000..94d48fafa6e88806c89d09a5262cbef2cd294470 GIT binary patch literal 58581 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 literal 0 HcmV?d00001 diff --git a/doc/pages/images/choose_ci_template.png b/doc/pages/images/choose_ci_template.png new file mode 100644 index 0000000000000000000000000000000000000000..dea4ad2ed28e3c00f4fb80bb71feb744747e0275 GIT binary patch literal 75580 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 aE`^QnMGa;+G4S(CxMxyIl3&G*-~Jz)wGcx9 literal 0 HcmV?d00001 diff --git a/doc/pages/images/dns_cname_record_example.png b/doc/pages/images/dns_cname_record_example.png new file mode 100644 index 0000000000000000000000000000000000000000..93e011d743dd2bb99ac8f7d9c0221bd9409b4546 GIT binary patch literal 11972 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 literal 0 HcmV?d00001 diff --git a/doc/pages/images/remove_fork_relashionship.png b/doc/pages/images/remove_fork_relashionship.png new file mode 100644 index 0000000000000000000000000000000000000000..8c4fab929904d359d5c891f1e968453316c5a5d1 GIT binary patch literal 39941 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

onIA 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

kHf)t@q}BfOzX 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�zEr1KTNhxXW5(@^Qu*)NTWtzV`5vUTN>C? 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 MMdxbqWy_HN0Lwr4qyPW_ literal 0 HcmV?d00001 diff --git a/doc/pages/images/setup_ci.png b/doc/pages/images/setup_ci.png new file mode 100644 index 0000000000000000000000000000000000000000..5569f6aacf5ee90ebd45929695c736731fc036eb GIT binary patch literal 27380 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 literal 0 HcmV?d00001 diff --git a/doc/pages/pages_quick_start_guide.md b/doc/pages/pages_quick_start_guide.md index 945e350e235..b86b451ba5e 100644 --- a/doc/pages/pages_quick_start_guide.md +++ b/doc/pages/pages_quick_start_guide.md @@ -47,7 +47,7 @@ Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've created for the s 1. Fork a project from the [Pages group](https://gitlab.com/pages) 1. Remove the fork relationship by navigating to your **Project**'s **Settings** > **Edit Project** - ![remove fork relashionship]() + ![remove fork relashionship](images/remove_fork_relashionship.png) 1. Enable Shared Runners for your fork: navigate to your **Project**'s **Settings** > **CI/CD Pipelines** 1. Trigger a build (push a change to any file) @@ -74,11 +74,11 @@ To turn a **project website** forked from the Pages group into a **user/group** 1. Clone it to your local computer, add your website files to your project, add, commit and push to GitLab. 1. From the your **Project**'s page, click **Set up CI**: - ![add new file]() + ![setup GitLab CI](images/setup_ci.png) 1. Choose one of the templates from the dropbox menu. Pick up the template corresponding to the SSG you're using (or plain HTML). - ![gitlab-ci templates]() + ![gitlab-ci templates](images/choose_ci_template.png) Once you have both site files and `.gitlab-ci.yml` in your project's root, GitLab CI will build your site and deploy it with Pages. Once the first build passes, you see your site is live by navigating to your **Project**'s **Settings** > **Pages**, where you'll find its default URL. diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index d32c8b76558..c6e2cab0bc3 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -86,7 +86,7 @@ In case you want to point a root domain (`example.com`) to your GitLab Pages sit **Practical Example:** -![DNS A record pointing to GitLab.com Pages server]() +![DNS A record pointing to GitLab.com Pages server](images/dns_a_record_example.png) #### DNS CNAME record @@ -96,7 +96,7 @@ Notice that, despite it's a user or project website, the `CNAME` should point to **Practical Example:** -![DNS CNAME record pointing to GitLab.com project]() +![DNS CNAME record pointing to GitLab.com project](images/dns_cname_record_example.png) #### TL;DR @@ -138,7 +138,7 @@ Regardless the CA you choose, the steps to add your certificate to your Pages pr 1. An intermediary certificate 1. A public key -![Pages project - adding certificates]() +![Pages project - adding certificates](images/add_certificate_to_pages.png) These fields are found under your **Project**'s **Settings** > **Pages** > **New Domain**. From 93e3cfec3abc7c0eed741ba94779bf014cd9bcb7 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Wed, 22 Feb 2017 08:52:49 +1100 Subject: [PATCH 124/247] Added space indentation in models/merge_requests_closing_issues.rb --- app/models/merge_requests_closing_issues.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index 97210900bd5..daafb137be4 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -8,8 +8,8 @@ class MergeRequestsClosingIssues < ActiveRecord::Base class << self def count_for_collection(ids) group(:issue_id). - where(issue_id: ids). - pluck('issue_id', 'COUNT(*) as count') + where(issue_id: ids). + pluck('issue_id', 'COUNT(*) as count') end end end From 5cc838d325fb3fcdd7a86a43c67a442ce5feb3d9 Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Wed, 22 Feb 2017 09:00:03 +1100 Subject: [PATCH 125/247] Refactored specs --- spec/features/issuables/issuable_list_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index 4ea801cd1ac..1fc1c20b8a3 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -60,15 +60,15 @@ describe 'issuable list', feature: true do create(:award_emoji, :downvote, awardable: issuable) create(:award_emoji, :upvote, awardable: issuable) - if issuable_type == :issue - issue = Issue.reorder(:iid).first - merge_request = create(:merge_request, - title: FFaker::Lorem.sentence, - source_project: project, - source_branch: FFaker::Name.name) + if issuable_type == :issue + issue = Issue.reorder(:iid).first + merge_request = create(:merge_request, + title: FFaker::Lorem.sentence, + source_project: project, + source_branch: FFaker::Name.name) - MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) if MergeRequestsClosingIssues.count.zero? - end + MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) if MergeRequestsClosingIssues.count.zero? + end end end end From d6584c94a4ad374d8c7e79205ffe7681c0b191b2 Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Mon, 23 Jan 2017 16:42:34 -0600 Subject: [PATCH 126/247] # This is a combination of 2 commits. # This is the 1st commit message: Add `copy` backup strategy to combat file changed errors The backup Rake task used to stream data directly from the live data directory into the backup. Under many circumstances this worked OK. However, really active instances would experience a 'file changed as we read it' error - especially with data like the registry. This now copies the data first, then compresses it. It will take a bit more disk space while the backup is in progress, but it's a necessary thing. # The commit message #2 will be skipped: # Add env var --- .../26881-backup-fails-if-data-changes.yml | 4 ++++ doc/raketasks/backup_restore.md | 22 +++++++++++++++++++ lib/backup/files.rb | 17 +++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/26881-backup-fails-if-data-changes.yml diff --git a/changelogs/unreleased/26881-backup-fails-if-data-changes.yml b/changelogs/unreleased/26881-backup-fails-if-data-changes.yml new file mode 100644 index 00000000000..00bf105560b --- /dev/null +++ b/changelogs/unreleased/26881-backup-fails-if-data-changes.yml @@ -0,0 +1,4 @@ +--- +title: Add `copy` backup strategy to combat file changed errors +merge_request: 8728 +author: diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md index b4e13f5812a..a5b8cd6455c 100644 --- a/doc/raketasks/backup_restore.md +++ b/doc/raketasks/backup_restore.md @@ -84,6 +84,28 @@ Deleting tmp directories...[DONE] Deleting old backups... [SKIPPING] ``` +## Backup Strategy Option + +> **Note:** Introduced as an option in 8.17 + +The default backup strategy is to essentially stream data from the respective +data locations to the backup using the Linux command `tar` and `gzip`. This works +fine in most cases, but can cause problems when data is rapidly changing. + +When data changes while `tar` is reading it, the error `file changed as we read +it` may occur, and will cause the backup process to fail. To combat this, 8.17 +introduces a new backup strategy called `copy`. The strategy copies data files +to a temporary location before calling `tar` and `gzip`, avoiding the error. + +A side-effect is that the backup process with take up to an additional 1X disk +space. The process does its best to clean up the temporary files at each stage +so the problem doesn't compound, but it could be a considerable change for large +installations. This is why the `copy` strategy is not the default in 8.17. + +To use the `copy` strategy instead of the default streaming strategy, specify +`STRATEGY=copy` in the Rake task command. For example, +`sudo gitlab-rake gitlab:backup:create STRATEGY=copy`. + ## Exclude specific directories from the backup You can choose what should be backed up by adding the environment variable `SKIP`. diff --git a/lib/backup/files.rb b/lib/backup/files.rb index cedbb289f6a..247c32c1c0a 100644 --- a/lib/backup/files.rb +++ b/lib/backup/files.rb @@ -8,6 +8,7 @@ module Backup @name = name @app_files_dir = File.realpath(app_files_dir) @files_parent_dir = File.realpath(File.join(@app_files_dir, '..')) + @backup_files_dir = File.join(Gitlab.config.backup.path, File.basename(@app_files_dir) ) @backup_tarball = File.join(Gitlab.config.backup.path, name + '.tar.gz') end @@ -15,7 +16,21 @@ module Backup def dump FileUtils.mkdir_p(Gitlab.config.backup.path) FileUtils.rm_f(backup_tarball) - run_pipeline!([%W(tar -C #{app_files_dir} -cf - .), %W(gzip -c -1)], out: [backup_tarball, 'w', 0600]) + + if ENV['STRATEGY'] == 'copy' + cmd = %W(cp -a #{app_files_dir} #{Gitlab.config.backup.path}) + output, status = Gitlab::Popen.popen(cmd) + + unless status.zero? + puts output + abort 'Backup failed' + end + + run_pipeline!([%W(tar -C #{@backup_files_dir} -cf - .), %W(gzip -c -1)], out: [backup_tarball, 'w', 0600]) + FileUtils.rm_rf(@backup_files_dir) + else + run_pipeline!([%W(tar -C #{app_files_dir} -cf - .), %W(gzip -c -1)], out: [backup_tarball, 'w', 0600]) + end end def restore From 0494930d7a939297a071bb817ad0227da17dda1b Mon Sep 17 00:00:00 2001 From: blackst0ne Date: Wed, 22 Feb 2017 09:08:20 +1100 Subject: [PATCH 127/247] Refactored specs --- spec/features/issuables/issuable_list_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index 1fc1c20b8a3..0bf7977fb02 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -59,6 +59,7 @@ describe 'issuable list', feature: true do create(:award_emoji, :downvote, awardable: issuable) create(:award_emoji, :upvote, awardable: issuable) + end if issuable_type == :issue issue = Issue.reorder(:iid).first @@ -67,8 +68,7 @@ describe 'issuable list', feature: true do source_project: project, source_branch: FFaker::Name.name) - MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) if MergeRequestsClosingIssues.count.zero? - end + MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) end end end From 9a11acabb90ca0bd0826c5c21b09f96015337537 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 20 Feb 2017 15:42:51 -0600 Subject: [PATCH 128/247] add webpack bundle analyzer to production output --- .gitignore | 1 + .gitlab-ci.yml | 11 ++++++++- config/webpack.config.js | 14 +++++++++++ package.json | 3 ++- yarn.lock | 51 ++++++++++++++++++++++++++++++++++++---- 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 0b602d613c7..680651986e8 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ eslint-report.html /builds/* /shared/* /.gitlab_workhorse_secret +/webpack-report/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index becf2db85fb..e9a1cbc29f4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -250,7 +250,14 @@ rake gitlab:assets:compile: SETUP_DB: "false" USE_DB: "false" SKIP_STORAGE_VALIDATION: "true" - script: bundle exec rake yarn:install gitlab:assets:compile + WEBPACK_REPORT: "true" + script: + - bundle exec rake yarn:install gitlab:assets:compile + artifacts: + name: webpack-report + expire_in: 31d + paths: + - webpack-report/ rake karma: cache: @@ -400,6 +407,7 @@ pages: dependencies: - coverage - rake karma + - rake gitlab:assets:compile - lint:javascript:report script: - mv public/ .public/ @@ -407,6 +415,7 @@ pages: - mv coverage/ public/coverage-ruby/ || true - mv coverage-javascript/ public/coverage-javascript/ || true - mv eslint-report.html public/ || true + - mv webpack-report/ public/webpack-report/ || true artifacts: paths: - public diff --git a/config/webpack.config.js b/config/webpack.config.js index 15899993874..e754f68553a 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -5,12 +5,14 @@ var path = require('path'); var webpack = require('webpack'); var StatsPlugin = require('stats-webpack-plugin'); var CompressionPlugin = require('compression-webpack-plugin'); +var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; var ROOT_PATH = path.resolve(__dirname, '..'); var IS_PRODUCTION = process.env.NODE_ENV === 'production'; var IS_DEV_SERVER = process.argv[1].indexOf('webpack-dev-server') !== -1; var DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808; var DEV_SERVER_LIVERELOAD = process.env.DEV_SERVER_LIVERELOAD !== 'false'; +var WEBPACK_REPORT = process.env.WEBPACK_REPORT; var config = { context: path.join(ROOT_PATH, 'app/assets/javascripts'), @@ -120,4 +122,16 @@ if (IS_DEV_SERVER) { config.output.publicPath = '//localhost:' + DEV_SERVER_PORT + config.output.publicPath; } +if (WEBPACK_REPORT) { + config.plugins.push( + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + generateStatsFile: true, + openAnalyzer: false, + reportFilename: path.join(ROOT_PATH, 'webpack-report/index.html'), + statsFilename: path.join(ROOT_PATH, 'webpack-report/stats.json'), + }) + ); +} + module.exports = config; diff --git a/package.json b/package.json index ad0aaef1897..66aa7e9fe5d 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "underscore": "^1.8.3", "vue": "^2.0.3", "vue-resource": "^0.9.3", - "webpack": "^2.2.1" + "webpack": "^2.2.1", + "webpack-bundle-analyzer": "^2.3.0" }, "devDependencies": { "babel-plugin-istanbul": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index ad4b5223d60..1eaa04e21c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,6 +33,10 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" + after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" @@ -1408,6 +1412,10 @@ dropzone@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.2.0.tgz#fbe7acbb9918e0706489072ef663effeef8a79f3" +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -1418,6 +1426,10 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" +ejs@^2.5.5: + version "2.5.6" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88" + elliptic@^6.0.0: version "6.3.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" @@ -1792,7 +1804,7 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -express@^4.13.3: +express@^4.13.3, express@^4.14.1: version "4.14.1" resolved "https://registry.yarnpkg.com/express/-/express-4.14.1.tgz#646c237f766f148c2120aff073817b9e4d7e0d33" dependencies: @@ -1893,6 +1905,10 @@ fileset@^2.0.2: glob "^7.0.3" minimatch "^3.0.3" +filesize@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.4.tgz#742fc7fb6aef4ee3878682600c22f840731e1fda" + fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" @@ -2118,6 +2134,12 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" +gzip-size@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-3.0.0.tgz#546188e9bdc337f673772f81660464b389dce520" + dependencies: + duplexer "^0.1.1" + handle-thing@^1.2.4: version "1.2.5" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" @@ -2627,7 +2649,7 @@ jquery-ujs@^1.2.1: dependencies: jquery ">=1.8.0" -jquery@^2.2.1, jquery@>=1.8.0: +jquery@>=1.8.0, jquery@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-2.2.1.tgz#3c3e16854ad3d2ac44ac65021b17426d22ad803f" @@ -2824,7 +2846,7 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@0.2.x, loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5: +loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5: version "0.2.16" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d" dependencies: @@ -2903,7 +2925,7 @@ lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.0.0, lodash@^4.0.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.0: +lodash@^4.0.0, lodash@^4.0.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3216,6 +3238,10 @@ onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" +opener@^1.4.2: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + opn@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" @@ -3964,7 +3990,7 @@ source-map-support@^0.4.2: dependencies: source-map "^0.5.3" -source-map@0.1.x, source-map@^0.1.41: +source-map@^0.1.41: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" dependencies: @@ -4402,6 +4428,21 @@ wbuf@^1.1.0, wbuf@^1.4.0: dependencies: minimalistic-assert "^1.0.0" +webpack-bundle-analyzer@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.3.0.tgz#0d05e96a43033f7cc57f6855b725782ba61e93a4" + dependencies: + acorn "^4.0.11" + chalk "^1.1.3" + commander "^2.9.0" + ejs "^2.5.5" + express "^4.14.1" + filesize "^3.5.4" + gzip-size "^3.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + opener "^1.4.2" + webpack-dev-middleware@^1.0.11, webpack-dev-middleware@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.0.tgz#7d5be2651e692fddfafd8aaed177c16ff51f0eb8" From f40716f48a25809d197ba2abf32ce150b7b73efa Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 16:31:14 -0600 Subject: [PATCH 129/247] No more and/or --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 7 ------- app/controllers/application_controller.rb | 8 ++++---- app/controllers/import/fogbugz_controller.rb | 2 +- app/controllers/import/google_code_controller.rb | 4 ++-- app/controllers/invites_controller.rb | 4 +--- app/controllers/omniauth_callbacks_controller.rb | 2 +- app/controllers/profiles/keys_controller.rb | 4 ++-- app/controllers/projects/blob_controller.rb | 2 +- app/controllers/projects/tree_controller.rb | 4 ++-- app/controllers/snippets_controller.rb | 2 +- app/models/project.rb | 2 +- app/models/project_services/drone_ci_service.rb | 2 +- app/models/project_services/irker_service.rb | 2 +- app/services/projects/upload_service.rb | 2 +- config/initializers/mysql_ignore_postgresql_options.rb | 2 +- config/initializers/rack_lineprof.rb | 2 +- config/routes/sidekiq.rb | 2 +- lib/api/helpers.rb | 2 +- lib/banzai/filter/plantuml_filter.rb | 2 +- lib/ci/ansi2html.rb | 2 +- lib/gitlab/metrics/system.rb | 2 +- 22 files changed, 31 insertions(+), 35 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b093d4d25d4..a836b469cc7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -54,6 +54,11 @@ Style/AlignArray: Style/AlignHash: Enabled: true +# Whether `and` and `or` are banned only in conditionals (conditionals) +# or completely (always). +Style/AndOr: + Enabled: true + # Use `Array#join` instead of `Array#*`. Style/ArrayJoin: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 648b3fc49d2..a5b4d2f5b02 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -180,13 +180,6 @@ Security/JSONLoad: Style/AlignParameters: Enabled: false -# Offense count: 27 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: always, conditionals -Style/AndOr: - Enabled: false - # Offense count: 54 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bf6be3d516b..5e7af3bff0d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -74,7 +74,7 @@ class ApplicationController < ActionController::Base def authenticate_user!(*args) if redirect_to_home_page_url? - redirect_to current_application_settings.home_page_url and return + return redirect_to current_application_settings.home_page_url end super(*args) @@ -131,7 +131,7 @@ class ApplicationController < ActionController::Base headers['X-UA-Compatible'] = 'IE=edge' headers['X-Content-Type-Options'] = 'nosniff' # Enabling HSTS for non-standard ports would send clients to the wrong port - if Gitlab.config.gitlab.https and Gitlab.config.gitlab.port == 443 + if Gitlab.config.gitlab.https && Gitlab.config.gitlab.port == 443 headers['Strict-Transport-Security'] = 'max-age=31536000' end end @@ -152,7 +152,7 @@ class ApplicationController < ActionController::Base def check_password_expiration if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user? - redirect_to new_profile_password_path and return + return redirect_to new_profile_password_path end end @@ -218,7 +218,7 @@ class ApplicationController < ActionController::Base def require_email if current_user && current_user.temp_oauth_email? && session[:impersonator_id].nil? - redirect_to profile_path, notice: 'Please complete your profile with email address' and return + return redirect_to profile_path, notice: 'Please complete your profile with email address' end end diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index 99b10b2f9b3..5df6bd34185 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -29,7 +29,7 @@ class Import::FogbugzController < Import::BaseController unless user_map.is_a?(Hash) && user_map.all? { |k, v| !v[:name].blank? } flash.now[:alert] = 'All users must have a name.' - render 'new_user_map' and return + return render 'new_user_map' end session[:fogbugz_user_map] = user_map diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb index 8d0de158f98..7d7f13ce5d5 100644 --- a/app/controllers/import/google_code_controller.rb +++ b/app/controllers/import/google_code_controller.rb @@ -44,13 +44,13 @@ class Import::GoogleCodeController < Import::BaseController rescue flash.now[:alert] = "The entered user map is not a valid JSON user map." - render "new_user_map" and return + return render "new_user_map" end unless user_map.is_a?(Hash) && user_map.all? { |k, v| k.is_a?(String) && v.is_a?(String) } flash.now[:alert] = "The entered user map is not a valid JSON user map." - render "new_user_map" and return + return render "new_user_map" end # This is the default, so let's not save it into the database. diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 58964a0e65d..7625187c7be 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -42,9 +42,7 @@ class InvitesController < ApplicationController @token = params[:id] @member = Member.find_by_invite_token(@token) - unless @member - render_404 and return - end + return render_404 unless @member @member end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 3ab7e6e0658..58d50ad647b 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -122,7 +122,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController else error_message = @user.errors.full_messages.to_sentence - redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return + return redirect_to omniauth_error_path(oauth['provider'], error: error_message) end end diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index 830e0b9591b..c8663a3c38e 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -45,13 +45,13 @@ class Profiles::KeysController < Profiles::ApplicationController if user.present? render text: user.all_ssh_keys.join("\n"), content_type: "text/plain" else - render_404 and return + return render_404 end rescue => e render text: e.message end else - render_404 and return + return render_404 end end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index a1db856dcfb..39ba815cfca 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -95,7 +95,7 @@ class Projects::BlobController < Projects::ApplicationController else if tree = @repository.tree(@commit.id, @path) if tree.entries.any? - redirect_to namespace_project_tree_path(@project.namespace, @project, File.join(@ref, @path)) and return + return redirect_to namespace_project_tree_path(@project.namespace, @project, File.join(@ref, @path)) end end diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index cb3ed0f6f9c..4f094146348 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -15,10 +15,10 @@ class Projects::TreeController < Projects::ApplicationController if tree.entries.empty? if @repository.blob_at(@commit.id, @path) - redirect_to( + return redirect_to( namespace_project_blob_path(@project.namespace, @project, File.join(@ref, @path)) - ) and return + ) elsif @path.present? return render_404 end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 366804ab17e..445898a2e9e 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -23,7 +23,7 @@ class SnippetsController < ApplicationController if params[:username].present? @user = User.find_by(username: params[:username]) - render_404 and return unless @user + return render_404 unless @user @snippets = SnippetsFinder.new.execute(current_user, { filter: :by_user, diff --git a/app/models/project.rb b/app/models/project.rb index fc5b1a66910..411299eef63 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -552,7 +552,7 @@ class Project < ActiveRecord::Base end def check_limit - unless creator.can_create_project? or namespace.kind == 'group' + unless creator.can_create_project? || namespace.kind == 'group' projects_limit = creator.projects_limit if projects_limit == 0 diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb index 942ec9371e5..1ad9efac196 100644 --- a/app/models/project_services/drone_ci_service.rb +++ b/app/models/project_services/drone_ci_service.rb @@ -52,7 +52,7 @@ class DroneCiService < CiService response = HTTParty.get(commit_status_path(sha, ref), verify: enable_ssl_verification) status = - if response.code == 200 and response['status'] + if response.code == 200 && response['status'] case response['status'] when 'killed' :canceled diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index 5d93064f9b3..5d6862d9faa 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -96,7 +96,7 @@ class IrkerService < Service rescue URI::InvalidURIError end - unless uri.present? and default_irc_uri.nil? + unless uri.present? && default_irc_uri.nil? begin new_recipient = URI.join(default_irc_uri, '/', recipient).to_s uri = consider_uri(URI.parse(new_recipient)) diff --git a/app/services/projects/upload_service.rb b/app/services/projects/upload_service.rb index 012e82a7704..be34d4fa9b8 100644 --- a/app/services/projects/upload_service.rb +++ b/app/services/projects/upload_service.rb @@ -5,7 +5,7 @@ module Projects end def execute - return nil unless @file and @file.size <= max_attachment_size + return nil unless @file && @file.size <= max_attachment_size uploader = FileUploader.new(@project) uploader.store!(@file) diff --git a/config/initializers/mysql_ignore_postgresql_options.rb b/config/initializers/mysql_ignore_postgresql_options.rb index 835f3ec5574..9a569be7674 100644 --- a/config/initializers/mysql_ignore_postgresql_options.rb +++ b/config/initializers/mysql_ignore_postgresql_options.rb @@ -31,7 +31,7 @@ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) end def add_index_options(table_name, column_name, options = {}) - if options[:using] and options[:using] == :gin + if options[:using] && options[:using] == :gin options = options.dup options.delete(:using) end diff --git a/config/initializers/rack_lineprof.rb b/config/initializers/rack_lineprof.rb index 22e77a32c61..f7172fce9bc 100644 --- a/config/initializers/rack_lineprof.rb +++ b/config/initializers/rack_lineprof.rb @@ -1,7 +1,7 @@ # The default colors of rack-lineprof can be very hard to look at in terminals # with darker backgrounds. This patch tweaks the colors a bit so the output is # actually readable. -if Rails.env.development? and RUBY_ENGINE == 'ruby' and ENV['ENABLE_LINEPROF'] +if Rails.env.development? && RUBY_ENGINE == 'ruby' && ENV['ENABLE_LINEPROF'] Rails.application.config.middleware.use(Rack::Lineprof) module Rack diff --git a/config/routes/sidekiq.rb b/config/routes/sidekiq.rb index d3e6bc4c292..0fa23f2b3d0 100644 --- a/config/routes/sidekiq.rb +++ b/config/routes/sidekiq.rb @@ -1,4 +1,4 @@ -constraint = lambda { |request| request.env['warden'].authenticate? and request.env['warden'].user.admin? } +constraint = lambda { |request| request.env['warden'].authenticate? && request.env['warden'].user.admin? } constraints constraint do mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 7b6fae866eb..ae62f1f9580 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -153,7 +153,7 @@ module API params_hash = custom_params || params attrs = {} keys.each do |key| - if params_hash[key].present? or (params_hash.has_key?(key) and params_hash[key] == false) + if params_hash[key].present? || (params_hash.has_key?(key) && params_hash[key] == false) attrs[key] = params_hash[key] end end diff --git a/lib/banzai/filter/plantuml_filter.rb b/lib/banzai/filter/plantuml_filter.rb index e194cf59275..b2537117558 100644 --- a/lib/banzai/filter/plantuml_filter.rb +++ b/lib/banzai/filter/plantuml_filter.rb @@ -7,7 +7,7 @@ module Banzai # class PlantumlFilter < HTML::Pipeline::Filter def call - return doc unless doc.at('pre.plantuml') and settings.plantuml_enabled + return doc unless doc.at('pre.plantuml') && settings.plantuml_enabled plantuml_setup diff --git a/lib/ci/ansi2html.rb b/lib/ci/ansi2html.rb index c10d3616f31..158a33f26fe 100644 --- a/lib/ci/ansi2html.rb +++ b/lib/ci/ansi2html.rb @@ -126,7 +126,7 @@ module Ci # We are only interested in color and text style changes - triggered by # sequences starting with '\e[' and ending with 'm'. Any other control # sequence gets stripped (including stuff like "delete last line") - return unless indicator == '[' and terminator == 'm' + return unless indicator == '[' && terminator == 'm' close_open_tags() diff --git a/lib/gitlab/metrics/system.rb b/lib/gitlab/metrics/system.rb index 287b7a83547..3aaebb3e9c3 100644 --- a/lib/gitlab/metrics/system.rb +++ b/lib/gitlab/metrics/system.rb @@ -11,7 +11,7 @@ module Gitlab mem = 0 match = File.read('/proc/self/status').match(/VmRSS:\s+(\d+)/) - if match and match[1] + if match && match[1] mem = match[1].to_f * 1024 end From 660e1eb5246f70e476bcb437d05ca4d7a3c51740 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 21 Feb 2017 16:33:58 -0600 Subject: [PATCH 130/247] approve opener license (MIT) --- config/dependency_decisions.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml index 7336d7c842a..072ed8a3864 100644 --- a/config/dependency_decisions.yml +++ b/config/dependency_decisions.yml @@ -320,3 +320,9 @@ :why: https://github.com/shinnn/spdx-license-ids/blob/v1.2.2/LICENSE :versions: [] :when: 2017-02-08 22:35:00.225232000 Z +- - :approve + - opener + - :who: Mike Greiling + :why: https://github.com/domenic/opener/blob/1.4.3/LICENSE.txt + :versions: [] + :when: 2017-02-21 22:33:41.729629000 Z From 1c4b8c1a50f6df18811c3af1820a76565da25619 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 21 Feb 2017 16:38:22 -0600 Subject: [PATCH 131/247] add CHANGELOG.md entry for !9396 --- ...50-test-compiling-frontend-assets-for-production-in-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml diff --git a/changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml b/changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml new file mode 100644 index 00000000000..196a9b788ea --- /dev/null +++ b/changelogs/unreleased/28450-test-compiling-frontend-assets-for-production-in-ci.yml @@ -0,0 +1,4 @@ +--- +title: test compiling production assets and generate webpack bundle report in CI +merge_request: 9396 +author: From e6c0c334e9596a90c21a614de047e4a3652fb763 Mon Sep 17 00:00:00 2001 From: Nur Rony Date: Wed, 22 Feb 2017 13:19:09 +0600 Subject: [PATCH 132/247] fixes delimiter removes when todo marked as done --- app/controllers/dashboard/todos_controller.rb | 6 ++++-- .../28462-fix-delimiter-removes-issue-in-todo-counter.yml | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index ee2358b986d..5848ca62777 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -1,4 +1,6 @@ class Dashboard::TodosController < Dashboard::ApplicationController + include ActionView::Helpers::NumberHelper + before_action :find_todos, only: [:index, :destroy_all] def index @@ -48,8 +50,8 @@ class Dashboard::TodosController < Dashboard::ApplicationController def todos_counts { - count: current_user.todos_pending_count, - done_count: current_user.todos_done_count + count: number_with_delimiter(current_user.todos_pending_count), + done_count: number_with_delimiter(current_user.todos_done_count) } end end diff --git a/changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml b/changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml new file mode 100644 index 00000000000..80995d75c23 --- /dev/null +++ b/changelogs/unreleased/28462-fix-delimiter-removes-issue-in-todo-counter.yml @@ -0,0 +1,4 @@ +--- +title: Fixes delimiter removes when todo marked as done +merge_request: 9435 +author: From d16eed3b096bb01efda90dfea47ac549a9d2ffbc Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 22 Feb 2017 08:39:50 +0100 Subject: [PATCH 133/247] Fix reprocessing skipped jobs when retrying pipeline --- app/services/ci/retry_pipeline_service.rb | 2 ++ .../ci/retry_pipeline_service_spec.rb | 25 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 2c5e130e5aa..7fcbac6399a 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -8,6 +8,8 @@ module Ci pipeline.builds.failed_or_canceled.find_each do |build| next unless build.retryable? + pipeline.mark_as_processable_after_stage(build.stage_idx) + Ci::RetryBuildService.new(project, current_user) .reprocess(build) end diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index c0af8b8450a..8b1ed6470e4 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -69,6 +69,25 @@ describe Ci::RetryPipelineService, '#execute', :services do end end + context 'when the last stage was skipepd' do + before do + create_build('build 1', :success, 0) + create_build('test 2', :failed, 1) + create_build('report 3', :skipped, 2) + create_build('report 4', :skipped, 2) + end + + it 'retries builds only in the first stage' do + service.execute(pipeline) + + expect(build('build 1')).to be_success + expect(build('test 2')).to be_pending + expect(build('report 3')).to be_created + expect(build('report 4')).to be_created + expect(pipeline.reload).to be_running + end + end + context 'when pipeline contains manual actions' do context 'when there is a canceled manual action in first stage' do before do @@ -90,14 +109,16 @@ describe Ci::RetryPipelineService, '#execute', :services do context 'when there is a skipped manual action in last stage' do before do create_build('rspec 1', :canceled, 0) + create_build('rspec 2', :skipped, 0, :manual) create_build('staging', :skipped, 1, :manual) end - it 'retries canceled job and skips manual action' do + it 'retries canceled job and reprocesses manual actions' do service.execute(pipeline) expect(build('rspec 1')).to be_pending - expect(build('staging')).to be_skipped + expect(build('rspec 2')).to be_skipped + expect(build('staging')).to be_created expect(pipeline.reload).to be_running end end From 1965482f12688f4f26342b91eca888567d0dac04 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Wed, 22 Feb 2017 09:06:58 +0100 Subject: [PATCH 134/247] Reprocess jobs in stages once when retrying pipeline --- app/services/ci/retry_pipeline_service.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 7fcbac6399a..ca19b828e1c 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -5,13 +5,18 @@ module Ci raise Gitlab::Access::AccessDeniedError end - pipeline.builds.failed_or_canceled.find_each do |build| - next unless build.retryable? + pipeline.builds.failed_or_canceled.tap do |builds| + stage_idx = builds.order('stage_idx ASC') + .pluck('DISTINCT stage_idx').first - pipeline.mark_as_processable_after_stage(build.stage_idx) + pipeline.mark_as_processable_after_stage(stage_idx) - Ci::RetryBuildService.new(project, current_user) - .reprocess(build) + builds.find_each do |build| + next unless build.retryable? + + Ci::RetryBuildService.new(project, current_user) + .reprocess(build) + end end MergeRequests::AddTodoWhenBuildFailsService From ca68c8173312c788e8f02669cfde20fbcdd76a3c Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 17 Feb 2017 10:49:45 +0100 Subject: [PATCH 135/247] Update documentation --- doc/api/issues.md | 8 ++++---- doc/api/labels.md | 10 +++++----- doc/api/merge_requests.md | 8 ++++---- doc/api/v3_to_v4.md | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/api/issues.md b/doc/api/issues.md index f40e0938b0f..6cd701215e9 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -514,7 +514,7 @@ If the user is already subscribed to the issue, the status code `304` is returned. ``` -POST /projects/:id/issues/:issue_id/subscription +POST /projects/:id/issues/:issue_id/subscribe ``` | Attribute | Type | Required | Description | @@ -523,7 +523,7 @@ POST /projects/:id/issues/:issue_id/subscription | `issue_id` | integer | yes | The ID of a project's issue | ```bash -curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/issues/93/subscription +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/issues/93/subscribe ``` Example response: @@ -569,7 +569,7 @@ from it. If the user is not subscribed to the issue, the status code `304` is returned. ``` -DELETE /projects/:id/issues/:issue_id/subscription +DELETE /projects/:id/issues/:issue_id/unsubscribe ``` | Attribute | Type | Required | Description | @@ -578,7 +578,7 @@ DELETE /projects/:id/issues/:issue_id/subscription | `issue_id` | integer | yes | The ID of a project's issue | ```bash -curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/issues/93/subscription +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/issues/93/unsubscribe ``` Example response: diff --git a/doc/api/labels.md b/doc/api/labels.md index 863b28c23b7..a1e7eb1a7b1 100644 --- a/doc/api/labels.md +++ b/doc/api/labels.md @@ -188,12 +188,12 @@ Example response: ## Subscribe to a label -Subscribes the authenticated user to a label to receive notifications. +Subscribes the authenticated user to a label to receive notifications. If the user is already subscribed to the label, the status code `304` is returned. ``` -POST /projects/:id/labels/:label_id/subscription +POST /projects/:id/labels/:label_id/subscribe ``` | Attribute | Type | Required | Description | @@ -202,7 +202,7 @@ POST /projects/:id/labels/:label_id/subscription | `label_id` | integer or string | yes | The ID or title of a project's label | ```bash -curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/labels/1/subscription +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/labels/1/subscribe ``` Example response: @@ -228,7 +228,7 @@ from it. If the user is not subscribed to the label, the status code `304` is returned. ``` -DELETE /projects/:id/labels/:label_id/subscription +DELETE /projects/:id/labels/:label_id/unsubscribe ``` | Attribute | Type | Required | Description | @@ -237,7 +237,7 @@ DELETE /projects/:id/labels/:label_id/subscription | `label_id` | integer or string | yes | The ID or title of a project's label | ```bash -curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/labels/1/subscription +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/labels/1/unsubscribe ``` Example response: diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 6ee377125d6..2a99ae822d7 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -667,7 +667,7 @@ Subscribes the authenticated user to a merge request to receive notification. If status code `304` is returned. ``` -POST /projects/:id/merge_requests/:merge_request_id/subscription +POST /projects/:id/merge_requests/:merge_request_id/subscribe ``` | Attribute | Type | Required | Description | @@ -676,7 +676,7 @@ POST /projects/:id/merge_requests/:merge_request_id/subscription | `merge_request_id` | integer | yes | The ID of the merge request | ```bash -curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/merge_requests/17/subscription +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/merge_requests/17/subscribe ``` Example response: @@ -741,7 +741,7 @@ notifications from that merge request. If the user is not subscribed to the merge request, the status code `304` is returned. ``` -DELETE /projects/:id/merge_requests/:merge_request_id/subscription +DELETE /projects/:id/merge_requests/:merge_request_id/unsubscribe ``` | Attribute | Type | Required | Description | @@ -750,7 +750,7 @@ DELETE /projects/:id/merge_requests/:merge_request_id/subscription | `merge_request_id` | integer | yes | The ID of the merge request | ```bash -curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/merge_requests/17/subscription +curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/merge_requests/17/unsubscribe ``` Example response: diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index e24ee0da204..2dd8886ab97 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -29,5 +29,5 @@ changes are in V4: - Return pagination headers for all endpoints that return an array - Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead - Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` -- Make subscription API more RESTful. Use `post ":id/#{type}/:subscribable_id/subscribe"` to subscribe and `post ":id/#{type}/:subscribable_id/unsubscribe"` to unsubscribe from a resource. +- Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. - Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) From 6f5b3dc7a08340b022070907b9e3a3fd031504bb Mon Sep 17 00:00:00 2001 From: Nur Rony Date: Wed, 22 Feb 2017 14:44:01 +0600 Subject: [PATCH 136/247] fix rspec issue after delimiter fix --- spec/controllers/dashboard/todos_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb index 0a3ac9f9512..7072bd5e87c 100644 --- a/spec/controllers/dashboard/todos_controller_spec.rb +++ b/spec/controllers/dashboard/todos_controller_spec.rb @@ -46,7 +46,7 @@ describe Dashboard::TodosController do expect(todo.reload).to be_pending expect(response).to have_http_status(200) - expect(json_response).to eq({ "count" => 1, "done_count" => 0 }) + expect(json_response).to eq({ "count" => "1", "done_count" => "0" }) end end end From b8c88a839da9722f17bc7a851af2fae15e1ab1c5 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 22 Feb 2017 10:40:58 +0100 Subject: [PATCH 137/247] Grapfiy the CI::Triggers API --- lib/ci/api/triggers.rb | 43 ++++++++++----------------- spec/requests/ci/api/triggers_spec.rb | 3 +- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/lib/ci/api/triggers.rb b/lib/ci/api/triggers.rb index 63b42113513..6e622601680 100644 --- a/lib/ci/api/triggers.rb +++ b/lib/ci/api/triggers.rb @@ -1,41 +1,30 @@ module Ci module API - # Build Trigger API class Triggers < Grape::API resource :projects do - # Trigger a GitLab CI project build - # - # Parameters: - # id (required) - The ID of a CI project - # ref (required) - The name of project's branch or tag - # token (required) - The uniq token of trigger - # Example Request: - # POST /projects/:id/ref/:ref/trigger + desc 'Trigger a GitLab CI project build' do + success Entities::TriggerRequest + end + params do + requires :id, type: Integer, desc: 'The ID of a CI project' + requires :ref, type: String, desc: "The name of project's branch or tag" + requires :token, type: String, desc: 'The unique token of the trigger' + optional :variables, type: Hash, desc: 'Optional build variables' + end post ":id/refs/:ref/trigger" do - required_attributes! [:token] - - project = Project.find_by(ci_id: params[:id].to_i) - trigger = Ci::Trigger.find_by_token(params[:token].to_s) + project = Project.find_by(ci_id: params[:id]) + trigger = Ci::Trigger.find_by_token(params[:token]) not_found! unless project && trigger unauthorized! unless trigger.project == project - # validate variables - variables = params[:variables] - if variables - unless variables.is_a?(Hash) - render_api_error!('variables needs to be a hash', 400) - end - - unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) } - render_api_error!('variables needs to be a map of key-valued strings', 400) - end - - # convert variables from Mash to Hash - variables = variables.to_h + # Validate variables + variables = params[:variables].to_h + unless variables.all? { |key, value| key.is_a?(String) && value.is_a?(String) } + render_api_error!('variables needs to be a map of key-valued strings', 400) end # create request and trigger builds - trigger_request = Ci::CreateTriggerRequestService.new.execute(project, trigger, params[:ref].to_s, variables) + trigger_request = Ci::CreateTriggerRequestService.new.execute(project, trigger, params[:ref], variables) if trigger_request present trigger_request, with: Entities::TriggerRequest else diff --git a/spec/requests/ci/api/triggers_spec.rb b/spec/requests/ci/api/triggers_spec.rb index a30be767119..5321f8b134f 100644 --- a/spec/requests/ci/api/triggers_spec.rb +++ b/spec/requests/ci/api/triggers_spec.rb @@ -60,7 +60,8 @@ describe Ci::API::Triggers do it 'validates variables to be a hash' do post ci_api("/projects/#{project.ci_id}/refs/master/trigger"), options.merge(variables: 'value') expect(response).to have_http_status(400) - expect(json_response['message']).to eq('variables needs to be a hash') + + expect(json_response['error']).to eq('variables is invalid') end it 'validates variables needs to be a map of key-valued strings' do From f0766fdefaeadcc526d6a87e29b65f5bf7b26318 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Mon, 6 Feb 2017 20:15:25 +0100 Subject: [PATCH 138/247] extract pipeline mails layout --- .../images/mailers/gitlab_footer_logo.gif | Bin 0 -> 3654 bytes .../images/mailers/gitlab_header_logo.gif | Bin 0 -> 3040 bytes app/mailers/emails/pipelines.rb | 4 +- app/views/layouts/mailer.html.haml | 72 +++++ app/views/layouts/mailer.text.haml | 5 + .../notify/pipeline_failed_email.html.haml | 280 +++++++----------- .../notify/pipeline_failed_email.text.erb | 4 - .../notify/pipeline_success_email.html.haml | 230 +++++--------- .../notify/pipeline_success_email.text.erb | 4 - 9 files changed, 264 insertions(+), 335 deletions(-) create mode 100644 app/assets/images/mailers/gitlab_footer_logo.gif create mode 100644 app/assets/images/mailers/gitlab_header_logo.gif create mode 100644 app/views/layouts/mailer.html.haml create mode 100644 app/views/layouts/mailer.text.haml diff --git a/app/assets/images/mailers/gitlab_footer_logo.gif b/app/assets/images/mailers/gitlab_footer_logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f4ef31947bc4a53d6b2d243d6e9f2c975c84b77 GIT binary patch literal 3654 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 z

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 +%html{ lang: "en" } + %head + %meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/ + %meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/ + %meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/ + %title= message.subject + :css + /* CLIENT-SPECIFIC STYLES */ + body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } + table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; } + img { -ms-interpolation-mode: bicubic; } + + /* iOS BLUE LINKS */ + a[x-apple-data-detectors] { + color: inherit !important; + text-decoration: none !important; + font-size: inherit !important; + font-family: inherit !important; + font-weight: inherit !important; + line-height: inherit !important; + } + + /* ANDROID MARGIN HACK */ + body { margin:0 !important; } + div[style*="margin: 16px 0"] { margin:0 !important; } + + @media only screen and (max-width: 639px) { + body, #body { + min-width: 320px !important; + } + table.wrapper { + width: 100% !important; + min-width: 320px !important; + } + table.wrapper > tbody > tr > td { + border-left: 0 !important; + border-right: 0 !important; + border-radius: 0 !important; + padding-left: 10px !important; + padding-right: 10px !important; + } + } + %body{ style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;height:100%;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } + %table#body{ border: "0", cellpadding: "0", cellspacing: "0", style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;" } + %tbody + %tr.line + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }   + %tr.header + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } + %img{ alt: "GitLab", height: "50", src: image_url('mailers/gitlab_header_logo.gif'), width: "55" }/ + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } + %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" } + %tbody + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;padding:18px 25px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } + %table.content{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" } + %tbody + = yield + + %tr.footer + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } + %img{ alt: "GitLab", height: "33", src: image_url('mailers/gitlab_footer_logo.gif'), style: "display:block;margin:0 auto 1em;", width: "90" }/ + %div + %a{ href: profile_notifications_url, style: "color:#3777b0;text-decoration:none;" } Manage all notifications + · + %a{ href: help_url, style: "color:#3777b0;text-decoration:none;" } Help + %div + You're receiving this email because of your account on + = succeed "." do + %a{ href: root_url, style: "color:#3777b0;text-decoration:none;" }= Gitlab.config.gitlab.host diff --git a/app/views/layouts/mailer.text.haml b/app/views/layouts/mailer.text.haml new file mode 100644 index 00000000000..6a9c6ced9cc --- /dev/null +++ b/app/views/layouts/mailer.text.haml @@ -0,0 +1,5 @@ += yield + +You're receiving this email because of your account on #{Gitlab.config.gitlab.host}. +Manage all notifications: #{profile_notifications_url} +Help: #{help_url} diff --git a/app/views/notify/pipeline_failed_email.html.haml b/app/views/notify/pipeline_failed_email.html.haml index d9ebbaa2704..85a1aea3a61 100644 --- a/app/views/notify/pipeline_failed_email.html.haml +++ b/app/views/notify/pipeline_failed_email.html.haml @@ -1,179 +1,109 @@ - -%html{ lang: "en" } - %head - %meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/ - %meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/ - %meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/ - %title= message.subject - :css - /* CLIENT-SPECIFIC STYLES */ - body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } - table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; } - img { -ms-interpolation-mode: bicubic; } - - /* iOS BLUE LINKS */ - a[x-apple-data-detectors] { - color: inherit !important; - text-decoration: none !important; - font-size: inherit !important; - font-family: inherit !important; - font-weight: inherit !important; - line-height: inherit !important; - } - - /* ANDROID MARGIN HACK */ - body { margin:0 !important; } - div[style*="margin: 16px 0"] { margin:0 !important; } - - @media only screen and (max-width: 639px) { - body, #body { - min-width: 320px !important; - } - table.wrapper { - width: 100% !important; - min-width: 320px !important; - } - table.wrapper > tbody > tr > td { - border-left: 0 !important; - border-right: 0 !important; - border-radius: 0 !important; - padding-left: 10px !important; - padding-right: 10px !important; - } - } - %body{ style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;height:100%;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } - %table#body{ border: "0", cellpadding: "0", cellspacing: "0", style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;" } +%tr.alert + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:10px;border-radius:3px;font-size:14px;line-height:1.3;text-align:center;overflow:hidden;background-color:#d22f57;color:#ffffff;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;margin:0 auto;" } %tbody - %tr.line - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }   - %tr.header - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } - %img{ alt: "GitLab", height: "50", src: image_url('mailers/ci_pipeline_notif_v1/gitlab-logo.gif'), width: "55" }/ %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } - %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" } + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;" } + %img{ alt: "x", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red-inverted.gif'), style: "display:block;", width: "13" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;" } + Your pipeline has failed. +%tr.spacer + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } +   +%tr.section + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } + %table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" } + %tbody + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" } Project + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;" } + - namespace_name = @project.group ? @project.group.name : @project.namespace.owner.name + - namespace_url = @project.group ? group_url(@project.group) : user_url(@project.namespace.owner) + %a.muted{ href: namespace_url, style: "color:#333333;text-decoration:none;" } + = namespace_name + \/ + %a.muted{ href: project_url(@project), style: "color:#333333;text-decoration:none;" } + = @project.name + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Branch + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } %tbody %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;padding:18px 25px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } - %table.content{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" } - %tbody - %tr.alert - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:10px;border-radius:3px;font-size:14px;line-height:1.3;text-align:center;overflow:hidden;background-color:#d22f57;color:#ffffff;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;margin:0 auto;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;" } - %img{ alt: "x", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red-inverted.gif'), style: "display:block;", width: "13" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;" } - Your pipeline has failed. - %tr.spacer - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } -   - %tr.section - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } - %table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" } Project - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;" } - - namespace_name = @project.group ? @project.group.name : @project.namespace.owner.name - - namespace_url = @project.group ? group_url(@project.group) : user_url(@project.namespace.owner) - %a.muted{ href: namespace_url, style: "color:#333333;text-decoration:none;" } - = namespace_name - \/ - %a.muted{ href: project_url(@project), style: "color:#333333;text-decoration:none;" } - = @project.name - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Branch - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } - %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-branch-gray.gif'), style: "display:block;", width: "13", alt: "Branch icon" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } - %a.muted{ href: commits_url(@pipeline), style: "color:#333333;text-decoration:none;" } - = @pipeline.ref - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Commit - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } - %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-commit-gray.gif'), style: "display:block;", width: "13", alt: "Commit icon" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } - %a{ href: commit_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } - = @pipeline.short_sha - - if @merge_request - in - %a{ href: merge_request_url(@merge_request), style: "color:#3777b0;text-decoration:none;" } - = @merge_request.to_reference - .commit{ style: "color:#5c5c5c;font-weight:300;" } - = @pipeline.git_commit_message.truncate(50) - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Author - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - - commit = @pipeline.commit - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } - %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } - - if commit.author - %a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" } - = commit.author.name - - else - %span - = commit.author_name - %tr.spacer - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } -   - - failed = @pipeline.statuses.latest.failed - %tr.pre-section - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#333333;font-size:15px;font-weight:400;line-height:1.4;padding:15px 0;" } - Pipeline - %a{ href: pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } - = "\##{@pipeline.id}" - had - = failed.size - failed - #{'build'.pluralize(failed.size)}. - %tr.warning - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;border:1px solid #ededed;border-bottom:0;border-radius:3px 3px 0 0;overflow:hidden;background-color:#fdf4f6;color:#d22852;font-size:14px;line-height:1.4;text-align:center;padding:8px 15px;" } - Logs may contain sensitive data. Please consider before forwarding this email. - %tr.section - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;border-top:0;border-radius:0 0 3px 3px;" } - %table.builds{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:collapse;" } - %tbody - - failed.each do |build| - %tr.build-state - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:20px 0;color:#8c8c8c;font-weight:500;font-size:15px;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#8c8c8c;font-weight:500;font-size:15px;vertical-align:middle;padding-right:5px;" } - %img{ alt: "x", height: "10", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red.gif'), style: "display:block;", width: "10" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#8c8c8c;font-weight:500;font-size:15px;vertical-align:middle;" } - = build.stage - %td{ align: "right", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:20px 0;color:#8c8c8c;font-weight:500;font-size:15px;" } - = render "notify/links/#{build.to_partial_path}", pipeline: @pipeline, build: build - %tr.build-log - - if build.has_trace? - %td{ colspan: "2", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 0 15px;" } - %pre{ style: "font-family:Monaco,'Lucida Console','Courier New',Courier,monospace;background-color:#fafafa;border-radius:3px;overflow:hidden;white-space:pre-wrap;word-break:break-all;font-size:13px;line-height:1.4;padding:12px;color:#333333;margin:0;" } - = build.trace_html(last_lines: 10).html_safe - - else - %td{ colspan: "2" } - %tr.footer - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } - %img{ alt: "GitLab", height: "33", src: image_url('mailers/ci_pipeline_notif_v1/gitlab-logo-full-horizontal.gif'), style: "display:block;margin:0 auto 1em;", width: "90" }/ - %div - %a{ href: profile_notifications_url, style: "color:#3777b0;text-decoration:none;" } Manage all notifications - · - %a{ href: help_url, style: "color:#3777b0;text-decoration:none;" } Help - %div - You're receiving this email because of your account on - = succeed "." do - %a{ href: root_url, style: "color:#3777b0;text-decoration:none;" }= Gitlab.config.gitlab.host + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } + %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-branch-gray.gif'), style: "display:block;", width: "13", alt: "Branch icon" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } + %a.muted{ href: commits_url(@pipeline), style: "color:#333333;text-decoration:none;" } + = @pipeline.ref + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Commit + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } + %tbody + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } + %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-commit-gray.gif'), style: "display:block;", width: "13", alt: "Commit icon" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } + %a{ href: commit_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } + = @pipeline.short_sha + - if @merge_request + in + %a{ href: merge_request_url(@merge_request), style: "color:#3777b0;text-decoration:none;" } + = @merge_request.to_reference + .commit{ style: "color:#5c5c5c;font-weight:300;" } + = @pipeline.git_commit_message.truncate(50) + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Author + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } + %tbody + %tr + - commit = @pipeline.commit + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } + %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } + - if commit.author + %a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" } + = commit.author.name + - else + %span + = commit.author_name +%tr.spacer + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } +   +- failed = @pipeline.statuses.latest.failed +%tr.pre-section + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#333333;font-size:15px;font-weight:400;line-height:1.4;padding:15px 0;" } + Pipeline + %a{ href: pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } + = "\##{@pipeline.id}" + had + = failed.size + failed + #{'build'.pluralize(failed.size)}. +%tr.warning + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;border:1px solid #ededed;border-bottom:0;border-radius:3px 3px 0 0;overflow:hidden;background-color:#fdf4f6;color:#d22852;font-size:14px;line-height:1.4;text-align:center;padding:8px 15px;" } + Logs may contain sensitive data. Please consider before forwarding this email. +%tr.section + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;border-top:0;border-radius:0 0 3px 3px;" } + %table.builds{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:collapse;" } + %tbody + - failed.each do |build| + %tr.build-state + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:20px 0;color:#8c8c8c;font-weight:500;font-size:15px;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } + %tbody + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#8c8c8c;font-weight:500;font-size:15px;vertical-align:middle;padding-right:5px;" } + %img{ alt: "x", height: "10", src: image_url('mailers/ci_pipeline_notif_v1/icon-x-red.gif'), style: "display:block;", width: "10" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#8c8c8c;font-weight:500;font-size:15px;vertical-align:middle;" } + = build.stage + %td{ align: "right", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:20px 0;color:#8c8c8c;font-weight:500;font-size:15px;" } + = render "notify/links/#{build.to_partial_path}", pipeline: @pipeline, build: build + %tr.build-log + - if build.has_trace? + %td{ colspan: "2", style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 0 15px;" } + %pre{ style: "font-family:Monaco,'Lucida Console','Courier New',Courier,monospace;background-color:#fafafa;border-radius:3px;overflow:hidden;white-space:pre-wrap;word-break:break-all;font-size:13px;line-height:1.4;padding:12px;color:#333333;margin:0;" } + = build.trace_html(last_lines: 10).html_safe + - else + %td{ colspan: "2" } diff --git a/app/views/notify/pipeline_failed_email.text.erb b/app/views/notify/pipeline_failed_email.text.erb index ab91c7ef350..520a2fc7d68 100644 --- a/app/views/notify/pipeline_failed_email.text.erb +++ b/app/views/notify/pipeline_failed_email.text.erb @@ -27,7 +27,3 @@ Trace: <%= build.trace_with_state(last_lines: 10)[:text] %> <% end -%> <% end -%> - -You're receiving this email because of your account on <%= Gitlab.config.gitlab.host %>. -Manage all notifications: <%= profile_notifications_url %> -Help: <%= help_url %> diff --git a/app/views/notify/pipeline_success_email.html.haml b/app/views/notify/pipeline_success_email.html.haml index 8add2e18206..19d4add06f5 100644 --- a/app/views/notify/pipeline_success_email.html.haml +++ b/app/views/notify/pipeline_success_email.html.haml @@ -1,154 +1,84 @@ - -%html{ lang: "en" } - %head - %meta{ content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/ - %meta{ content: "width=device-width, initial-scale=1", name: "viewport" }/ - %meta{ content: "IE=edge", "http-equiv" => "X-UA-Compatible" }/ - %title= message.subject - :css - /* CLIENT-SPECIFIC STYLES */ - body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } - table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; } - img { -ms-interpolation-mode: bicubic; } - - /* iOS BLUE LINKS */ - a[x-apple-data-detectors] { - color: inherit !important; - text-decoration: none !important; - font-size: inherit !important; - font-family: inherit !important; - font-weight: inherit !important; - line-height: inherit !important; - } - - /* ANDROID MARGIN HACK */ - body { margin:0 !important; } - div[style*="margin: 16px 0"] { margin:0 !important; } - - @media only screen and (max-width: 639px) { - body, #body { - min-width: 320px !important; - } - table.wrapper { - width: 100% !important; - min-width: 320px !important; - } - table.wrapper > tbody > tr > td { - border-left: 0 !important; - border-right: 0 !important; - border-radius: 0 !important; - padding-left: 10px !important; - padding-right: 10px !important; - } - } - %body{ style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;height:100%;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } - %table#body{ border: "0", cellpadding: "0", cellspacing: "0", style: "background-color:#fafafa;margin:0;padding:0;text-align:center;min-width:640px;width:100%;" } +%tr.success + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:10px;border-radius:3px;font-size:14px;line-height:1.3;text-align:center;overflow:hidden;color:#ffffff;background-color:#31af64;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;margin:0 auto;" } %tbody - %tr.line - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }   - %tr.header - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } - %img{ alt: "GitLab", height: "50", src: image_url('mailers/ci_pipeline_notif_v1/gitlab-logo.gif'), width: "55" }/ %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } - %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" } + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;" } + %img{ alt: "✓", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-check-green-inverted.gif'), style: "display:block;", width: "13" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;" } + Your pipeline has passed. +%tr.spacer + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } +   +%tr.section + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } + %table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" } + %tbody + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" } Project + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;" } + - namespace_name = @project.group ? @project.group.name : @project.namespace.owner.name + - namespace_url = @project.group ? group_url(@project.group) : user_url(@project.namespace.owner) + %a.muted{ href: namespace_url, style: "color:#333333;text-decoration:none;" } + = namespace_name + \/ + %a.muted{ href: project_url(@project), style: "color:#333333;text-decoration:none;" } + = @project.name + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Branch + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } %tbody %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#ffffff;text-align:left;padding:18px 25px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } - %table.content{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;border-collapse:separate;border-spacing:0;" } - %tbody - %tr.success - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:10px;border-radius:3px;font-size:14px;line-height:1.3;text-align:center;overflow:hidden;color:#ffffff;background-color:#31af64;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;margin:0 auto;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;padding-right:5px;" } - %img{ alt: "✓", height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-check-green-inverted.gif'), style: "display:block;", width: "13" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;vertical-align:middle;color:#ffffff;text-align:center;" } - Your pipeline has passed. - %tr.spacer - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } -   - %tr.section - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:0 15px;border:1px solid #ededed;border-radius:3px;overflow:hidden;" } - %table.info{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:100%;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;" } Project - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;" } - - namespace_name = @project.group ? @project.group.name : @project.namespace.owner.name - - namespace_url = @project.group ? group_url(@project.group) : user_url(@project.namespace.owner) - %a.muted{ href: namespace_url, style: "color:#333333;text-decoration:none;" } - = namespace_name - \/ - %a.muted{ href: project_url(@project), style: "color:#333333;text-decoration:none;" } - = @project.name - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Branch - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } - %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-branch-gray.gif'), style: "display:block;", width: "13", alt: "Branch icon" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } - %a.muted{ href: commits_url(@pipeline), style: "color:#333333;text-decoration:none;" } - = @pipeline.ref - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Commit - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } - %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-commit-gray.gif'), style: "display:block;", width: "13", alt: "Commit icon" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } - %a{ href: commit_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } - = @pipeline.short_sha - - if @merge_request - in - %a{ href: merge_request_url(@merge_request), style: "color:#3777b0;text-decoration:none;" } - = @merge_request.to_reference - .commit{ style: "color:#5c5c5c;font-weight:300;" } - = @pipeline.git_commit_message.truncate(50) - %tr - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Author - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } - %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } - %tbody - %tr - - commit = @pipeline.commit - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } - %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/ - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } - - if commit.author - %a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" } - = commit.author.name - - else - %span - = commit.author_name - %tr.spacer - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } -   - %tr.success-message - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#333333;font-size:15px;font-weight:400;line-height:1.4;padding:15px 5px;text-align:center;" } - - build_count = @pipeline.statuses.latest.size - - stage_count = @pipeline.stages_count - Pipeline - %a{ href: pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } - = "\##{@pipeline.id}" - successfully completed - #{build_count} #{'build'.pluralize(build_count)} - in - #{stage_count} #{'stage'.pluralize(stage_count)}. - %tr.footer - %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } - %img{ alt: "GitLab", height: "33", src: image_url('mailers/ci_pipeline_notif_v1/gitlab-logo-full-horizontal.gif'), style: "display:block;margin:0 auto 1em;", width: "90" }/ - %div - %a{ href: profile_notifications_url, style: "color:#3777b0;text-decoration:none;" } Manage all notifications - · - %a{ href: help_url, style: "color:#3777b0;text-decoration:none;" } Help - %div - You're receiving this email because of your account on - = succeed "." do - %a{ href: root_url, style: "color:#3777b0;text-decoration:none;" }= Gitlab.config.gitlab.host + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } + %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-branch-gray.gif'), style: "display:block;", width: "13", alt: "Branch icon" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } + %a.muted{ href: commits_url(@pipeline), style: "color:#333333;text-decoration:none;" } + = @pipeline.ref + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Commit + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } + %tbody + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } + %img{ height: "13", src: image_url('mailers/ci_pipeline_notif_v1/icon-commit-gray.gif'), style: "display:block;", width: "13", alt: "Commit icon" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } + %a{ href: commit_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } + = @pipeline.short_sha + - if @merge_request + in + %a{ href: merge_request_url(@merge_request), style: "color:#3777b0;text-decoration:none;" } + = @merge_request.to_reference + .commit{ style: "color:#5c5c5c;font-weight:300;" } + = @pipeline.git_commit_message.truncate(50) + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;border-top:1px solid #ededed;" } Author + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#8c8c8c;font-weight:300;padding:14px 0;margin:0;color:#333333;font-weight:400;width:75%;padding-left:5px;border-top:1px solid #ededed;" } + %table.img{ border: "0", cellpadding: "0", cellspacing: "0", style: "border-collapse:collapse;" } + %tbody + %tr + - commit = @pipeline.commit + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" } + %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/ + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" } + - if commit.author + %a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" } + = commit.author.name + - else + %span + = commit.author_name +%tr.spacer + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;height:18px;font-size:18px;line-height:18px;" } +   +%tr.success-message + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;color:#333333;font-size:15px;font-weight:400;line-height:1.4;padding:15px 5px;text-align:center;" } + - build_count = @pipeline.statuses.latest.size + - stage_count = @pipeline.stages_count + Pipeline + %a{ href: pipeline_url(@pipeline), style: "color:#3777b0;text-decoration:none;" } + = "\##{@pipeline.id}" + successfully completed + #{build_count} #{'build'.pluralize(build_count)} + in + #{stage_count} #{'stage'.pluralize(stage_count)}. diff --git a/app/views/notify/pipeline_success_email.text.erb b/app/views/notify/pipeline_success_email.text.erb index 40e5e306426..0970a3a4e09 100644 --- a/app/views/notify/pipeline_success_email.text.erb +++ b/app/views/notify/pipeline_success_email.text.erb @@ -18,7 +18,3 @@ Commit Author: <%= commit.author_name %> <% build_count = @pipeline.statuses.latest.size -%> <% stage_count = @pipeline.stages_count -%> Pipeline #<%= @pipeline.id %> ( <%= pipeline_url(@pipeline) %> ) successfully completed <%= build_count %> <%= 'build'.pluralize(build_count) %> in <%= stage_count %> <%= 'stage'.pluralize(stage_count) %>. - -You're receiving this email because of your account on <%= Gitlab.config.gitlab.host %>. -Manage all notifications: <%= profile_notifications_url %> -Help: <%= help_url %> From 0df104a389438665df2c7248ae022cdbb767f838 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 7 Feb 2017 16:06:27 +0100 Subject: [PATCH 139/247] use custom brand logo in pipeline mails --- app/helpers/emails_helper.rb | 14 +++++++++++++ app/views/layouts/mailer.html.haml | 2 +- spec/helpers/emails_helper_spec.rb | 32 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 2843ad96efa..3beddff9206 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -1,4 +1,6 @@ module EmailsHelper + include AppearancesHelper + # Google Actions # https://developers.google.com/gmail/markup/reference/go-to-action def email_action(url) @@ -49,4 +51,16 @@ module EmailsHelper msg = "This link is valid for #{password_reset_token_valid_time}. " msg << "After it expires, you can #{link_tag}." end + + def header_logo + if brand_item && brand_item.header_logo? + brand_header_logo + else + image_tag( + image_url('mailers/gitlab_header_logo.gif'), + size: "55x50", + alt: "GitLab" + ) + end + end end diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml index 39133f8cdb3..53268cc22f8 100644 --- a/app/views/layouts/mailer.html.haml +++ b/app/views/layouts/mailer.html.haml @@ -48,7 +48,7 @@ %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }   %tr.header %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } - %img{ alt: "GitLab", height: "50", src: image_url('mailers/gitlab_header_logo.gif'), width: "55" }/ + = header_logo %tr %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } %table.wrapper{ border: "0", cellpadding: "0", cellspacing: "0", style: "width:640px;margin:0 auto;border-collapse:separate;border-spacing:0;" } diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb index 3223556e1d3..b9519e387eb 100644 --- a/spec/helpers/emails_helper_spec.rb +++ b/spec/helpers/emails_helper_spec.rb @@ -43,4 +43,36 @@ describe EmailsHelper do end end end + + describe '#header_logo' do + context 'there is a brand item with a logo' do + it 'returns the brand header logo' do + appearance = create :appearance, header_logo: fixture_file_upload( + Rails.root.join('spec/fixtures/dk.png') + ) + + expect(header_logo).to eq( + %{Dk} + ) + end + end + + context 'there is a brand item without a logo' do + it 'returns the default header logo' do + create :appearance, header_logo: nil + + expect(header_logo).to eq( + %{GitLab} + ) + end + end + + context 'there is no brand item' do + it 'returns the default header logo' do + expect(header_logo).to eq( + %{GitLab} + ) + end + end + end end From 84420c89d5fbf98a19fb831a4489e9d5441e18ad Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 7 Feb 2017 18:23:58 +0100 Subject: [PATCH 140/247] add documentation for custom brand logo in email --- doc/README.md | 1 + .../branded_page_and_email_header.md | 15 +++++++++++++++ .../appearance.png | Bin 0 -> 10253 bytes .../custom_brand_header.png | Bin 0 -> 10014 bytes .../custom_email_header.png | Bin 0 -> 37472 bytes 5 files changed, 16 insertions(+) create mode 100644 doc/customization/branded_page_and_email_header.md create mode 100644 doc/customization/branded_page_and_email_header/appearance.png create mode 100644 doc/customization/branded_page_and_email_header/custom_brand_header.png create mode 100644 doc/customization/branded_page_and_email_header/custom_email_header.png diff --git a/doc/README.md b/doc/README.md index 1943d656aa7..c082b91a6b1 100644 --- a/doc/README.md +++ b/doc/README.md @@ -50,6 +50,7 @@ - [System hooks](system_hooks/system_hooks.md) Notifications when users, projects and keys are changed. - [Update](update/README.md) Update guides to upgrade your installation. - [Welcome message](customization/welcome_message.md) Add a custom welcome message to the sign-in page. +- [Header logo](customization/branded_page_and_email_header.md) Change the logo on the overall page and email header. - [Reply by email](administration/reply_by_email.md) Allow users to comment on issues and merge requests by replying to notification emails. - [Migrate GitLab CI to CE/EE](migrate_ci_to_ce/README.md) Follow this guide to migrate your existing GitLab CI data to GitLab CE/EE. - [Git LFS configuration](workflow/lfs/lfs_administration.md) diff --git a/doc/customization/branded_page_and_email_header.md b/doc/customization/branded_page_and_email_header.md new file mode 100644 index 00000000000..9a0f0b382fa --- /dev/null +++ b/doc/customization/branded_page_and_email_header.md @@ -0,0 +1,15 @@ +# Changing the logo on the overall page and email header + +Navigate to the **Admin** area and go to the **Appearance** page. + +Upload the custom logo (**Header logo**) in the section **Navigation bar**. + +![appearance](branded_page_and_email_header/appearance.png) + +After saving the page, your GitLab navigation bar will contain the custom logo: + +![custom_brand_header](branded_page_and_email_header/custom_brand_header.png) + +The GitLab pipeline emails will also have the custom logo: + +![custom_email_header](branded_page_and_email_header/custom_email_header.png) diff --git a/doc/customization/branded_page_and_email_header/appearance.png b/doc/customization/branded_page_and_email_header/appearance.png new file mode 100644 index 0000000000000000000000000000000000000000..abbba6f9ac9facf1b58d2caf1c3aa09830cf0342 GIT binary patch literal 10253 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 literal 0 HcmV?d00001 diff --git a/doc/customization/branded_page_and_email_header/custom_brand_header.png b/doc/customization/branded_page_and_email_header/custom_brand_header.png new file mode 100644 index 0000000000000000000000000000000000000000..7390f8a5e4e82cf3a5fc9f8127e3d7a17f54d764 GIT binary patch literal 10014 zcmcI~cQ{*p*swl*N~={>R9ma1W-5xJcB@A1)(#OXA$Wu5dEWPXzw3Ix>;2<9mrKrl&iUQvUcY;u_m6ee8R)Om)6mc`XgpHU zr=d9mq@FvRrKSG&_2>9PLvw>hL*;>?&!^>7m}AO|=Qz*3EM-y~_;X98((sqisZI(q zXSHDWmi?ae^M81D%cfW4(i=W}^3LxPt;bxaGQhu(n|!+W z?rquK^71X4=}$|k4-@TPGHsr^|6(9X#c8Na@E8=tmybHO z!KS1Qn)rBlc%H}X4AHeo1$Hjw9aPVho@Zj(!x;+afPn%uBeKG<;a$~}#~6{0kim(! z-VTHgLKiz}EOU;l-h6b!whh9~!?Rt}Ze2d0L-#ZK21475LJXAP15xd!8!jNB4Uw)XHf~IzoP>WDRV{Pvm_I+5`J^+9Dv%)3d(c-e=+}xl%Veuex$9Z-x z_qDC3LrLA-QQj0!DvyVn{}o%pYuA-;bz1{C$`C^gd0=hNIBI<1|H9`~5`ZtFk9238 zDxTOXb%sqO7ZX+CO6kixOR6g058|Qcdb!RX%Xmbp6utSvlhy2Z{c$IDaF>@r&709Ijp4GvUizG+QKq(tl{8YW% z_n!}k`jS6Q`EL0t>~9Y6k^MMm$xw=k#u>c?hdTqn8d`6q2yfVk83}sP$WZmw3L$*`Yo<6oYvoX~1+lJ!scn zp@HO?np)S806!M?cc3R8RUpYbQzhLb5i>aSUf3r~uo%uq) z7a%NOW)UKQv4m0BllS)_!&PnQjHbA8ELZ{5L;dw!7W0l=ih*Ul{6&R~e7f?QOmy2I zN>tN@>x5#8a>Abd2>Wg`TJ1Oc9v)s6*J*D>Jwy`B}Zm^>k z)BO%pF;-`c?Cf0l)gB>Yu@rlvt&k~-T`B!uP2q32H#~DXM~PDFbX^fz7%GmXIov+zU;4BJ zgqzP|w59!&&5Y$UKi6EB;E*&Ly*u!J-Ae7NTaK+U^(wU2zcb8-_@g6QodsCD66rsK z!uOv|Gzl6`JO8s9m4KbL@s{)9$NiKc^LewA38j_&O$4A^ol$^psgikMAf}--eXvDa z&0PTEon;$Qc;|1G+TpkACZH%-9sK|)|M#rdK6$_KGwjZt&!>9SS0{5Rap>G;n*)vX zgB|m6%{G|R)BBlo@ovKe2W338OCpItV6tae9uz-x9S zH}kUAKj+P7M?ldy!_5J;i%w^Hq|9`E-CM>rgLE(oOhD14>Gld)lI_;ycZa|& zM+fPJn9iCz42hIr||1| z&0+v~!mSNQr=s$U+Z@$uGZtA}$p4n9MO!PU1rE|;;>|Zz9q2S;x~5inp!wqq5j(oO z?4%VlIC&AhO9n~Y=Dlh)#OL@4ZSLv|dhsI7vw61N-EVbhw{M+{?WwBNk%#l1kd-Q} zU{jY*#!QUY)IpQ@gx+qQ&_h-G=u96!R^`P2*7eY zoH`Pe&<>MOL|{=sac4_Ar0?if;MR_`VG^qF0A<-&H?w-0x))=LLoqxc5Yt1oJ0+FO z2EAv6o%0fOP0WfCUC%H){20t9kZL^UT9fKxiHy7qe70e?STYTHDTZxw)2fmKTMoB> zu>*OOP9erWxt~Ofy3VG$Mu-ys3a+GS%HJ4wuKs;p1XeEh60&B^_h2p~x{;CUQkABH zkek(Z>`bE$&dZ6FFUOI^Kg{suEydHpS|g5B=Qp|h(*gB6p}Y`oEtMUJchePEaz2ME z^qw=Tizb*|J`PNEy(x#QsjW}e5JNY`x5jZVuZj?1ODTm}gmfuWd+G*qwxm4ydrNoW zjN~)yZr{X|+sIYdSxnrqR?)UeNZ@4XxYHDlsCI1o=maVc&nb6n$%!)_6T@1%3i;0X zN)y*w-AfBJkipx~!mpX7SJ*tsZeoVHo?B+d7!<1ru#!u3oEb>G4sKgFYN*iwh(!EN z+DOyEkaV}uuhI&?_4d~B7L$YQ?r;okU-?NS8klR&$uYeJb``;V=6PbETfm)b)51&7 z#?APSwKyyy`kIK6?NxeOUd`;unZ*#y(2Q!~in1;;I9fkH3~rJ*IIpOf;OL9&WXU2_ z_#KcJ?R?$hvTT6r$fKzK%g+UUIJ@`**@K<%TI2KvK-fhfh0G6Q4yn=*pentTeN^}& zRNcU|Z#tpStz>Hc%~5cvSHv_Iz=54qPMsmz1N~I202hAvxZho;q4?hrlo$>&m}1z!?-G-Dttd zm4|sIzBjVS3YX?8J_|oY@tYmYLj)V$vQBa&$Wf3U*>wOLgK_Jl*HR~&{u4=e3iopH z#Si`+(zE|TFQp?UGKHbIdSvD7j(x7P#IlA zLW90*17_X$_iW?7t&o}JZj?U;?*?fZ{+(mkMvS4ZPCQu+9aTJW#0oDJ(@pTHIJdX6 zhxJ+^0yPfgwGOB0sc=kVEhe!0aMzQtL5}WWXJT5FKL@8-etjI2!Yl~ITCURC2S2$8 z5#ucp-pq&Yq}oL3!&P(6bgJ;DQ2!+_tLs(<7Anu082QXOcO9nq$5W#G4R;3W40o1b zB`E-`oT8G7N__<%_>W4u<7AP?t2o3P2GNQmEfy-(nuHwgH$?Z)F)@izo!TFj=l_1D zN;TRe;N4B( zuOKvY;=63+4mQw;6GJ{q0GY~`ZXNrZqr{WvIrhXZjx0^(dr900*T)I5g}_O=dAz7j z_k^0`MP8{V3Fq;mU$S(u?b(;gq`{`9^E(`uj$Z+r#a#^>>AHB9S{0lepD{PUfBXa7 z$38&*`48}_q{{?zIF9A>e1ASilf4-{oOYFG>W^#SL* zB(~o!ltoybO#S18%FlWlIr<$0x70M+`+Bh$LcC^9a?ru_bmo;SR}2MNs-ea-TS6@K zW~QcgLY4>46yGQ{?t%SP-G$dPb!88y4p-vUvSJq2;*>_3^d7A$p9p2%Ahz8)FOQ~o zpmJT}u9A{oCDl_1vY3T0XSpb9R{pxY3iH;a5>qBZ@z?~O2<4Sx2=v@nF*EYDX(B`I zYh%SwD$V=RbaJ=-aqKu;lb+gtVm~WH!%h`>11-MXn-4r3dLsSayi58tQndKXehf`E ztD49n#(!A6nN8z(p^0zvdN5`x0Se+i(aHUE;Hi3U@DvnWt8lfEm~u;O&xN%?apr+suZAuGu{Rxro(Cs9B9UeM&;B=xM+ZNY ze;OFtutGN0@_%z685TRMJQcDT#V^Bo; zz{kgrp7_U^s9gqTymhodRODPNOa*_vT^$^oGn(DRE~C-e=6|e!u-aTjZ95uD#vU`=?KjR|3kuDTOV6R->i8d*@EBDP!>aB2JT$ zq(s~*9Jh+CWHRjR&@5-&-eaw-omH)r0Czl*ziMc0pll9rh+)tGaQ%iW(%DGQD6GDP z`l<)<)6jfoN2WrrMd!trlAuoa9WMbf07=F#gV#6gyVAm5LIkrP+o{pTBx@$@&c)j5 zaSVU^>OIk!vACQ)<@@3ySO4p4B$>TT*RI@+*hEQhYqgArM5FHHYpF^s`a7oObDq{7 z_>r5Of@uPGvremPCy1sZuuTj3O)ccrh{fPkd#IynXmsiT%0OLn<05zXl5*~JqyyS^ zo>i6=C}O3YrI;Q-{j*|Dj%EW`7#sWO%c*z7gg6ykr48h3V+FBp8@Dxkc!1GNjoKQq zS@|$!IrRvu$d>`a;QfuHDweeve|PqwogH1WFwgTD-%?2>^Rk6=QRIMivf5omR^uUv zCsyVK4k}RyXpcwNqINSVnY=Gta|)hS2ec5jv^wVB=>~u;GmygIR>$dJwWON|OLkVx>(#e2Tdp%b*gMTQ7z%C<7jn(%57m%qmIQD zldK zA*^HGhQwd-`tC%JTO9qJeKI6hmx;i(?mB=1F;JE`-0_1v$GaPA92m7*oq zmS(k=j08PQb3)QE?y};{{rItjbV(wj4yxIQ2={$traM|reM`=q$HB;{5am$GIz!^f zM%%;<-=9g{UEMuhfH$yVn>W2!J>TTz*QB9@77`ztDhtU+A#!*W{_;Y)W;mX#4 ztmN=p)}X{rpNWV7=c^nsrVbQ^fCi|&ye2I>kVQ8#O5j<3{3nT(yjOGTWb|tL0vvnpsM(P(l`Twn*&$e9O4` znrvWnaM7B8iICm*EcU*OY%gB#LUpDhikA%afB8`xqKXcmvNK2q(~c2|rpG ztLWLYtoj2`AYDmpHrWg&hjT?MWeLo=JPOeYPdm)m4xqe?2E#pO+WfMoliZMC{{u!2 zQtJR8XPIqf+o!%wGI#CxPy^I=P2wS=faPHGd!m`yIciALW3LX+V@(;ED=FDLW35qs z!KI4O8-E$30W$9^5MyAh6>}f|p|X|OVIwx*#I;jdrU%QSFOxKE?6})m4 z-g6##dR*=9H9eF1;qvAnEs%|kI=`gsY+xWXC4l*3RA_(H(@+A5?)vxp(j|r^^?<3Z zuJ>moEhv6B^7D;2ZU7{%$BS8@%u1)Qw@9_256;xPMnb{5LoNgkKAv~pY4+FDK7U(m ztn7UB_;vrzfOt~^w#jjY@)}w+eO0~h6+~^wX=NBu+F$;h(3TgKFKwAc5(5Zu0TpoE zXT9!q)Z*Rzwn{zuG(ZyI{R96#IXl~`1JY+pBzS4Rv8zX$FcNU&L-j@?9l-DOd~Q~> zLs2gaclyt8(ua871|7h6`W+235LudYOOfVU4Q&!cPeGP`CjZeroP?|_oRk)%yr)d( zS>lD1ow4rbG!zWbF7V44PVtscD0Tl8Ynyemivs~roys{M+EHrXfW4sb(8Q5dPhE0_ zJpmVMt!tm%J``VQ4+KY>Ty$n1TVU_A<^jksMePNQ8Tm$6QFn27T^}X9M+|^wN%`Pn z-H~cgNc{E887Q+mJ4k0)UzyNuqK0Agm}_E{teA6KY9?rnxl&{re%t7F)E9?3G!xoS z*P1eOaqqsjuw?aJ1&hHVe!9bD)}z#(kulHZ4>;~kAn(uC z)ce`>FGVd#4xrJG_T6NQZc_lLVL>`^V0RYGJmvA`7h1bI8gWwiRX zL@x9%QJDSKuj@n-dw6oSBOoKJY&Xd*+YE+oS>rjURqfP%HzG#ThdVX@j|2M<=4y_k z;+%m8TxTi=*0e`F@K&`o1A*}Nt1zvu0LCxPHtwr1hjfJIjy4U={X?iZ7Af!cpgrV_ zh)*uOzTYbaFP<)IJQZZ&K9Jrq6e$v-wdz2pn`cxfDer#pS(#3^^uXUO)pgxHl$D+{ zaa?{w6LK%3nXW1MTnI}t;)&qhtgLoFym;ws-?fm;iX7H>GK!ZzB(ofz;?vbD;UNqj z>$6`Tllj7wu801}L=NCh7Uye^6R2kXP@$;GoP^aEQxqk4ud7zu9SzUP(kW30f*gpYaW`&)V}2OqNH-P%SOjSlrT zw2~DUT3fh9v^FY47hfYYcrhldsr!Zq_SFUajNU?@7B;)(w5K!D0NrZKw_!5nT4OJL z7QPZ7T$2eWLTy&~mh)w78^~DB7$_>Ia$!y$gb0Fo=Cd<&B;Er2JcD|s!`J_%9ys?? z*QLd30PmK)#%)>E)1FKp=>rfHnC_6eo`oO}aXI+6#VhAz<$HHN8Yu|-@NkS3P*TuS zyO#0Ic+K%SyxJH0XOw53u&@BW_;>O};mgthWsSITP(|*ALl1JGS(R{cH#WR&BmqL- zvC3GNUf`juwv1wTW-XOKvspKLRpZH+!ZQ(VNMeycbw3nKTfV1V&EhOEYZ>#s4xZ_6 z_!&)#4}KHW82RY&fRQ`o(El+j&^++4!D^VoW%%tVChvyoI14#?t!L^%O(%76` zfDBg7r3E_y6|(8()~EWDc1pQzmc*EMX17B=J1{1`$tDONza3)BqM%SXt88|@eLxne zhScUf5Ac{*UT9S%&pzog48cfRN^D->JO?+vZ-r*kxhjT86v5oRYf1kqHa>w>;x6G# zr@chsTvJX#J5xIUb8{9T_7lkr@1{NQz5}B(TE6VjGUKg_jDI<86Va#t(h4b$HfP+Q zHL&r}*n1&bAPcrM7!2qe2U=``R*`v|^EvGLa|{Xrb8X2G#VmEbhFm>*p?%e9zU9W7 z7DZq&koy4vK({%MfNwsUmIx(1d=ers<^#m^ATSD|s& zS(ajiiL5hnJl`roDSrvZ_@&9Fa22+YB#EZ`!WGd&E&n&qQ;UWfBfNNll?3ZyV^~eG zoY~%%+KkkikD}A!eLFSvx%x-7cMF>(o^ht84t>1l;_odnV;GDfj1^CiWjN7YP}GXU zyR-~uytp~a$SgL#x8w^H^!G{C%L z_5zag<<(VH!2VMVbHpg6KD()7|gZ1V4QLLMLew?nivjGvA$xbWiptF8@r@=SfXGtaVGsqp2I*;pkM zbd3+o0CzZY`I~R%e}?hr=H4~RU~*rK24%7U)vFeJoCWx;o`1LSmAUizb%uu1CjVSY zL=ES?OK}5&CHGc3s-AYnFJ}`*#9WM$2hETd1YcqgX#JzU4y{2)rvtQ#s@x<2ZIMF1 zTE65@wlg;SnYT<5lfF%Fu>oAHhf1KRR?__;t2G1-&8whiTFp8AvVk|U5zWMSv)F9D zqoQa2KA3GTHaVr?b2iCy&(1WX_d!d~=t`H9ZO@YO+LdvgcbNVtS6jWMALtKMmu#PL zx6h`FGu5@mJ2YmfF?zNZ0MxUC*r|o;^#~)(dX@X@ms#OU=((KpvK(oBHzg)_U=K~c z4&mLb;r_gzRGtjzk0lQ$xv11dCTU}0ZQfx3Y^g~+eZhNMDk=t9icz~d8urr9S2h93 zP?u!0RV!<^GD`iS_uR?s^YMtCli20sy zN2i51?z&Jh5^Qyp3>yc$tbEz2ay!#*VYQZO7U?L2Nh*6}sg{2;fm#nOzEX@eM9cJ4 z_|2^|Xb5qV9o765162Kk*56s)GcThTbDsZEo;~f!AG114Qq)4lb<|tb&g|p{W2U>j z=&OS~4nqB!ZsR@?`)Z|$AeVz4pBR5>BKbF~!bTi+^T*ywndpmKllQXNI!!8x0(6_- z+ij=Jn+Rr=lHjqHly$>kEzl_j=`vP-$G?l^v|+X89DiPS^}e<6jiNH6dIZ^s(}CPz zC0zYROOtK&ld)fbsR5xbK`=ETKHA5M0bZK1z-3|CU>hnaH6N`sYU6FDD{z6l|6sJ7 zb*&W5yt%lHs(w@a4l`~1Tdh>Vp(Ln2r+9km3dEtIg>LBo1JWTfXKp6{Sqw&ov8XDTsqi+F9z@8{-KIv8HqqPcanPF(8Gx~jG zTnEn_nsX}e`fJm@uw~f-P9#C@X{>ssd-*hc(pV)c518q)^0PaUpYaY*3W6uOsMqIHZbqdwSPYEAOIDIdij$e!FNwUUd#FqEv3fJnf zY3aoynSu@GuvN~zZFYW!0LjufrN_d6#JDX&nz46AGRTWgc?x)ho_j(H-Q4ad} zfpr}p-G<_xs$tEpaRzt`d8Bq)S8W4wVCt`1;(DA!0u<5plmg3bsa5Dfi?(@n!$FkkaEi((Wxu z%&B&@&H!D8@gSUG9;dop`J{Z5RMav$x+v#&CFH@XD88jGvd*Q?5BIk6`P4`YDZ7e< zQ?OlLeZY5Ipup@zvN!K(RmjS_-_IKWt6r9hDLxOMeAM7TZ7!C1;>-0We{QdI#X~{q zz_V~S*ph_Imz$#e&KpsHOQq!I{`Z(hchk2mz0&ux@qOpch*WU^L*Lc^u5nVSYf7x+ zu`d=IPJuL7RV4BlSW)Z0=nu_V1_WrLBx@SS5Og7WrujO_**dnWDfy}pE@7euklQn3 zaGg`Qt@|5ZOh;9&E?Ic#7RxzW;gTV?4@}X8m2yKGNN=m{J?eyO7Wfs@@jleX5R7$^ zy|l^YAO+UcH?zGvKXvs7yApUSWudaj6iGqC%w9h=EcC`+;Z1nr=X~R8!H99+1o`wg zQ?e&k!FHc)tU&$P0_JW;4D1{eyEZ@|-MLgE4->G1x^p!`Ui+Bo-hN!6AYY8c!<8I` z>Q+eiJCZ*pvxXI;4+~>J`wIDrX~&WIbOX2kFmGv2$eA3rIcu(qfBCexsCk^A2!Eqj-#ejOnJM{Ph`4W&_898w& z@ekhdj>7waYAsdl8PX#Yj}kmNM&Ey>9K3o?A)z&P<-qGl?nJkL@8+4$6%!!*<=s>N zbcEe_t(nIpXPvmY5x)EVf(#~yL)apk`?p;7K9ZSKD~ zY5%uv>tL2wQ4f&8mT#e>b(eul5C7@v|4)5)HGtB?jg5_3&!yoj-Ly}g=tJJ<7Z?uo zG_H23dmfe*P&@e(#e2Ba{u-R0<9Q{{hV%b)=Mm}YCP4Vo=3N@USTGQ)|7VA_ICb9e zIOFk16X?`n-eW<#XU`rWv~w4%xRl7JqtFTkdpJHzFIlr_>S>$a!PE0fH~$kI2n2c} zoS-j`Q2BmECr6)Jn%OVB0LHcdmI&n(OVF%h5s8owTBqCHHji0AOQT~r*T-EH)GEQJ z|G!LXj)yw`(@01s1cM78YyC3#cm7k$)I{Js`X=r8xG&vrhy;Vd$D^v_8JEaq<7UbK i)wt*w(f>(A^dY13LnFToKjibHyBeyxDkaKK-~0zHf1jTK literal 0 HcmV?d00001 diff --git a/doc/customization/branded_page_and_email_header/custom_email_header.png b/doc/customization/branded_page_and_email_header/custom_email_header.png new file mode 100644 index 0000000000000000000000000000000000000000..705698ef4a8ca046c47b1702a5a731753d63c7dd GIT binary patch literal 37472 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 Ivaf^x8xA~MP5=M^ literal 0 HcmV?d00001 From 26da2c45ac4071f7a33a34c89162709d5a1bc470 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 7 Feb 2017 22:17:59 +0100 Subject: [PATCH 141/247] add changelog entry --- changelogs/unreleased/feature-brand-logo-in-emails.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/unreleased/feature-brand-logo-in-emails.yml diff --git a/changelogs/unreleased/feature-brand-logo-in-emails.yml b/changelogs/unreleased/feature-brand-logo-in-emails.yml new file mode 100644 index 00000000000..a7674b9b25e --- /dev/null +++ b/changelogs/unreleased/feature-brand-logo-in-emails.yml @@ -0,0 +1,4 @@ +--- +title: Brand header logo for pipeline emails +merge_request: 9049 +author: Alexis Reigel From c1e94479bd565a3deebe7452f186815157082cbb Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Fri, 17 Feb 2017 10:05:13 +0100 Subject: [PATCH 142/247] restrict height of the custom brand logo in emails --- app/helpers/emails_helper.rb | 5 ++++- spec/helpers/emails_helper_spec.rb | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 3beddff9206..a6d9e37ac76 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -54,7 +54,10 @@ module EmailsHelper def header_logo if brand_item && brand_item.header_logo? - brand_header_logo + image_tag( + brand_item.header_logo, + style: 'height: 50px' + ) else image_tag( image_url('mailers/gitlab_header_logo.gif'), diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb index b9519e387eb..cd112dbb2fb 100644 --- a/spec/helpers/emails_helper_spec.rb +++ b/spec/helpers/emails_helper_spec.rb @@ -52,7 +52,7 @@ describe EmailsHelper do ) expect(header_logo).to eq( - %{Dk} + %{Dk} ) end end From ad88cf3e1747f1214d6d5de45862cdac98b11504 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Fri, 10 Feb 2017 10:32:59 +0000 Subject: [PATCH 143/247] updated ci skip regex to accept underscores and hyphens --- app/services/ci/create_pipeline_service.rb | 3 +- .../ci/create_pipeline_service_spec.rb | 83 ++++++++----------- 2 files changed, 37 insertions(+), 49 deletions(-) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index e3bc9847200..38a85e9fc42 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -59,7 +59,8 @@ module Ci private def skip_ci? - pipeline.git_commit_message =~ /\[(ci skip|skip ci)\]/i if pipeline.git_commit_message + return false unless pipeline.git_commit_message + pipeline.git_commit_message =~ /\[(ci[ _-]skip|skip[ _-]ci)\]/i end def commit diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index ceaca96e25b..8459a3d8cfb 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -79,60 +79,34 @@ describe Ci::CreatePipelineService, services: true do context 'when commit contains a [ci skip] directive' do let(:message) { "some message[ci skip]" } - let(:messageFlip) { "some message[skip ci]" } - let(:capMessage) { "some message[CI SKIP]" } - let(:capMessageFlip) { "some message[SKIP CI]" } + + ci_messages = [ + "some message[ci skip]", + "some message[skip ci]", + "some message[CI SKIP]", + "some message[SKIP CI]", + "some message[ci_skip]", + "some message[skip_ci]", + "some message[ci-skip]", + "some message[skip-ci]" + ] before do allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { message } end - it "skips builds creation if there is [ci skip] tag in commit message" do - commits = [{ message: message }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) + ci_messages.each do |ci_message| + it "skips builds creation if the commit message is #{ci_message}" do + commits = [{ message: ci_message }] + pipeline = execute(ref: 'refs/heads/master', + before: '00000000', + after: project.commit.id, + commits: commits) - expect(pipeline).to be_persisted - expect(pipeline.builds.any?).to be false - expect(pipeline.status).to eq("skipped") - end - - it "skips builds creation if there is [skip ci] tag in commit message" do - commits = [{ message: messageFlip }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) - - expect(pipeline).to be_persisted - expect(pipeline.builds.any?).to be false - expect(pipeline.status).to eq("skipped") - end - - it "skips builds creation if there is [CI SKIP] tag in commit message" do - commits = [{ message: capMessage }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) - - expect(pipeline).to be_persisted - expect(pipeline.builds.any?).to be false - expect(pipeline.status).to eq("skipped") - end - - it "skips builds creation if there is [SKIP CI] tag in commit message" do - commits = [{ message: capMessageFlip }] - pipeline = execute(ref: 'refs/heads/master', - before: '00000000', - after: project.commit.id, - commits: commits) - - expect(pipeline).to be_persisted - expect(pipeline.builds.any?).to be false - expect(pipeline.status).to eq("skipped") + expect(pipeline).to be_persisted + expect(pipeline.builds.any?).to be false + expect(pipeline.status).to eq("skipped") + end end it "does not skips builds creation if there is no [ci skip] or [skip ci] tag in commit message" do @@ -148,6 +122,19 @@ describe Ci::CreatePipelineService, services: true do expect(pipeline.builds.first.name).to eq("rspec") end + it "does not skip builds creation if the commit message is nil" do + allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { nil } + + commits = [{ message: nil }] + pipeline = execute(ref: 'refs/heads/master', + before: '00000000', + after: project.commit.id, + commits: commits) + + expect(pipeline).to be_persisted + expect(pipeline.builds.first.name).to eq("rspec") + end + it "fails builds creation if there is [ci skip] tag in commit message and yaml is invalid" do stub_ci_pipeline_yaml_file('invalid: file: fiile') commits = [{ message: message }] From 3bf60f8a64d7f6fd0d642378e6ed70785b65405c Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 12:34:16 +0100 Subject: [PATCH 144/247] Change images location (s/images/img) --- doc/pages/images/add_certificate_to_pages.png | Bin 58581 -> 0 bytes doc/pages/images/choose_ci_template.png | Bin 75580 -> 0 bytes doc/pages/images/dns_a_record_example.png | Bin 10681 -> 0 bytes doc/pages/images/dns_cname_record_example.png | Bin 11972 -> 0 bytes doc/pages/images/remove_fork_relashionship.png | Bin 39941 -> 0 bytes doc/pages/images/setup_ci.png | Bin 27380 -> 0 bytes doc/pages/img/add_certificate_to_pages.png | Bin 0 -> 14608 bytes doc/pages/img/choose_ci_template.png | Bin 0 -> 23532 bytes doc/pages/img/dns_a_record_example.png | Bin 0 -> 4709 bytes doc/pages/img/dns_cname_record_example.png | Bin 0 -> 5004 bytes doc/pages/img/remove_fork_relashionship.png | Bin 0 -> 13646 bytes doc/pages/img/setup_ci.png | Bin 0 -> 10033 bytes doc/pages/pages_quick_start_guide.md | 12 ++++++------ ..._domains_dns_records_ssl_tls_certificates.md | 6 +++--- 14 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 doc/pages/images/add_certificate_to_pages.png delete mode 100644 doc/pages/images/choose_ci_template.png delete mode 100644 doc/pages/images/dns_a_record_example.png delete mode 100644 doc/pages/images/dns_cname_record_example.png delete mode 100644 doc/pages/images/remove_fork_relashionship.png delete mode 100644 doc/pages/images/setup_ci.png create mode 100644 doc/pages/img/add_certificate_to_pages.png create mode 100644 doc/pages/img/choose_ci_template.png create mode 100644 doc/pages/img/dns_a_record_example.png create mode 100644 doc/pages/img/dns_cname_record_example.png create mode 100644 doc/pages/img/remove_fork_relashionship.png create mode 100644 doc/pages/img/setup_ci.png diff --git a/doc/pages/images/add_certificate_to_pages.png b/doc/pages/images/add_certificate_to_pages.png deleted file mode 100644 index 94d48fafa6e88806c89d09a5262cbef2cd294470..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58581 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 diff --git a/doc/pages/images/choose_ci_template.png b/doc/pages/images/choose_ci_template.png deleted file mode 100644 index dea4ad2ed28e3c00f4fb80bb71feb744747e0275..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75580 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 aE`^QnMGa;+G4S(CxMxyIl3&G*-~Jz)wGcx9 diff --git a/doc/pages/images/dns_cname_record_example.png b/doc/pages/images/dns_cname_record_example.png deleted file mode 100644 index 93e011d743dd2bb99ac8f7d9c0221bd9409b4546..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11972 zcmdsdWmr{P+b-SR-Q6A14bq{~vFK1FB&3mM(MU*x(o#!01&KvVr!>-ClHb(5x9_{X zuJhykI_LU+0F$-m9P_C$#&h5Ih}6c$E}^ zKd^2(O0qB&!xY=VKd3L24cuU0(D8r%z{0%CB!Pk9vR9Fp(er}c&qB_8(oI_Lc}NsR zlN+3$Z|6i4+W8nFGMk7w!3TSp>QKpQC$X-D9LNu*chiA&H7`W%KxfL?X( z^K#J3_26L9Cv|tz^rBJ9KULJtW^+*dd-m*)k(=SnerOW&v#W$a1O^&dRAp&6y!fA& zK^oFDBMkDR6^17A#?IJN$p{{Pj>)Xdqe@WWj!(^}ojWd5O5?{Lheoe}Mzs^8z}1>Ph5%U)PicOp2pj$zlL z=SBbaBn_b!ZYTkNehWD3KvcBxq-%guC@jr``W941+WgEX)Cm zy3TY2JRx;=HvWFr{0*jqgM&^awfB0$_4W1VH^|&IeRL(dC0*E(SIeKqHFm$X-t;BV z>lTS8|1OVHwxAY*W$RRvshOD>vf#;QW+sR;WSQTyeGZy-E7tb<*(-g=RG1l)TFNXyF!OEqs? zedpG5t-uk<8;%j#lgryL_?n~f=Tm0fvzb%bC01me)zgMAKO?SL3i@0)UDvBICHa!5 z48HQt^CYZ0;Eymd_q^-?+U~# zDYjEwFiK^c>Cz+mJ@fRqmpTc&NPID48JFcT$7&-(Zvr@rQ7VgZ{e4sp+r*`t&@%W0 z)2Z#p=H-GLHX3H!C_J`!Rc)B~=^+2Ksn7n+VLLT`dE@50aB6>%tq7TuEU(qb45u1Y zHLk|>#IP_VI_b3Qb1=e_>wus**G@iN z8FfZYriZ@bA0(it5^;K;jzr0 z({7eSMkK}byJX*;+}ZSbjmjWvKlmKBUJeN_Ienz%a0tdLfWE<&^y;Pb{8HHOK`gxR zQjSkT<3)r628}s`LCH7~pHScu`&Xc2REmM=(4DKP@~nh5T2PrM7!p7W{VRJPy0Ry!7d zr7#G`W)`eJY?=5uAeFN&1=o7j3nIx z1LNQcM%qEk>F~UByTtp?Q4wj8^B1f==i<;1#I({BN(eP{;^q zj;m>Zi0ksYNWxM)K5W|M(xD2tJs#j{=77znr|P;nXvU5UOD?jLMEvg+fG3D<2Bw5J zg|Q9SiKH2Y#<0qo7qcCR4AVShC5&8gV1paZm3B%?TBlG!2D6YO?%A~~c}R{s|zRx)$Akw@rtSUtI4;W@8{ zdW>=RKG~1M>EFJBMys-c_@2~+b=ZHqWXmm8iH@oE4 zXy^wbJG5lU6 zbb9%s?4P2t%t5ECR-%nse7Qm zXRQR|MtuOEcCXJ%ju9vlAN~rG#|dNuv6gI7=`}|X$EdnBc$}-m3;TB?A+3VT5({T# zPf8VuLf%4Q5JhA)^5-{l7{hwBfxI}dT@h&1Z0nfpFi8fR)jT@sCZ;pE z$UcY}SxiRZUW)ghSNiDVFrq40sH&p5n(P|rPlaX}RJyXlVGiKk1z99+v1XLe;6)rG zEl<(?3Rl(8DorANf(nHSR)g|=eTk0jZM~njr2MCK(c(ggf?&l@)$ogz-Am?3N;oCO z^Swl*xLgVd;DHC_p&50X^I#})`qnFVMPOc*_QiVp)ir>_PZiBeKBUaO-u-Al(Ef0D zXcY}C)#O+%0~lReDOi$69q>?uee^X-CB^bsku4@w^V7-oJPXuh)}X39T%X6<54BT< z?Ay9pTm0Q*o#rIH#UyrGoeeH)iB|fy0}iH5OixdH>Sf|Pkl9qARsY2CgIcbgkTe-| zlS>37@o;;J(V5t$UwubX8!LHjr$>Fb2bfbIu>|xHod$4rvQslhk`-^C8b&@Nt||^A zbZO~;c^K30Y{8v*UcZ>_d+RdcS|h5j)Ei4V(8JmCG{J&JfW(do{}cD%<|B-R>iA5L zIr}}>E;e;}!RUgS9vn-{n|^^*gva49hanBuJ7wEC#X6<)_PzX}VOGyZGMwAenO$P< zGAT>>9t72Ub{Q|`9JxKlDFq!S7Co1SFwnU}zwe}BdaK%Qn^!aaUMF(};T{AV>^Zfw zkFU%^?@V~MsM%-G8;ZM+9GcZ_QWL?hDUNpVh?U_NBTh-N+n5;Bw zhlNM7O4U8!Rc^k+7NMC$%k1y$r~5=bB~>Sjs66vR@@>s%7k#Wq@N?zaFl1rTj*~I0 zIwu7*BE#5iMy+6kEjKSQaYCai&73VOs-4+b+o;xeosLMn84&L=9jPBs@9$Zub0+o! zob}?zU+}lz=?{wA43dCD_7*bc0zV~o2&um3{Wxqa=D>5a*FxDvPBxQ|FCr)?sNl@H%TEdc znLBCc5Z}2Hu>|SRi~=?dvx$eP(QEl1S-)m+|8$Y2H@p<80ac zm5%fUFzxJIl?)?1lO*&?FO4y@ByHF&g7d7`M-ILaoGe&y8d&=wD@9r?o0W(e!mOL| zg(dx?-JF^Y+;3mBbP%F)VYL06)*{Czw!RjmqfkrwHjJ+@zKZ(@{-+xM#x&BoC}{DQ zkH93n!K*Kgt>TjMIZRG3eq)}$ZIu3sN+1J!LS-dHW-&`e-tno<)ww9k1N7b9BY^ca zJjXu`!*7>P7_1+hOK<{9_^goQOVa|o) zxG}PW|6{Oq6=}pYW|kzCf1@TA9{~2$w1*1)`{Vz$!)uvba8|+oo|1og9VMSzQ^S`8 zJu-QJ;=cfTmytnEPLAHBXl-I*B15VM;GTac+4`|G_b6Yh%TuG@kl@!1(w~8xAky={ z`6DNMj6hDt$!%+YZ(@JpAp$jNM13AU{(p~-$D#}5uP7x254IWu*~k{x2O^j*I>QfKKo252>4*WF>ek zF=>sgRq!Xn*%CKDzUKhj4GhYG^mB=c{1pw>X~qOmEWWHCN^%!pDx+J8Pwg0f~5n$p+n<_p|$^KMB+ilbS%4wR2FME?zXE{bncd; zq?}I+{K*OUM-veQg8x-BqogQ$^#uv9 zxRk&4!d%c@i(QKN{mZ>{r=C23o ztSh-{dUjY!E?naPRchYz#P38^)z%Zs|9{_f=71gg!2Dov}l`9p94Bo#fyXz)469*bG z_KJp8p?Rkys1+MKyI2EU)`hEXkw)k(K&rF=hzc2nqPXH@Zz(+%u`3P%bjHJche&L5HBf`MB>}L`n{^_HSpZTLSg7-tl< zN`O=GdVk!!ba!ys{@@qR+OdcBQ2(h#Rq5& zoNa}Vl~FaAGU(S%2)Y|MMhTcdr;aN+aKz3a&pnN4o*(KH~aOxxSza)JgopyiIM+nh8XFZ z6w$*`mYSkk>ErYB^Q%(E@pYD*v+X3x z95LtnnEYG&@xm4NcYcwTZP!uCddNeOm}*S)*_sh~I86mpbF$BwHM7;;S$T9q@g%Re z3bx0KnDLjRl`E#?#h&zkh1KD^Fl{Qd3W5&E+;?G1sb#B&m7u2HU+-2XB|v%F(}kCO zA>9Y5AQwkXrWc%Qw#tk}YU#4%GQG_1?-!Eq?{0djoB_`4wpfI4Z2jtET~9iic{k={ z?&hb~TDH(DJz%nU1%K!^Q&qG4YvJBhfwSK=I8YR7^R;!eblWFleq!Zn<5YTBb0^BL zbiXufsj+(vY5%0X8KV7G@X6$W(^MZ^C-Gs);#R$kevk3cD@bYBeapcCuG~&aDxNYX~V>TPJQi6zHl}Ah0q>Jr=e?&a#GwkH<*oOgtQgd4lLhdQ$i*4M>kABg( zL4<@Lk3}Z1HKD87t;E9Ahf8w^;9UPMOyLlhCx_o!vBmbP_Uo70x;gqFiyrg)0PX_s z;w=FX1EA6}CSTJl#exkk=AEUS2m*c#WRg$Y`~axM-8LY#0HDu&HD!R|_tLHDq@UeV zo3}&cjiQSvh@_U$t~MCBc#?bSB}^!hn>d$wOWlR%_d0QGWRzvy8!GgMq!>ah4~deJIL-LPyO z08lg6ENB>1#gv{4)e5@gI_s4Ice|Pa*SbzFd7l=%Pn`+Sc7E;vz|!_cZ3m!Yfg+=- z2-a%`c;WQil_+{e@UqW`w@>Hni?Vcv^5SIQA74T2Vr+xx>gK4~H zgyO@rVG3#G3~|FTc?eC!7{(T|4v~y0A^>4$aOQOaWqy8Kp%`@=R7En-1 zg4)6Y4>bc^st=?Gh^Yl5>#jf(Y}i0Sx$GQpGe0CW&q3r5Y-Ha6+_55w2Yvpb^K|5) zD>xXSx>DP?m}UTI2VlLe_`8GV!~4^m2MQ}%srPGfQvR*yhS@LWK`yiyeh7(tf@k6G zEoVv0S?+ie{3dtp_vhUGaqUK~)|VHJqDifFbwtl}P;x(szVDUXOtUmJqRuXtwj+~@ zl)68TivzG^8hS3=0*!b`mqGil=FB{sIbOHVy0-1Oib-Y@(u3 zZZXMo0=uo!rg4gRM?g@h#mjl}#PP|Ldl_ld&0u8QMEkKco1dGd-%ym;)KUO0QD^DL zVeqqc997FnI`$_M0nTrtiXOA^+(mESx+t7tP(DgtVSRiU#a^NRdi%p#U}F0!Sc%k| z$6SFOU_NWx$s})^$Y1o?R-*Jc0L(E@sq@F$DG<+>ctpmY%maWkPsgIa*oBg&j-DR5g7qZ+;|x zd=t{B{1u?vAsWHv#Gap(%Cmg5rc}h+*CXB;pPJy}XzHOXZ+t?+WtqM*E#k4K?_sOr zfJf&|ryLk41ChAdgNWz-+<^gJ!>F8`EUbv!tl6~nb@d=NV^4T*WA~SmJ_>Ji2ZGmc zLlYvX^+>I2l(2L>HV4yp%OP07$U~wotMZDsgA%Xy=W4sZCr9O3&ax&CI{?f#&wI$~ zR~vt32e!vld{%w1$P^ttLgH7cCa$QULqG(GjLApXy1SlkFC=5gt)vGV%fwQ7F1UEX z#$T0|Rpk4=c-r^20RH_h4Kd|F&ixtlRXc#=BYZ`A2V77MC48@5PM~}40QFe_`Jib8 z#9EH*%k7krb88QoV|*6*kS}RY@v+@9P@VMv1KEju9#Ip6)if&hJ=0C({AW2nk3&;1 zN=)7CE$fBZpaI)&d(1x%UpWA}Fy?yrlJ+@=vTgy|K!W$wzHTVM99%^L~B!SskQq*c@nY7679BX>z)EEH?33)i1 zZzHkSio^$$6#24RJ|mG^nQ?vL@q&ZvLU-rp6~KYO(9;r{JAMIkC&Mt&ge(DK12{dR zMc-+Za=oZY(q~cu5Gg-Syyki9lQa za)H$FMOC>yx_U4wak&cC-EfwHvB|R`qoMgyjW}rWZ30HHV>idN^eMKR#30lX>5R;h z+eqeYk^^*1+g0bwMUSGDW8`=?9&hFF!CRDk+~=C&f=cFx$I%jLc?GE&g#v$pS3q`C zyT^3Qz9YN|c5(G3+rq|H+C1^X6A8}w0>0gu6WymH_qr6h92ZXyd$!KvWWb3t zDXZ=EhQvGDsmWFkPmw1NW1NITgo5n*iCHH%Y5k8=-rXHl=GROnOWmU)g&xyku>5Ey z_f3hAM?1+nn>T(n`Gho*Zxw7{h`vnST_Qq*4ow@h!Rhf0h;E!Rc2ghb+gar(P+Z_6 z<>eW*cuz8Bd0>7N>6oE1q< zD{mtt$V;Dz_!Q|zO~guV#7p8~Lx-SGmnfQzC4Mj?pdi@D=8OaL*%$Y)JyDQPHi`3)i}rXC4!rJfCbc}{3a4;#99Vv|9XD=SAgha=4mdVS9R3)IeMw_r@QC`k+lxEHa zKby(QGrQYqv8FC$Gh9&{#>_6=s}WA|=m$=mr}vWnsqcw4QsX)$E} zjm#0o5}j!-9o{A|x}Ky+8Nc+a%@10G3}?cwo6MxU>wOdvlH6 z^H^3?|1OM|Yv0IAI*+Aoo(AU#YlO|{==jhlkU)Da69>ELGqX6DI$X#Om7+dK%M%+W z|dh(57+B#l-y5<~^v8r4UR zkX3YZt=#q^z8%pJUl|)z>>dNrWOi1CHQRt0xEb97Abxf~S}g+PypfuZO*|JBYMkKB zIZB6s*>^0Ahwu~^@t=Pe}EQT`i~}oma9W2MCJY+ z+WAR|N2T^X;e?Pjr)w{V>6n0|0KxlkR!BHHw4bM3K5RuH9n6r~rORGuRTe1{AC*AM z1omrmr-%&mW7Pt`NioY_;hwJ-KO2=R$ECw;rmrGFa%8xXTc-SC&YnE=Gj#_@VFI(3 z#}f^lQ%iveb4r1qh4C>fTTc1`wz>O&j77Qyc`YTfTCHb_L&35o`dsWv5rhuvqr%5w z+3JO^J|ar9py{k6M+}wxEG$N{k!W2<@`B$vJLYj@(0XkRb?f@9p2#Hxyvro{UC(}c z(bM)DGOlcq%ya_B`$E;!bqkd5#c~;xG@aN|I!zoDYmG#gSV`u_V&TV}uNut}u%0o{ zL(IKYMvL+=w(ssQ>f0r5vUU*~I|YoRU!gnXv_1(2tC`XXW)W*tAG{Nc;;1O7D~JE$ zA3<+7CX&vPH}q066Y`y2RxNr+#e|nNZ>{7goc_i;5*6bYpVQGIpUZ=&FZeR%+V-Hr zXZvD~&~q?J)_UK!c0QAD_ZokPN}RZTl-gBLSh($_=lR&1=7ZPW*a`tj74_G~PmZ z;5Dv-(>*D^^&H8jiA9mdU1G$VCsrtQ? zm5Ay`lp`_dcr3Dq+DoRpVa7v(wcbz_Lx1mdy3?}d%`hK1F8i$3zOkdWi0 zO8hzq6675y4Z90t|9t;iY1rFwsR1`8r{!J1T3PD1hSzA88&7K2LjT0*(w)8wo8#=8AjaHpWm@NFyNov#!?0$V_94(tL!PFq;pHoh=M7)Oz?n1ju!l5zB(yF!{c*%muv2in zGO_!NJ-JfVlV9ZE@mRQEIb6YEUAaO}`1qOhn?%T0dHv)yxAppcv2aaL`t0nP(XpR- zy_L<<1e<8AUFjvp1ytW?ocv5d^Y9KJw8#&spIh28o`<2!A8tu;f+ci_e@~&3C$U zozPaQ_GBq+UpR>)Q$_VDsHwBL$zYDOqps8bStbSaVy5@*PH-Vv?wyXP;YN@U;()nvlH^!{2|# zzeijGhIVa+^)wwnW3*&z=G5Z1yRlM>3?Uso0&&$D+qMJ~lhO-$Bz^C4O=TG|EMsfV z=O>QM!0#du7j=mslXxwlnx}u5+La&C8f-zaMpb7U(N?(k#0|=rx=h@3IxN;ZP+NJM zCV}LojX;j{^CSZ}er78;5BrtI9H-@Dcsx65*p!uHgzA~Myb^WXSjWd}$eAW&Q4x>^ zZaSEFhZYl5MHl;vd8-1|QuSt%QT`0M zk2nm+q$3ao(ZoE8E#ads`E{);K<(zgRP_enEerd#z-wj(uFF(TwFa)?l-@ z^G`g>Z|O{~zxe8xhg8ix&Po5RiYh6KRKV1}>xNb~Tm?=f=Vd1n z-D_(Nma(F%#RbJY&TnYMmRe@$#j1IKaeq9Tcr0qL!MPrzSS`Vo{)5|?+%eDnFQ`Cl zW&GvXw1Gi5k4*KZceImhDaQ9IspxJC~cR zg}0y4%Iu#QO?pakk2^~jK0_b4w4~iLF!Vg^K8}ZR#^O*%R9+-etSa8zNuWP|f%dA0 zJyPljdR9*X?CflWX5YXqT&1W*NR|l!`4(hm8|awL zYpFKNfpbb(m#{}fL3_#GJx5HM6NqCGIRbnzQqmaUlF-nPgl~V*Y`#q3Ews@b8RW5` zTr2(A`MD4CxFhWN_H)IK6*4|r!gb$P77torD=8HiA?sT(E0M`Dl=R`oxXS?z>fQlp2^6mET}baKvRyVwTM7>W;^&KQvT1|@c;WaIADwtM7`;~UJCuAzB`!W% z*PO+Hq-HaICv?DKHhPu6oECiFrS>RS8&})n`;#*%yoBtOOZ?Rp>Kf*DgVd|avI;ck zzGY1O!G6Y(%`VdCac>+QF|i%tj3BVC_}ek|WR*p|-}=U6Y%sU-wb!5yB)<;F1$n1Q zTVFiBzBK|U=OV%w2>&U!kh6%@=F$;0D7C zLIz@lI)k8Kyj-q$Of?}wzv=j?N7AO+9q7!XnJk~S+ElaB_g6V__tYP!wG`K^vy*}f z8n~0CzmX(S(ujG&>N;Gou2bxPa8!`%F+<0B>1ewOPBVYm1=FYMM~Ck#Kif#)NDe31 zJc#oKB%i=XKLrXF7pF?QQzRoti9<{0}}2(>&=iwEes%@t}hr4L3S5Ff|+rSxX}qeC*!6!T5j}!2qg7oFt?EAtnP{T7hHU>WU3Sv}0vnOaz#j*GwRRAUk@a^x`>y}g zmx%!3ty=ci14E@pN2hfqfl4G41j44g`T=xZhTTCgeClr{c;Mdr847Nr0v zg&c_~|2ZM>YrxzIR6uvT!!nTiLwEZ>+pib+!9Tn_=MOtUxLUA8(eF3@)B#@sI-pLw z+?3`Yc2)y=U$nxQ>mP0Nz#%?-$(LdaJoCSno;xPU^>G#Rm wUw3G60Ph7Qe4_Zntq&SN82+DxfB6A^DO=pYeDfh2IEfCUqM#vPA!{D|KYo-n!2kdN diff --git a/doc/pages/images/remove_fork_relashionship.png b/doc/pages/images/remove_fork_relashionship.png deleted file mode 100644 index 8c4fab929904d359d5c891f1e968453316c5a5d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39941 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

onIA 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

kHf)t@q}BfOzX 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�zEr1KTNhxXW5(@^Qu*)NTWtzV`5vUTN>C? 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 MMdxbqWy_HN0Lwr4qyPW_ diff --git a/doc/pages/images/setup_ci.png b/doc/pages/images/setup_ci.png deleted file mode 100644 index 5569f6aacf5ee90ebd45929695c736731fc036eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27380 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 diff --git a/doc/pages/img/add_certificate_to_pages.png b/doc/pages/img/add_certificate_to_pages.png new file mode 100644 index 0000000000000000000000000000000000000000..d92a981dc6037962f043956be97ecc5e45378869 GIT binary patch literal 14608 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 literal 0 HcmV?d00001 diff --git a/doc/pages/img/choose_ci_template.png b/doc/pages/img/choose_ci_template.png new file mode 100644 index 0000000000000000000000000000000000000000..0697542abc863152a37e1ebe3b25a7beb5c773fc GIT binary patch literal 23532 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 literal 0 HcmV?d00001 diff --git a/doc/pages/img/dns_a_record_example.png b/doc/pages/img/dns_a_record_example.png new file mode 100644 index 0000000000000000000000000000000000000000..b923730388a8dfa2bac3abc66490bd65b2475f6f GIT binary patch literal 4709 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 literal 0 HcmV?d00001 diff --git a/doc/pages/img/setup_ci.png b/doc/pages/img/setup_ci.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce0431f4d4bb4076bef87e0680c383a362ff79f GIT binary patch literal 10033 zcmcJ#byOTr@aQ`%P9VWGKuB=c0KtLlFxV~P>Ehzz?(Xj9=H>)}sPgrR@bZE{ARb=P?!Lu{t1ZM8WcLbjJelw2*ZA}Z zx!i2~w@?q>0zW)FOhDkpL;L6F=f}s#*Vj*bL-|Kni0doZjzA#(#`$_D z39eb=mF9$;oE+$MEA;FN4ukE$5FTao0Xa1sKBXuq&&00IGb zP9JPS&%j%dlchE!B&17lkAL34Xo)Wb`uv({=*DnEw$JPqWTH8L{Q|yob~OfuWyg5+ z=J-CsmiH!$X6n4Bmv<0XFc#~ovZ?*rSfAAHjoG6|uf&P=p&1KChN1DPl9H04p&=L) zLe6YE^|$N+I#N8aalY2_4+3r|DViJ~+=4(xmJVBDee&~50?HQ3oj4a47sSQIC%f_v zz|;LrdC7nG*I#a1WW;>4`7zn%uZTz%LKlroorsk>$a*p|0ko$>IE# z$)whe_?-NWm38lgw$GnGOTT;9UJ!S@+@sGx*V*2YniS{#XQ3^}=NXK7?s$Dp+`lVW zY?N0>M1*`;*T4D7bI7vY@1lwfx6R>l_!XoiHz&Sqa=bA%ARwS~u$P;g+g^d8eHymC zH08_6)YMc|*}wTlyS6Yiny`W8=oD>>r$-!@#jztS4~T zU}vs~?AwapmIqr92IcR!i0cqnS3aBXs&3h2i@Lu7;0+)rC9dJQa-8YosG&_c=s=YY z$8{#CrD!z!jtd%PF(Hv)!iniaiTkCLF7fwc3Zq8J5{bGk9omb5z9M(>%8x{3koupw z#AWlbsiL2bIP>RMK4kt;hDU!;ZwOer(?-u!eVV#xj&`AL^MRexABVsWs3+FjuGcnU z9#oqbD>;nMN&3H)n6%ITjT?`Ae@&6f1Ar5%eeQ;mF~05YbbeE zl~chxVMC~_K6gh52Zpq-l$n}s`lX^@Or+r#+p#jV-H~4f91{b-E?L7+P`CNK;-Xl^ zWzav09y(ZCTiv~=;YehbMamMP00~1uYZ>o{6n^~mB?KGeVqt%zQqyg1_gWEJZa07> zsz*p+t@JKay|(>iHyK68GK1DapOPKStm+HwQWq93N_MRo5Xe#g`r*#mar^Vc_%Di} z7%J({S06>y)PqPB(fxh^2XZkq-Oo&rLIBCY|5_NFD5M~4Bs3rpTKqZIx^p;_q+ql9 zKe*kru2qh>1*W&>!XjvtQp*5Pg_n!_6`;>H#sy&mXY$&MZd>$8U;yQL5jFpj4*ZXs z|4#vd+<(W%y6LY8WBj|&p3MWfZ{24npDa{jUVdR{dt7`!#G(bZlzk4M=BM=&kM09a zlrSduvnw#s!v{hT_M87DO4lk}W8gVR0K*aMtSP4$cwmD_h~uR4GLQ6?`~6l^l>Hfv zM&!UdgPEqVlw?!V-%gg46&^}HPOHFR`)Y{H2P}JiW_A71R5`Dw7rYLSJk z4()n!ymQ{RWBq+2CuC_w6gAqTp&o2X!DBYcIhvX8bbr}zj%p_$o{bWvoY;5sB>b2wo}Y7Vo0RK-qnSP zfw+%+Jp$_wuxaskj5B&-#=SvB(V45LKxwvp*)m-+lWp3f(TwGo>NKgE_$7xwD(st0 z_j!hq!h&~w-fjKm@r;4y{dlkB9@KEts`C~T@$cOL+)~$UA-?5>FNyT<4_4dHYM$Bj zbS!LiT(U!lrG&=gf$N_>HT~Hdq1;u^y6e*r3oy^sKhh4QOr+;P5on_mxc*o`0LB_6 zWZ5~-#Mj~Yvr-KtKN@_~V-ZpG%%(i8dle;u;kXP@X|vd=l^_DAze2}O5_H%+-@hrs zzVtXF;#sV-J!})ey`e?Xsb7kJ2gcX z@*=a>#L87WpV_}HoA?l|fWnj@XCBT#w`L!6og*PQ^}6tR;k;9|K%kTf3_g9LtIg+F zx)4YlBT%5cRv$A^ula=utA>e*o^!@u*Wnr~REzcA(~gK6CJG`I*_ocMUdh1r^jd!{ z+>fprpr$mGRO($brhTe&UP%G@l-t$6V$lCd<`(*EkWAC!k5jX<<{d-Gef{#fq}{EE zhp7sMUG_f#T27Y8l<_gdKn4Jd`)9%A1hp4uE-N}IkzzJsp>BN1Gd5bnn2tYh zPlkUlp|cEb4)pVN-$(jZu90W$GIZ@P!2irD5@7W1W^bZn!Y zc${d-*SAwp?c<0;lkA!_Rm;>W77Ll(L=BGVyDwjSEz~-tqUck%joOxO)yeMEqvQ?99FvYRduV45eO#KlZ}G+B}2Z4K4OjduTy@=9`h#9P9BpsB#gFVe)6 z@AG_mV+F}e2ZjyuNDacbEEc?O60%%;qATSjYALrl6r&=);jijtGXvr5JB&0&YPNLZ zmS`J%iNqm$+|f$3yD0p|=L1g$^2mj_&V-Ew{uKaB31P(jF?+69 zl}*#crJt6o*I6P<;{I7ZrFbQ9m@m!0L$3H#I`Ef43%jE+i+frOHy*U-NuLZl#*oS& z3HNdx^gq!^4DL@QZV7Do^sZAvKhkSaYt4exVCY+XI@?Nw9`U#jU|=r8|Ox$m^Xwurnf)>o1pEkT(h@GJ;b_&0f* z^L`1hhSKZ+q@qt^T6FEpEW}YlDbw|MqK*vH6~w*XP}HFZ;KpwN72VSes2zZFbBW<}wm5{$qq98Ysh;XN~IDhd=P! zg+##~())&VK-(r!vr7GU?JaKCoqyXx3IZM{u-n~h&0;TzE$ALY)|NyZ{AU2(>bW?f z&&yyS(ysl5F#jaUfz?`5%hi6N)^2KI|HL>udu{R#_|rVLl0=-G`4;z%YM%Tb<;kyL zM9Us!MK#_a&q0I!K4Vg&>G+J!i>CYMY30GJz2E$C+B%$aBhYbb0m!%G5qp@qJ8yL=ZP)iP zf>G?Prlo?2qh&LHNhwUr zJSb$!vQ>7Gm0!rfCrNaoNN}JCyBS*^RDsN+q+$OCvMK2me}niY7d8u3UX050!fRw( zB7I3)O}!|tKM&*iQs-f%s~J0}HgXjgPI^+r#`6MyCM>7Ug~E5+q?M5iZeGLrKFV!y zFa9A-y|983zHVCb&#a#r`tGNpI`i{Ubl7Hp#`+c|lfK)60)KuD5kbJw1->NxHQtc) z)yaT?0PO6OxqUzzxj>UmZ1!dO_q}UcP_XVJ%}dd*yd(o?g^pUZ@S2rc=1qcd_y|>| z_OZEs5z$KM-GPAtO9lMFS|QwAbrvRC5@7Ea`fzrUMDx?OmQSIBeEG4~eVhz!S@VgQ zLSgD}RTcTwq|s%sIyEaF%2LXNKhN2GTQERvq2Crhp0D-&?FD#Y>!WeQ?QfFM&?w2k z*%vh*LbFw&%N%Kxm3NdzD)^uE=wGU#vnwN(^)ARvVf}`I<$L4GrfBWjM$$!h$Avbc zJ8vD2gU5%HhNOtN>MM4ijty;WH3o?q7xmf}%}A;{=D(U&n{K~}u?Ud2 z|63@$mxG49ZH}SI#Q5=haE_LyCod*$oC-dE3H}!*&|FDra7-B*TqZ3>OLMhE>6Ro; zLo1QGa!$~4<6xr0=X%-*{%AURx*_B;kt(>EF__UN+#9(mc*M;`7l2-}^>0r6LCnUP^%k}YVsgf)h3 zqjd#zy1T@cXFBJH6lvvrZ8%|~#fx0d37G(=RNUra7RXC?li={^2){GOT^}c^iGe*f5 ze0>5ud#JerP!YN){MCr=xqS2W&4)1D7j~gYH6q2eDZRm?C|UsM42oSuCMw@=SC`ud zjG59K&V<#bRIkJuVFK>zkeRo-G*G_nPx_6icot?Jmce5jkw&raffQ)p4u!xT3LDSZ zug(Wp#6!mAcYdBklncjLk%Nea9Ta1E64miS6fmmsDZ)ZFz>#=$(4%e=_PUb%UQO8l z!pOAT0BF|)&ZZ7zF}Xnku{yryLhI;x~hcD{Z~7yDT`6tnvk#%X7mfdNxxW}!@O(4xca?AOhZ6BQr;=|L2n>l zpU(0tPL+>5c6TsdC8^`|*W43afZnA{hL)UO&`2$=EWv0k7>5oG%$^~|Oc`TWSrvh| zg_B$Rnow)u2B}#_zV#Je@{rcJ;*D>v1%5>(=1y?xWD>o&Lccsh5c-aOdgg=Pu8xpD z;4V9(@!wRG5jGi7Ojhn3c!>QToRsBx|GnFq-b4`aWXa%8JAW5($z1MT-aA8u3g%wT zEQkr6d{>wY$oju*JMuZ{LsoZ_Sn7-B6DdMEMmKKvci1j*rl@`~7pDwd6-qbCqJlcO z)3ufh&%=b%Y3Kuz;;hMwc4X8@lv_z}%fG0H?xKVY#FY!a!qREzM7?H4!t>uC- zaRCIMto~g3eC5;THO_s zGe2--_l%Fhd%0obf?UcrU*s)t?_VgkjrWO9#cP2{*G8%hM`DE%c&+^5ICK;0M}j7z z>*RXhjzkFwCmpfie-C;*R^@MZh;Y&g8Fv4UvWKNwwxx|Jq_pQux~~_x8)9{9LKvtC zAv~?FP&GP^rErDa+6UZ4AO|{CPiYbYJmf0V!^QJum-O~6Gwvm*tnEdOmT%Bk<6r%{ z+U3?^w|m!(^3dSq{Ne!UD6R(-Nokt+)mZB((YmiPKoD7E>(mhk{cyQuOTFiRwh+ge z2kC9XfM>+U(o&;B;$F^_lfSY9!OiZwT0W%a_A!vLwd31R38a*(+}kw=f$xwNC!`vM zxT0_DF~i@BLqywIIB)i+%f@38_>v4Sss~Z~LXc~MSGsh8hY>~q-R3b`dOTt;=|yYp zKpp<4GnDql=DxBb=3)g!Du*Vm3v6m$6@Y5RSRi+P09W0%SlUDR15)$w$O$)~PT5?zl zhLzgxd<4i# zNZqe;d$o$hk65i7ixOqD)zcqJF+$2J8|KVufY+Z|ohlOwBEXZM*^&vRn*#R;sO@Xq zab7K^990Gb*u;)Bz(a6p49?@5?>0?hGU`{>vbyJm0xz1^>s*rAru6|^JO0=4As|PM z#$sRK!7qDXiYH=Yrxi<#UV&7+f15;9M3XmnW1n}h4cP#MBnsfKqTk)MpgZMZ5eaha1Ppcz zp%X(dx-wfYC4vr8(MkK)Yv_D-v>Y5@;#Z${{%$O@BQJTqBqh0io9&%2BC3bo+%F0P z_wGvy&)5-+ne7^zFnqpAE7}YmudvW?}H&U@=tf0m6KfOeqNgLZ~_p<^T zAS3>S+jE9vWp>Wl+C{Is(+4Yj1NAR~NiYquqI>ZPC(w96D8u&x1(T zz>|=o?ujZHi>_U12b{>1@1f`*f%(CF50nbw$#>51uf6_Rd(4QW8_y3Y%+uKJs zW;{Z_>eJOi*q+wY#rUd!STCy@Eajkb)Ic~vCstt7p~Kj=_6m9j_?s0? zlq!&PQDUU@vojOjlHUj-oU_h!jvs2m0=xQsWQbPW#QgFFJdJS_r(5U57~e_R{a>Lu z@d{SkT|dp+N}cPnMY4*%r{73ml^GfivxvjgNcU*@H$*bz=VIs)6S|GN*g%%8aI95$ z{~;^iKUducd-gp+Z~|}4R}5<&+NwZ@h`$rJ6JmvaR}HU$IaH0(0fSbNe!wxhivP#3 zL{5J2_R&9-6rB^W+zvVzx6xAbN@9fID=tB<*V9CFfA#%*k{!>3%zqf~Nx3BR7>$*^ zQmZLJ&r9`>br6ZJ^Z3M~HTDuQzlo%r$Q1m;UK8rOCiqM`=v)Cs4P(|>Rc|nsWk7Rb z6z9Ve#|PjAm84x(ueWyFl8c#myl4iXxcJhKmKrD=)%tH&!Ia&<6S_+g(G9YX9E6=A z%kezz82+P_Tw(o^%6qMlnn!25em|})`0+bb8jak6vLWytQ1hYb>b;qc`Ci;H&v-Yh zTb15nwoWw?fQ^}3lH|HQ=ONwidZGEsge2p%63mdCqxQND-S(WvTGTTqPX)-L#V-Ch zV{i zt%b~Hn%Tg{jXPUoqMk?~hj;4W1I&)N=CTL2?48Rjd{9j`9+xT?SIdY^Oc2*94WPJB z7}Q3;CeXg?5`WkCysu6Ww||FD)+A(2s=X7=nRsfg!8|HX zjx%rZ-tLL@-y_S2NVk5}Xkv;Oza&=+Hc~*IaMy>(++MZpl~8Gcn$`zS16@o^}TpIQ0d({COlL zA+8r^sm(SzGqVnLR<7r_d_GW=b|duujES`L7enBesO8OD#Xhu~s7APQOT1ANM`1tc z&jF#uBdg$TeacK9s$KZ1g`_wNT8>OKSElhIB87A@8(o7*p8sdN3i>-RExmJ~0}e|r zYbyT~I5xrwsrwkScz^r~*%5hFutQY%&5U@>+(cYFa_s>5l>ceHD_)G~+J8ynRY3Yb zNrK9?Z1{qF^E=_w!&21uuHSL-#&d|v_{SJRoC#~IEQmq*2Gv*~KVq2U-(U|2!Hn3v zI%Sh8`w+Nu^Y_za#P-DD>4%@C=A%)SUdw1B@E>1!De@S9$m$mtjJ;{a5FxZ@r1{k# zNh|yNW(ueGeB4}WjjDhSUg+inF~KA9p8A!=>K(rSF!^MFuw?gf-yb_R=*%XuTo7z} zYI&I03qU*_4UQZ6+;bC}ig6x-E1qFZ*U;>1E_Kup*T(7$M$tC~=Ap5||f z7cCqfMcKQb(WyD|ECfN7VT!8?O}iz&y+(q1zt|TtItRj09h(l!24*SL&g@@xIGn9G z=-G9cxN+TtKlsn4HFzY}UQY(j)>PWEHm|N4FSsJ>SRZINQkzV!3ohfPKl%KL9AMKq znkDS-G-MxK2-y4Pm=>FQ6j5#$)C#=`9o9azsYS)=DdqE3-KhNM=W#9id7Z5#h;cQc znaX8#+-vO`TgPx+o+}{{M;hklIblljYn5U2_^vzuJVw(Ib3SwK@Z&c4extGKV&SAt z*%G^x1?-YVzq9A{TUSz<)SDTrKXMS?wZmq;mTsyD1IcjWlVzI_i_2@ z`EWsZ&2YmkK*(Bj_Hm24kO$2#=y_878z{D$X`jwR&uwp`gcerY(JSmz8F*pl>-J6o zgCFL7PeKG->Q842zmPDT`e@%vXf97>ifiwA)O8N79w!QxR<|#{W$CldgcdJB`HvZd zMv)h%6RRaM1T7q5N2N$US-LNy-?p3&XA5&ISx($g-J6Vz+5_py9ML*_b@!Wb*V78@ zt$ev_s6n&J3G-dUP34()JL8m4Uc&hF6hiQIB=uL{(%XHKh>mFhD6%Q#aQS!fAu#` zoyYPQu91q2&Q4S=PN*jTDsI@|vVe0pT@GXy)^58EbC$-#)5BrbVyl(q zlBU3qr>#f502yi$9$z#`KdbMlEl10M!FCy?j;WXKBZ$ZnGr1bIWr zx?BCb4}8xy3LmwR1f{^XtWVu=ozPtAty;=Yec4StoE zB(+Y_M{UQ0J(IZIv+5=B(8iyM4LkbI@~9H+3FE8yl%L0k@|x_3*{s_Zye;;^uB;by z6*Y_bVGlFBJ`q@^do4Q_EHa(dt)xjjht*3yZN#U#WvGBhu6ld}d2g_Le5q>>AhI0-Q-ty6eLD}oXp31WvNN=Nu8XPquNJ_t>G6Z? zYL6PcBfMg=ETc!$C|w=3NsRasyF9}L16)MxxLIlk6wi8l$!km}eNDg}y4fF5lshB0n8AWKh7fWnD{joXdl zs1By_FeKzg!VWb1*3i$|#%2|)J0!jGBg<(G2_#!YMzD)BL2nfOI><(C2!#^>H8)`W z0O$iTje%zmiU2`3@bOu>k#_5vCID!G^h3o(0YmGIKVNg=g+@rn^FJF-S-l`P!B`=7 zT}-TS_iYbfi~)GXHvWpUp+xppZDHC8tnwFdd{G3D*;o>-!U}hZUmr3B!mTW%_~{v7 zpGmdztU;t!O8;aXF0P{z4M@+!2(;8! zk7gf|FEbMav8mJP%Ukip@^1k@Gv+FX^u|nn0FisUSk<+IJrrKSlN_na+?KPyb3Ot(-743@xWc<#U6@?%2mj5KK zeMbXw-V;Zz@eo^M_R5m>YWxKOIa>J0pRWAri~i?v-3O Sr#=G!06A%8sVWKMAO8>AE09?L literal 0 HcmV?d00001 diff --git a/doc/pages/pages_quick_start_guide.md b/doc/pages/pages_quick_start_guide.md index b86b451ba5e..b0a33136d06 100644 --- a/doc/pages/pages_quick_start_guide.md +++ b/doc/pages/pages_quick_start_guide.md @@ -46,8 +46,8 @@ Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've created for the s 1. Choose your SSG template 1. Fork a project from the [Pages group](https://gitlab.com/pages) 1. Remove the fork relationship by navigating to your **Project**'s **Settings** > **Edit Project** - - ![remove fork relashionship](images/remove_fork_relashionship.png) + + ![remove fork relashionship](img/remove_fork_relashionship.png) 1. Enable Shared Runners for your fork: navigate to your **Project**'s **Settings** > **CI/CD Pipelines** 1. Trigger a build (push a change to any file) @@ -73,17 +73,17 @@ To turn a **project website** forked from the Pages group into a **user/group** 1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, click **New project**, and name it considering the [examples above](#practical-examples). 1. Clone it to your local computer, add your website files to your project, add, commit and push to GitLab. 1. From the your **Project**'s page, click **Set up CI**: - - ![setup GitLab CI](images/setup_ci.png) + + ![setup GitLab CI](img/setup_ci.png) 1. Choose one of the templates from the dropbox menu. Pick up the template corresponding to the SSG you're using (or plain HTML). - ![gitlab-ci templates](images/choose_ci_template.png) + ![gitlab-ci templates](img/choose_ci_template.png) Once you have both site files and `.gitlab-ci.yml` in your project's root, GitLab CI will build your site and deploy it with Pages. Once the first build passes, you see your site is live by navigating to your **Project**'s **Settings** > **Pages**, where you'll find its default URL. > **Notes:** -> +> > - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but, if you don't find yours among the templates, you'll need to configure your own `.gitlab-ci.yml`. Do do that, please read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html). New SSGs are very welcome among the [example projects](https://gitlab.com/pages). If you set up a new one, please [contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md) to our examples. > > - The second step _"Clone it to your local computer"_, can be done differently, achieving the same results: instead of cloning the bare repository to you local computer and moving your site files into it, you can run `git init` in your local website directory, add the remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`, then add, commit, and push. diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md index c6e2cab0bc3..2564d87ac3a 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md @@ -86,7 +86,7 @@ In case you want to point a root domain (`example.com`) to your GitLab Pages sit **Practical Example:** -![DNS A record pointing to GitLab.com Pages server](images/dns_a_record_example.png) +![DNS A record pointing to GitLab.com Pages server](img/dns_a_record_example.png) #### DNS CNAME record @@ -96,7 +96,7 @@ Notice that, despite it's a user or project website, the `CNAME` should point to **Practical Example:** -![DNS CNAME record pointing to GitLab.com project](images/dns_cname_record_example.png) +![DNS CNAME record pointing to GitLab.com project](img/dns_cname_record_example.png) #### TL;DR @@ -138,7 +138,7 @@ Regardless the CA you choose, the steps to add your certificate to your Pages pr 1. An intermediary certificate 1. A public key -![Pages project - adding certificates](images/add_certificate_to_pages.png) +![Pages project - adding certificates](img/add_certificate_to_pages.png) These fields are found under your **Project**'s **Settings** > **Pages** > **New Domain**. From bb483230e60692e203775346ac3ad4407e3864a5 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 12 Jan 2017 14:00:06 +0000 Subject: [PATCH 145/247] added specs for version check image --- .../javascripts/version_check_image.js.es6 | 16 ++++----- spec/features/help_pages_spec.rb | 26 ++++++++++++++ spec/helpers/version_check_helper_spec.rb | 34 +++++++++++++++++++ spec/javascripts/.eslintrc | 3 +- .../helpers/class_spec_helper.js.es6 | 2 ++ .../version_check_image_spec.js.es6 | 33 ++++++++++++++++++ 6 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 spec/helpers/version_check_helper_spec.rb create mode 100644 spec/javascripts/version_check_image_spec.js.es6 diff --git a/app/assets/javascripts/version_check_image.js.es6 b/app/assets/javascripts/version_check_image.js.es6 index 1fa2b5ac399..d4f716acb72 100644 --- a/app/assets/javascripts/version_check_image.js.es6 +++ b/app/assets/javascripts/version_check_image.js.es6 @@ -1,10 +1,10 @@ -(() => { - class VersionCheckImage { - static bindErrorEvent(imageElement) { - imageElement.off('error').on('error', () => imageElement.hide()); - } +class VersionCheckImage { + static bindErrorEvent(imageElement) { + imageElement.off('error').on('error', () => imageElement.hide()); } +} - window.gl = window.gl || {}; - gl.VersionCheckImage = VersionCheckImage; -})(); +window.gl = window.gl || {}; +gl.VersionCheckImage = VersionCheckImage; + +module.exports = VersionCheckImage; diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb index 40a1fced8d8..e0b2404e60a 100644 --- a/spec/features/help_pages_spec.rb +++ b/spec/features/help_pages_spec.rb @@ -33,4 +33,30 @@ describe 'Help Pages', feature: true do it_behaves_like 'help page', prefix: '/gitlab' end end + + context 'in a production environment with version check enabled', js: true do + before do + allow(Rails.env).to receive(:production?) { true } + allow(current_application_settings).to receive(:version_check_enabled) { true } + allow_any_instance_of(VersionCheck).to receive(:url) { '/version-check-url' } + + login_as :user + visit help_path + end + + it 'should display a version check image' do + expect(find('.js-version-status-badge')).to be_visible + end + + it 'should have a src url' do + expect(find('.js-version-status-badge')['src']).to match(/\/version-check-url/) + end + + it 'should hide the version check image if the image request fails' do + # We use '--load-images=no' with poltergeist so we must trigger manually + execute_script("$('.js-version-status-badge').trigger('error');") + + expect(find('.js-version-status-badge', visible: false)).not_to be_visible + end + end end diff --git a/spec/helpers/version_check_helper_spec.rb b/spec/helpers/version_check_helper_spec.rb new file mode 100644 index 00000000000..889fe441171 --- /dev/null +++ b/spec/helpers/version_check_helper_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe VersionCheckHelper do + describe '#version_status_badge' do + it 'should return nil if not dev environment and not enabled' do + allow(Rails.env).to receive(:production?) { false } + allow(current_application_settings).to receive(:version_check_enabled) { false } + + expect(helper.version_status_badge).to be(nil) + end + + context 'when production and enabled' do + before do + allow(Rails.env).to receive(:production?) { true } + allow(current_application_settings).to receive(:version_check_enabled) { true } + allow_any_instance_of(VersionCheck).to receive(:url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } + + @image_tag = helper.version_status_badge + end + + it 'should return an image tag' do + expect(@image_tag).to match(/^

'); + }); + + it('registers an error event', function () { + spyOn($.prototype, 'on'); + spyOn($.prototype, 'off').and.callFake(function () { return this; }); + + VersionCheckImage.bindErrorEvent(this.imageElement); + + expect($.prototype.off).toHaveBeenCalledWith('error'); + expect($.prototype.on).toHaveBeenCalledWith('error', jasmine.any(Function)); + }); + + it('hides the imageElement on error', function () { + spyOn($.prototype, 'hide'); + + VersionCheckImage.bindErrorEvent(this.imageElement); + + this.imageElement.trigger('error'); + + expect($.prototype.hide).toHaveBeenCalled(); + }); + }); +}); From 87fe6a27dd4c17cf6b202de809faa821712a3e17 Mon Sep 17 00:00:00 2001 From: Mark Fletcher Date: Wed, 22 Feb 2017 17:07:17 +0530 Subject: [PATCH 146/247] Document when current coverage configuration option was introduced * Introduced in v8.17 [skip ci] --- .../28524-gitlab-ci-yml-coverage-key-is-unknown.yml | 4 ++++ doc/ci/yaml/README.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml diff --git a/changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml b/changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml new file mode 100644 index 00000000000..eda5764c13e --- /dev/null +++ b/changelogs/unreleased/28524-gitlab-ci-yml-coverage-key-is-unknown.yml @@ -0,0 +1,4 @@ +--- +title: Document when current coverage configuration option was introduced +merge_request: 9443 +author: diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index a73598df812..dd3ba1283f8 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -1003,6 +1003,9 @@ job: ### coverage +**Notes:** +- [Introduced][ce-7447] in GitLab 8.17. + `coverage` allows you to configure how code coverage will be extracted from the job output. @@ -1361,3 +1364,4 @@ CI with various languages. [ce-6669]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6669 [variables]: ../variables/README.md [ce-7983]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7983 +[ce-7447]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7447 From 699aab02d09cee93570c41ba19251f7a772f8171 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 13:03:05 +0100 Subject: [PATCH 147/247] Generalize the naming of the getting started docs --- ...ficates.md => getting_started_part_one.md} | 10 ++-- ...ab-ci.md => getting_started_part_three.md} | 12 ++--- ...t_guide.md => getting_started_part_two.md} | 10 ++-- doc/pages/index.md | 46 +++++++++---------- doc/user/project/pages/index.md | 2 +- 5 files changed, 40 insertions(+), 40 deletions(-) rename doc/pages/{pages_static_sites_domains_dns_records_ssl_tls_certificates.md => getting_started_part_one.md} (94%) rename doc/pages/{pages_creating_and_tweaking_gitlab-ci.md => getting_started_part_three.md} (92%) rename doc/pages/{pages_quick_start_guide.md => getting_started_part_two.md} (91%) diff --git a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md b/doc/pages/getting_started_part_one.md similarity index 94% rename from doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md rename to doc/pages/getting_started_part_one.md index 2564d87ac3a..8a98afeeb86 100644 --- a/doc/pages/pages_static_sites_domains_dns_records_ssl_tls_certificates.md +++ b/doc/pages/getting_started_part_one.md @@ -5,8 +5,8 @@ > Level: beginner - **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates** -- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ -- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ +- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ +- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ ---- @@ -145,7 +145,7 @@ These fields are found under your **Project**'s **Settings** > **Pages** > **New #### What's what? - A PEM certificate is the certificate generated by the CA, which needs to be added to the field **Certificate (PEM)**. -- An [intermediary certificate][] (aka "root certificate") is the part of the encryption keychain that identifies the CA. Usually it's combined with the PEM certificate, but there are some cases in which you need to add them manually. [CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) are one of these cases. +- An [intermediary certificate][] \(aka "root certificate"\) is the part of the encryption keychain that identifies the CA. Usually it's combined with the PEM certificate, but there are some cases in which you need to add them manually. [CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) are one of these cases. - A public key is an encrypted key which validates your PEM against your domain. #### Now what? @@ -160,5 +160,5 @@ Now that you hopefully understand why you need all of this, it's simple: ## Further Reading -- Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ -- Read through GitLab Pages from A to Z _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ +- Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ +- Read through GitLab Pages from A to Z _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ diff --git a/doc/pages/pages_creating_and_tweaking_gitlab-ci.md b/doc/pages/getting_started_part_three.md similarity index 92% rename from doc/pages/pages_creating_and_tweaking_gitlab-ci.md rename to doc/pages/getting_started_part_three.md index 8e1877c4981..0bc6a601a09 100644 --- a/doc/pages/pages_creating_and_tweaking_gitlab-ci.md +++ b/doc/pages/getting_started_part_three.md @@ -4,15 +4,15 @@ > > Level: intermediate +- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ +- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ - **Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages** -- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ -- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ ----- +--- ### Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages -[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves inumerous purposes, to build, test, and deploy your app from GitLab through [Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) methods. You will need it to build your website with GitLab Pages, and deploy it to the Pages server. +[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves numerous purposes, to build, test, and deploy your app from GitLab through [Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) methods. You will need it to build your website with GitLab Pages, and deploy it to the Pages server. What this file actually does is telling the [GitLab Runner](https://docs.gitlab.com/runner/) to run scripts as you would do from the command line. The Runner acts as your terminal. GitLab CI tells the Runner which commands to run. Both are built-in in GitLab, and you don't need to set up anything for them to work. @@ -275,5 +275,5 @@ What you can do with GitLab CI is pretty much up to your creativity. Once you ge ## Further Reading -- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ -- Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html)_ +- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ +- Read through _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ diff --git a/doc/pages/pages_quick_start_guide.md b/doc/pages/getting_started_part_two.md similarity index 91% rename from doc/pages/pages_quick_start_guide.md rename to doc/pages/getting_started_part_two.md index b0a33136d06..b1d58b5b024 100644 --- a/doc/pages/pages_quick_start_guide.md +++ b/doc/pages/getting_started_part_two.md @@ -4,9 +4,9 @@ > > Level: beginner +- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ - **Part 2: Quick Start Guide - Setting Up GitLab Pages** -- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ -- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ +- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ ---- @@ -84,7 +84,7 @@ Once you have both site files and `.gitlab-ci.yml` in your project's root, GitLa > **Notes:** > -> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but, if you don't find yours among the templates, you'll need to configure your own `.gitlab-ci.yml`. Do do that, please read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci_.html). New SSGs are very welcome among the [example projects](https://gitlab.com/pages). If you set up a new one, please [contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md) to our examples. +> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but, if you don't find yours among the templates, you'll need to configure your own `.gitlab-ci.yml`. Do do that, please read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md). New SSGs are very welcome among the [example projects](https://gitlab.com/pages). If you set up a new one, please [contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md) to our examples. > > - The second step _"Clone it to your local computer"_, can be done differently, achieving the same results: instead of cloning the bare repository to you local computer and moving your site files into it, you can run `git init` in your local website directory, add the remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`, then add, commit, and push. @@ -108,5 +108,5 @@ baseurl: "" ## Further Reading -- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html)_ -- Read through _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html)_ +- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ +- Read through _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ diff --git a/doc/pages/index.md b/doc/pages/index.md index 54a951f0a2a..fe328748668 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -2,39 +2,39 @@ ## Product -- [Product Webpage](https://pages.gitlab.io) -- [We're Bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/) -- [Pages Group - Templates](https://gitlab.com/pages) +- [Product webpage](https://pages.gitlab.io) +- [We're bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/) +- [Pages group - templates](https://gitlab.com/pages) -## Getting Started +## Getting started -- Comprehensive Step-by-Step Guide: [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) +- [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) a comprehensive step-by-step guide - GitLab Pages from A to Z - - [Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](pages_static_sites_domains_dns_records_ssl_tls_certificates.html) - - [Part 2: Quick Start Guide - Setting Up GitLab Pages](pages_quick_start_guide.html) - - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg) - - Video tutorial: [How to Publish a Website with GitLab Pages on GitLab.com: from scratch](#LINK) - - [Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](pages_creating_and_tweaking_gitlab-ci.html) -- Secure GitLab Pages Custom Domain with SSL/TLS Certificates + - [Part 1: Static sites, domains, DNS records, and SSL/TLS certificates](getting_started_part_one.md) + - [Part 2: Quick start guide - Setting up GitLab Pages](getting_started_part_two.md) + - Video tutorial: [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg) + - Video tutorial: [How to publish a website with GitLab Pages on GitLab.com: from scratch](#LINK) + - [Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md) +- Secure GitLab Pages custom domain with SSL/TLS certificates - [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) - [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) - [StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/) -- Static Site Generators - Blog Posts Series - - [SSGs Part 1: Static vs Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) - - [SSGs Part 2: Modern Static Site Generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) - - [SSGs Part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) +- Static Site Generators - Blog posts series + - [SSGs part 1: Static vs dynamic websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) + - [SSGs part 2: Modern static site generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) + - [SSGs part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) - [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/) -## Advanced Use +## Advanced use - Blog Posts: - - [GitLab CI: Run jobs Sequentially, in Parallel, or Build a Custom Pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/) - - [GitLab CI: Deployment & Environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/) - - [Building a new GitLab Docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) - - [Publish Code Coverage Report with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/) + - [GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/) + - [GitLab CI: Deployment & environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/) + - [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) + - [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/) -## General Documentation +## General documentation -- [User docs](../user/project/pages/) -- [Admin docs](administration.html) +- [User docs](../user/project/pages/index.md) +- [Admin docs](../administration/pages/index.md) - Video tutorial - [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s) diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index e07b7e83f81..816600964de 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -445,5 +445,5 @@ For a list of known issues, visit GitLab's [public issue tracker]. [ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605 [quick start guide]: ../../../ci/quick_start/README.md [pages-index-guide]: ../../../pages/ -[pages-quick]: ../../../pages/pages_quick_start_guide.html +[pages-quick]: ../../../pages/getting_started_part_one.md [video-pages-fork]: https://youtu.be/TWqh9MtT4Bg From 0b402e11e355dc8d834fbc139f4bca810a9f766e Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Mon, 20 Feb 2017 15:35:05 +0100 Subject: [PATCH 148/247] Remove deprecated `upvotes` and `downvotes` from the notes API --- .../unreleased/api-notes-entity-fields.yml | 4 + doc/api/notes.md | 18 +- doc/api/projects.md | 2 - doc/api/users.md | 2 - doc/api/v3_to_v4.md | 2 +- lib/api/api.rb | 1 + lib/api/entities.rb | 3 - lib/api/v3/entities.rb | 34 ++ lib/api/v3/notes.rb | 148 ++++++ lib/api/v3/projects.rb | 4 +- lib/api/v3/users.rb | 21 + spec/requests/api/v3/notes_spec.rb | 432 ++++++++++++++++++ spec/requests/api/v3/users_spec.rb | 77 ++++ 13 files changed, 723 insertions(+), 25 deletions(-) create mode 100644 changelogs/unreleased/api-notes-entity-fields.yml create mode 100644 lib/api/v3/notes.rb create mode 100644 spec/requests/api/v3/notes_spec.rb diff --git a/changelogs/unreleased/api-notes-entity-fields.yml b/changelogs/unreleased/api-notes-entity-fields.yml new file mode 100644 index 00000000000..f7631df31e2 --- /dev/null +++ b/changelogs/unreleased/api-notes-entity-fields.yml @@ -0,0 +1,4 @@ +--- +title: 'API: Remove deprecated fields Notes#upvotes and Notes#downvotes' +merge_request: 9384 +author: Robert Schilling diff --git a/doc/api/notes.md b/doc/api/notes.md index 214dfa4068d..dced821cc6d 100644 --- a/doc/api/notes.md +++ b/doc/api/notes.md @@ -34,8 +34,6 @@ Parameters: "created_at": "2013-10-02T09:22:45Z", "updated_at": "2013-10-02T10:22:45Z", "system": true, - "upvote": false, - "downvote": false, "noteable_id": 377, "noteable_type": "Issue" }, @@ -54,8 +52,6 @@ Parameters: "created_at": "2013-10-02T09:56:03Z", "updated_at": "2013-10-02T09:56:03Z", "system": true, - "upvote": false, - "downvote": false, "noteable_id": 121, "noteable_type": "Issue" } @@ -147,9 +143,7 @@ Example Response: "created_at": "2016-04-05T22:10:44.164Z", "system": false, "noteable_id": 11, - "noteable_type": "Issue", - "upvote": false, - "downvote": false + "noteable_type": "Issue" } ``` @@ -271,9 +265,7 @@ Example Response: "created_at": "2016-04-06T16:51:53.239Z", "system": false, "noteable_id": 52, - "noteable_type": "Snippet", - "upvote": false, - "downvote": false + "noteable_type": "Snippet" } ``` @@ -322,8 +314,6 @@ Parameters: "created_at": "2013-10-02T08:57:14Z", "updated_at": "2013-10-02T08:57:14Z", "system": false, - "upvote": false, - "downvote": false, "noteable_id": 2, "noteable_type": "MergeRequest" } @@ -400,8 +390,6 @@ Example Response: "created_at": "2016-04-05T22:11:59.923Z", "system": false, "noteable_id": 7, - "noteable_type": "MergeRequest", - "upvote": false, - "downvote": false + "noteable_type": "MergeRequest" } ``` diff --git a/doc/api/projects.md b/doc/api/projects.md index e9ef03a0c0c..7fe36d27804 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -407,8 +407,6 @@ Parameters: }, "created_at": "2015-12-04T10:33:56.698Z", "system": false, - "upvote": false, - "downvote": false, "noteable_id": 377, "noteable_type": "Issue" }, diff --git a/doc/api/users.md b/doc/api/users.md index 852c7ac8ec2..d14548e8bbb 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -812,8 +812,6 @@ Example response: }, "created_at": "2015-12-04T10:33:56.698Z", "system": false, - "upvote": false, - "downvote": false, "noteable_id": 377, "noteable_type": "Issue" }, diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index 59d7f0634b2..ff8d227a794 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -36,4 +36,4 @@ changes are in V4: - POST `:id/repository/commits` - POST/PUT/DELETE `:id/repository/files` - Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response - +- Notes do not return deprecated field `upvote` and `downvote` [!9384](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384) diff --git a/lib/api/api.rb b/lib/api/api.rb index a0282ff8deb..1803387bb8c 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -15,6 +15,7 @@ module API mount ::API::V3::Members mount ::API::V3::MergeRequestDiffs mount ::API::V3::MergeRequests + mount ::API::V3::Notes mount ::API::V3::ProjectHooks mount ::API::V3::Projects mount ::API::V3::ProjectSnippets diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 400ee7c92aa..85aa6932f81 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -339,9 +339,6 @@ module API expose :created_at, :updated_at expose :system?, as: :system expose :noteable_id, :noteable_type - # upvote? and downvote? are deprecated, always return false - expose(:upvote?) { |note| false } - expose(:downvote?) { |note| false } end class AwardEmoji < Grape::Entity diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb index 3cc0dc968a8..11d0e6dbf71 100644 --- a/lib/api/v3/entities.rb +++ b/lib/api/v3/entities.rb @@ -11,6 +11,40 @@ module API Gitlab::UrlBuilder.build(snippet) end end + + class Note < Grape::Entity + expose :id + expose :note, as: :body + expose :attachment_identifier, as: :attachment + expose :author, using: ::API::Entities::UserBasic + expose :created_at, :updated_at + expose :system?, as: :system + expose :noteable_id, :noteable_type + # upvote? and downvote? are deprecated, always return false + expose(:upvote?) { |note| false } + expose(:downvote?) { |note| false } + end + + class Event < Grape::Entity + expose :title, :project_id, :action_name + expose :target_id, :target_type, :author_id + expose :data, :target_title + expose :created_at + expose :note, using: Entities::Note, if: ->(event, options) { event.note? } + expose :author, using: ::API::Entities::UserBasic, if: ->(event, options) { event.author } + + expose :author_username do |event, options| + event.author&.username + end + end + + class AwardEmoji < Grape::Entity + expose :id + expose :name + expose :user, using: ::API::Entities::UserBasic + expose :created_at, :updated_at + expose :awardable_id, :awardable_type + end end end end diff --git a/lib/api/v3/notes.rb b/lib/api/v3/notes.rb new file mode 100644 index 00000000000..6531598d590 --- /dev/null +++ b/lib/api/v3/notes.rb @@ -0,0 +1,148 @@ +module API + module V3 + class Notes < Grape::API + include PaginationParams + + before { authenticate! } + + NOTEABLE_TYPES = [Issue, MergeRequest, Snippet] + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects do + NOTEABLE_TYPES.each do |noteable_type| + noteables_str = noteable_type.to_s.underscore.pluralize + + desc 'Get a list of project +noteable+ notes' do + success ::API::V3::Entities::Note + end + params do + requires :noteable_id, type: Integer, desc: 'The ID of the noteable' + use :pagination + end + get ":id/#{noteables_str}/:noteable_id/notes" do + noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id]) + + if can?(current_user, noteable_read_ability_name(noteable), noteable) + # We exclude notes that are cross-references and that cannot be viewed + # by the current user. By doing this exclusion at this level and not + # at the DB query level (which we cannot in that case), the current + # page can have less elements than :per_page even if + # there's more than one page. + notes = + # paginate() only works with a relation. This could lead to a + # mismatch between the pagination headers info and the actual notes + # array returned, but this is really a edge-case. + paginate(noteable.notes). + reject { |n| n.cross_reference_not_visible_for?(current_user) } + present notes, with: ::API::V3::Entities::Note + else + not_found!("Notes") + end + end + + desc 'Get a single +noteable+ note' do + success ::API::V3::Entities::Note + end + params do + requires :note_id, type: Integer, desc: 'The ID of a note' + requires :noteable_id, type: Integer, desc: 'The ID of the noteable' + end + get ":id/#{noteables_str}/:noteable_id/notes/:note_id" do + noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id]) + note = noteable.notes.find(params[:note_id]) + can_read_note = can?(current_user, noteable_read_ability_name(noteable), noteable) && !note.cross_reference_not_visible_for?(current_user) + + if can_read_note + present note, with: ::API::V3::Entities::Note + else + not_found!("Note") + end + end + + desc 'Create a new +noteable+ note' do + success ::API::V3::Entities::Note + end + params do + requires :noteable_id, type: Integer, desc: 'The ID of the noteable' + requires :body, type: String, desc: 'The content of a note' + optional :created_at, type: String, desc: 'The creation date of the note' + end + post ":id/#{noteables_str}/:noteable_id/notes" do + opts = { + note: params[:body], + noteable_type: noteables_str.classify, + noteable_id: params[:noteable_id] + } + + noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id]) + + if can?(current_user, noteable_read_ability_name(noteable), noteable) + if params[:created_at] && (current_user.is_admin? || user_project.owner == current_user) + opts[:created_at] = params[:created_at] + end + + note = ::Notes::CreateService.new(user_project, current_user, opts).execute + if note.valid? + present note, with: ::API::V3::Entities::const_get(note.class.name) + else + not_found!("Note #{note.errors.messages}") + end + else + not_found!("Note") + end + end + + desc 'Update an existing +noteable+ note' do + success ::API::V3::Entities::Note + end + params do + requires :noteable_id, type: Integer, desc: 'The ID of the noteable' + requires :note_id, type: Integer, desc: 'The ID of a note' + requires :body, type: String, desc: 'The content of a note' + end + put ":id/#{noteables_str}/:noteable_id/notes/:note_id" do + note = user_project.notes.find(params[:note_id]) + + authorize! :admin_note, note + + opts = { + note: params[:body] + } + + note = ::Notes::UpdateService.new(user_project, current_user, opts).execute(note) + + if note.valid? + present note, with: ::API::V3::Entities::Note + else + render_api_error!("Failed to save note #{note.errors.messages}", 400) + end + end + + desc 'Delete a +noteable+ note' do + success ::API::V3::Entities::Note + end + params do + requires :noteable_id, type: Integer, desc: 'The ID of the noteable' + requires :note_id, type: Integer, desc: 'The ID of a note' + end + delete ":id/#{noteables_str}/:noteable_id/notes/:note_id" do + note = user_project.notes.find(params[:note_id]) + authorize! :admin_note, note + + ::Notes::DestroyService.new(user_project, current_user).execute(note) + + present note, with: ::API::V3::Entities::Note + end + end + end + + helpers do + def noteable_read_ability_name(noteable) + "read_#{noteable.class.to_s.underscore}".to_sym + end + end + end + end +end diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index 6796da83f07..4bc836f2a3a 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -232,13 +232,13 @@ module API end desc 'Get events for a single project' do - success ::API::Entities::Event + success ::API::V3::Entities::Event end params do use :pagination end get ":id/events" do - present paginate(user_project.events.recent), with: ::API::Entities::Event + present paginate(user_project.events.recent), with: ::API::V3::Entities::Event end desc 'Fork new project for the current user or provided namespace.' do diff --git a/lib/api/v3/users.rb b/lib/api/v3/users.rb index e05e457a5df..7838cdc46a7 100644 --- a/lib/api/v3/users.rb +++ b/lib/api/v3/users.rb @@ -71,6 +71,27 @@ module API user.activate end end + + desc 'Get the contribution events of a specified user' do + detail 'This feature was introduced in GitLab 8.13.' + success ::API::V3::Entities::Event + end + params do + requires :id, type: Integer, desc: 'The ID of the user' + use :pagination + end + get ':id/events' do + user = User.find_by(id: params[:id]) + not_found!('User') unless user + + events = user.events. + merge(ProjectsFinder.new.execute(current_user)). + references(:project). + with_associations. + recent + + present paginate(events), with: ::API::V3::Entities::Event + end end resource :user do diff --git a/spec/requests/api/v3/notes_spec.rb b/spec/requests/api/v3/notes_spec.rb new file mode 100644 index 00000000000..b51cb3055d5 --- /dev/null +++ b/spec/requests/api/v3/notes_spec.rb @@ -0,0 +1,432 @@ +require 'spec_helper' + +describe API::V3::Notes, api: true do + include ApiHelpers + let(:user) { create(:user) } + let!(:project) { create(:empty_project, :public, namespace: user.namespace) } + let!(:issue) { create(:issue, project: project, author: user) } + let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) } + let!(:snippet) { create(:project_snippet, project: project, author: user) } + let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) } + let!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) } + let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) } + + # For testing the cross-reference of a private issue in a public issue + let(:private_user) { create(:user) } + let(:private_project) do + create(:empty_project, namespace: private_user.namespace). + tap { |p| p.team << [private_user, :master] } + end + let(:private_issue) { create(:issue, project: private_project) } + + let(:ext_proj) { create(:empty_project, :public) } + let(:ext_issue) { create(:issue, project: ext_proj) } + + let!(:cross_reference_note) do + create :note, + noteable: ext_issue, project: ext_proj, + note: "mentioned in issue #{private_issue.to_reference(ext_proj)}", + system: true + end + + before { project.team << [user, :reporter] } + + describe "GET /projects/:id/noteable/:noteable_id/notes" do + context "when noteable is an Issue" do + it "returns an array of issue notes" do + get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['body']).to eq(issue_note.note) + expect(json_response.first['upvote']).to be_falsey + expect(json_response.first['downvote']).to be_falsey + end + + it "returns a 404 error when issue id not found" do + get v3_api("/projects/#{project.id}/issues/12345/notes", user) + + expect(response).to have_http_status(404) + end + + context "and current user cannot view the notes" do + it "returns an empty array" do + get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response).to be_empty + end + + context "and issue is confidential" do + before { ext_issue.update_attributes(confidential: true) } + + it "returns 404" do + get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user) + + expect(response).to have_http_status(404) + end + end + + context "and current user can view the note" do + it "returns an empty array" do + get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", private_user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['body']).to eq(cross_reference_note.note) + end + end + end + end + + context "when noteable is a Snippet" do + it "returns an array of snippet notes" do + get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['body']).to eq(snippet_note.note) + end + + it "returns a 404 error when snippet id not found" do + get v3_api("/projects/#{project.id}/snippets/42/notes", user) + + expect(response).to have_http_status(404) + end + + it "returns 404 when not authorized" do + get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", private_user) + + expect(response).to have_http_status(404) + end + end + + context "when noteable is a Merge Request" do + it "returns an array of merge_requests notes" do + get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.first['body']).to eq(merge_request_note.note) + end + + it "returns a 404 error if merge request id not found" do + get v3_api("/projects/#{project.id}/merge_requests/4444/notes", user) + + expect(response).to have_http_status(404) + end + + it "returns 404 when not authorized" do + get v3_api("/projects/#{project.id}/merge_requests/4444/notes", private_user) + + expect(response).to have_http_status(404) + end + end + end + + describe "GET /projects/:id/noteable/:noteable_id/notes/:note_id" do + context "when noteable is an Issue" do + it "returns an issue note by id" do + get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['body']).to eq(issue_note.note) + end + + it "returns a 404 error if issue note not found" do + get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user) + + expect(response).to have_http_status(404) + end + + context "and current user cannot view the note" do + it "returns a 404 error" do + get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", user) + + expect(response).to have_http_status(404) + end + + context "when issue is confidential" do + before { issue.update_attributes(confidential: true) } + + it "returns 404" do + get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", private_user) + + expect(response).to have_http_status(404) + end + end + + context "and current user can view the note" do + it "returns an issue note by id" do + get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", private_user) + + expect(response).to have_http_status(200) + expect(json_response['body']).to eq(cross_reference_note.note) + end + end + end + end + + context "when noteable is a Snippet" do + it "returns a snippet note by id" do + get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes/#{snippet_note.id}", user) + + expect(response).to have_http_status(200) + expect(json_response['body']).to eq(snippet_note.note) + end + + it "returns a 404 error if snippet note not found" do + get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes/12345", user) + + expect(response).to have_http_status(404) + end + end + end + + describe "POST /projects/:id/noteable/:noteable_id/notes" do + context "when noteable is an Issue" do + it "creates a new issue note" do + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!' + + expect(response).to have_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + end + + it "returns a 400 bad request error if body not given" do + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user) + + expect(response).to have_http_status(400) + end + + it "returns a 401 unauthorized error if user not authenticated" do + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes"), body: 'hi!' + + expect(response).to have_http_status(401) + end + + context 'when an admin or owner makes the request' do + it 'accepts the creation date to be set' do + creation_time = 2.weeks.ago + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), + body: 'hi!', created_at: creation_time + + expect(response).to have_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) + end + end + + context 'when the user is posting an award emoji on an issue created by someone else' do + let(:issue2) { create(:issue, project: project) } + + it 'returns an award emoji' do + post v3_api("/projects/#{project.id}/issues/#{issue2.id}/notes", user), body: ':+1:' + + expect(response).to have_http_status(201) + expect(json_response['awardable_id']).to eq issue2.id + end + end + + context 'when the user is posting an award emoji on his/her own issue' do + it 'creates a new issue note' do + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: ':+1:' + + expect(response).to have_http_status(201) + expect(json_response['body']).to eq(':+1:') + end + end + end + + context "when noteable is a Snippet" do + it "creates a new snippet note" do + post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user), body: 'hi!' + + expect(response).to have_http_status(201) + expect(json_response['body']).to eq('hi!') + expect(json_response['author']['username']).to eq(user.username) + end + + it "returns a 400 bad request error if body not given" do + post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user) + + expect(response).to have_http_status(400) + end + + it "returns a 401 unauthorized error if user not authenticated" do + post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes"), body: 'hi!' + + expect(response).to have_http_status(401) + end + end + + context 'when user does not have access to read the noteable' do + it 'responds with 404' do + project = create(:empty_project, :private) { |p| p.add_guest(user) } + issue = create(:issue, :confidential, project: project) + + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), + body: 'Foo' + + expect(response).to have_http_status(404) + end + end + + context 'when user does not have access to create noteable' do + let(:private_issue) { create(:issue, project: create(:empty_project, :private)) } + + ## + # We are posting to project user has access to, but we use issue id + # from a different project, see #15577 + # + before do + post v3_api("/projects/#{project.id}/issues/#{private_issue.id}/notes", user), + body: 'Hi!' + end + + it 'responds with resource not found error' do + expect(response.status).to eq 404 + end + + it 'does not create new note' do + expect(private_issue.notes.reload).to be_empty + end + end + end + + describe "POST /projects/:id/noteable/:noteable_id/notes to test observer on create" do + it "creates an activity event when an issue note is created" do + expect(Event).to receive(:create) + + post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!' + end + end + + describe 'PUT /projects/:id/noteable/:noteable_id/notes/:note_id' do + context 'when noteable is an Issue' do + it 'returns modified note' do + put v3_api("/projects/#{project.id}/issues/#{issue.id}/"\ + "notes/#{issue_note.id}", user), body: 'Hello!' + + expect(response).to have_http_status(200) + expect(json_response['body']).to eq('Hello!') + end + + it 'returns a 404 error when note id not found' do + put v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user), + body: 'Hello!' + + expect(response).to have_http_status(404) + end + + it 'returns a 400 bad request error if body not given' do + put v3_api("/projects/#{project.id}/issues/#{issue.id}/"\ + "notes/#{issue_note.id}", user) + + expect(response).to have_http_status(400) + end + end + + context 'when noteable is a Snippet' do + it 'returns modified note' do + put v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\ + "notes/#{snippet_note.id}", user), body: 'Hello!' + + expect(response).to have_http_status(200) + expect(json_response['body']).to eq('Hello!') + end + + it 'returns a 404 error when note id not found' do + put v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\ + "notes/12345", user), body: "Hello!" + + expect(response).to have_http_status(404) + end + end + + context 'when noteable is a Merge Request' do + it 'returns modified note' do + put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\ + "notes/#{merge_request_note.id}", user), body: 'Hello!' + + expect(response).to have_http_status(200) + expect(json_response['body']).to eq('Hello!') + end + + it 'returns a 404 error when note id not found' do + put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\ + "notes/12345", user), body: "Hello!" + + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE /projects/:id/noteable/:noteable_id/notes/:note_id' do + context 'when noteable is an Issue' do + it 'deletes a note' do + delete v3_api("/projects/#{project.id}/issues/#{issue.id}/"\ + "notes/#{issue_note.id}", user) + + expect(response).to have_http_status(200) + # Check if note is really deleted + delete v3_api("/projects/#{project.id}/issues/#{issue.id}/"\ + "notes/#{issue_note.id}", user) + expect(response).to have_http_status(404) + end + + it 'returns a 404 error when note id not found' do + delete v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user) + + expect(response).to have_http_status(404) + end + end + + context 'when noteable is a Snippet' do + it 'deletes a note' do + delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\ + "notes/#{snippet_note.id}", user) + + expect(response).to have_http_status(200) + # Check if note is really deleted + delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\ + "notes/#{snippet_note.id}", user) + expect(response).to have_http_status(404) + end + + it 'returns a 404 error when note id not found' do + delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\ + "notes/12345", user) + + expect(response).to have_http_status(404) + end + end + + context 'when noteable is a Merge Request' do + it 'deletes a note' do + delete v3_api("/projects/#{project.id}/merge_requests/"\ + "#{merge_request.id}/notes/#{merge_request_note.id}", user) + + expect(response).to have_http_status(200) + # Check if note is really deleted + delete v3_api("/projects/#{project.id}/merge_requests/"\ + "#{merge_request.id}/notes/#{merge_request_note.id}", user) + expect(response).to have_http_status(404) + end + + it 'returns a 404 error when note id not found' do + delete v3_api("/projects/#{project.id}/merge_requests/"\ + "#{merge_request.id}/notes/12345", user) + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v3/users_spec.rb b/spec/requests/api/v3/users_spec.rb index 5020ef18a3a..17bbb0b53c1 100644 --- a/spec/requests/api/v3/users_spec.rb +++ b/spec/requests/api/v3/users_spec.rb @@ -186,4 +186,81 @@ describe API::V3::Users, api: true do expect(response).to have_http_status(404) end end + + describe 'GET /users/:id/events' do + let(:user) { create(:user) } + let(:project) { create(:empty_project) } + let(:note) { create(:note_on_issue, note: 'What an awesome day!', project: project) } + + before do + project.add_user(user, :developer) + EventCreateService.new.leave_note(note, user) + end + + context "as a user than cannot see the event's project" do + it 'returns no events' do + other_user = create(:user) + + get api("/users/#{user.id}/events", other_user) + + expect(response).to have_http_status(200) + expect(json_response).to be_empty + end + end + + context "as a user than can see the event's project" do + context 'joined event' do + it 'returns the "joined" event' do + get v3_api("/users/#{user.id}/events", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + + comment_event = json_response.find { |e| e['action_name'] == 'commented on' } + + expect(comment_event['project_id'].to_i).to eq(project.id) + expect(comment_event['author_username']).to eq(user.username) + expect(comment_event['note']['id']).to eq(note.id) + expect(comment_event['note']['body']).to eq('What an awesome day!') + + joined_event = json_response.find { |e| e['action_name'] == 'joined' } + + expect(joined_event['project_id'].to_i).to eq(project.id) + expect(joined_event['author_username']).to eq(user.username) + expect(joined_event['author']['name']).to eq(user.name) + end + end + + context 'when there are multiple events from different projects' do + let(:second_note) { create(:note_on_issue, project: create(:empty_project)) } + let(:third_note) { create(:note_on_issue, project: project) } + + before do + second_note.project.add_user(user, :developer) + + [second_note, third_note].each do |note| + EventCreateService.new.leave_note(note, user) + end + end + + it 'returns events in the correct order (from newest to oldest)' do + get v3_api("/users/#{user.id}/events", user) + + comment_events = json_response.select { |e| e['action_name'] == 'commented on' } + + expect(comment_events[0]['target_id']).to eq(third_note.id) + expect(comment_events[1]['target_id']).to eq(second_note.id) + expect(comment_events[2]['target_id']).to eq(note.id) + end + end + end + + it 'returns a 404 error if not found' do + get v3_api('/users/42/events', user) + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 User Not Found') + end + end end From d3425933dddf4e849199c06dd3ce00c212d0c6da Mon Sep 17 00:00:00 2001 From: Mark Fletcher Date: Tue, 21 Feb 2017 20:21:31 +0530 Subject: [PATCH 149/247] Add housekeeping endpoint for Projects API --- .../27032-add-a-house-keeping-api-call.yml | 4 ++ doc/api/projects.md | 14 ++++++ lib/api/projects.rb | 13 +++++ spec/requests/api/projects_spec.rb | 49 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 changelogs/unreleased/27032-add-a-house-keeping-api-call.yml diff --git a/changelogs/unreleased/27032-add-a-house-keeping-api-call.yml b/changelogs/unreleased/27032-add-a-house-keeping-api-call.yml new file mode 100644 index 00000000000..a9f70e339c0 --- /dev/null +++ b/changelogs/unreleased/27032-add-a-house-keeping-api-call.yml @@ -0,0 +1,4 @@ +--- +title: Add housekeeping endpoint for Projects API +merge_request: 9421 +author: diff --git a/doc/api/projects.md b/doc/api/projects.md index e9ef03a0c0c..872f570e0f6 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -1195,3 +1195,17 @@ Parameters: | `query` | string | yes | A string contained in the project name | | `order_by` | string | no | Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields | | `sort` | string | no | Return requests sorted in `asc` or `desc` order | + +## Start the Housekeeping task for a Project + +>**Note:** This feature was introduced in GitLab 9.0 + +``` +POST /projects/:id/housekeeping +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer/string | yes | The ID of the project or NAMESPACE/PROJECT_NAME | diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 366e5679edd..f1cb1b22143 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -374,6 +374,19 @@ module API present paginate(users), with: Entities::UserBasic end + + desc 'Start the housekeeping task for a project' do + detail 'This feature was introduced in GitLab 9.0.' + end + post ':id/housekeeping' do + authorize_admin_project + + begin + ::Projects::HousekeepingService.new(user_project).execute + rescue ::Projects::HousekeepingService::LeaseTaken => error + conflict!(error.message) + end + end end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 4e90aae9279..2f1181b2e8c 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -1422,4 +1422,53 @@ describe API::Projects, api: true do end end end + + describe 'POST /projects/:id/housekeeping' do + let(:housekeeping) { Projects::HousekeepingService.new(project) } + + before do + allow(Projects::HousekeepingService).to receive(:new).with(project).and_return(housekeeping) + end + + context 'when authenticated as owner' do + it 'starts the housekeeping process' do + expect(housekeeping).to receive(:execute).once + + post api("/projects/#{project.id}/housekeeping", user) + + expect(response).to have_http_status(201) + end + + context 'when housekeeping lease is taken' do + it 'returns conflict' do + expect(housekeeping).to receive(:execute).once.and_raise(Projects::HousekeepingService::LeaseTaken) + + post api("/projects/#{project.id}/housekeeping", user) + + expect(response).to have_http_status(409) + expect(json_response['message']).to match(/Somebody already triggered housekeeping for this project/) + end + end + end + + context 'when authenticated as developer' do + before do + project_member2 + end + + it 'returns forbidden error' do + post api("/projects/#{project.id}/housekeeping", user3) + + expect(response).to have_http_status(403) + end + end + + context 'when unauthenticated' do + it 'returns authentication error' do + post api("/projects/#{project.id}/housekeeping") + + expect(response).to have_http_status(401) + end + end + end end From 3d013487cea47272ff40d3f9a4b02960d2c2591f Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 22 Feb 2017 11:03:04 +0100 Subject: [PATCH 150/247] Grapify the CI::Runners API --- lib/ci/api/runners.rb | 44 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/lib/ci/api/runners.rb b/lib/ci/api/runners.rb index bcc82969eb3..2a611a67eaf 100644 --- a/lib/ci/api/runners.rb +++ b/lib/ci/api/runners.rb @@ -1,44 +1,36 @@ module Ci module API - # Runners API class Runners < Grape::API resource :runners do - # Delete runner - # Parameters: - # token (required) - The unique token of runner - # - # Example Request: - # GET /runners/delete + desc 'Delete a runner' + params do + requires :token, type: String, desc: 'The unique token of the runner' + end delete "delete" do - required_attributes! [:token] authenticate_runner! Ci::Runner.find_by_token(params[:token]).destroy end - # Register a new runner - # - # Note: This is an "internal" API called when setting up - # runners, so it is authenticated differently. - # - # Parameters: - # token (required) - The unique token of runner - # - # Example Request: - # POST /runners/register + desc 'Register a new runner' do + success Entities::Runner + end + params do + requires :token, type: String, desc: 'The unique token of the runner' + optional :description, type: String, desc: 'The description of the runner' + optional :tag_list, type: Array[String], desc: 'A list of tags the runner should run for' + optional :run_untagged, type: Boolean, desc: 'Flag if the runner should execute untagged jobs' + optional :locked, type: Boolean, desc: 'Lock this runner for this specific project' + end post "register" do - required_attributes! [:token] - - attributes = attributes_for_keys( - [:description, :tag_list, :run_untagged, :locked] - ) + runner_params = declared(params, include_missing: false) runner = if runner_registration_token_valid? # Create shared runner. Requires admin access - Ci::Runner.create(attributes.merge(is_shared: true)) - elsif project = Project.find_by(runners_token: params[:token]) + Ci::Runner.create(runner_params.merge(is_shared: true)) + elsif project = Project.find_by(runners_token: runner_params[:token]) # Create a specific runner for project. - project.runners.create(attributes) + project.runners.create(runner_params) end return forbidden! unless runner From 80033d8c326aa2b4c4e4ed7da7ab7e174af27451 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Wed, 22 Feb 2017 11:33:23 -0300 Subject: [PATCH 151/247] Update CHANGELOG.md for 8.17.0 [ci skip] --- CHANGELOG.md | 180 ++++++++++++++++++ changelogs/unreleased/17662-rename-builds.yml | 4 - ...uire-from-request_profiler-initializer.yml | 4 - ...ect-better-blank-state-for-labels-view.yml | 4 - .../21518_recaptcha_spam_issues.yml | 4 - .../22007-unify-projects-search.yml | 4 - ...ing-a-branch-matching-a-wildcard-fails.yml | 4 - ...974-trigger-service-events-through-api.yml | 4 - ...-notify-automerge-user-of-failed-build.yml | 4 - .../23634-remove-project-grouping.yml | 4 - ...sable-storing-of-sensitive-information.yml | 4 - .../unreleased/24147-delete-env-button.yml | 4 - ...606-force-password-reset-on-next-login.yml | 4 - .../unreleased/24716-fix-ctrl-click-links.yml | 4 - ...5_refactor_merge_request_build_service.yml | 4 - ...o-search-by-commit-hash-within-project.yml | 4 - changelogs/unreleased/24923_nested_tasks.yml | 4 - ...w-doesn-t-show-organization-membership.yml | 4 - .../25312-search-input-cmd-click-issue.yml | 4 - ...0-remove-flash-warning-from-login-page.yml | 4 - .../25460-replace-word-users-with-members.yml | 4 - ...ipate-obstacles-to-removing-turbolinks.yml | 4 - ...-update-when-new-pipeline-is-triggered.yml | 4 - ...cons-to-svg-to-propperly-position-them.yml | 4 - ...25989-fix-rogue-scrollbars-on-comments.yml | 4 - .../unreleased/26059-segoe-ui-vertical.yml | 4 - .../unreleased/26068_tasklist_issue.yml | 4 - .../26117-sort-pipeline-for-commit.yml | 4 - ...and-minus-signs-as-part-of-line-number.yml | 4 - .../26445-accessible-piplelines-buttons.yml | 4 - .../unreleased/26447-fix-tab-list-order.yml | 4 - .../26468-fix-users-sort-in-admin-area.yml | 4 - .../26787-add-copy-icon-hover-state.yml | 4 - ...ible-when-there-are-no-lines-to-unfold.yml | 5 - .../26852-fix-slug-for-openshift.yml | 4 - ...move-hover-animation-from-row-elements.yml | 4 - .../26881-backup-fails-if-data-changes.yml | 4 - ...920-hover-cursor-on-pagination-element.yml | 4 - .../26947-build-status-self-link.yml | 4 - ...ipeline-status-icon-linking-in-widgets.yml | 4 - .../27013-regression-in-commit-title-bar.yml | 4 - .../27014-fix-pipeline-tooltip-wrapping.yml | 4 - ...21-line-numbers-now-in-copy-pasta-data.yml | 4 - ...update-builds-link-in-project-settings.yml | 4 - .../27240-make-progress-bars-consistent.yml | 4 - ...-mini-pipeline-graph-glitch-upon-hover.yml | 4 - .../27291-unify-mr-diff-file-buttons.yml | 4 - ...parator-line-in-edit-projects-settings.yml | 4 - ...-no-line-spacing-in-firefox-and-safari.yml | 4 - .../27352-search-label-filter-header.yml | 4 - ...95-reduce-group-activity-sql-queries-2.yml | 4 - ...7395-reduce-group-activity-sql-queries.yml | 4 - .../27484-environment-show-name.yml | 4 - .../unreleased/27488-fix-jwt-version.yml | 4 - .../27494-environment-list-column-headers.yml | 4 - ...avatar-border-flicker-mention-dropdown.yml | 4 - .../unreleased/27632_fix_mr_widget_url.yml | 4 - ...er-the-side-panel-in-the-merge-request.yml | 4 - .../unreleased/27656-doc-ci-enable-ci.yml | 4 - ...alization-graph-page-with-roboto-fonts.yml | 4 - .../27822-default-bulk-assign-labels.yml | 4 - ...it-comments-are-shared-across-projects.yml | 4 - ...elines-table-not-showing-commit-branch.yml | 4 - ...acter-is-part-of-an-autocompleted-text.yml | 4 - .../27922-cmd-click-todo-doesn-t-work.yml | 5 - ...925-fix-mr-stray-pipelines-api-request.yml | 4 - ...-merge-request-pipelines-displays-json.yml | 4 - .../27939-fix-current-build-arrow.yml | 4 - ...-list-on-profile-page-is-aligned-right.yml | 4 - ...-icon-and-text-in-merge-request-widget.yml | 4 - ...-mr-notification-use-pipeline-language.yml | 4 - changelogs/unreleased/27963-tooltips-jobs.yml | 4 - ...ranch-ref-switcher-input-filter-broken.yml | 4 - .../27987-skipped-pipeline-mr-graph.yml | 4 - .../27991-success-with-warnings-caret.yml | 4 - ...mprove-blockquote-formatting-on-emails.yml | 4 - .../unreleased/28032-tooltips-file-name.yml | 5 - ...-add-pagination-to-admin-abuse-reports.yml | 4 - ...x-notification-when-group-set-to-watch.yml | 4 - changelogs/unreleased/8-15-stable.yml | 4 - .../unreleased/8082-permalink-to-file.yml | 4 - changelogs/unreleased/9-0-api-changes.yml | 4 - ...ommand-for-target-merge-request-branch.yml | 4 - .../unreleased/add_project_update_hook.yml | 4 - .../api-remove-snippets-expires-at.yml | 4 - .../unreleased/babel-all-the-things.yml | 5 - ..._doing_offline_update_check-help_page-.yml | 4 - changelogs/unreleased/change_queue_weight.yml | 4 - .../clipboard-button-commit-sha.yml | 3 - .../contribution-calendar-scroll.yml | 4 - changelogs/unreleased/cop-gem-fetcher.yml | 4 - changelogs/unreleased/copy-as-md.yml | 4 - ...-autologin-on-email-confirmation-links.yml | 4 - changelogs/unreleased/display-project-id.yml | 4 - changelogs/unreleased/document-how-to-vue.yml | 4 - .../unreleased/dynamic-todos-fixture.yml | 4 - .../dz-nested-groups-improvements-2.yml | 4 - .../empty-selection-reply-shortcut.yml | 4 - .../unreleased/fe-commit-mr-pipelines.yml | 4 - ...success-warning-icons-in-stages-builds.yml | 4 - changelogs/unreleased/fix-27479.yml | 4 - .../unreleased/fix-api-mr-permissions.yml | 4 - .../unreleased/fix-ar-connection-leaks.yml | 4 - changelogs/unreleased/fix-ci-build-policy.yml | 4 - .../unreleased/fix-deleting-project-again.yml | 4 - changelogs/unreleased/fix-depr-warn.yml | 4 - ...ackwards-compatibility-coverage-ci-yml.yml | 4 - .../fix-guest-access-posting-to-notes.yml | 4 - .../unreleased/fix-import-encrypt-atts.yml | 4 - .../unreleased/fix-import-group-members.yml | 4 - .../fix-job-to-pipeline-renaming.yml | 4 - .../fix-references-header-parsing.yml | 5 - changelogs/unreleased/fix-scroll-test.yml | 4 - ...-users-deleting-public-deployment-keys.yml | 4 - .../fix_broken_diff_discussions.yml | 4 - ...g_message_in_admin_background_job_page.yml | 4 - .../unreleased/fwn-to-find-by-full-path.yml | 4 - ...tification_service_spec-to-make-it-DRY.yml | 4 - .../unreleased/git_to_html_redirection.yml | 4 - .../unreleased/go-go-gadget-webpack.yml | 4 - .../unreleased/group-label-sidebar-link.yml | 4 - .../unreleased/hardcode-title-system-note.yml | 4 - .../unreleased/improve-ci-example-php-doc.yml | 4 - .../improve-handleLocationHash-tests.yml | 4 - .../unreleased/issuable-sidebar-bug.yml | 4 - changelogs/unreleased/issue-20428.yml | 4 - .../issue-sidebar-empty-assignee.yml | 4 - changelogs/unreleased/issue_19262.yml | 4 - changelogs/unreleased/issue_23317.yml | 4 - changelogs/unreleased/issue_27211.yml | 4 - .../unreleased/jej-pages-picked-from-ee.yml | 4 - changelogs/unreleased/label-promotion.yml | 4 - .../unreleased/lfs-noauth-public-repo.yml | 4 - changelogs/unreleased/markdown-plantuml.yml | 4 - .../unreleased/merge-request-tabs-fixture.yml | 4 - ...linged-discussion-with-no-avatar-26854.yml | 4 - .../unreleased/mr-tabs-container-offset.yml | 4 - changelogs/unreleased/newline-eslint-rule.yml | 4 - .../no-sidebar-on-action-btn-click.yml | 4 - changelogs/unreleased/no_project_notes.yml | 4 - .../unreleased/pms-lowercase-system-notes.yml | 4 - ...redesign-searchbar-admin-project-26794.yml | 4 - ...irect-to-commit-when-only-commit-found.yml | 5 - changelogs/unreleased/relative-url-assets.yml | 4 - .../unreleased/remove-deploy-key-endpoint.yml | 4 - ...e-issue-and-mr-counts-from-labels-page.yml | 4 - changelogs/unreleased/route-map.yml | 4 - .../unreleased/rs-warden-blocked-users.yml | 4 - .../sh-add-index-to-ci-trigger-requests.yml | 4 - changelogs/unreleased/sh-add-labels-index.yml | 4 - changelogs/unreleased/slash-commands-typo.yml | 4 - .../small-screen-fullscreen-button.yml | 4 - .../snippets-search-performance.yml | 4 - .../tc-only-mr-button-if-allowed.yml | 4 - .../unreleased/terminal-max-session-time.yml | 4 - changelogs/unreleased/updated-pages-0-3-1.yml | 4 - changelogs/unreleased/upgrade-babel-v6.yml | 4 - changelogs/unreleased/upgrade-omniauth.yml | 4 - .../unreleased/upgrade-webpack-v2-2.yml | 4 - changelogs/unreleased/wip-mr-from-commits.yml | 4 - .../unreleased/zj-format-chat-messages.yml | 4 - .../zj-remove-deprecated-ci-service.yml | 4 - .../unreleased/zj-requeue-pending-delete.yml | 4 - 163 files changed, 180 insertions(+), 653 deletions(-) delete mode 100644 changelogs/unreleased/17662-rename-builds.yml delete mode 100644 changelogs/unreleased/20452-remove-require-from-request_profiler-initializer.yml delete mode 100644 changelogs/unreleased/20852-getting-started-project-better-blank-state-for-labels-view.yml delete mode 100644 changelogs/unreleased/21518_recaptcha_spam_issues.yml delete mode 100644 changelogs/unreleased/22007-unify-projects-search.yml delete mode 100644 changelogs/unreleased/22638-creating-a-branch-matching-a-wildcard-fails.yml delete mode 100644 changelogs/unreleased/22974-trigger-service-events-through-api.yml delete mode 100644 changelogs/unreleased/23524-notify-automerge-user-of-failed-build.yml delete mode 100644 changelogs/unreleased/23634-remove-project-grouping.yml delete mode 100644 changelogs/unreleased/23767-disable-storing-of-sensitive-information.yml delete mode 100644 changelogs/unreleased/24147-delete-env-button.yml delete mode 100644 changelogs/unreleased/24606-force-password-reset-on-next-login.yml delete mode 100644 changelogs/unreleased/24716-fix-ctrl-click-links.yml delete mode 100644 changelogs/unreleased/24795_refactor_merge_request_build_service.yml delete mode 100644 changelogs/unreleased/24833-Allow-to-search-by-commit-hash-within-project.yml delete mode 100644 changelogs/unreleased/24923_nested_tasks.yml delete mode 100644 changelogs/unreleased/25134-mobile-issue-view-doesn-t-show-organization-membership.yml delete mode 100644 changelogs/unreleased/25312-search-input-cmd-click-issue.yml delete mode 100644 changelogs/unreleased/25360-remove-flash-warning-from-login-page.yml delete mode 100644 changelogs/unreleased/25460-replace-word-users-with-members.yml delete mode 100644 changelogs/unreleased/25624-anticipate-obstacles-to-removing-turbolinks.yml delete mode 100644 changelogs/unreleased/25811-pipeline-number-and-url-do-not-update-when-new-pipeline-is-triggered.yml delete mode 100644 changelogs/unreleased/25910-convert-manual-action-icons-to-svg-to-propperly-position-them.yml delete mode 100644 changelogs/unreleased/25989-fix-rogue-scrollbars-on-comments.yml delete mode 100644 changelogs/unreleased/26059-segoe-ui-vertical.yml delete mode 100644 changelogs/unreleased/26068_tasklist_issue.yml delete mode 100644 changelogs/unreleased/26117-sort-pipeline-for-commit.yml delete mode 100644 changelogs/unreleased/26186-diff-view-plus-and-minus-signs-as-part-of-line-number.yml delete mode 100644 changelogs/unreleased/26445-accessible-piplelines-buttons.yml delete mode 100644 changelogs/unreleased/26447-fix-tab-list-order.yml delete mode 100644 changelogs/unreleased/26468-fix-users-sort-in-admin-area.yml delete mode 100644 changelogs/unreleased/26787-add-copy-icon-hover-state.yml delete mode 100644 changelogs/unreleased/26824-diff-unfold-link-is-still-visible-when-there-are-no-lines-to-unfold.yml delete mode 100644 changelogs/unreleased/26852-fix-slug-for-openshift.yml delete mode 100644 changelogs/unreleased/26863-Remove-hover-animation-from-row-elements.yml delete mode 100644 changelogs/unreleased/26881-backup-fails-if-data-changes.yml delete mode 100644 changelogs/unreleased/26920-hover-cursor-on-pagination-element.yml delete mode 100644 changelogs/unreleased/26947-build-status-self-link.yml delete mode 100644 changelogs/unreleased/26982-improve-pipeline-status-icon-linking-in-widgets.yml delete mode 100644 changelogs/unreleased/27013-regression-in-commit-title-bar.yml delete mode 100644 changelogs/unreleased/27014-fix-pipeline-tooltip-wrapping.yml delete mode 100644 changelogs/unreleased/27021-line-numbers-now-in-copy-pasta-data.yml delete mode 100644 changelogs/unreleased/27178-update-builds-link-in-project-settings.yml delete mode 100644 changelogs/unreleased/27240-make-progress-bars-consistent.yml delete mode 100644 changelogs/unreleased/27277-small-mini-pipeline-graph-glitch-upon-hover.yml delete mode 100644 changelogs/unreleased/27291-unify-mr-diff-file-buttons.yml delete mode 100644 changelogs/unreleased/27321-double-separator-line-in-edit-projects-settings.yml delete mode 100644 changelogs/unreleased/27332-mini-pipeline-graph-with-many-stages-has-no-line-spacing-in-firefox-and-safari.yml delete mode 100644 changelogs/unreleased/27352-search-label-filter-header.yml delete mode 100644 changelogs/unreleased/27395-reduce-group-activity-sql-queries-2.yml delete mode 100644 changelogs/unreleased/27395-reduce-group-activity-sql-queries.yml delete mode 100644 changelogs/unreleased/27484-environment-show-name.yml delete mode 100644 changelogs/unreleased/27488-fix-jwt-version.yml delete mode 100644 changelogs/unreleased/27494-environment-list-column-headers.yml delete mode 100644 changelogs/unreleased/27602-fix-avatar-border-flicker-mention-dropdown.yml delete mode 100644 changelogs/unreleased/27632_fix_mr_widget_url.yml delete mode 100644 changelogs/unreleased/27639-emoji-panel-under-the-side-panel-in-the-merge-request.yml delete mode 100644 changelogs/unreleased/27656-doc-ci-enable-ci.yml delete mode 100644 changelogs/unreleased/27774-text-color-contrast-is-barely-readable-for-pipelines-visualization-graph-page-with-roboto-fonts.yml delete mode 100644 changelogs/unreleased/27822-default-bulk-assign-labels.yml delete mode 100644 changelogs/unreleased/27873-when-a-commit-appears-in-several-projects-commit-comments-are-shared-across-projects.yml delete mode 100644 changelogs/unreleased/27880-pipelines-table-not-showing-commit-branch.yml delete mode 100644 changelogs/unreleased/27883-autocomplete-seems-to-not-trigger-when-at-character-is-part-of-an-autocompleted-text.yml delete mode 100644 changelogs/unreleased/27922-cmd-click-todo-doesn-t-work.yml delete mode 100644 changelogs/unreleased/27925-fix-mr-stray-pipelines-api-request.yml delete mode 100644 changelogs/unreleased/27932-merge-request-pipelines-displays-json.yml delete mode 100644 changelogs/unreleased/27939-fix-current-build-arrow.yml delete mode 100644 changelogs/unreleased/27943-contribution-list-on-profile-page-is-aligned-right.yml delete mode 100644 changelogs/unreleased/27947-missing-margin-between-loading-icon-and-text-in-merge-request-widget.yml delete mode 100644 changelogs/unreleased/27955-mr-notification-use-pipeline-language.yml delete mode 100644 changelogs/unreleased/27963-tooltips-jobs.yml delete mode 100644 changelogs/unreleased/27966-branch-ref-switcher-input-filter-broken.yml delete mode 100644 changelogs/unreleased/27987-skipped-pipeline-mr-graph.yml delete mode 100644 changelogs/unreleased/27991-success-with-warnings-caret.yml delete mode 100644 changelogs/unreleased/28029-improve-blockquote-formatting-on-emails.yml delete mode 100644 changelogs/unreleased/28032-tooltips-file-name.yml delete mode 100644 changelogs/unreleased/28059-add-pagination-to-admin-abuse-reports.yml delete mode 100644 changelogs/unreleased/395-fix-notification-when-group-set-to-watch.yml delete mode 100644 changelogs/unreleased/8-15-stable.yml delete mode 100644 changelogs/unreleased/8082-permalink-to-file.yml delete mode 100644 changelogs/unreleased/9-0-api-changes.yml delete mode 100644 changelogs/unreleased/Add-a-shash-command-for-target-merge-request-branch.yml delete mode 100644 changelogs/unreleased/add_project_update_hook.yml delete mode 100644 changelogs/unreleased/api-remove-snippets-expires-at.yml delete mode 100644 changelogs/unreleased/babel-all-the-things.yml delete mode 100644 changelogs/unreleased/broken_iamge_when_doing_offline_update_check-help_page-.yml delete mode 100644 changelogs/unreleased/change_queue_weight.yml delete mode 100644 changelogs/unreleased/clipboard-button-commit-sha.yml delete mode 100644 changelogs/unreleased/contribution-calendar-scroll.yml delete mode 100644 changelogs/unreleased/cop-gem-fetcher.yml delete mode 100644 changelogs/unreleased/copy-as-md.yml delete mode 100644 changelogs/unreleased/disable-autologin-on-email-confirmation-links.yml delete mode 100644 changelogs/unreleased/display-project-id.yml delete mode 100644 changelogs/unreleased/document-how-to-vue.yml delete mode 100644 changelogs/unreleased/dynamic-todos-fixture.yml delete mode 100644 changelogs/unreleased/dz-nested-groups-improvements-2.yml delete mode 100644 changelogs/unreleased/empty-selection-reply-shortcut.yml delete mode 100644 changelogs/unreleased/fe-commit-mr-pipelines.yml delete mode 100644 changelogs/unreleased/feature-success-warning-icons-in-stages-builds.yml delete mode 100644 changelogs/unreleased/fix-27479.yml delete mode 100644 changelogs/unreleased/fix-api-mr-permissions.yml delete mode 100644 changelogs/unreleased/fix-ar-connection-leaks.yml delete mode 100644 changelogs/unreleased/fix-ci-build-policy.yml delete mode 100644 changelogs/unreleased/fix-deleting-project-again.yml delete mode 100644 changelogs/unreleased/fix-depr-warn.yml delete mode 100644 changelogs/unreleased/fix-gb-backwards-compatibility-coverage-ci-yml.yml delete mode 100644 changelogs/unreleased/fix-guest-access-posting-to-notes.yml delete mode 100644 changelogs/unreleased/fix-import-encrypt-atts.yml delete mode 100644 changelogs/unreleased/fix-import-group-members.yml delete mode 100644 changelogs/unreleased/fix-job-to-pipeline-renaming.yml delete mode 100644 changelogs/unreleased/fix-references-header-parsing.yml delete mode 100644 changelogs/unreleased/fix-scroll-test.yml delete mode 100644 changelogs/unreleased/fix-users-deleting-public-deployment-keys.yml delete mode 100644 changelogs/unreleased/fix_broken_diff_discussions.yml delete mode 100644 changelogs/unreleased/fix_sidekiq_concurrency_warning_message_in_admin_background_job_page.yml delete mode 100644 changelogs/unreleased/fwn-to-find-by-full-path.yml delete mode 100644 changelogs/unreleased/get-rid-of-water-from-notification_service_spec-to-make-it-DRY.yml delete mode 100644 changelogs/unreleased/git_to_html_redirection.yml delete mode 100644 changelogs/unreleased/go-go-gadget-webpack.yml delete mode 100644 changelogs/unreleased/group-label-sidebar-link.yml delete mode 100644 changelogs/unreleased/hardcode-title-system-note.yml delete mode 100644 changelogs/unreleased/improve-ci-example-php-doc.yml delete mode 100644 changelogs/unreleased/improve-handleLocationHash-tests.yml delete mode 100644 changelogs/unreleased/issuable-sidebar-bug.yml delete mode 100644 changelogs/unreleased/issue-20428.yml delete mode 100644 changelogs/unreleased/issue-sidebar-empty-assignee.yml delete mode 100644 changelogs/unreleased/issue_19262.yml delete mode 100644 changelogs/unreleased/issue_23317.yml delete mode 100644 changelogs/unreleased/issue_27211.yml delete mode 100644 changelogs/unreleased/jej-pages-picked-from-ee.yml delete mode 100644 changelogs/unreleased/label-promotion.yml delete mode 100644 changelogs/unreleased/lfs-noauth-public-repo.yml delete mode 100644 changelogs/unreleased/markdown-plantuml.yml delete mode 100644 changelogs/unreleased/merge-request-tabs-fixture.yml delete mode 100644 changelogs/unreleased/misalinged-discussion-with-no-avatar-26854.yml delete mode 100644 changelogs/unreleased/mr-tabs-container-offset.yml delete mode 100644 changelogs/unreleased/newline-eslint-rule.yml delete mode 100644 changelogs/unreleased/no-sidebar-on-action-btn-click.yml delete mode 100644 changelogs/unreleased/no_project_notes.yml delete mode 100644 changelogs/unreleased/pms-lowercase-system-notes.yml delete mode 100644 changelogs/unreleased/redesign-searchbar-admin-project-26794.yml delete mode 100644 changelogs/unreleased/redirect-to-commit-when-only-commit-found.yml delete mode 100644 changelogs/unreleased/relative-url-assets.yml delete mode 100644 changelogs/unreleased/remove-deploy-key-endpoint.yml delete mode 100644 changelogs/unreleased/remove-issue-and-mr-counts-from-labels-page.yml delete mode 100644 changelogs/unreleased/route-map.yml delete mode 100644 changelogs/unreleased/rs-warden-blocked-users.yml delete mode 100644 changelogs/unreleased/sh-add-index-to-ci-trigger-requests.yml delete mode 100644 changelogs/unreleased/sh-add-labels-index.yml delete mode 100644 changelogs/unreleased/slash-commands-typo.yml delete mode 100644 changelogs/unreleased/small-screen-fullscreen-button.yml delete mode 100644 changelogs/unreleased/snippets-search-performance.yml delete mode 100644 changelogs/unreleased/tc-only-mr-button-if-allowed.yml delete mode 100644 changelogs/unreleased/terminal-max-session-time.yml delete mode 100644 changelogs/unreleased/updated-pages-0-3-1.yml delete mode 100644 changelogs/unreleased/upgrade-babel-v6.yml delete mode 100644 changelogs/unreleased/upgrade-omniauth.yml delete mode 100644 changelogs/unreleased/upgrade-webpack-v2-2.yml delete mode 100644 changelogs/unreleased/wip-mr-from-commits.yml delete mode 100644 changelogs/unreleased/zj-format-chat-messages.yml delete mode 100644 changelogs/unreleased/zj-remove-deprecated-ci-service.yml delete mode 100644 changelogs/unreleased/zj-requeue-pending-delete.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 58b8cf2ad83..7f5b101ad6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,186 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 8.17.0 (2017-02-22) + +- API: Fix file downloading. !0 (8267) +- Changed composer installer script in the CI PHP example doc. !4342 (Jeffrey Cafferata) +- Display fullscreen button on small screens. !5302 (winniehell) +- Add system hook for when a project is updated (other than rename/transfer). !5711 (Tommy Beadle) +- Fix notifications when set at group level. !6813 (Alexandre Maia) +- Project labels can now be promoted to group labels. !7242 (Olaf Tomalka) +- use webpack to bundle frontend assets and use karma for frontend testing. !7288 +- Adds back ability to stop all environments. !7379 +- Added labels empty state. !7443 +- Add ability to define a coverage regex in the .gitlab-ci.yml. !7447 (Leandro Camargo) +- Disable automatic login after clicking email confirmation links. !7472 +- Search feature: redirects to commit page if query is commit sha and only commit found. !8028 (YarNayar) +- Create a TODO for user who set auto-merge when a build fails, merge conflict occurs. !8056 (twonegatives) +- Don't group issues by project on group-level and dashboard issue indexes. !8111 (Bernardo Castro) +- Mark MR as WIP when pushing WIP commits. !8124 (Jurre Stender @jurre) +- Flag multiple empty lines in eslint, fix offenses. !8137 +- Add sorting pipeline for a commit. !8319 (Takuya Noguchi) +- Adds service trigger events to api. !8324 +- Update pipeline and commit links when CI status is updated. !8351 +- Hide version check image if there is no internet connection. !8355 (Ken Ding) +- Prevent removal of input fields if it is the parent dropdown element. !8397 +- Introduce maximum session time for terminal websocket connection. !8413 +- Allow creating protected branches when user can merge to such branch. !8458 +- Refactor MergeRequests::BuildService. !8462 (Rydkin Maxim) +- Added GitLab Pages to CE. !8463 +- Support notes when a project is not specified (personal snippet notes). !8468 +- Use warning icon in mini-graph if stage passed conditionally. !8503 +- Don’t count tasks that are not defined as list items correctly. !8526 +- Reformat messages ChatOps. !8528 +- Copy commit SHA to clipboard. !8547 +- Improve button accessibility on pipelines page. !8561 +- Display project ID in project settings. !8572 (winniehell) +- PlantUML support for Markdown. !8588 (Horacio Sanson) +- Fix reply by email without sub-addressing for some clients from Microsoft and Apple. !8620 +- Fix nested tasks in ordered list. !8626 +- Fix Sort by Recent Sign-in in Admin Area. !8637 (Poornima M) +- Avoid repeated dashes in $CI_ENVIRONMENT_SLUG. !8638 +- Only show Merge Request button when user can create a MR. !8639 +- Prevent copying of line numbers in parallel diff view. !8706 +- Improve build policy and access abilities. !8711 +- API: Remove /projects/:id/keys/.. endpoints. !8716 (Robert Schilling) +- API: Remove deprecated 'expires_at' from project snippets. !8723 (Robert Schilling) +- Add `copy` backup strategy to combat file changed errors. !8728 +- adds avatar for discussion note. !8734 +- Add link verification to badge partial in order to render a badge without a link. !8740 +- Reduce hits to LDAP on Git HTTP auth by reordering auth mechanisms. !8752 +- prevent diff unfolding link from appearing when there are no more lines to show. !8761 +- Redesign searchbar in admin project list. !8776 +- Rename Builds to Pipelines, CI/CD Pipelines, or Jobs everywhere. !8787 +- dismiss sidebar on repo buttons click. !8798 (Adam Pahlevi) +- fixed small mini pipeline graph line glitch. !8804 +- Make all system notes lowercase. !8807 +- Support unauthenticated LFS object downloads for public projects. !8824 (Ben Boeckel) +- Add read-only full_path and full_name attributes to Group API. !8827 +- allow relative url change without recompiling frontend assets. !8831 +- Use vue.js Pipelines table in commit and merge request view. !8844 +- Use reCaptcha when an issue is identified as a spam. !8846 +- resolve deprecation warnings. !8855 (Adam Pahlevi) +- Cop for gem fetched from a git source. !8856 (Adam Pahlevi) +- Remove flash warning from login page. !8864 (Gerald J. Padilla) +- Adds documentation for how to use Vue.js. !8866 +- Add 'View on [env]' link to blobs and individual files in diffs. !8867 +- Replace word user with member. !8872 +- Change the reply shortcut to focus the field even without a selection. !8873 (Brian Hall) +- Unify MR diff file button style. !8874 +- Unify projects search by removing /projects/:search endpoint. !8877 +- Fix disable storing of sensitive information when importing a new repo. !8885 (Bernard Pietraga) +- Fix pipeline graph vertical spacing in Firefox and Safari. !8886 +- Fix filtered search user autocomplete for gitlab instances that are hosted on a subdirectory. !8891 +- Fix Ctrl+Click support for Todos and Merge Request page tabs. !8898 +- Fix wrong call to ProjectCacheWorker.perform. !8910 +- Don't perform Devise trackable updates on blocked User records. !8915 +- Add ability to export project inherited group members to Import/Export. !8923 +- replace `find_with_namespace` with `find_by_full_path`. !8949 (Adam Pahlevi) +- Fixes flickering of avatar border in mention dropdown. !8950 +- Remove unnecessary queries for .atom and .json in Dashboard::ProjectsController#index. !8956 +- Fix deleting projects with pipelines and builds. !8960 +- Fix broken anchor links when special characters are used. !8961 (Andrey Krivko) +- Ensure autogenerated title does not cause failing spec. !8963 (brian m. carlson) +- Update doc for enabling or disabling GitLab CI. !8965 (Takuya Noguchi) +- Remove deprecated MR and Issue endpoints and preserve V3 namespace. !8967 +- Fixed "substract" typo on /help/user/project/slash_commands. !8976 (Jason Aquino) +- Preserve backward compatibility CI/CD and disallow setting `coverage` regexp in global context. !8981 +- use babel to transpile all non-vendor javascript assets regardless of file extension. !8988 +- Fix MR widget url. !8989 +- Fixes hover cursor on pipeline pagenation. !9003 +- Layer award emoji dropdown over the right sidebar. !9004 +- Do not display deploy keys in user's own ssh keys list. !9024 +- upgrade babel 5.8.x to babel 6.22.x. !9072 +- upgrade to webpack v2.2. !9078 +- Trigger autocomplete after selecting a slash command. !9117 +- Add space between text and loading icon in Megre Request Widget. !9119 +- Fix job to pipeline renaming. !9147 +- Replace static fixture for merge_request_tabs_spec.js. !9172 (winniehell) +- Replace static fixture for right_sidebar_spec.js. !9211 (winniehell) +- Show merge errors in merge request widget. !9229 +- Increase process_commit queue weight from 2 to 3. !9326 (blackst0ne) +- Don't require lib/gitlab/request_profiler/middleware.rb in config/initializers/request_profiler.rb. +- Force new password after password reset via API. (George Andrinopoulos) +- Allows to search within project by commit hash. (YarNayar) +- Show organisation membership and delete comment on smaller viewports, plus change comment author name to username. +- Remove turbolinks. +- Convert pipeline action icons to svg to have them propperly positioned. +- Remove rogue scrollbars for issue comments with inline elements. +- Align Segoe UI label text. +- Color + and - signs in diffs to increase code legibility. +- Fix tab index order on branch commits list page. (Ryan Harris) +- Add hover style to copy icon on commit page header. (Ryan Harris) +- Remove hover animation from row elements. +- Improve pipeline status icon linking in widgets. +- Fix commit title bar and repository view copy clipboard button order on last commit in repository view. +- Fix mini-pipeline stage tooltip text wrapping. +- Updated builds info link on the project settings page. (Ryan Harris) +- 27240 Make progress bars consistent. +- Only render hr when user can't archive project. +- 27352-search-label-filter-header. +- Include :author, :project, and :target in Event.with_associations. +- Don't instantiate AR objects in Event.in_projects. +- Don't capitalize environment name in show page. +- Update and pin the `jwt` gem to ~> 1.5.6. +- Edited the column header for the environments list from created to updated and added created to environments detail page colum header titles. +- Give ci status text on pipeline graph a better font-weight. +- Add default labels to bulk assign dropdowns. +- Only return target project's comments for a commit. +- Fixes Pipelines table is not showing branch name for commit. +- Fix regression where cmd-click stopped working for todos and merge request tabs. +- Fix stray pipelines API request when showing MR. +- Fix Merge request pipelines displays JSON. +- Fix current build arrow indicator. +- Fix contribution activity alignment. +- Show Pipeline(not Job) in MR desktop notification. +- Fix tooltips in mini pipeline graph. +- Display loading indicator when filtering ref switcher dropdown. +- Show pipeline graph in MR widget if there are any stages. +- Fix icon colors in merge request widget mini graph. +- Improve blockquote formatting in notification emails. +- Adds container to tooltip in order to make it work with overflow:hidden in parent element. +- Restore pagination to admin abuse reports. +- Ensure export files are removed after a namespace is deleted. +- Add `y` keyboard shortcut to move to file permalink. +- Adds /target_branch slash command functionality for merge requests. (YarNayar) +- Patch Asciidocs rendering to block XSS. +- contribution calendar scrolls from right to left. +- Copying a rendered issue/comment will paste into GFM textareas as actual GFM. +- Don't delete assigned MRs/issues when user is deleted. +- Remove new branch button for confidential issues. +- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling) +- Don't connect in Gitlab::Database.adapter_name. +- Prevent users from creating notes on resources they can't access. +- Ignore encrypted attributes in Import/Export. +- Change rspec test to guarantee window is resized before visiting page. +- Prevent users from deleting system deploy keys via the project deploy key API. +- Fix XSS vulnerability in SVG attachments. +- Make MR-review-discussions more reliable. +- fix incorrect sidekiq concurrency count in admin background page. (wendy0402) +- Make notification_service spec DRYer by making test reusable. (YarNayar) +- Redirect http://someproject.git to http://someproject. (blackst0ne) +- Fixed group label links in issue/merge request sidebar. +- Improve gl.utils.handleLocationHash tests. +- Fixed Issuable sidebar not closing on smaller/mobile sized screens. +- Resets assignee dropdown when sidebar is open. +- Disallow system notes for closed issuables. +- Fix timezone on issue boards due date. +- Remove unused js response from refs controller. +- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects. +- Fixed merge requests tab extra margin when fixed to window. +- Patch XSS vulnerability in RDOC support. +- Refresh authorizations when transferring projects. +- Remove issue and MR counts from labels index. +- Don't use backup Active Record connections for Sidekiq. +- Add index to ci_trigger_requests for commit_id. +- Add indices to improve loading of labels page. +- Reduced query count for snippet search. +- Update GitLab Pages to v0.3.1. +- Upgrade omniauth gem to 1.3.2. +- Remove deprecated GitlabCiService. +- Requeue pending deletion projects. + ## 8.16.6 (2017-02-17) - API: Fix file downloading. !0 (8267) diff --git a/changelogs/unreleased/17662-rename-builds.yml b/changelogs/unreleased/17662-rename-builds.yml deleted file mode 100644 index 12f2998d1c8..00000000000 --- a/changelogs/unreleased/17662-rename-builds.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Rename Builds to Pipelines, CI/CD Pipelines, or Jobs everywhere -merge_request: 8787 -author: diff --git a/changelogs/unreleased/20452-remove-require-from-request_profiler-initializer.yml b/changelogs/unreleased/20452-remove-require-from-request_profiler-initializer.yml deleted file mode 100644 index 965d0648adf..00000000000 --- a/changelogs/unreleased/20452-remove-require-from-request_profiler-initializer.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't require lib/gitlab/request_profiler/middleware.rb in config/initializers/request_profiler.rb -merge_request: -author: diff --git a/changelogs/unreleased/20852-getting-started-project-better-blank-state-for-labels-view.yml b/changelogs/unreleased/20852-getting-started-project-better-blank-state-for-labels-view.yml deleted file mode 100644 index eda872049fd..00000000000 --- a/changelogs/unreleased/20852-getting-started-project-better-blank-state-for-labels-view.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Added labels empty state -merge_request: 7443 -author: diff --git a/changelogs/unreleased/21518_recaptcha_spam_issues.yml b/changelogs/unreleased/21518_recaptcha_spam_issues.yml deleted file mode 100644 index bd6c9d7521e..00000000000 --- a/changelogs/unreleased/21518_recaptcha_spam_issues.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use reCaptcha when an issue is identified as a spam -merge_request: 8846 -author: diff --git a/changelogs/unreleased/22007-unify-projects-search.yml b/changelogs/unreleased/22007-unify-projects-search.yml deleted file mode 100644 index f43c1925ad0..00000000000 --- a/changelogs/unreleased/22007-unify-projects-search.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Unify projects search by removing /projects/:search endpoint -merge_request: 8877 -author: diff --git a/changelogs/unreleased/22638-creating-a-branch-matching-a-wildcard-fails.yml b/changelogs/unreleased/22638-creating-a-branch-matching-a-wildcard-fails.yml deleted file mode 100644 index 2c6883bcf7b..00000000000 --- a/changelogs/unreleased/22638-creating-a-branch-matching-a-wildcard-fails.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Allow creating protected branches when user can merge to such branch -merge_request: 8458 -author: diff --git a/changelogs/unreleased/22974-trigger-service-events-through-api.yml b/changelogs/unreleased/22974-trigger-service-events-through-api.yml deleted file mode 100644 index 57106e8c676..00000000000 --- a/changelogs/unreleased/22974-trigger-service-events-through-api.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Adds service trigger events to api -merge_request: 8324 -author: diff --git a/changelogs/unreleased/23524-notify-automerge-user-of-failed-build.yml b/changelogs/unreleased/23524-notify-automerge-user-of-failed-build.yml deleted file mode 100644 index 268be6b9b83..00000000000 --- a/changelogs/unreleased/23524-notify-automerge-user-of-failed-build.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Create a TODO for user who set auto-merge when a build fails, merge conflict occurs -merge_request: 8056 -author: twonegatives diff --git a/changelogs/unreleased/23634-remove-project-grouping.yml b/changelogs/unreleased/23634-remove-project-grouping.yml deleted file mode 100644 index dde8b2d1815..00000000000 --- a/changelogs/unreleased/23634-remove-project-grouping.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't group issues by project on group-level and dashboard issue indexes. -merge_request: 8111 -author: Bernardo Castro diff --git a/changelogs/unreleased/23767-disable-storing-of-sensitive-information.yml b/changelogs/unreleased/23767-disable-storing-of-sensitive-information.yml deleted file mode 100644 index 587ef4f9a73..00000000000 --- a/changelogs/unreleased/23767-disable-storing-of-sensitive-information.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix disable storing of sensitive information when importing a new repo -merge_request: 8885 -author: Bernard Pietraga diff --git a/changelogs/unreleased/24147-delete-env-button.yml b/changelogs/unreleased/24147-delete-env-button.yml deleted file mode 100644 index 14e80cacbfb..00000000000 --- a/changelogs/unreleased/24147-delete-env-button.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Adds back ability to stop all environments -merge_request: 7379 -author: diff --git a/changelogs/unreleased/24606-force-password-reset-on-next-login.yml b/changelogs/unreleased/24606-force-password-reset-on-next-login.yml deleted file mode 100644 index fd671d04a9f..00000000000 --- a/changelogs/unreleased/24606-force-password-reset-on-next-login.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Force new password after password reset via API -merge_request: -author: George Andrinopoulos diff --git a/changelogs/unreleased/24716-fix-ctrl-click-links.yml b/changelogs/unreleased/24716-fix-ctrl-click-links.yml deleted file mode 100644 index 13de5db5e41..00000000000 --- a/changelogs/unreleased/24716-fix-ctrl-click-links.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Ctrl+Click support for Todos and Merge Request page tabs -merge_request: 8898 -author: diff --git a/changelogs/unreleased/24795_refactor_merge_request_build_service.yml b/changelogs/unreleased/24795_refactor_merge_request_build_service.yml deleted file mode 100644 index b735fb57649..00000000000 --- a/changelogs/unreleased/24795_refactor_merge_request_build_service.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Refactor MergeRequests::BuildService -merge_request: 8462 -author: Rydkin Maxim diff --git a/changelogs/unreleased/24833-Allow-to-search-by-commit-hash-within-project.yml b/changelogs/unreleased/24833-Allow-to-search-by-commit-hash-within-project.yml deleted file mode 100644 index be66c370f36..00000000000 --- a/changelogs/unreleased/24833-Allow-to-search-by-commit-hash-within-project.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'Allows to search within project by commit hash' -merge_request: -author: YarNayar diff --git a/changelogs/unreleased/24923_nested_tasks.yml b/changelogs/unreleased/24923_nested_tasks.yml deleted file mode 100644 index de35cad3dd6..00000000000 --- a/changelogs/unreleased/24923_nested_tasks.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix nested tasks in ordered list -merge_request: 8626 -author: diff --git a/changelogs/unreleased/25134-mobile-issue-view-doesn-t-show-organization-membership.yml b/changelogs/unreleased/25134-mobile-issue-view-doesn-t-show-organization-membership.yml deleted file mode 100644 index d35ad0be0db..00000000000 --- a/changelogs/unreleased/25134-mobile-issue-view-doesn-t-show-organization-membership.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Show organisation membership and delete comment on smaller viewports, plus change comment author name to username -merge_request: -author: diff --git a/changelogs/unreleased/25312-search-input-cmd-click-issue.yml b/changelogs/unreleased/25312-search-input-cmd-click-issue.yml deleted file mode 100644 index 56e03a48692..00000000000 --- a/changelogs/unreleased/25312-search-input-cmd-click-issue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent removal of input fields if it is the parent dropdown element -merge_request: 8397 -author: diff --git a/changelogs/unreleased/25360-remove-flash-warning-from-login-page.yml b/changelogs/unreleased/25360-remove-flash-warning-from-login-page.yml deleted file mode 100644 index 50a5c879446..00000000000 --- a/changelogs/unreleased/25360-remove-flash-warning-from-login-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove flash warning from login page -merge_request: 8864 -author: Gerald J. Padilla diff --git a/changelogs/unreleased/25460-replace-word-users-with-members.yml b/changelogs/unreleased/25460-replace-word-users-with-members.yml deleted file mode 100644 index dac90eaa34d..00000000000 --- a/changelogs/unreleased/25460-replace-word-users-with-members.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replace word user with member -merge_request: 8872 -author: diff --git a/changelogs/unreleased/25624-anticipate-obstacles-to-removing-turbolinks.yml b/changelogs/unreleased/25624-anticipate-obstacles-to-removing-turbolinks.yml deleted file mode 100644 index d7f950d7be9..00000000000 --- a/changelogs/unreleased/25624-anticipate-obstacles-to-removing-turbolinks.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove turbolinks. -merge_request: !8570 -author: diff --git a/changelogs/unreleased/25811-pipeline-number-and-url-do-not-update-when-new-pipeline-is-triggered.yml b/changelogs/unreleased/25811-pipeline-number-and-url-do-not-update-when-new-pipeline-is-triggered.yml deleted file mode 100644 index f74e9fa8b6d..00000000000 --- a/changelogs/unreleased/25811-pipeline-number-and-url-do-not-update-when-new-pipeline-is-triggered.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update pipeline and commit links when CI status is updated -merge_request: 8351 -author: diff --git a/changelogs/unreleased/25910-convert-manual-action-icons-to-svg-to-propperly-position-them.yml b/changelogs/unreleased/25910-convert-manual-action-icons-to-svg-to-propperly-position-them.yml deleted file mode 100644 index 9506692dd40..00000000000 --- a/changelogs/unreleased/25910-convert-manual-action-icons-to-svg-to-propperly-position-them.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Convert pipeline action icons to svg to have them propperly positioned -merge_request: -author: diff --git a/changelogs/unreleased/25989-fix-rogue-scrollbars-on-comments.yml b/changelogs/unreleased/25989-fix-rogue-scrollbars-on-comments.yml deleted file mode 100644 index e67a9c0da15..00000000000 --- a/changelogs/unreleased/25989-fix-rogue-scrollbars-on-comments.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove rogue scrollbars for issue comments with inline elements -merge_request: -author: diff --git a/changelogs/unreleased/26059-segoe-ui-vertical.yml b/changelogs/unreleased/26059-segoe-ui-vertical.yml deleted file mode 100644 index fc3f1af5b61..00000000000 --- a/changelogs/unreleased/26059-segoe-ui-vertical.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Align Segoe UI label text -merge_request: -author: diff --git a/changelogs/unreleased/26068_tasklist_issue.yml b/changelogs/unreleased/26068_tasklist_issue.yml deleted file mode 100644 index c938351b8a7..00000000000 --- a/changelogs/unreleased/26068_tasklist_issue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don’t count tasks that are not defined as list items correctly -merge_request: 8526 -author: diff --git a/changelogs/unreleased/26117-sort-pipeline-for-commit.yml b/changelogs/unreleased/26117-sort-pipeline-for-commit.yml deleted file mode 100644 index b2f5294d380..00000000000 --- a/changelogs/unreleased/26117-sort-pipeline-for-commit.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add sorting pipeline for a commit -merge_request: 8319 -author: Takuya Noguchi diff --git a/changelogs/unreleased/26186-diff-view-plus-and-minus-signs-as-part-of-line-number.yml b/changelogs/unreleased/26186-diff-view-plus-and-minus-signs-as-part-of-line-number.yml deleted file mode 100644 index 565672917b2..00000000000 --- a/changelogs/unreleased/26186-diff-view-plus-and-minus-signs-as-part-of-line-number.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Color + and - signs in diffs to increase code legibility -merge_request: -author: diff --git a/changelogs/unreleased/26445-accessible-piplelines-buttons.yml b/changelogs/unreleased/26445-accessible-piplelines-buttons.yml deleted file mode 100644 index fb5274e5253..00000000000 --- a/changelogs/unreleased/26445-accessible-piplelines-buttons.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve button accessibility on pipelines page -merge_request: 8561 -author: diff --git a/changelogs/unreleased/26447-fix-tab-list-order.yml b/changelogs/unreleased/26447-fix-tab-list-order.yml deleted file mode 100644 index 351c53bd076..00000000000 --- a/changelogs/unreleased/26447-fix-tab-list-order.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix tab index order on branch commits list page -merge_request: -author: Ryan Harris diff --git a/changelogs/unreleased/26468-fix-users-sort-in-admin-area.yml b/changelogs/unreleased/26468-fix-users-sort-in-admin-area.yml deleted file mode 100644 index 87ae8233c4a..00000000000 --- a/changelogs/unreleased/26468-fix-users-sort-in-admin-area.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Sort by Recent Sign-in in Admin Area -merge_request: 8637 -author: Poornima M diff --git a/changelogs/unreleased/26787-add-copy-icon-hover-state.yml b/changelogs/unreleased/26787-add-copy-icon-hover-state.yml deleted file mode 100644 index 31f1812c6f8..00000000000 --- a/changelogs/unreleased/26787-add-copy-icon-hover-state.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add hover style to copy icon on commit page header -merge_request: -author: Ryan Harris diff --git a/changelogs/unreleased/26824-diff-unfold-link-is-still-visible-when-there-are-no-lines-to-unfold.yml b/changelogs/unreleased/26824-diff-unfold-link-is-still-visible-when-there-are-no-lines-to-unfold.yml deleted file mode 100644 index 182a9ae126b..00000000000 --- a/changelogs/unreleased/26824-diff-unfold-link-is-still-visible-when-there-are-no-lines-to-unfold.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: prevent diff unfolding link from appearing when there are no more lines to - show -merge_request: 8761 -author: diff --git a/changelogs/unreleased/26852-fix-slug-for-openshift.yml b/changelogs/unreleased/26852-fix-slug-for-openshift.yml deleted file mode 100644 index fb65b068b23..00000000000 --- a/changelogs/unreleased/26852-fix-slug-for-openshift.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Avoid repeated dashes in $CI_ENVIRONMENT_SLUG -merge_request: 8638 -author: diff --git a/changelogs/unreleased/26863-Remove-hover-animation-from-row-elements.yml b/changelogs/unreleased/26863-Remove-hover-animation-from-row-elements.yml deleted file mode 100644 index 8dfabf87c2a..00000000000 --- a/changelogs/unreleased/26863-Remove-hover-animation-from-row-elements.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove hover animation from row elements -merge_request: -author: diff --git a/changelogs/unreleased/26881-backup-fails-if-data-changes.yml b/changelogs/unreleased/26881-backup-fails-if-data-changes.yml deleted file mode 100644 index 00bf105560b..00000000000 --- a/changelogs/unreleased/26881-backup-fails-if-data-changes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add `copy` backup strategy to combat file changed errors -merge_request: 8728 -author: diff --git a/changelogs/unreleased/26920-hover-cursor-on-pagination-element.yml b/changelogs/unreleased/26920-hover-cursor-on-pagination-element.yml deleted file mode 100644 index ea567437ac2..00000000000 --- a/changelogs/unreleased/26920-hover-cursor-on-pagination-element.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixes hover cursor on pipeline pagenation -merge_request: 9003 -author: diff --git a/changelogs/unreleased/26947-build-status-self-link.yml b/changelogs/unreleased/26947-build-status-self-link.yml deleted file mode 100644 index 15c5821874e..00000000000 --- a/changelogs/unreleased/26947-build-status-self-link.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add link verification to badge partial in order to render a badge without a link -merge_request: 8740 -author: diff --git a/changelogs/unreleased/26982-improve-pipeline-status-icon-linking-in-widgets.yml b/changelogs/unreleased/26982-improve-pipeline-status-icon-linking-in-widgets.yml deleted file mode 100644 index c5c57af5aaf..00000000000 --- a/changelogs/unreleased/26982-improve-pipeline-status-icon-linking-in-widgets.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve pipeline status icon linking in widgets -merge_request: -author: diff --git a/changelogs/unreleased/27013-regression-in-commit-title-bar.yml b/changelogs/unreleased/27013-regression-in-commit-title-bar.yml deleted file mode 100644 index 7cb5e4b273d..00000000000 --- a/changelogs/unreleased/27013-regression-in-commit-title-bar.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix commit title bar and repository view copy clipboard button order on last commit in repository view -merge_request: -author: diff --git a/changelogs/unreleased/27014-fix-pipeline-tooltip-wrapping.yml b/changelogs/unreleased/27014-fix-pipeline-tooltip-wrapping.yml deleted file mode 100644 index f0301c849b6..00000000000 --- a/changelogs/unreleased/27014-fix-pipeline-tooltip-wrapping.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix mini-pipeline stage tooltip text wrapping -merge_request: -author: diff --git a/changelogs/unreleased/27021-line-numbers-now-in-copy-pasta-data.yml b/changelogs/unreleased/27021-line-numbers-now-in-copy-pasta-data.yml deleted file mode 100644 index b5584749098..00000000000 --- a/changelogs/unreleased/27021-line-numbers-now-in-copy-pasta-data.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent copying of line numbers in parallel diff view -merge_request: 8706 -author: diff --git a/changelogs/unreleased/27178-update-builds-link-in-project-settings.yml b/changelogs/unreleased/27178-update-builds-link-in-project-settings.yml deleted file mode 100644 index 52406bba464..00000000000 --- a/changelogs/unreleased/27178-update-builds-link-in-project-settings.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Updated builds info link on the project settings page -merge_request: -author: Ryan Harris diff --git a/changelogs/unreleased/27240-make-progress-bars-consistent.yml b/changelogs/unreleased/27240-make-progress-bars-consistent.yml deleted file mode 100644 index 3f902fb324e..00000000000 --- a/changelogs/unreleased/27240-make-progress-bars-consistent.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 27240 Make progress bars consistent -merge_request: -author: diff --git a/changelogs/unreleased/27277-small-mini-pipeline-graph-glitch-upon-hover.yml b/changelogs/unreleased/27277-small-mini-pipeline-graph-glitch-upon-hover.yml deleted file mode 100644 index 9456251025b..00000000000 --- a/changelogs/unreleased/27277-small-mini-pipeline-graph-glitch-upon-hover.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: fixed small mini pipeline graph line glitch -merge_request: 8804 -author: diff --git a/changelogs/unreleased/27291-unify-mr-diff-file-buttons.yml b/changelogs/unreleased/27291-unify-mr-diff-file-buttons.yml deleted file mode 100644 index 293aab67d39..00000000000 --- a/changelogs/unreleased/27291-unify-mr-diff-file-buttons.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Unify MR diff file button style -merge_request: 8874 -author: diff --git a/changelogs/unreleased/27321-double-separator-line-in-edit-projects-settings.yml b/changelogs/unreleased/27321-double-separator-line-in-edit-projects-settings.yml deleted file mode 100644 index 502927cd160..00000000000 --- a/changelogs/unreleased/27321-double-separator-line-in-edit-projects-settings.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Only render hr when user can't archive project. -merge_request: !8917 -author: diff --git a/changelogs/unreleased/27332-mini-pipeline-graph-with-many-stages-has-no-line-spacing-in-firefox-and-safari.yml b/changelogs/unreleased/27332-mini-pipeline-graph-with-many-stages-has-no-line-spacing-in-firefox-and-safari.yml deleted file mode 100644 index 79316abbaf7..00000000000 --- a/changelogs/unreleased/27332-mini-pipeline-graph-with-many-stages-has-no-line-spacing-in-firefox-and-safari.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix pipeline graph vertical spacing in Firefox and Safari -merge_request: 8886 -author: diff --git a/changelogs/unreleased/27352-search-label-filter-header.yml b/changelogs/unreleased/27352-search-label-filter-header.yml deleted file mode 100644 index 191b530aee8..00000000000 --- a/changelogs/unreleased/27352-search-label-filter-header.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 27352-search-label-filter-header -merge_request: -author: diff --git a/changelogs/unreleased/27395-reduce-group-activity-sql-queries-2.yml b/changelogs/unreleased/27395-reduce-group-activity-sql-queries-2.yml deleted file mode 100644 index f3ce1709518..00000000000 --- a/changelogs/unreleased/27395-reduce-group-activity-sql-queries-2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Include :author, :project, and :target in Event.with_associations -merge_request: -author: diff --git a/changelogs/unreleased/27395-reduce-group-activity-sql-queries.yml b/changelogs/unreleased/27395-reduce-group-activity-sql-queries.yml deleted file mode 100644 index 3f6d922f2a0..00000000000 --- a/changelogs/unreleased/27395-reduce-group-activity-sql-queries.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't instantiate AR objects in Event.in_projects -merge_request: -author: diff --git a/changelogs/unreleased/27484-environment-show-name.yml b/changelogs/unreleased/27484-environment-show-name.yml deleted file mode 100644 index dc400d65006..00000000000 --- a/changelogs/unreleased/27484-environment-show-name.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't capitalize environment name in show page -merge_request: -author: diff --git a/changelogs/unreleased/27488-fix-jwt-version.yml b/changelogs/unreleased/27488-fix-jwt-version.yml deleted file mode 100644 index 5135ff0fd60..00000000000 --- a/changelogs/unreleased/27488-fix-jwt-version.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update and pin the `jwt` gem to ~> 1.5.6 -merge_request: -author: diff --git a/changelogs/unreleased/27494-environment-list-column-headers.yml b/changelogs/unreleased/27494-environment-list-column-headers.yml deleted file mode 100644 index 798c01f3238..00000000000 --- a/changelogs/unreleased/27494-environment-list-column-headers.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Edited the column header for the environments list from created to updated and added created to environments detail page colum header titles -merge_request: -author: diff --git a/changelogs/unreleased/27602-fix-avatar-border-flicker-mention-dropdown.yml b/changelogs/unreleased/27602-fix-avatar-border-flicker-mention-dropdown.yml deleted file mode 100644 index a5bb37ec8a9..00000000000 --- a/changelogs/unreleased/27602-fix-avatar-border-flicker-mention-dropdown.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixes flickering of avatar border in mention dropdown -merge_request: 8950 -author: diff --git a/changelogs/unreleased/27632_fix_mr_widget_url.yml b/changelogs/unreleased/27632_fix_mr_widget_url.yml deleted file mode 100644 index 958621a43a1..00000000000 --- a/changelogs/unreleased/27632_fix_mr_widget_url.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix MR widget url -merge_request: 8989 -author: diff --git a/changelogs/unreleased/27639-emoji-panel-under-the-side-panel-in-the-merge-request.yml b/changelogs/unreleased/27639-emoji-panel-under-the-side-panel-in-the-merge-request.yml deleted file mode 100644 index 0531ef2c038..00000000000 --- a/changelogs/unreleased/27639-emoji-panel-under-the-side-panel-in-the-merge-request.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Layer award emoji dropdown over the right sidebar -merge_request: 9004 -author: diff --git a/changelogs/unreleased/27656-doc-ci-enable-ci.yml b/changelogs/unreleased/27656-doc-ci-enable-ci.yml deleted file mode 100644 index e6315d683d4..00000000000 --- a/changelogs/unreleased/27656-doc-ci-enable-ci.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update doc for enabling or disabling GitLab CI -merge_request: 8965 -author: Takuya Noguchi diff --git a/changelogs/unreleased/27774-text-color-contrast-is-barely-readable-for-pipelines-visualization-graph-page-with-roboto-fonts.yml b/changelogs/unreleased/27774-text-color-contrast-is-barely-readable-for-pipelines-visualization-graph-page-with-roboto-fonts.yml deleted file mode 100644 index aa89d9f9850..00000000000 --- a/changelogs/unreleased/27774-text-color-contrast-is-barely-readable-for-pipelines-visualization-graph-page-with-roboto-fonts.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Give ci status text on pipeline graph a better font-weight -merge_request: -author: diff --git a/changelogs/unreleased/27822-default-bulk-assign-labels.yml b/changelogs/unreleased/27822-default-bulk-assign-labels.yml deleted file mode 100644 index ee2431869f0..00000000000 --- a/changelogs/unreleased/27822-default-bulk-assign-labels.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add default labels to bulk assign dropdowns -merge_request: -author: diff --git a/changelogs/unreleased/27873-when-a-commit-appears-in-several-projects-commit-comments-are-shared-across-projects.yml b/changelogs/unreleased/27873-when-a-commit-appears-in-several-projects-commit-comments-are-shared-across-projects.yml deleted file mode 100644 index 89e2bdc69bc..00000000000 --- a/changelogs/unreleased/27873-when-a-commit-appears-in-several-projects-commit-comments-are-shared-across-projects.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Only return target project's comments for a commit -merge_request: -author: diff --git a/changelogs/unreleased/27880-pipelines-table-not-showing-commit-branch.yml b/changelogs/unreleased/27880-pipelines-table-not-showing-commit-branch.yml deleted file mode 100644 index 4251754618b..00000000000 --- a/changelogs/unreleased/27880-pipelines-table-not-showing-commit-branch.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixes Pipelines table is not showing branch name for commit -merge_request: -author: diff --git a/changelogs/unreleased/27883-autocomplete-seems-to-not-trigger-when-at-character-is-part-of-an-autocompleted-text.yml b/changelogs/unreleased/27883-autocomplete-seems-to-not-trigger-when-at-character-is-part-of-an-autocompleted-text.yml deleted file mode 100644 index 52b7e96682d..00000000000 --- a/changelogs/unreleased/27883-autocomplete-seems-to-not-trigger-when-at-character-is-part-of-an-autocompleted-text.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Trigger autocomplete after selecting a slash command -merge_request: 9117 -author: diff --git a/changelogs/unreleased/27922-cmd-click-todo-doesn-t-work.yml b/changelogs/unreleased/27922-cmd-click-todo-doesn-t-work.yml deleted file mode 100644 index 79a54429ee8..00000000000 --- a/changelogs/unreleased/27922-cmd-click-todo-doesn-t-work.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix regression where cmd-click stopped working for todos and merge request - tabs -merge_request: -author: diff --git a/changelogs/unreleased/27925-fix-mr-stray-pipelines-api-request.yml b/changelogs/unreleased/27925-fix-mr-stray-pipelines-api-request.yml deleted file mode 100644 index f7bdb62b7f3..00000000000 --- a/changelogs/unreleased/27925-fix-mr-stray-pipelines-api-request.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix stray pipelines API request when showing MR -merge_request: -author: diff --git a/changelogs/unreleased/27932-merge-request-pipelines-displays-json.yml b/changelogs/unreleased/27932-merge-request-pipelines-displays-json.yml deleted file mode 100644 index b7505e28401..00000000000 --- a/changelogs/unreleased/27932-merge-request-pipelines-displays-json.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix Merge request pipelines displays JSON -merge_request: -author: diff --git a/changelogs/unreleased/27939-fix-current-build-arrow.yml b/changelogs/unreleased/27939-fix-current-build-arrow.yml deleted file mode 100644 index 280ab090f2c..00000000000 --- a/changelogs/unreleased/27939-fix-current-build-arrow.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix current build arrow indicator -merge_request: -author: diff --git a/changelogs/unreleased/27943-contribution-list-on-profile-page-is-aligned-right.yml b/changelogs/unreleased/27943-contribution-list-on-profile-page-is-aligned-right.yml deleted file mode 100644 index fcbd48b0357..00000000000 --- a/changelogs/unreleased/27943-contribution-list-on-profile-page-is-aligned-right.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix contribution activity alignment -merge_request: -author: diff --git a/changelogs/unreleased/27947-missing-margin-between-loading-icon-and-text-in-merge-request-widget.yml b/changelogs/unreleased/27947-missing-margin-between-loading-icon-and-text-in-merge-request-widget.yml deleted file mode 100644 index 1dfabd3813b..00000000000 --- a/changelogs/unreleased/27947-missing-margin-between-loading-icon-and-text-in-merge-request-widget.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add space between text and loading icon in Megre Request Widget -merge_request: 9119 -author: diff --git a/changelogs/unreleased/27955-mr-notification-use-pipeline-language.yml b/changelogs/unreleased/27955-mr-notification-use-pipeline-language.yml deleted file mode 100644 index d9f78db4bec..00000000000 --- a/changelogs/unreleased/27955-mr-notification-use-pipeline-language.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Show Pipeline(not Job) in MR desktop notification -merge_request: -author: diff --git a/changelogs/unreleased/27963-tooltips-jobs.yml b/changelogs/unreleased/27963-tooltips-jobs.yml deleted file mode 100644 index ba418d86433..00000000000 --- a/changelogs/unreleased/27963-tooltips-jobs.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix tooltips in mini pipeline graph -merge_request: -author: diff --git a/changelogs/unreleased/27966-branch-ref-switcher-input-filter-broken.yml b/changelogs/unreleased/27966-branch-ref-switcher-input-filter-broken.yml deleted file mode 100644 index 6fa13395a7d..00000000000 --- a/changelogs/unreleased/27966-branch-ref-switcher-input-filter-broken.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Display loading indicator when filtering ref switcher dropdown -merge_request: -author: diff --git a/changelogs/unreleased/27987-skipped-pipeline-mr-graph.yml b/changelogs/unreleased/27987-skipped-pipeline-mr-graph.yml deleted file mode 100644 index e4287d6276c..00000000000 --- a/changelogs/unreleased/27987-skipped-pipeline-mr-graph.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Show pipeline graph in MR widget if there are any stages -merge_request: -author: diff --git a/changelogs/unreleased/27991-success-with-warnings-caret.yml b/changelogs/unreleased/27991-success-with-warnings-caret.yml deleted file mode 100644 index 703d34a5ede..00000000000 --- a/changelogs/unreleased/27991-success-with-warnings-caret.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix icon colors in merge request widget mini graph -merge_request: -author: diff --git a/changelogs/unreleased/28029-improve-blockquote-formatting-on-emails.yml b/changelogs/unreleased/28029-improve-blockquote-formatting-on-emails.yml deleted file mode 100644 index be2a0afbc52..00000000000 --- a/changelogs/unreleased/28029-improve-blockquote-formatting-on-emails.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve blockquote formatting in notification emails -merge_request: -author: diff --git a/changelogs/unreleased/28032-tooltips-file-name.yml b/changelogs/unreleased/28032-tooltips-file-name.yml deleted file mode 100644 index 9fe11e7c2b6..00000000000 --- a/changelogs/unreleased/28032-tooltips-file-name.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Adds container to tooltip in order to make it work with overflow:hidden in - parent element -merge_request: -author: diff --git a/changelogs/unreleased/28059-add-pagination-to-admin-abuse-reports.yml b/changelogs/unreleased/28059-add-pagination-to-admin-abuse-reports.yml deleted file mode 100644 index 1b2e678bbed..00000000000 --- a/changelogs/unreleased/28059-add-pagination-to-admin-abuse-reports.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Restore pagination to admin abuse reports -merge_request: -author: diff --git a/changelogs/unreleased/395-fix-notification-when-group-set-to-watch.yml b/changelogs/unreleased/395-fix-notification-when-group-set-to-watch.yml deleted file mode 100644 index 11d1f55172b..00000000000 --- a/changelogs/unreleased/395-fix-notification-when-group-set-to-watch.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix notifications when set at group level -merge_request: 6813 -author: Alexandre Maia diff --git a/changelogs/unreleased/8-15-stable.yml b/changelogs/unreleased/8-15-stable.yml deleted file mode 100644 index 75502e139e7..00000000000 --- a/changelogs/unreleased/8-15-stable.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Ensure export files are removed after a namespace is deleted -merge_request: -author: diff --git a/changelogs/unreleased/8082-permalink-to-file.yml b/changelogs/unreleased/8082-permalink-to-file.yml deleted file mode 100644 index 136d2108c63..00000000000 --- a/changelogs/unreleased/8082-permalink-to-file.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add `y` keyboard shortcut to move to file permalink -merge_request: -author: diff --git a/changelogs/unreleased/9-0-api-changes.yml b/changelogs/unreleased/9-0-api-changes.yml deleted file mode 100644 index 2f0f1887257..00000000000 --- a/changelogs/unreleased/9-0-api-changes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove deprecated MR and Issue endpoints and preserve V3 namespace -merge_request: 8967 -author: diff --git a/changelogs/unreleased/Add-a-shash-command-for-target-merge-request-branch.yml b/changelogs/unreleased/Add-a-shash-command-for-target-merge-request-branch.yml deleted file mode 100644 index 9fd6ea5bc52..00000000000 --- a/changelogs/unreleased/Add-a-shash-command-for-target-merge-request-branch.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Adds /target_branch slash command functionality for merge requests -merge_request: -author: YarNayar diff --git a/changelogs/unreleased/add_project_update_hook.yml b/changelogs/unreleased/add_project_update_hook.yml deleted file mode 100644 index 915c9538843..00000000000 --- a/changelogs/unreleased/add_project_update_hook.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add system hook for when a project is updated (other than rename/transfer) -merge_request: 5711 -author: Tommy Beadle diff --git a/changelogs/unreleased/api-remove-snippets-expires-at.yml b/changelogs/unreleased/api-remove-snippets-expires-at.yml deleted file mode 100644 index 67603bfab3b..00000000000 --- a/changelogs/unreleased/api-remove-snippets-expires-at.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'API: Remove deprecated ''expires_at'' from project snippets' -merge_request: 8723 -author: Robert Schilling diff --git a/changelogs/unreleased/babel-all-the-things.yml b/changelogs/unreleased/babel-all-the-things.yml deleted file mode 100644 index fda1c3bd562..00000000000 --- a/changelogs/unreleased/babel-all-the-things.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: use babel to transpile all non-vendor javascript assets regardless of file - extension -merge_request: 8988 -author: diff --git a/changelogs/unreleased/broken_iamge_when_doing_offline_update_check-help_page-.yml b/changelogs/unreleased/broken_iamge_when_doing_offline_update_check-help_page-.yml deleted file mode 100644 index 77750b55e7e..00000000000 --- a/changelogs/unreleased/broken_iamge_when_doing_offline_update_check-help_page-.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Hide version check image if there is no internet connection -merge_request: 8355 -author: Ken Ding diff --git a/changelogs/unreleased/change_queue_weight.yml b/changelogs/unreleased/change_queue_weight.yml deleted file mode 100644 index e4c650e8f79..00000000000 --- a/changelogs/unreleased/change_queue_weight.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Increase process_commit queue weight from 2 to 3 -merge_request: 9326 -author: blackst0ne diff --git a/changelogs/unreleased/clipboard-button-commit-sha.yml b/changelogs/unreleased/clipboard-button-commit-sha.yml deleted file mode 100644 index 6aa4a5664e7..00000000000 --- a/changelogs/unreleased/clipboard-button-commit-sha.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 'Copy commit SHA to clipboard' -merge_request: 8547 diff --git a/changelogs/unreleased/contribution-calendar-scroll.yml b/changelogs/unreleased/contribution-calendar-scroll.yml deleted file mode 100644 index a504d59e61c..00000000000 --- a/changelogs/unreleased/contribution-calendar-scroll.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: contribution calendar scrolls from right to left -merge_request: -author: diff --git a/changelogs/unreleased/cop-gem-fetcher.yml b/changelogs/unreleased/cop-gem-fetcher.yml deleted file mode 100644 index 506815a5b54..00000000000 --- a/changelogs/unreleased/cop-gem-fetcher.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Cop for gem fetched from a git source -merge_request: 8856 -author: Adam Pahlevi diff --git a/changelogs/unreleased/copy-as-md.yml b/changelogs/unreleased/copy-as-md.yml deleted file mode 100644 index 637e9dc36e2..00000000000 --- a/changelogs/unreleased/copy-as-md.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Copying a rendered issue/comment will paste into GFM textareas as actual GFM -merge_request: -author: diff --git a/changelogs/unreleased/disable-autologin-on-email-confirmation-links.yml b/changelogs/unreleased/disable-autologin-on-email-confirmation-links.yml deleted file mode 100644 index 6dd0d748001..00000000000 --- a/changelogs/unreleased/disable-autologin-on-email-confirmation-links.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disable automatic login after clicking email confirmation links -merge_request: 7472 -author: diff --git a/changelogs/unreleased/display-project-id.yml b/changelogs/unreleased/display-project-id.yml deleted file mode 100644 index 8705ed28400..00000000000 --- a/changelogs/unreleased/display-project-id.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Display project ID in project settings -merge_request: 8572 -author: winniehell diff --git a/changelogs/unreleased/document-how-to-vue.yml b/changelogs/unreleased/document-how-to-vue.yml deleted file mode 100644 index 863e41b6413..00000000000 --- a/changelogs/unreleased/document-how-to-vue.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Adds documentation for how to use Vue.js -merge_request: 8866 -author: diff --git a/changelogs/unreleased/dynamic-todos-fixture.yml b/changelogs/unreleased/dynamic-todos-fixture.yml deleted file mode 100644 index 580bc729e3c..00000000000 --- a/changelogs/unreleased/dynamic-todos-fixture.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replace static fixture for right_sidebar_spec.js -merge_request: 9211 -author: winniehell diff --git a/changelogs/unreleased/dz-nested-groups-improvements-2.yml b/changelogs/unreleased/dz-nested-groups-improvements-2.yml deleted file mode 100644 index 8e4eb7f1fff..00000000000 --- a/changelogs/unreleased/dz-nested-groups-improvements-2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add read-only full_path and full_name attributes to Group API -merge_request: 8827 -author: diff --git a/changelogs/unreleased/empty-selection-reply-shortcut.yml b/changelogs/unreleased/empty-selection-reply-shortcut.yml deleted file mode 100644 index 5a42c98a800..00000000000 --- a/changelogs/unreleased/empty-selection-reply-shortcut.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Change the reply shortcut to focus the field even without a selection. -merge_request: 8873 -author: Brian Hall diff --git a/changelogs/unreleased/fe-commit-mr-pipelines.yml b/changelogs/unreleased/fe-commit-mr-pipelines.yml deleted file mode 100644 index b5cc6bbf8b6..00000000000 --- a/changelogs/unreleased/fe-commit-mr-pipelines.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use vue.js Pipelines table in commit and merge request view -merge_request: 8844 -author: diff --git a/changelogs/unreleased/feature-success-warning-icons-in-stages-builds.yml b/changelogs/unreleased/feature-success-warning-icons-in-stages-builds.yml deleted file mode 100644 index 5fba0332881..00000000000 --- a/changelogs/unreleased/feature-success-warning-icons-in-stages-builds.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Use warning icon in mini-graph if stage passed conditionally -merge_request: 8503 -author: diff --git a/changelogs/unreleased/fix-27479.yml b/changelogs/unreleased/fix-27479.yml deleted file mode 100644 index cc72a830695..00000000000 --- a/changelogs/unreleased/fix-27479.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove new branch button for confidential issues -merge_request: -author: diff --git a/changelogs/unreleased/fix-api-mr-permissions.yml b/changelogs/unreleased/fix-api-mr-permissions.yml deleted file mode 100644 index 33b677b1f29..00000000000 --- a/changelogs/unreleased/fix-api-mr-permissions.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't allow project guests to subscribe to merge requests through the API -merge_request: -author: Robert Schilling diff --git a/changelogs/unreleased/fix-ar-connection-leaks.yml b/changelogs/unreleased/fix-ar-connection-leaks.yml deleted file mode 100644 index 9da715560ad..00000000000 --- a/changelogs/unreleased/fix-ar-connection-leaks.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't connect in Gitlab::Database.adapter_name -merge_request: -author: diff --git a/changelogs/unreleased/fix-ci-build-policy.yml b/changelogs/unreleased/fix-ci-build-policy.yml deleted file mode 100644 index 26003713ed4..00000000000 --- a/changelogs/unreleased/fix-ci-build-policy.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve build policy and access abilities -merge_request: 8711 -author: diff --git a/changelogs/unreleased/fix-deleting-project-again.yml b/changelogs/unreleased/fix-deleting-project-again.yml deleted file mode 100644 index e13215f22a7..00000000000 --- a/changelogs/unreleased/fix-deleting-project-again.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix deleting projects with pipelines and builds -merge_request: 8960 -author: diff --git a/changelogs/unreleased/fix-depr-warn.yml b/changelogs/unreleased/fix-depr-warn.yml deleted file mode 100644 index 61817027720..00000000000 --- a/changelogs/unreleased/fix-depr-warn.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: resolve deprecation warnings -merge_request: 8855 -author: Adam Pahlevi diff --git a/changelogs/unreleased/fix-gb-backwards-compatibility-coverage-ci-yml.yml b/changelogs/unreleased/fix-gb-backwards-compatibility-coverage-ci-yml.yml deleted file mode 100644 index df7e3776700..00000000000 --- a/changelogs/unreleased/fix-gb-backwards-compatibility-coverage-ci-yml.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Preserve backward compatibility CI/CD and disallow setting `coverage` regexp in global context -merge_request: 8981 -author: diff --git a/changelogs/unreleased/fix-guest-access-posting-to-notes.yml b/changelogs/unreleased/fix-guest-access-posting-to-notes.yml deleted file mode 100644 index 81377c0c6f0..00000000000 --- a/changelogs/unreleased/fix-guest-access-posting-to-notes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent users from creating notes on resources they can't access -merge_request: -author: diff --git a/changelogs/unreleased/fix-import-encrypt-atts.yml b/changelogs/unreleased/fix-import-encrypt-atts.yml deleted file mode 100644 index e34d895570b..00000000000 --- a/changelogs/unreleased/fix-import-encrypt-atts.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Ignore encrypted attributes in Import/Export -merge_request: -author: diff --git a/changelogs/unreleased/fix-import-group-members.yml b/changelogs/unreleased/fix-import-group-members.yml deleted file mode 100644 index fe580af31b3..00000000000 --- a/changelogs/unreleased/fix-import-group-members.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add ability to export project inherited group members to Import/Export -merge_request: 8923 -author: diff --git a/changelogs/unreleased/fix-job-to-pipeline-renaming.yml b/changelogs/unreleased/fix-job-to-pipeline-renaming.yml deleted file mode 100644 index d5f34b4b25d..00000000000 --- a/changelogs/unreleased/fix-job-to-pipeline-renaming.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix job to pipeline renaming -merge_request: 9147 -author: diff --git a/changelogs/unreleased/fix-references-header-parsing.yml b/changelogs/unreleased/fix-references-header-parsing.yml deleted file mode 100644 index b927279cdf4..00000000000 --- a/changelogs/unreleased/fix-references-header-parsing.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix reply by email without sub-addressing for some clients from - Microsoft and Apple -merge_request: 8620 -author: diff --git a/changelogs/unreleased/fix-scroll-test.yml b/changelogs/unreleased/fix-scroll-test.yml deleted file mode 100644 index e98ac755b88..00000000000 --- a/changelogs/unreleased/fix-scroll-test.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Change rspec test to guarantee window is resized before visiting page -merge_request: -author: diff --git a/changelogs/unreleased/fix-users-deleting-public-deployment-keys.yml b/changelogs/unreleased/fix-users-deleting-public-deployment-keys.yml deleted file mode 100644 index c9edd1de86c..00000000000 --- a/changelogs/unreleased/fix-users-deleting-public-deployment-keys.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Prevent users from deleting system deploy keys via the project deploy key API -merge_request: -author: diff --git a/changelogs/unreleased/fix_broken_diff_discussions.yml b/changelogs/unreleased/fix_broken_diff_discussions.yml deleted file mode 100644 index 4551212759f..00000000000 --- a/changelogs/unreleased/fix_broken_diff_discussions.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make MR-review-discussions more reliable -merge_request: -author: diff --git a/changelogs/unreleased/fix_sidekiq_concurrency_warning_message_in_admin_background_job_page.yml b/changelogs/unreleased/fix_sidekiq_concurrency_warning_message_in_admin_background_job_page.yml deleted file mode 100644 index e09d03bb608..00000000000 --- a/changelogs/unreleased/fix_sidekiq_concurrency_warning_message_in_admin_background_job_page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: fix incorrect sidekiq concurrency count in admin background page -merge_request: -author: wendy0402 diff --git a/changelogs/unreleased/fwn-to-find-by-full-path.yml b/changelogs/unreleased/fwn-to-find-by-full-path.yml deleted file mode 100644 index 1427e4e7624..00000000000 --- a/changelogs/unreleased/fwn-to-find-by-full-path.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: replace `find_with_namespace` with `find_by_full_path` -merge_request: 8949 -author: Adam Pahlevi diff --git a/changelogs/unreleased/get-rid-of-water-from-notification_service_spec-to-make-it-DRY.yml b/changelogs/unreleased/get-rid-of-water-from-notification_service_spec-to-make-it-DRY.yml deleted file mode 100644 index f60417d185e..00000000000 --- a/changelogs/unreleased/get-rid-of-water-from-notification_service_spec-to-make-it-DRY.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make notification_service spec DRYer by making test reusable -merge_request: -author: YarNayar diff --git a/changelogs/unreleased/git_to_html_redirection.yml b/changelogs/unreleased/git_to_html_redirection.yml deleted file mode 100644 index b2959c02c07..00000000000 --- a/changelogs/unreleased/git_to_html_redirection.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Redirect http://someproject.git to http://someproject -merge_request: -author: blackst0ne diff --git a/changelogs/unreleased/go-go-gadget-webpack.yml b/changelogs/unreleased/go-go-gadget-webpack.yml deleted file mode 100644 index 7f372ccb428..00000000000 --- a/changelogs/unreleased/go-go-gadget-webpack.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: use webpack to bundle frontend assets and use karma for frontend testing -merge_request: 7288 -author: diff --git a/changelogs/unreleased/group-label-sidebar-link.yml b/changelogs/unreleased/group-label-sidebar-link.yml deleted file mode 100644 index c11c2d4ede1..00000000000 --- a/changelogs/unreleased/group-label-sidebar-link.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed group label links in issue/merge request sidebar -merge_request: -author: diff --git a/changelogs/unreleased/hardcode-title-system-note.yml b/changelogs/unreleased/hardcode-title-system-note.yml deleted file mode 100644 index 1b0a63efa51..00000000000 --- a/changelogs/unreleased/hardcode-title-system-note.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Ensure autogenerated title does not cause failing spec -merge_request: 8963 -author: brian m. carlson diff --git a/changelogs/unreleased/improve-ci-example-php-doc.yml b/changelogs/unreleased/improve-ci-example-php-doc.yml deleted file mode 100644 index 39a85e3d261..00000000000 --- a/changelogs/unreleased/improve-ci-example-php-doc.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Changed composer installer script in the CI PHP example doc -merge_request: 4342 -author: Jeffrey Cafferata diff --git a/changelogs/unreleased/improve-handleLocationHash-tests.yml b/changelogs/unreleased/improve-handleLocationHash-tests.yml deleted file mode 100644 index 8ae3dfe079c..00000000000 --- a/changelogs/unreleased/improve-handleLocationHash-tests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Improve gl.utils.handleLocationHash tests -merge_request: -author: diff --git a/changelogs/unreleased/issuable-sidebar-bug.yml b/changelogs/unreleased/issuable-sidebar-bug.yml deleted file mode 100644 index 4086292eb89..00000000000 --- a/changelogs/unreleased/issuable-sidebar-bug.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed Issuable sidebar not closing on smaller/mobile sized screens -merge_request: -author: diff --git a/changelogs/unreleased/issue-20428.yml b/changelogs/unreleased/issue-20428.yml deleted file mode 100644 index 60da1c14702..00000000000 --- a/changelogs/unreleased/issue-20428.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add ability to define a coverage regex in the .gitlab-ci.yml -merge_request: 7447 -author: Leandro Camargo diff --git a/changelogs/unreleased/issue-sidebar-empty-assignee.yml b/changelogs/unreleased/issue-sidebar-empty-assignee.yml deleted file mode 100644 index 263af75b9e9..00000000000 --- a/changelogs/unreleased/issue-sidebar-empty-assignee.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Resets assignee dropdown when sidebar is open -merge_request: -author: diff --git a/changelogs/unreleased/issue_19262.yml b/changelogs/unreleased/issue_19262.yml deleted file mode 100644 index 5dea1493f23..00000000000 --- a/changelogs/unreleased/issue_19262.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Disallow system notes for closed issuables -merge_request: -author: diff --git a/changelogs/unreleased/issue_23317.yml b/changelogs/unreleased/issue_23317.yml deleted file mode 100644 index 788ae159f5e..00000000000 --- a/changelogs/unreleased/issue_23317.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix timezone on issue boards due date -merge_request: -author: diff --git a/changelogs/unreleased/issue_27211.yml b/changelogs/unreleased/issue_27211.yml deleted file mode 100644 index ad48fec5d85..00000000000 --- a/changelogs/unreleased/issue_27211.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove unused js response from refs controller -merge_request: -author: diff --git a/changelogs/unreleased/jej-pages-picked-from-ee.yml b/changelogs/unreleased/jej-pages-picked-from-ee.yml deleted file mode 100644 index ee4a43a93db..00000000000 --- a/changelogs/unreleased/jej-pages-picked-from-ee.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Added GitLab Pages to CE -merge_request: 8463 -author: diff --git a/changelogs/unreleased/label-promotion.yml b/changelogs/unreleased/label-promotion.yml deleted file mode 100644 index 2ab997bf420..00000000000 --- a/changelogs/unreleased/label-promotion.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Project labels can now be promoted to group labels" -merge_request: 7242 -author: Olaf Tomalka diff --git a/changelogs/unreleased/lfs-noauth-public-repo.yml b/changelogs/unreleased/lfs-noauth-public-repo.yml deleted file mode 100644 index 60f62d7691b..00000000000 --- a/changelogs/unreleased/lfs-noauth-public-repo.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Support unauthenticated LFS object downloads for public projects -merge_request: 8824 -author: Ben Boeckel diff --git a/changelogs/unreleased/markdown-plantuml.yml b/changelogs/unreleased/markdown-plantuml.yml deleted file mode 100644 index c855f0cbcf7..00000000000 --- a/changelogs/unreleased/markdown-plantuml.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: PlantUML support for Markdown -merge_request: 8588 -author: Horacio Sanson diff --git a/changelogs/unreleased/merge-request-tabs-fixture.yml b/changelogs/unreleased/merge-request-tabs-fixture.yml deleted file mode 100644 index 289cd7b604a..00000000000 --- a/changelogs/unreleased/merge-request-tabs-fixture.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Replace static fixture for merge_request_tabs_spec.js -merge_request: 9172 -author: winniehell diff --git a/changelogs/unreleased/misalinged-discussion-with-no-avatar-26854.yml b/changelogs/unreleased/misalinged-discussion-with-no-avatar-26854.yml deleted file mode 100644 index f32b3aea3c8..00000000000 --- a/changelogs/unreleased/misalinged-discussion-with-no-avatar-26854.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: adds avatar for discussion note -merge_request: 8734 -author: diff --git a/changelogs/unreleased/mr-tabs-container-offset.yml b/changelogs/unreleased/mr-tabs-container-offset.yml deleted file mode 100644 index c5df8abfcf2..00000000000 --- a/changelogs/unreleased/mr-tabs-container-offset.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed merge requests tab extra margin when fixed to window -merge_request: -author: diff --git a/changelogs/unreleased/newline-eslint-rule.yml b/changelogs/unreleased/newline-eslint-rule.yml deleted file mode 100644 index 5ce080b6912..00000000000 --- a/changelogs/unreleased/newline-eslint-rule.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Flag multiple empty lines in eslint, fix offenses. -merge_request: 8137 -author: diff --git a/changelogs/unreleased/no-sidebar-on-action-btn-click.yml b/changelogs/unreleased/no-sidebar-on-action-btn-click.yml deleted file mode 100644 index 09e0b3a12d8..00000000000 --- a/changelogs/unreleased/no-sidebar-on-action-btn-click.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: dismiss sidebar on repo buttons click -merge_request: 8798 -author: Adam Pahlevi diff --git a/changelogs/unreleased/no_project_notes.yml b/changelogs/unreleased/no_project_notes.yml deleted file mode 100644 index 6106c027360..00000000000 --- a/changelogs/unreleased/no_project_notes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Support notes when a project is not specified (personal snippet notes) -merge_request: 8468 -author: diff --git a/changelogs/unreleased/pms-lowercase-system-notes.yml b/changelogs/unreleased/pms-lowercase-system-notes.yml deleted file mode 100644 index c2fa1a7fad0..00000000000 --- a/changelogs/unreleased/pms-lowercase-system-notes.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Make all system notes lowercase -merge_request: 8807 -author: diff --git a/changelogs/unreleased/redesign-searchbar-admin-project-26794.yml b/changelogs/unreleased/redesign-searchbar-admin-project-26794.yml deleted file mode 100644 index 547a7c6755c..00000000000 --- a/changelogs/unreleased/redesign-searchbar-admin-project-26794.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Redesign searchbar in admin project list -merge_request: 8776 -author: diff --git a/changelogs/unreleased/redirect-to-commit-when-only-commit-found.yml b/changelogs/unreleased/redirect-to-commit-when-only-commit-found.yml deleted file mode 100644 index e0f7e11b6d1..00000000000 --- a/changelogs/unreleased/redirect-to-commit-when-only-commit-found.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: 'Search feature: redirects to commit page if query is commit sha and only commit - found' -merge_request: 8028 -author: YarNayar diff --git a/changelogs/unreleased/relative-url-assets.yml b/changelogs/unreleased/relative-url-assets.yml deleted file mode 100644 index 0877664aca4..00000000000 --- a/changelogs/unreleased/relative-url-assets.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: allow relative url change without recompiling frontend assets -merge_request: 8831 -author: diff --git a/changelogs/unreleased/remove-deploy-key-endpoint.yml b/changelogs/unreleased/remove-deploy-key-endpoint.yml deleted file mode 100644 index 3ff69adb4d3..00000000000 --- a/changelogs/unreleased/remove-deploy-key-endpoint.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: 'API: Remove /projects/:id/keys/.. endpoints' -merge_request: 8716 -author: Robert Schilling diff --git a/changelogs/unreleased/remove-issue-and-mr-counts-from-labels-page.yml b/changelogs/unreleased/remove-issue-and-mr-counts-from-labels-page.yml deleted file mode 100644 index b75b4644ba3..00000000000 --- a/changelogs/unreleased/remove-issue-and-mr-counts-from-labels-page.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove issue and MR counts from labels index -merge_request: -author: diff --git a/changelogs/unreleased/route-map.yml b/changelogs/unreleased/route-map.yml deleted file mode 100644 index 9b6df0c54af..00000000000 --- a/changelogs/unreleased/route-map.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add 'View on [env]' link to blobs and individual files in diffs -merge_request: 8867 -author: diff --git a/changelogs/unreleased/rs-warden-blocked-users.yml b/changelogs/unreleased/rs-warden-blocked-users.yml deleted file mode 100644 index c0c23fb6f11..00000000000 --- a/changelogs/unreleased/rs-warden-blocked-users.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Don't perform Devise trackable updates on blocked User records -merge_request: 8915 -author: diff --git a/changelogs/unreleased/sh-add-index-to-ci-trigger-requests.yml b/changelogs/unreleased/sh-add-index-to-ci-trigger-requests.yml deleted file mode 100644 index bab76812a17..00000000000 --- a/changelogs/unreleased/sh-add-index-to-ci-trigger-requests.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add index to ci_trigger_requests for commit_id -merge_request: -author: diff --git a/changelogs/unreleased/sh-add-labels-index.yml b/changelogs/unreleased/sh-add-labels-index.yml deleted file mode 100644 index b948a75081c..00000000000 --- a/changelogs/unreleased/sh-add-labels-index.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Add indices to improve loading of labels page -merge_request: -author: diff --git a/changelogs/unreleased/slash-commands-typo.yml b/changelogs/unreleased/slash-commands-typo.yml deleted file mode 100644 index e6ffb94bd08..00000000000 --- a/changelogs/unreleased/slash-commands-typo.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed "substract" typo on /help/user/project/slash_commands -merge_request: 8976 -author: Jason Aquino diff --git a/changelogs/unreleased/small-screen-fullscreen-button.yml b/changelogs/unreleased/small-screen-fullscreen-button.yml deleted file mode 100644 index f4c269bc473..00000000000 --- a/changelogs/unreleased/small-screen-fullscreen-button.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Display fullscreen button on small screens -merge_request: 5302 -author: winniehell diff --git a/changelogs/unreleased/snippets-search-performance.yml b/changelogs/unreleased/snippets-search-performance.yml deleted file mode 100644 index 2895478abfd..00000000000 --- a/changelogs/unreleased/snippets-search-performance.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Reduced query count for snippet search -merge_request: -author: diff --git a/changelogs/unreleased/tc-only-mr-button-if-allowed.yml b/changelogs/unreleased/tc-only-mr-button-if-allowed.yml deleted file mode 100644 index a7f5dcb560c..00000000000 --- a/changelogs/unreleased/tc-only-mr-button-if-allowed.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Only show Merge Request button when user can create a MR -merge_request: 8639 -author: diff --git a/changelogs/unreleased/terminal-max-session-time.yml b/changelogs/unreleased/terminal-max-session-time.yml deleted file mode 100644 index db1e66770d1..00000000000 --- a/changelogs/unreleased/terminal-max-session-time.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Introduce maximum session time for terminal websocket connection -merge_request: 8413 -author: diff --git a/changelogs/unreleased/updated-pages-0-3-1.yml b/changelogs/unreleased/updated-pages-0-3-1.yml deleted file mode 100644 index 8622b823c86..00000000000 --- a/changelogs/unreleased/updated-pages-0-3-1.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Update GitLab Pages to v0.3.1 -merge_request: -author: diff --git a/changelogs/unreleased/upgrade-babel-v6.yml b/changelogs/unreleased/upgrade-babel-v6.yml deleted file mode 100644 index 55f9b3e407c..00000000000 --- a/changelogs/unreleased/upgrade-babel-v6.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: upgrade babel 5.8.x to babel 6.22.x -merge_request: 9072 -author: diff --git a/changelogs/unreleased/upgrade-omniauth.yml b/changelogs/unreleased/upgrade-omniauth.yml deleted file mode 100644 index 7e0334566dc..00000000000 --- a/changelogs/unreleased/upgrade-omniauth.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Upgrade omniauth gem to 1.3.2 -merge_request: -author: diff --git a/changelogs/unreleased/upgrade-webpack-v2-2.yml b/changelogs/unreleased/upgrade-webpack-v2-2.yml deleted file mode 100644 index 6a49859d68c..00000000000 --- a/changelogs/unreleased/upgrade-webpack-v2-2.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: upgrade to webpack v2.2 -merge_request: 9078 -author: diff --git a/changelogs/unreleased/wip-mr-from-commits.yml b/changelogs/unreleased/wip-mr-from-commits.yml deleted file mode 100644 index 0083798be08..00000000000 --- a/changelogs/unreleased/wip-mr-from-commits.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Mark MR as WIP when pushing WIP commits -merge_request: 8124 -author: Jurre Stender @jurre diff --git a/changelogs/unreleased/zj-format-chat-messages.yml b/changelogs/unreleased/zj-format-chat-messages.yml deleted file mode 100644 index 2494884f5c9..00000000000 --- a/changelogs/unreleased/zj-format-chat-messages.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Reformat messages ChatOps -merge_request: 8528 -author: diff --git a/changelogs/unreleased/zj-remove-deprecated-ci-service.yml b/changelogs/unreleased/zj-remove-deprecated-ci-service.yml deleted file mode 100644 index 044f4ae627d..00000000000 --- a/changelogs/unreleased/zj-remove-deprecated-ci-service.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove deprecated GitlabCiService -merge_request: -author: diff --git a/changelogs/unreleased/zj-requeue-pending-delete.yml b/changelogs/unreleased/zj-requeue-pending-delete.yml deleted file mode 100644 index 464c5948f8c..00000000000 --- a/changelogs/unreleased/zj-requeue-pending-delete.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Requeue pending deletion projects -merge_request: -author: From 12ac140a119b6802ebdfc3c596264f7fc292d4df Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Wed, 22 Feb 2017 11:36:02 -0300 Subject: [PATCH 152/247] Update VERSION to 8.18.0-pre --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5c99c061a47..64de8316674 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.17.0-pre +8.18.0-pre From cf521c95761540f273804d23a1150dbb0af4e63b Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Wed, 22 Feb 2017 15:43:01 +0100 Subject: [PATCH 153/247] Allow setting of a custom connection pool host This allows you to set a custom host when calling Gitlab::Database.create_connection_pool. This is necessary for load balancing as in this case we want to inherit all settings except for the hostname. --- lib/gitlab/database.rb | 7 ++++++- spec/lib/gitlab/database_spec.rb | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index a47d7e98a62..d160cadc2d0 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -79,11 +79,16 @@ module Gitlab end end - def self.create_connection_pool(pool_size) + # pool_size - The size of the DB pool. + # host - An optional host name to use instead of the default one. + def self.create_connection_pool(pool_size, host = nil) # See activerecord-4.2.7.1/lib/active_record/connection_adapters/connection_specification.rb env = Rails.env original_config = ActiveRecord::Base.configurations + env_config = original_config[env].merge('pool' => pool_size) + env_config['host'] = host if host + config = original_config.merge(env => env_config) spec = diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index f01c42aff91..edd01d032c8 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -119,9 +119,24 @@ describe Gitlab::Database, lib: true do it 'creates a new connection pool with specific pool size' do pool = described_class.create_connection_pool(5) - expect(pool) - .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) - expect(pool.spec.config[:pool]).to eq(5) + begin + expect(pool) + .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) + + expect(pool.spec.config[:pool]).to eq(5) + ensure + pool.disconnect! + end + end + + it 'allows setting of a custom hostname' do + pool = described_class.create_connection_pool(5, '127.0.0.1') + + begin + expect(pool.spec.config[:host]).to eq('127.0.0.1') + ensure + pool.disconnect! + end end end From 27e4b9050caedcc8808dec683246051526eb5450 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 16:24:55 +0100 Subject: [PATCH 154/247] Add links to previous/next articles --- doc/pages/getting_started_part_one.md | 9 ++++----- doc/pages/getting_started_part_three.md | 7 +++---- doc/pages/getting_started_part_two.md | 7 +++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/doc/pages/getting_started_part_one.md b/doc/pages/getting_started_part_one.md index 8a98afeeb86..8ae4779108c 100644 --- a/doc/pages/getting_started_part_one.md +++ b/doc/pages/getting_started_part_one.md @@ -26,7 +26,7 @@ GitLab Pages only supports static websites, meaning, your output files must be H To create your static site, you can either hardcode in HTML, CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/) to simplify your code and build the static site for you, which is highly recommendable and much faster than hardcoding. -#### Further Reading +--- - Read through this technical overview on [Static versus Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) - Understand [how modern Static Site Generators work](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) and what you can add to your static site @@ -158,7 +158,6 @@ Now that you hopefully understand why you need all of this, it's simple: > Note: **do not** open certificates or encryption keys in regular text editors. Always use code editors (such as Sublime Text, Atom, Dreamweaver, Brackets, etc). -## Further Reading - -- Read through GitLab Pages from A to Z _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ -- Read through GitLab Pages from A to Z _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ +||| +|:--|--:| +||[**Part 2: Quick start guide - Setting up GitLab Pages →**](getting_started_part_two.md)| diff --git a/doc/pages/getting_started_part_three.md b/doc/pages/getting_started_part_three.md index 0bc6a601a09..28fb7f08bdf 100644 --- a/doc/pages/getting_started_part_three.md +++ b/doc/pages/getting_started_part_three.md @@ -273,7 +273,6 @@ What you can do with GitLab CI is pretty much up to your creativity. Once you ge - On this blog post, we go through the process of [pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) to deploy this website you're looking at, docs.gitlab.com. - On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/). -## Further Reading - -- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ -- Read through _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ +||| +|:--|--:| +|[**← Part 1: Static sites, domains, DNS records, and SSL/TLS certificates**](getting_started_part_one.md)|[**Part 2: Quick start guide - Setting up GitLab Pages →**](getting_started_part_two.md)| diff --git a/doc/pages/getting_started_part_two.md b/doc/pages/getting_started_part_two.md index b1d58b5b024..19e393f2623 100644 --- a/doc/pages/getting_started_part_two.md +++ b/doc/pages/getting_started_part_two.md @@ -106,7 +106,6 @@ On the contrary, if you deploy your website after forking one of our [default ex baseurl: "" ``` -## Further Reading - -- Read through _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ -- Read through _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ +||| +|:--|--:| +|[**← Part 1: Static sites, domains, DNS records, and SSL/TLS certificates**](getting_started_part_one.md)|[**Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages →**](getting_started_part_three.md)| From 9f56b57b55307fc3fa25737b89806564259354f8 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Tue, 21 Feb 2017 16:47:25 -0300 Subject: [PATCH 155/247] Present GitLab version for each V3 to V4 API change on v3_to_v4.md --- .../28458-present-gitlab-version-for-v4-changes-on-docs.yml | 4 ++++ doc/api/v3_to_v4.md | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml diff --git a/changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml b/changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml new file mode 100644 index 00000000000..dbbe8a19204 --- /dev/null +++ b/changelogs/unreleased/28458-present-gitlab-version-for-v4-changes-on-docs.yml @@ -0,0 +1,4 @@ +--- +title: Present GitLab version for each V3 to V4 API change on v3_to_v4.md +merge_request: +author: diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index 59d7f0634b2..d99a52e4dc2 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -4,7 +4,7 @@ Our V4 API version is currently available as *Beta*! It means that V3 will still be supported and remain unchanged for now, but be aware that the following changes are in V4: -### Changes +### 8.17 - Removed `/projects/:search` (use: `/projects?search=x`) - `iid` filter has been removed from `projects/:id/issues` @@ -12,6 +12,9 @@ changes are in V4: - Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`) - Project snippets do not return deprecated field `expires_at` - Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`) + +### 9.0 + - Status 409 returned for POST `project/:id/members` when a member already exists - Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar` - Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix) From eeb567d1b1b1988e9d3e07f1a6d7fa23ce7d06e3 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Wed, 22 Feb 2017 10:24:38 +0100 Subject: [PATCH 156/247] Add Merge Request link to the v3 to v4 documentation Similar to changelog, mention the Merge Request id & link for each change. --- doc/api/v3_to_v4.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md index d99a52e4dc2..1fea3d3407f 100644 --- a/doc/api/v3_to_v4.md +++ b/doc/api/v3_to_v4.md @@ -6,18 +6,18 @@ changes are in V4: ### 8.17 -- Removed `/projects/:search` (use: `/projects?search=x`) -- `iid` filter has been removed from `projects/:id/issues` -- `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids` -- Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`) -- Project snippets do not return deprecated field `expires_at` -- Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`) +- Removed `/projects/:search` (use: `/projects?search=x`) [!8877](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8877) +- `iid` filter has been removed from `projects/:id/issues` [!8967](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8967) +- `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793) +- Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`) [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793) +- Project snippets do not return deprecated field `expires_at` [!8723](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8723) +- Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`) [!8716](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8716) ### 9.0 -- Status 409 returned for POST `project/:id/members` when a member already exists -- Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar` -- Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix) +- Status 409 returned for POST `project/:id/members` when a member already exists [!9093](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9093) +- Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar` [!9328](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9328) +- Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix) [!8853](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8853) - `/licences` - `/licences/:key` - `/gitignores` @@ -26,17 +26,17 @@ changes are in V4: - `/gitignores/:key` - `/gitlab_ci_ymls/:key` - `/dockerfiles/:key` -- Moved `/projects/fork/:id` to `/projects/:id/fork` -- Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` -- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters -- Return pagination headers for all endpoints that return an array -- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead -- Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` -- Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. -- Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) -- Renamed param `branch_name` to `branch` on the following endpoints +- Moved `/projects/fork/:id` to `/projects/:id/fork` [!8940](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8940) +- Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` [!9410](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9410) +- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962) +- Return pagination headers for all endpoints that return an array [!8606](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8606) +- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead [!9366](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9366) +- Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` [!9371](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9371) +- Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. [!9325](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9325) +- Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) [!8849](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8849) +- Renamed param `branch_name` to `branch` on the following endpoints [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936) - POST `:id/repository/branches` - POST `:id/repository/commits` - POST/PUT/DELETE `:id/repository/files` -- Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response - +- Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936) +- Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736) From e5e7fb55ed325bedd8aab4fb2c07d514bc920f95 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 12:59:01 -0300 Subject: [PATCH 157/247] remove link to unfinished video --- doc/pages/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/pages/index.md b/doc/pages/index.md index fe328748668..242fdf3147f 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -13,7 +13,6 @@ - [Part 1: Static sites, domains, DNS records, and SSL/TLS certificates](getting_started_part_one.md) - [Part 2: Quick start guide - Setting up GitLab Pages](getting_started_part_two.md) - Video tutorial: [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg) - - Video tutorial: [How to publish a website with GitLab Pages on GitLab.com: from scratch](#LINK) - [Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md) - Secure GitLab Pages custom domain with SSL/TLS certificates - [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) From 23e43ec5b18b35e6fe92adcbf3ca3d9a51a210b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 22 Feb 2017 16:00:49 +0000 Subject: [PATCH 158/247] Improve `Gitlab::EeCompatCheck` by using the `git apply --3way` flag This should solve 99% of the false-positive of the `ee_compat_check` job. --- lib/gitlab/ee_compat_check.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/ee_compat_check.rb b/lib/gitlab/ee_compat_check.rb index c8e36d8ff4a..e0fdf3f3d64 100644 --- a/lib/gitlab/ee_compat_check.rb +++ b/lib/gitlab/ee_compat_check.rb @@ -119,7 +119,7 @@ module Gitlab step("Reseting to latest master", %w[git reset --hard origin/master]) step("Checking if #{patch_path} applies cleanly to EE/master") - output, status = Gitlab::Popen.popen(%W[git apply --check #{patch_path}]) + output, status = Gitlab::Popen.popen(%W[git apply --check --3way #{patch_path}]) unless status.zero? failed_files = output.lines.reduce([]) do |memo, line| From 3dcc2ca593ecc989265f3ed9487220836e91619e Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:06:44 -0300 Subject: [PATCH 159/247] fix spelling, add intermediate cert link --- doc/pages/getting_started_part_one.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/pages/getting_started_part_one.md b/doc/pages/getting_started_part_one.md index 8ae4779108c..c3bee1f164c 100644 --- a/doc/pages/getting_started_part_one.md +++ b/doc/pages/getting_started_part_one.md @@ -135,7 +135,7 @@ Regardless the CA you choose, the steps to add your certificate to your Pages pr #### What do you need 1. A PEM certificate -1. An intermediary certificate +1. An intermediate certificate 1. A public key ![Pages project - adding certificates](img/add_certificate_to_pages.png) @@ -145,7 +145,7 @@ These fields are found under your **Project**'s **Settings** > **Pages** > **New #### What's what? - A PEM certificate is the certificate generated by the CA, which needs to be added to the field **Certificate (PEM)**. -- An [intermediary certificate][] \(aka "root certificate"\) is the part of the encryption keychain that identifies the CA. Usually it's combined with the PEM certificate, but there are some cases in which you need to add them manually. [CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) are one of these cases. +- An [intermediate certificate](https://en.wikipedia.org/wiki/Intermediate_certificate_authority) \(aka "root certificate"\) is the part of the encryption keychain that identifies the CA. Usually it's combined with the PEM certificate, but there are some cases in which you need to add them manually. [CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) are one of these cases. - A public key is an encrypted key which validates your PEM against your domain. #### Now what? @@ -153,7 +153,7 @@ These fields are found under your **Project**'s **Settings** > **Pages** > **New Now that you hopefully understand why you need all of this, it's simple: - Your PEM certificate needs to be added to the first field -- If your certificate is missing its intermediary, copy and paste the root certificate (usually available from your CA website) and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/), just jumping a line between them. +- If your certificate is missing its intermediate, copy and paste the root certificate (usually available from your CA website) and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/), just jumping a line between them. - Copy your public key and paste it in the last field > Note: **do not** open certificates or encryption keys in regular text editors. Always use code editors (such as Sublime Text, Atom, Dreamweaver, Brackets, etc). From 20009ca9a29cc1011c7235aae652592d77318d98 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:07:14 -0300 Subject: [PATCH 160/247] typo --- doc/pages/getting_started_part_three.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages/getting_started_part_three.md b/doc/pages/getting_started_part_three.md index 28fb7f08bdf..10ae3abb9e5 100644 --- a/doc/pages/getting_started_part_three.md +++ b/doc/pages/getting_started_part_three.md @@ -187,7 +187,7 @@ test: The `test` job is running on the stage `test`, Jekyll will build the site in a directory called `test`, and this job will affect all the branches except `master`. -The best benefit of applying _stages_ to different _jobs_ is that every job in the same stage builds in parallel. So, if your web app needs more than one test before being deployed, you can run all your test at the same time, it's not necessary to wait on test to finish to run the other. Of course, this is just a brief introduction of GitLab CI and GitLab Runner, which are tools much more powerful than that. This is what you need to be able to create and tweak your builds for your GitLab Pages site. +The best benefit of applying _stages_ to different _jobs_ is that every job in the same stage builds in parallel. So, if your web app needs more than one test before being deployed, you can run all your test at the same time, it's not necessary to wait one test to finish to run the other. Of course, this is just a brief introduction of GitLab CI and GitLab Runner, which are tools much more powerful than that. This is what you need to be able to create and tweak your builds for your GitLab Pages site. #### Before Script From 94255217e9c595579b83deb0a1dd5b7bca9572c5 Mon Sep 17 00:00:00 2001 From: wendy0402 Date: Sun, 9 Oct 2016 21:17:14 +0700 Subject: [PATCH 161/247] on branch deletion show loading icon and disabled the button after user click delete branch, there is no processing indication, and user can click many times till. It seems flaw in UX. this will fix it fix bug in branch deletion link --- .../javascripts/ajax_loading_spinner.js | 35 +++++++++++ app/assets/javascripts/dispatcher.js.es6 | 3 + app/views/projects/branches/_branch.html.haml | 2 +- changelogs/unreleased/branch_deletion.yml | 4 ++ spec/javascripts/ajax_loading_spinner_spec.js | 58 +++++++++++++++++++ .../fixtures/ajax_loading_spinner.html.haml | 2 + 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/ajax_loading_spinner.js create mode 100644 changelogs/unreleased/branch_deletion.yml create mode 100644 spec/javascripts/ajax_loading_spinner_spec.js create mode 100644 spec/javascripts/fixtures/ajax_loading_spinner.html.haml diff --git a/app/assets/javascripts/ajax_loading_spinner.js b/app/assets/javascripts/ajax_loading_spinner.js new file mode 100644 index 00000000000..38a8317dbd7 --- /dev/null +++ b/app/assets/javascripts/ajax_loading_spinner.js @@ -0,0 +1,35 @@ +class AjaxLoadingSpinner { + static init() { + const $elements = $('.js-ajax-loading-spinner'); + + $elements.on('ajax:beforeSend', AjaxLoadingSpinner.ajaxBeforeSend); + $elements.on('ajax:complete', AjaxLoadingSpinner.ajaxComplete); + } + + static ajaxBeforeSend(e) { + e.target.setAttribute('disabled', ''); + const iconElement = e.target.querySelector('i'); + // get first fa- icon + const originalIcon = iconElement.className.match(/(fa-)([^\s]+)/g).first(); + iconElement.dataset.icon = originalIcon; + AjaxLoadingSpinner.toggleLoadingIcon(iconElement); + $(e.target).off('ajax:beforeSend', AjaxLoadingSpinner.ajaxBeforeSend); + } + + static ajaxComplete(e) { + e.target.removeAttribute('disabled'); + const iconElement = e.target.querySelector('i'); + AjaxLoadingSpinner.toggleLoadingIcon(iconElement); + $(e.target).off('ajax:complete', AjaxLoadingSpinner.ajaxComplete); + } + + static toggleLoadingIcon(iconElement) { + const classList = iconElement.classList; + classList.toggle(iconElement.dataset.icon); + classList.toggle('fa-spinner'); + classList.toggle('fa-spin'); + } +} + +window.gl = window.gl || {}; +gl.AjaxLoadingSpinner = AjaxLoadingSpinner; diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 index 45aa6050aed..56610544f63 100644 --- a/app/assets/javascripts/dispatcher.js.es6 +++ b/app/assets/javascripts/dispatcher.js.es6 @@ -108,6 +108,9 @@ const ShortcutsBlob = require('./shortcuts_blob'); case 'projects:compare:show': new gl.Diff(); break; + case 'projects:branches:index': + gl.AjaxLoadingSpinner.init(); + break; case 'projects:issues:new': case 'projects:issues:edit': shortcut_handler = new ShortcutsNavigation(); diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index 19ffe73a08d..ae63f8184df 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -31,7 +31,7 @@ - if can?(current_user, :push_code, @project) = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), - class: "btn btn-remove remove-row #{can_remove_branch?(@project, branch.name) ? '' : 'disabled'}", + class: "btn btn-remove remove-row js-ajax-loading-spinner #{can_remove_branch?(@project, branch.name) ? '' : 'disabled'}", method: :delete, data: { confirm: "Deleting the '#{branch.name}' branch cannot be undone. Are you sure?" }, remote: true, diff --git a/changelogs/unreleased/branch_deletion.yml b/changelogs/unreleased/branch_deletion.yml new file mode 100644 index 00000000000..dbc9265a1fb --- /dev/null +++ b/changelogs/unreleased/branch_deletion.yml @@ -0,0 +1,4 @@ +--- +title: on branch deletion show loading icon and disabled the button +merge_request: 6761 +author: wendy0402 diff --git a/spec/javascripts/ajax_loading_spinner_spec.js b/spec/javascripts/ajax_loading_spinner_spec.js new file mode 100644 index 00000000000..a68bccb16f4 --- /dev/null +++ b/spec/javascripts/ajax_loading_spinner_spec.js @@ -0,0 +1,58 @@ +require('~/extensions/array'); +require('jquery'); +require('jquery-ujs'); +require('~/ajax_loading_spinner'); + +describe('Ajax Loading Spinner', () => { + const fixtureTemplate = 'static/ajax_loading_spinner.html.raw'; + preloadFixtures(fixtureTemplate); + + beforeEach(() => { + loadFixtures(fixtureTemplate); + gl.AjaxLoadingSpinner.init(); + }); + + it('change current icon with spinner icon and disable link while waiting ajax response', (done) => { + spyOn(jQuery, 'ajax').and.callFake((req) => { + const xhr = new XMLHttpRequest(); + const ajaxLoadingSpinner = document.querySelector('.js-ajax-loading-spinner'); + const icon = ajaxLoadingSpinner.querySelector('i'); + + req.beforeSend(xhr, { dataType: 'text/html' }); + + expect(icon).not.toHaveClass('fa-trash-o'); + expect(icon).toHaveClass('fa-spinner'); + expect(icon).toHaveClass('fa-spin'); + expect(icon.dataset.icon).toEqual('fa-trash-o'); + expect(ajaxLoadingSpinner.getAttribute('disabled')).toEqual(''); + + req.complete({}); + + done(); + const deferred = $.Deferred(); + return deferred.promise(); + }); + document.querySelector('.js-ajax-loading-spinner').click(); + }); + + it('use original icon again and enabled the link after complete the ajax request', (done) => { + spyOn(jQuery, 'ajax').and.callFake((req) => { + const xhr = new XMLHttpRequest(); + const ajaxLoadingSpinner = document.querySelector('.js-ajax-loading-spinner'); + + req.beforeSend(xhr, { dataType: 'text/html' }); + req.complete({}); + + const icon = ajaxLoadingSpinner.querySelector('i'); + expect(icon).toHaveClass('fa-trash-o'); + expect(icon).not.toHaveClass('fa-spinner'); + expect(icon).not.toHaveClass('fa-spin'); + expect(ajaxLoadingSpinner.getAttribute('disabled')).toEqual(null); + + done(); + const deferred = $.Deferred(); + return deferred.promise(); + }); + document.querySelector('.js-ajax-loading-spinner').click(); + }); +}); diff --git a/spec/javascripts/fixtures/ajax_loading_spinner.html.haml b/spec/javascripts/fixtures/ajax_loading_spinner.html.haml new file mode 100644 index 00000000000..09d8c9df3b2 --- /dev/null +++ b/spec/javascripts/fixtures/ajax_loading_spinner.html.haml @@ -0,0 +1,2 @@ +%a.js-ajax-loading-spinner{href: "http://goesnowhere.nothing/whereami", data: {remote: true}} + %i.fa.fa-trash-o From f9079cb5ae43fa2cae0346c8dfd77b1e817fb78f Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:16:54 -0300 Subject: [PATCH 162/247] wrap text - part 1 - [ci skip] --- doc/pages/getting_started_part_one.md | 179 ++++++++++++++++++++------ 1 file changed, 141 insertions(+), 38 deletions(-) diff --git a/doc/pages/getting_started_part_one.md b/doc/pages/getting_started_part_one.md index c3bee1f164c..57fc5d21b96 100644 --- a/doc/pages/getting_started_part_one.md +++ b/doc/pages/getting_started_part_one.md @@ -10,11 +10,17 @@ ---- -This is a comprehensive guide, made for those who want to publish a website with GitLab Pages but aren't familiar with the entire process involved. +This is a comprehensive guide, made for those who want to +publish a website with GitLab Pages but aren't familiar with +the entire process involved. -To **enable** GitLab Pages for GitLab CE (Community Edition) and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s). +To **enable** GitLab Pages for GitLab CE (Community Edition) +and GitLab EE (Enterprise Edition), please read the +[admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), +and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s). -> For this guide, we assume you already have GitLab Pages server up and running for your GitLab instance. +> For this guide, we assume you already have GitLab Pages +server up and running for your GitLab instance. ## What you need to know before getting started @@ -22,9 +28,13 @@ Before we begin, let's understand a few concepts first. ### Static Sites -GitLab Pages only supports static websites, meaning, your output files must be HTML, CSS, and JavaScript only. +GitLab Pages only supports static websites, meaning, +your output files must be HTML, CSS, and JavaScript only. -To create your static site, you can either hardcode in HTML, CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/) to simplify your code and build the static site for you, which is highly recommendable and much faster than hardcoding. +To create your static site, you can either hardcode in HTML, +CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/) +to simplify your code and build the static site for you, +which is highly recommendable and much faster than hardcoding. --- @@ -35,37 +45,72 @@ To create your static site, you can either hardcode in HTML, CSS, and JS, or use ### GitLab Pages Domain -If you set up a GitLab Pages project on GitLab.com, it will automatically be accessible under a [subdomain of `.pages.io`](https://docs.gitlab.com/ce/user/project/pages/). The `` is defined by your username on GitLab.com, or the group name you created this project under. +If you set up a GitLab Pages project on GitLab.com, +it will automatically be accessible under a +[subdomain of `.pages.io`](https://docs.gitlab.com/ce/user/project/pages/). +The `` is defined by your username on GitLab.com, +or the group name you created this project under. -> Note: If you use your own GitLab instance to deploy your site with GitLab Pages, check with your sysadmin what's your Pages wildcard domain. This guide is valid for any GitLab instance, you just need to replace Pages wildcard domain on GitLab.com (`*.gitlab.io`) with your own. +> Note: If you use your own GitLab instance to deploy your +site with GitLab Pages, check with your sysadmin what's your +Pages wildcard domain. This guide is valid for any GitLab instance, +you just need to replace Pages wildcard domain on GitLab.com +(`*.gitlab.io`) with your own. #### Practical examples **Project Websites:** -- You created a project called `blog` under your username `john`, therefore your project URL is `https://gitlab.com/john/blog/`. Once you enable GitLab Pages for this project, and build your site, it will be available under `https://john.gitlab.io/blog/`. -- You created a group for all your websites called `websites`, and a project within this group is called `blog`. Your project URL is `https://gitlab.com/websites/blog/`. Once you enable GitLab Pages for this project, the site will live under `https://websites.gitlab.io/blog/`. +- You created a project called `blog` under your username `john`, +therefore your project URL is `https://gitlab.com/john/blog/`. +Once you enable GitLab Pages for this project, and build your site, +it will be available under `https://john.gitlab.io/blog/`. +- You created a group for all your websites called `websites`, +and a project within this group is called `blog`. Your project +URL is `https://gitlab.com/websites/blog/`. Once you enable +GitLab Pages for this project, the site will live under +`https://websites.gitlab.io/blog/`. **User and Group Websites:** -- Under your username, `john`, you created a project called `john.gitlab.io`. Your project URL will be `https://gitlab.com/john/john.gitlab.io`. Once you enable GitLab Pages for your project, your website will be published under `https://john.gitlab.io`. -- Under your group `websites`, you created a project called `websites.gitlab.io`. your project's URL will be `https://gitlab.com/websites/websites.gitlab.io`. Once you enable GitLab Pages for your project, your website will be published under `https://websites.gitlab.io`. +- Under your username, `john`, you created a project called +`john.gitlab.io`. Your project URL will be `https://gitlab.com/john/john.gitlab.io`. +Once you enable GitLab Pages for your project, your website +will be published under `https://john.gitlab.io`. +- Under your group `websites`, you created a project called +`websites.gitlab.io`. your project's URL will be `https://gitlab.com/websites/websites.gitlab.io`. Once you enable GitLab Pages for your project, +your website will be published under `https://websites.gitlab.io`. **General example:** -- On GitLab.com, a project site will always be available under `https://namespace.gitlab.io/project-name` -- On GitLab.com, a user or group website will be available under `https://namespace.gitlab.io/` -- On your GitLab instance, replace `gitlab.io` above with your Pages server domain. Ask your sysadmin for this information. +- On GitLab.com, a project site will always be available under +`https://namespace.gitlab.io/project-name` +- On GitLab.com, a user or group website will be available under +`https://namespace.gitlab.io/` +- On your GitLab instance, replace `gitlab.io` above with your +Pages server domain. Ask your sysadmin for this information. ### DNS Records -A Domain Name System (DNS) web service routes visitors to websites by translating domain names (such as `www.example.com`) into the numeric IP addresses (such as `192.0.2.1`) that computers use to connect to each other. +A Domain Name System (DNS) web service routes visitors to websites +by translating domain names (such as `www.example.com`) into the +numeric IP addresses (such as `192.0.2.1`) that computers use to +connect to each other. -A DNS record is created to point a (sub)domain to a certain location, which can be an IP address or another domain. In case you want to use GitLab Pages with your own (sub)domain, you need to access your domain's registrar control panel to add a DNS record pointing it back to your GitLab Pages site. +A DNS record is created to point a (sub)domain to a certain location, +which can be an IP address or another domain. In case you want to use +GitLab Pages with your own (sub)domain, you need to access your domain's +registrar control panel to add a DNS record pointing it back to your +GitLab Pages site. -Note that **how to** add DNS records depends on which server your domain is hosted on. Every control panel has its own place to do it. If you are not an admin of your domain, and don't have access to your registrar, you'll need to ask for the technical support of your hosting service to do it for you. +Note that **how to** add DNS records depends on which server your domain +is hosted on. Every control panel has its own place to do it. If you are +not an admin of your domain, and don't have access to your registrar, +you'll need to ask for the technical support of your hosting service +to do it for you. -To help you out, we've gathered some instructions on how to do that for the most popular hosting services: +To help you out, we've gathered some instructions on how to do that +for the most popular hosting services: - [Amazon](http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-configure-route53.html) - [Bluehost](https://my.bluehost.com/cgi/help/559) @@ -78,11 +123,19 @@ To help you out, we've gathered some instructions on how to do that for the most - [Media Temple](https://mediatemple.net/community/products/dv/204403794/how-can-i-change-the-dns-records-for-my-domain) - [Microsoft](https://msdn.microsoft.com/en-us/library/bb727018.aspx) -If your hosting service is not listed above, you can just try to search the web for "how to add dns record on ". +If your hosting service is not listed above, you can just try to +search the web for "how to add dns record on ". #### DNS A record -In case you want to point a root domain (`example.com`) to your GitLab Pages site, deployed to `namespace.gitlab.io`, you need to log into your domain's admin control panel and add a DNS `A` record pointing your domain to Pages' server IP address. For projects on GitLab.com, this IP is `104.208.235.32`. For projects leaving in other GitLab instances (CE or EE), please contact your sysadmin asking for this information (which IP address is Pages server running on your instance). +In case you want to point a root domain (`example.com`) to your +GitLab Pages site, deployed to `namespace.gitlab.io`, you need to +log into your domain's admin control panel and add a DNS `A` record +pointing your domain to Pages' server IP address. For projects on +GitLab.com, this IP is `104.208.235.32`. For projects leaving in +other GitLab instances (CE or EE), please contact your sysadmin +asking for this information (which IP address is Pages server +running on your instance). **Practical Example:** @@ -90,9 +143,15 @@ In case you want to point a root domain (`example.com`) to your GitLab Pages sit #### DNS CNAME record -In case you want to point a subdomain (`hello-world.example.com`) to your GitLab Pages site initially deployed to `namespace.gitlab.io`, you need to log into your domain's admin control panel and add a DNS `CNAME` record pointing your subdomain to your website URL (`namespace.gitlab.io`) address. +In case you want to point a subdomain (`hello-world.example.com`) +to your GitLab Pages site initially deployed to `namespace.gitlab.io`, +you need to log into your domain's admin control panel and add a DNS +`CNAME` record pointing your subdomain to your website URL +(`namespace.gitlab.io`) address. -Notice that, despite it's a user or project website, the `CNAME` should point to your Pages domain (`namespace.gitlab.io`), without any `/project-name`. +Notice that, despite it's a user or project website, the `CNAME` +should point to your Pages domain (`namespace.gitlab.io`), +without any `/project-name`. **Practical Example:** @@ -107,30 +166,61 @@ Notice that, despite it's a user or project website, the `CNAME` should point to > **Notes**: > -> - **Do not** use a CNAME record if you want to point your `domain.com` to your GitLab Pages site. Use an `A` record instead. -> - **Do not** add any special chars after the default Pages domain. E.g., **do not** point your `subdomain.domain.com` to `namespace.gitlab.io.` or `namespace.gitlab.io/`. +> - **Do not** use a CNAME record if you want to point your +`domain.com` to your GitLab Pages site. Use an `A` record instead. +> - **Do not** add any special chars after the default Pages +domain. E.g., **do not** point your `subdomain.domain.com` to +`namespace.gitlab.io.` or `namespace.gitlab.io/`. ### SSL/TLS Certificates -Every GitLab Pages project on GitLab.com will be available under HTTPS for the default Pages domain (`*.gitlab.io`). Once you set up your Pages project with your custom (sub)domain, if you want it secured by HTTPS, you will have to issue a certificate for that (sub)domain and install it on your project. +Every GitLab Pages project on GitLab.com will be available under +HTTPS for the default Pages domain (`*.gitlab.io`). Once you set +up your Pages project with your custom (sub)domain, if you want +it secured by HTTPS, you will have to issue a certificate for that +(sub)domain and install it on your project. -> Note: certificates are NOT required to add to your custom (sub)domain on your GitLab Pages project, though they are highly recommendable. +> Note: certificates are NOT required to add to your custom +(sub)domain on your GitLab Pages project, though they are +highly recommendable. -The importance of having any website securely served under HTTPS is explained on the introductory section of the blog post [Secure GitLab Pages with StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/#https-a-quick-overview). +The importance of having any website securely served under HTTPS +is explained on the introductory section of the blog post +[Secure GitLab Pages with StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/#https-a-quick-overview). -The reason why certificates are so important is that they encrypt the connection between the **client** (you, me, your visitors) and the **server** (where you site lives), through a keychain of authentications and validations. +The reason why certificates are so important is that they encrypt +the connection between the **client** (you, me, your visitors) +and the **server** (where you site lives), through a keychain of +authentications and validations. ### Issuing Certificates -GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by [Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority) and self-signed certificates. Of course, [you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate), for security reasons and for having browsers trusting your site's certificate. +GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by +[Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority) +and self-signed certificates. Of course, +[you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate), +for security reasons and for having browsers trusting your +site's certificate. -There are several different kinds of certificates, each one with certain security level. A static personal website will not require the same security level as an online banking web app, for instance. There are a couple Certificate Authorities that offer free certificates, aiming to make the internet more secure to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/), which issues certificates trusted by most of browsers, it's open source, and free to use. Please read through this tutorial to understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/). +There are several different kinds of certificates, each one +with certain security level. A static personal website will +not require the same security level as an online banking web app, +for instance. There are a couple Certificate Authorities that +offer free certificates, aiming to make the internet more secure +to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/), +which issues certificates trusted by most of browsers, it's open +source, and free to use. Please read through this tutorial to +understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/). -With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/), which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/). Their certs are valid up to 15 years. Read through the tutorial on [how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/). +With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/), +which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/). +Their certs are valid up to 15 years. Read through the tutorial on +[how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/). ### Adding certificates to your project -Regardless the CA you choose, the steps to add your certificate to your Pages project are the same. +Regardless the CA you choose, the steps to add your certificate to +your Pages project are the same. #### What do you need @@ -144,19 +234,32 @@ These fields are found under your **Project**'s **Settings** > **Pages** > **New #### What's what? -- A PEM certificate is the certificate generated by the CA, which needs to be added to the field **Certificate (PEM)**. -- An [intermediate certificate](https://en.wikipedia.org/wiki/Intermediate_certificate_authority) \(aka "root certificate"\) is the part of the encryption keychain that identifies the CA. Usually it's combined with the PEM certificate, but there are some cases in which you need to add them manually. [CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) are one of these cases. -- A public key is an encrypted key which validates your PEM against your domain. +- A PEM certificate is the certificate generated by the CA, +which needs to be added to the field **Certificate (PEM)**. +- An [intermediate certificate](https://en.wikipedia.org/wiki/Intermediate_certificate_authority) (aka "root certificate") is +the part of the encryption keychain that identifies the CA. +Usually it's combined with the PEM certificate, but there are +some cases in which you need to add them manually. +[CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) +are one of these cases. +- A public key is an encrypted key which validates +your PEM against your domain. #### Now what? -Now that you hopefully understand why you need all of this, it's simple: +Now that you hopefully understand why you need all +of this, it's simple: - Your PEM certificate needs to be added to the first field -- If your certificate is missing its intermediate, copy and paste the root certificate (usually available from your CA website) and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/), just jumping a line between them. +- If your certificate is missing its intermediate, copy +and paste the root certificate (usually available from your CA website) +and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/), +just jumping a line between them. - Copy your public key and paste it in the last field -> Note: **do not** open certificates or encryption keys in regular text editors. Always use code editors (such as Sublime Text, Atom, Dreamweaver, Brackets, etc). +> Note: **do not** open certificates or encryption keys in +regular text editors. Always use code editors (such as +Sublime Text, Atom, Dreamweaver, Brackets, etc). ||| |:--|--:| From ce5420ab8fde3b147d3e2e1068b6b6313883a224 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:22:14 -0300 Subject: [PATCH 163/247] fix link --- doc/pages/getting_started_part_two.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages/getting_started_part_two.md b/doc/pages/getting_started_part_two.md index 19e393f2623..f211b0a3363 100644 --- a/doc/pages/getting_started_part_two.md +++ b/doc/pages/getting_started_part_two.md @@ -70,7 +70,7 @@ To turn a **project website** forked from the Pages group into a **user/group** #### Create a Project from Scratch -1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, click **New project**, and name it considering the [examples above](#practical-examples). +1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, click **New project**, and name it considering the [pratical examples](getting_started_part_one.md#practical-examples). 1. Clone it to your local computer, add your website files to your project, add, commit and push to GitLab. 1. From the your **Project**'s page, click **Set up CI**: From 08e9d2b5c8fdf813e88a0594d6f96a4767661f68 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:27:02 -0300 Subject: [PATCH 164/247] wrapping text - part 2 [ci skip] --- doc/pages/getting_started_part_two.md | 79 +++++++++++++++++++++------ 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/doc/pages/getting_started_part_two.md b/doc/pages/getting_started_part_two.md index f211b0a3363..15f628ac1fb 100644 --- a/doc/pages/getting_started_part_two.md +++ b/doc/pages/getting_started_part_two.md @@ -12,7 +12,9 @@ ## Setting Up GitLab Pages -For a complete step-by-step tutorial, please read the blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain what do you need and why do you need them. +For a complete step-by-step tutorial, please read the +blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain +what do you need and why do you need them. @@ -20,17 +22,20 @@ For a complete step-by-step tutorial, please read the blog post [Hosting on GitL 1. A project 1. A configuration file (`.gitlab-ci.yml`) to deploy your site -1. A specific `job` called `pages` in the configuration file that will make GitLab aware that you are deploying a GitLab Pages website +1. A specific `job` called `pages` in the configuration file +that will make GitLab aware that you are deploying a GitLab Pages website #### Optional Features 1. A custom domain or subdomain 1. A DNS pointing your (sub)domain to your Pages site - 1. **Optional**: an SSL/TLS certificate so your custom domain is accessible under HTTPS. + 1. **Optional**: an SSL/TLS certificate so your custom + domain is accessible under HTTPS. ### Project -Your GitLab Pages project is a regular project created the same way you do for the other ones. To get started with GitLab Pages, you have two ways: +Your GitLab Pages project is a regular project created the +same way you do for the other ones. To get started with GitLab Pages, you have two ways: - Fork one of the templates from Page Examples, or - Create a new project from scratch @@ -39,9 +44,12 @@ Let's go over both options. #### Fork a Project to Get Started From -To make things easy for you, we've created this [group](https://gitlab.com/pages) of default projects containing the most popular SSGs templates. +To make things easy for you, we've created this +[group](https://gitlab.com/pages) of default projects +containing the most popular SSGs templates. -Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've created for the steps below. +Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've +created for the steps below. 1. Choose your SSG template 1. Fork a project from the [Pages group](https://gitlab.com/pages) @@ -62,45 +70,82 @@ To turn a **project website** forked from the Pages group into a **user/group** > >1. Why do I need to remove the fork relationship? > -> Unless you want to contribute to the original project, you won't need it connected to the upstream. A [fork](https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/#fork) is useful for submitting merge requests to the upstream. +> Unless you want to contribute to the original project, +you won't need it connected to the upstream. A +[fork](https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/#fork) +is useful for submitting merge requests to the upstream. > > 2. Why do I need to enable Shared Runners? > -> Shared Runners will run the script set by your GitLab CI configuration file. They're enabled by default to new projects, but not to forks. +> Shared Runners will run the script set by your GitLab CI +configuration file. They're enabled by default to new projects, +but not to forks. #### Create a Project from Scratch -1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, click **New project**, and name it considering the [pratical examples](getting_started_part_one.md#practical-examples). -1. Clone it to your local computer, add your website files to your project, add, commit and push to GitLab. +1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, +click **New project**, and name it considering the +[pratical examples](getting_started_part_one.md#practical-examples). +1. Clone it to your local computer, add your website +files to your project, add, commit and push to GitLab. 1. From the your **Project**'s page, click **Set up CI**: ![setup GitLab CI](img/setup_ci.png) -1. Choose one of the templates from the dropbox menu. Pick up the template corresponding to the SSG you're using (or plain HTML). +1. Choose one of the templates from the dropbox menu. +Pick up the template corresponding to the SSG you're using (or plain HTML). ![gitlab-ci templates](img/choose_ci_template.png) -Once you have both site files and `.gitlab-ci.yml` in your project's root, GitLab CI will build your site and deploy it with Pages. Once the first build passes, you see your site is live by navigating to your **Project**'s **Settings** > **Pages**, where you'll find its default URL. +Once you have both site files and `.gitlab-ci.yml` in your project's +root, GitLab CI will build your site and deploy it with Pages. +Once the first build passes, you see your site is live by +navigating to your **Project**'s **Settings** > **Pages**, +where you'll find its default URL. > **Notes:** > -> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but, if you don't find yours among the templates, you'll need to configure your own `.gitlab-ci.yml`. Do do that, please read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md). New SSGs are very welcome among the [example projects](https://gitlab.com/pages). If you set up a new one, please [contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md) to our examples. +> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but, +if you don't find yours among the templates, you'll need +to configure your own `.gitlab-ci.yml`. Do do that, please +read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md). New SSGs are very welcome among +the [example projects](https://gitlab.com/pages). If you set +up a new one, please +[contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md) +to our examples. > -> - The second step _"Clone it to your local computer"_, can be done differently, achieving the same results: instead of cloning the bare repository to you local computer and moving your site files into it, you can run `git init` in your local website directory, add the remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`, then add, commit, and push. +> - The second step _"Clone it to your local computer"_, can be done +differently, achieving the same results: instead of cloning the bare +repository to you local computer and moving your site files into it, +you can run `git init` in your local website directory, add the +remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`, +then add, commit, and push. ### URLs and Baseurls -Every Static Site Generator (SSG) default configuration expects to find your website under a (sub)domain (`example.com`), not in a subdirectory of that domain (`example.com/subdir`). Therefore, whenever you publish a project website (`namespace.gitlab.io/project-name`), you'll have to look for this configuration (base URL) on your SSG's documentation and set it up to reflect this pattern. +Every Static Site Generator (SSG) default configuration expects +to find your website under a (sub)domain (`example.com`), not +in a subdirectory of that domain (`example.com/subdir`). Therefore, +whenever you publish a project website (`namespace.gitlab.io/project-name`), +you'll have to look for this configuration (base URL) on your SSG's +documentation and set it up to reflect this pattern. -For example, for a Jekyll site, the `baseurl` is defined in the Jekyll configuration file, `_config.yml`. If your website URL is `https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`: +For example, for a Jekyll site, the `baseurl` is defined in the Jekyll +configuration file, `_config.yml`. If your website URL is +`https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`: ```yaml baseurl: "/blog" ``` -On the contrary, if you deploy your website after forking one of our [default examples](https://gitlab.com/pages), the baseurl will already be configured this way, as all examples there are project websites. If you decide to make yours a user or group website, you'll have to remove this configuration from your project. For the Jekyll example we've just mentioned, you'd have to change Jekyll's `_config.yml` to: +On the contrary, if you deploy your website after forking one of +our [default examples](https://gitlab.com/pages), the baseurl will +already be configured this way, as all examples there are project +websites. If you decide to make yours a user or group website, you'll +have to remove this configuration from your project. For the Jekyll +example we've just mentioned, you'd have to change Jekyll's `_config.yml` to: ```yaml baseurl: "" From 6ec9e318dc002303a02e07f972d01536bc1e884f Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:32:44 -0300 Subject: [PATCH 165/247] wrapping text - part 3 --- doc/pages/getting_started_part_three.md | 162 ++++++++++++++++++++---- 1 file changed, 135 insertions(+), 27 deletions(-) diff --git a/doc/pages/getting_started_part_three.md b/doc/pages/getting_started_part_three.md index 10ae3abb9e5..8acf8a85d5a 100644 --- a/doc/pages/getting_started_part_three.md +++ b/doc/pages/getting_started_part_three.md @@ -12,15 +12,38 @@ ### Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages -[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves numerous purposes, to build, test, and deploy your app from GitLab through [Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) methods. You will need it to build your website with GitLab Pages, and deploy it to the Pages server. +[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves +numerous purposes, to build, test, and deploy your app +from GitLab through +[Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/) +methods. You will need it to build your website with GitLab Pages, +and deploy it to the Pages server. -What this file actually does is telling the [GitLab Runner](https://docs.gitlab.com/runner/) to run scripts as you would do from the command line. The Runner acts as your terminal. GitLab CI tells the Runner which commands to run. Both are built-in in GitLab, and you don't need to set up anything for them to work. +What this file actually does is telling the +[GitLab Runner](https://docs.gitlab.com/runner/) to run scripts +as you would do from the command line. The Runner acts as your +terminal. GitLab CI tells the Runner which commands to run. +Both are built-in in GitLab, and you don't need to set up +anything for them to work. -Explaining [every detail of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) and GitLab Runner is out of the scope of this guide, but we'll need to understand just a few things to be able to write our own `.gitlab-ci.yml` or tweak an existing one. It's an [Yaml](http://docs.ansible.com/ansible/YAMLSyntax.html) file, with its own syntax. You can always check your CI syntax with the [GitLab CI Lint Tool](https://gitlab.com/ci/lint). +Explaining [every detail of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) +and GitLab Runner is out of the scope of this guide, but we'll +need to understand just a few things to be able to write our own +`.gitlab-ci.yml` or tweak an existing one. It's an +[Yaml](http://docs.ansible.com/ansible/YAMLSyntax.html) file, +with its own syntax. You can always check your CI syntax with +the [GitLab CI Lint Tool](https://gitlab.com/ci/lint). **Practical Example:** -Let's consider you have a [Jekyll](https://jekyllrb.com/) site. To build it locally, you would open your terminal, and run `jekyll build`. Of course, before building it, you had to install Jekyll in your computer. For that, you had to open your terminal and run `gem install jekyll`. Right? GitLab CI + GitLab Runner do the same thing. But you need to write in the `.gitlab-ci.yml` the script you want to run so the GitLab Runner will do it for you. It looks more complicated then it is. What you need to tell the Runner: +Let's consider you have a [Jekyll](https://jekyllrb.com/) site. +To build it locally, you would open your terminal, and run `jekyll build`. +Of course, before building it, you had to install Jekyll in your computer. +For that, you had to open your terminal and run `gem install jekyll`. +Right? GitLab CI + GitLab Runner do the same thing. But you need to +write in the `.gitlab-ci.yml` the script you want to run so +GitLab Runner will do it for you. It looks more complicated then it +is. What you need to tell the Runner: ``` $ gem install jekyll @@ -39,7 +62,9 @@ script: #### Job -So far so good. Now, each `script`, in GitLab is organized by a `job`, which is a bunch of scripts and settings you want to apply to that specific task. +So far so good. Now, each `script`, in GitLab is organized by +a `job`, which is a bunch of scripts and settings you want to +apply to that specific task. ```yaml job: @@ -48,7 +73,9 @@ job: - jekyll build ``` -For GitLab Pages, this `job` has a specific name, called `pages`, which tells the Runner you want that task to deploy your website with GitLab Pages: +For GitLab Pages, this `job` has a specific name, called `pages`, +which tells the Runner you want that task to deploy your website +with GitLab Pages: ```yaml pages: @@ -59,7 +86,12 @@ pages: #### `public` Dir -We also need to tell Jekyll where do you want the website to build, and GitLab Pages will only consider files in a directory called `public`. To do that with Jekyll, we need to add a flag specifying the [destination (`-d`)](https://jekyllrb.com/docs/usage/) of the built website: `jekyll build -d public`. Of course, we need to tell this to our Runner: +We also need to tell Jekyll where do you want the website to build, +and GitLab Pages will only consider files in a directory called `public`. +To do that with Jekyll, we need to add a flag specifying the +[destination (`-d`)](https://jekyllrb.com/docs/usage/) of the +built website: `jekyll build -d public`. Of course, we need +to tell this to our Runner: ```yaml pages: @@ -70,7 +102,9 @@ pages: #### Artifacts -We also need to tell the Runner that this _job_ generates _artifacts_, which is the site built by Jekyll. Where are these artifacts stored? In the `public` directory: +We also need to tell the Runner that this _job_ generates +_artifacts_, which is the site built by Jekyll. +Where are these artifacts stored? In the `public` directory: ```yaml pages: @@ -82,7 +116,12 @@ pages: - public ``` -The script above would be enough to build your Jekyll site with GitLab Pages. But, from Jekyll 3.4.0 on, its default template originated by `jekyll new project` requires [Bundler](http://bundler.io/) to install Jekyll dependencies and the default theme. To adjust our script to meet these new requirements, we only need to install and build Jekyll with Bundler: +The script above would be enough to build your Jekyll +site with GitLab Pages. But, from Jekyll 3.4.0 on, its default +template originated by `jekyll new project` requires +[Bundler](http://bundler.io/) to install Jekyll dependencies +and the default theme. To adjust our script to meet these new +requirements, we only need to install and build Jekyll with Bundler: ```yaml pages: @@ -94,11 +133,18 @@ pages: - public ``` -That's it! A `.gitlab-ci.yml` with the content above would deploy your Jekyll 3.4.0 site with GitLab Pages. This is the minimum configuration for our example. On the steps below, we'll refine the script by adding extra options to our GitLab CI. +That's it! A `.gitlab-ci.yml` with the content above would deploy +your Jekyll 3.4.0 site with GitLab Pages. This is the minimum +configuration for our example. On the steps below, we'll refine +the script by adding extra options to our GitLab CI. #### Image -At this point, you probably ask yourself: "okay, but to install Jekyll I need Ruby. Where is Ruby on that script?". The answer is simple: the first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a [Docker](https://www.docker.com/) image specifying what do you need in your container to run that script: +At this point, you probably ask yourself: "okay, but to install Jekyll +I need Ruby. Where is Ruby on that script?". The answer is simple: the +first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a +[Docker](https://www.docker.com/) image specifying what do you need in +your container to run that script: ```yaml image: ruby:2.3 @@ -112,17 +158,32 @@ pages: - public ``` -In this case, you're telling the Runner to pull this image, which contains Ruby 2.3 as part of its file system. When you don't specify this image in your configuration, the Runner will use a default image, which is Ruby 2.1. +In this case, you're telling the Runner to pull this image, which +contains Ruby 2.3 as part of its file system. When you don't specify +this image in your configuration, the Runner will use a default +image, which is Ruby 2.1. -If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll need to specify which image you want to use, and this image should contain NodeJS as part of its file system. E.g., for a [Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`. +If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll +need to specify which image you want to use, and this image should +contain NodeJS as part of its file system. E.g., for a +[Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`. -> Note: we're not trying to explain what a Docker image is, we just need to introduce the concept with a minimum viable explanation. To know more about Docker images, please visit their website or take a look at a [summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here. +> Note: we're not trying to explain what a Docker image is, +we just need to introduce the concept with a minimum viable +explanation. To know more about Docker images, please visit +their website or take a look at a +[summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here. Let's go a little further. #### Branching -If you use GitLab as a version control platform, you will have your branching strategy to work on your project. Meaning, you will have other branches in your project, but you'll want only pushes to the default branch (usually `master`) to be deployed to your website. To do that, we need to add another line to our CI, telling the Runner to only perform that _job_ called `pages` on the `master` branch `only`: +If you use GitLab as a version control platform, you will have your +branching strategy to work on your project. Meaning, you will have +other branches in your project, but you'll want only pushes to the +default branch (usually `master`) to be deployed to your website. +To do that, we need to add another line to our CI, telling the Runner +to only perform that _job_ called `pages` on the `master` branch `only`: ```yaml image: ruby:2.3 @@ -140,7 +201,12 @@ pages: #### Stages -Another interesting concept to keep in mind are build stages. Your web app can pass through a lot of tests and other tasks until it's deployed to staging or production environments. There are three default stages on GitLab CI: build, test, and deploy. To specify which stage your _job_ is running, simply add another line to your CI: +Another interesting concept to keep in mind are build stages. +Your web app can pass through a lot of tests and other tasks +until it's deployed to staging or production environments. +There are three default stages on GitLab CI: build, test, +and deploy. To specify which stage your _job_ is running, +simply add another line to your CI: ```yaml image: ruby:2.3 @@ -157,7 +223,13 @@ pages: - master ``` -You might ask yourself: "why should I bother with stages at all?" Well, let's say you want to be able to test your script and check the built site before deploying your site to production. You want to run the test exactly as your script will do when you push to `master`. It's simple, let's add another task (_job_) to our CI, telling it to test every push to other branches, `except` the `master` branch: +You might ask yourself: "why should I bother with stages +at all?" Well, let's say you want to be able to test your +script and check the built site before deploying your site +to production. You want to run the test exactly as your +script will do when you push to `master`. It's simple, +let's add another task (_job_) to our CI, telling it to +test every push to other branches, `except` the `master` branch: ```yaml image: ruby:2.3 @@ -185,13 +257,29 @@ test: - master ``` -The `test` job is running on the stage `test`, Jekyll will build the site in a directory called `test`, and this job will affect all the branches except `master`. +The `test` job is running on the stage `test`, Jekyll +will build the site in a directory called `test`, and +this job will affect all the branches except `master`. -The best benefit of applying _stages_ to different _jobs_ is that every job in the same stage builds in parallel. So, if your web app needs more than one test before being deployed, you can run all your test at the same time, it's not necessary to wait one test to finish to run the other. Of course, this is just a brief introduction of GitLab CI and GitLab Runner, which are tools much more powerful than that. This is what you need to be able to create and tweak your builds for your GitLab Pages site. +The best benefit of applying _stages_ to different +_jobs_ is that every job in the same stage builds in +parallel. So, if your web app needs more than one test +before being deployed, you can run all your test at the +same time, it's not necessary to wait one test to finish +to run the other. Of course, this is just a brief +introduction of GitLab CI and GitLab Runner, which are +tools much more powerful than that. This is what you +need to be able to create and tweak your builds for +your GitLab Pages site. #### Before Script -To avoid running the same script multiple times across your _jobs_, you can add the parameter `before_script`, in which you specify which commands you want to run for every single _job_. In our example, notice that we run `bundle install` for both jobs, `pages` and `test`. We don't need to repeat it: +To avoid running the same script multiple times across +your _jobs_, you can add the parameter `before_script`, +in which you specify which commands you want to run for +every single _job_. In our example, notice that we run +`bundle install` for both jobs, `pages` and `test`. +We don't need to repeat it: ```yaml image: ruby:2.3 @@ -222,7 +310,11 @@ test: #### Caching Dependencies -If you want to cache the installation files for your projects dependencies, for building faster, you can use the parameter `cache`. For this example, we'll cache Jekyll dependencies in a `vendor` directory when we run `bundle install`: +If you want to cache the installation files for your +projects dependencies, for building faster, you can +use the parameter `cache`. For this example, we'll +cache Jekyll dependencies in a `vendor` directory +when we run `bundle install`: ```yaml image: ruby:2.3 @@ -255,22 +347,38 @@ test: - master ``` -For this specific case, we need to exclude `/vendor` from Jekyll `_config.yml` file, otherwise Jekyll will understand it as a regular directory to build together with the site: +For this specific case, we need to exclude `/vendor` +from Jekyll `_config.yml` file, otherwise Jekyll will +understand it as a regular directory to build +together with the site: ```yml exclude: - vendor ``` -There we go! Now our GitLab CI not only builds our website, but also **continuously test** pushes to feature-branches, **caches** dependencies installed with Bundler, and **continuously deploy** every push to the `master` branch. +There we go! Now our GitLab CI not only builds our website, +but also **continuously test** pushes to feature-branches, +**caches** dependencies installed with Bundler, and +**continuously deploy** every push to the `master` branch. ### Advanced GitLab CI for GitLab Pages -What you can do with GitLab CI is pretty much up to your creativity. Once you get used to it, you start creating awesome scripts that automate most of tasks you'd do manually in the past. Read through the [documentation of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) to understand how to go even further on your scripts. +What you can do with GitLab CI is pretty much up to your +creativity. Once you get used to it, you start creating +awesome scripts that automate most of tasks you'd do +manually in the past. Read through the +[documentation of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) +to understand how to go even further on your scripts. -- On this blog post, understand the concept of [using GitLab CI `environments` to deploy your web app to staging and production](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/). -- On this post, learn [how to run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/) -- On this blog post, we go through the process of [pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) to deploy this website you're looking at, docs.gitlab.com. +- On this blog post, understand the concept of +[using GitLab CI `environments` to deploy your +web app to staging and production](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/). +- On this post, learn [how to run jobs sequentially, +in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/) +- On this blog post, we go through the process of +[pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) +to deploy this website you're looking at, docs.gitlab.com. - On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/). ||| From 1a802b82d6c5c8a0fca20ab3eeb526416ef076a3 Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:37:15 -0300 Subject: [PATCH 166/247] remove <> --- doc/pages/getting_started_part_one.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/pages/getting_started_part_one.md b/doc/pages/getting_started_part_one.md index 57fc5d21b96..ed39301df39 100644 --- a/doc/pages/getting_started_part_one.md +++ b/doc/pages/getting_started_part_one.md @@ -47,8 +47,8 @@ which is highly recommendable and much faster than hardcoding. If you set up a GitLab Pages project on GitLab.com, it will automatically be accessible under a -[subdomain of `.pages.io`](https://docs.gitlab.com/ce/user/project/pages/). -The `` is defined by your username on GitLab.com, +[subdomain of `namespace.pages.io`](https://docs.gitlab.com/ce/user/project/pages/). +The `namespace` is defined by your username on GitLab.com, or the group name you created this project under. > Note: If you use your own GitLab instance to deploy your From 324260cef9ac8282bfb5b729b510f47e64b680fa Mon Sep 17 00:00:00 2001 From: Marcia Ramos Date: Wed, 22 Feb 2017 13:39:57 -0300 Subject: [PATCH 167/247] remove html comments --- doc/pages/getting_started_part_two.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/pages/getting_started_part_two.md b/doc/pages/getting_started_part_two.md index 15f628ac1fb..94b9d11e5d5 100644 --- a/doc/pages/getting_started_part_two.md +++ b/doc/pages/getting_started_part_two.md @@ -16,8 +16,6 @@ For a complete step-by-step tutorial, please read the blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain what do you need and why do you need them. - - ### What You Need to Get Started 1. A project @@ -123,8 +121,6 @@ then add, commit, and push. ### URLs and Baseurls - - Every Static Site Generator (SSG) default configuration expects to find your website under a (sub)domain (`example.com`), not in a subdirectory of that domain (`example.com/subdir`). Therefore, From 969754c25ad678081dca3359fde4080022bccaec Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 18:44:31 +0100 Subject: [PATCH 168/247] Reorder main index items in Pages overview [ci skip] --- doc/pages/getting_started_part_one.md | 20 ++++++++-------- doc/pages/getting_started_part_three.md | 31 +++++++++++-------------- doc/pages/getting_started_part_two.md | 14 +++++------ doc/pages/index.md | 20 ++++++++++++---- 4 files changed, 46 insertions(+), 39 deletions(-) diff --git a/doc/pages/getting_started_part_one.md b/doc/pages/getting_started_part_one.md index ed39301df39..c5b1aa4b654 100644 --- a/doc/pages/getting_started_part_one.md +++ b/doc/pages/getting_started_part_one.md @@ -1,9 +1,5 @@ # GitLab Pages from A to Z: Part 1 -> Type: user guide -> -> Level: beginner - - **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates** - _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ - _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_ @@ -19,14 +15,15 @@ and GitLab EE (Enterprise Edition), please read the [admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html), and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s). -> For this guide, we assume you already have GitLab Pages +>**Note:** +For this guide, we assume you already have GitLab Pages server up and running for your GitLab instance. ## What you need to know before getting started Before we begin, let's understand a few concepts first. -### Static Sites +### Static sites GitLab Pages only supports static websites, meaning, your output files must be HTML, CSS, and JavaScript only. @@ -43,7 +40,7 @@ which is highly recommendable and much faster than hardcoding. - You can use [any SSG with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) - Fork an [example project](https://gitlab.com/pages) to build your website based upon -### GitLab Pages Domain +### GitLab Pages domain If you set up a GitLab Pages project on GitLab.com, it will automatically be accessible under a @@ -51,7 +48,8 @@ it will automatically be accessible under a The `namespace` is defined by your username on GitLab.com, or the group name you created this project under. -> Note: If you use your own GitLab instance to deploy your +>**Note:** +If you use your own GitLab instance to deploy your site with GitLab Pages, check with your sysadmin what's your Pages wildcard domain. This guide is valid for any GitLab instance, you just need to replace Pages wildcard domain on GitLab.com @@ -180,7 +178,8 @@ up your Pages project with your custom (sub)domain, if you want it secured by HTTPS, you will have to issue a certificate for that (sub)domain and install it on your project. -> Note: certificates are NOT required to add to your custom +>**Note:** +Certificates are NOT required to add to your custom (sub)domain on your GitLab Pages project, though they are highly recommendable. @@ -257,7 +256,8 @@ and paste it in the [same field as your PEM certificate](https://about.gitlab.co just jumping a line between them. - Copy your public key and paste it in the last field -> Note: **do not** open certificates or encryption keys in +>**Note:** +**Do not** open certificates or encryption keys in regular text editors. Always use code editors (such as Sublime Text, Atom, Dreamweaver, Brackets, etc). diff --git a/doc/pages/getting_started_part_three.md b/doc/pages/getting_started_part_three.md index 8acf8a85d5a..ef47abef3a0 100644 --- a/doc/pages/getting_started_part_three.md +++ b/doc/pages/getting_started_part_three.md @@ -1,16 +1,12 @@ # GitLab Pages from A to Z: Part 3 -> Type: user guide -> -> Level: intermediate - - _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_ - _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_ - **Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages** --- -### Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages +## Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages [GitLab CI](https://about.gitlab.com/gitlab-ci/) serves numerous purposes, to build, test, and deploy your app @@ -50,7 +46,7 @@ $ gem install jekyll $ jekyll build ``` -#### Script +### Script To transpose this script to Yaml, it would be like this: @@ -60,7 +56,7 @@ script: - jekyll build ``` -#### Job +### Job So far so good. Now, each `script`, in GitLab is organized by a `job`, which is a bunch of scripts and settings you want to @@ -84,7 +80,7 @@ pages: - jekyll build ``` -#### `public` Dir +### The `public` directory We also need to tell Jekyll where do you want the website to build, and GitLab Pages will only consider files in a directory called `public`. @@ -100,7 +96,7 @@ pages: - jekyll build -d public ``` -#### Artifacts +### Artifacts We also need to tell the Runner that this _job_ generates _artifacts_, which is the site built by Jekyll. @@ -138,7 +134,7 @@ your Jekyll 3.4.0 site with GitLab Pages. This is the minimum configuration for our example. On the steps below, we'll refine the script by adding extra options to our GitLab CI. -#### Image +### Image At this point, you probably ask yourself: "okay, but to install Jekyll I need Ruby. Where is Ruby on that script?". The answer is simple: the @@ -168,7 +164,8 @@ need to specify which image you want to use, and this image should contain NodeJS as part of its file system. E.g., for a [Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`. -> Note: we're not trying to explain what a Docker image is, +>**Note:** +We're not trying to explain what a Docker image is, we just need to introduce the concept with a minimum viable explanation. To know more about Docker images, please visit their website or take a look at a @@ -176,7 +173,7 @@ their website or take a look at a Let's go a little further. -#### Branching +### Branching If you use GitLab as a version control platform, you will have your branching strategy to work on your project. Meaning, you will have @@ -199,7 +196,7 @@ pages: - master ``` -#### Stages +### Stages Another interesting concept to keep in mind are build stages. Your web app can pass through a lot of tests and other tasks @@ -272,7 +269,7 @@ tools much more powerful than that. This is what you need to be able to create and tweak your builds for your GitLab Pages site. -#### Before Script +### Before Script To avoid running the same script multiple times across your _jobs_, you can add the parameter `before_script`, @@ -308,7 +305,7 @@ test: - master ``` -#### Caching Dependencies +### Caching Dependencies If you want to cache the installation files for your projects dependencies, for building faster, you can @@ -362,7 +359,7 @@ but also **continuously test** pushes to feature-branches, **caches** dependencies installed with Bundler, and **continuously deploy** every push to the `master` branch. -### Advanced GitLab CI for GitLab Pages +## Advanced GitLab CI for GitLab Pages What you can do with GitLab CI is pretty much up to your creativity. Once you get used to it, you start creating @@ -383,4 +380,4 @@ to deploy this website you're looking at, docs.gitlab.com. ||| |:--|--:| -|[**← Part 1: Static sites, domains, DNS records, and SSL/TLS certificates**](getting_started_part_one.md)|[**Part 2: Quick start guide - Setting up GitLab Pages →**](getting_started_part_two.md)| +|[**← Part 2: Quick start guide - Setting up GitLab Pages**](getting_started_part_two.md)|| diff --git a/doc/pages/getting_started_part_two.md b/doc/pages/getting_started_part_two.md index 94b9d11e5d5..07dd24122c4 100644 --- a/doc/pages/getting_started_part_two.md +++ b/doc/pages/getting_started_part_two.md @@ -10,27 +10,27 @@ ---- -## Setting Up GitLab Pages +## Setting up GitLab Pages For a complete step-by-step tutorial, please read the blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain what do you need and why do you need them. -### What You Need to Get Started +## What you need to get started 1. A project 1. A configuration file (`.gitlab-ci.yml`) to deploy your site 1. A specific `job` called `pages` in the configuration file that will make GitLab aware that you are deploying a GitLab Pages website -#### Optional Features +Optional Features: 1. A custom domain or subdomain 1. A DNS pointing your (sub)domain to your Pages site 1. **Optional**: an SSL/TLS certificate so your custom domain is accessible under HTTPS. -### Project +## Project Your GitLab Pages project is a regular project created the same way you do for the other ones. To get started with GitLab Pages, you have two ways: @@ -40,7 +40,7 @@ same way you do for the other ones. To get started with GitLab Pages, you have t Let's go over both options. -#### Fork a Project to Get Started From +### Fork a project to get started from To make things easy for you, we've created this [group](https://gitlab.com/pages) of default projects @@ -79,11 +79,11 @@ is useful for submitting merge requests to the upstream. configuration file. They're enabled by default to new projects, but not to forks. -#### Create a Project from Scratch +### Create a project from scratch 1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**, click **New project**, and name it considering the -[pratical examples](getting_started_part_one.md#practical-examples). +[practical examples](getting_started_part_one.md#practical-examples). 1. Clone it to your local computer, add your website files to your project, add, commit and push to GitLab. 1. From the your **Project**'s page, click **Set up CI**: diff --git a/doc/pages/index.md b/doc/pages/index.md index 242fdf3147f..a6f928cc243 100644 --- a/doc/pages/index.md +++ b/doc/pages/index.md @@ -1,6 +1,13 @@ # All you need to know about GitLab Pages -## Product +With GitLab Pages you can create static websites for your GitLab projects, +groups, or user accounts. You can use any static website generator: Jekyll, +Middleman, Hexo, Hugo, Pelican, you name it! Connect as many customs domains +as you like and bring your own TLS certificate to secure them. + +Here's some info we have gathered to get you started. + +## General info - [Product webpage](https://pages.gitlab.io) - [We're bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/) @@ -8,12 +15,11 @@ ## Getting started -- [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) a comprehensive step-by-step guide - GitLab Pages from A to Z - [Part 1: Static sites, domains, DNS records, and SSL/TLS certificates](getting_started_part_one.md) - [Part 2: Quick start guide - Setting up GitLab Pages](getting_started_part_two.md) - - Video tutorial: [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg) - [Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md) +- [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) a comprehensive step-by-step guide - Secure GitLab Pages custom domain with SSL/TLS certificates - [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/) - [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) @@ -24,6 +30,11 @@ - [SSGs part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) - [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/) +## Video tutorials + +- [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg) +- [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s) + ## Advanced use - Blog Posts: @@ -32,8 +43,7 @@ - [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/) - [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/) -## General documentation +## Specific documentation - [User docs](../user/project/pages/index.md) - [Admin docs](../administration/pages/index.md) - - Video tutorial - [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s) From 9f322f2b3866833af1bca7ecd3624428d968b017 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Tue, 21 Feb 2017 22:48:02 +0000 Subject: [PATCH 169/247] Added double newline after file upload markdown insert --- app/assets/javascripts/dropzone_input.js | 5 +++-- spec/features/issues_spec.rb | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js index 64a7a9eaf37..646f836aff0 100644 --- a/app/assets/javascripts/dropzone_input.js +++ b/app/assets/javascripts/dropzone_input.js @@ -126,13 +126,14 @@ require('./preview_markdown'); }; pasteText = function(text) { var afterSelection, beforeSelection, caretEnd, caretStart, textEnd; + var formattedText = text + "\n\n"; caretStart = $(child)[0].selectionStart; caretEnd = $(child)[0].selectionEnd; textEnd = $(child).val().length; beforeSelection = $(child).val().substring(0, caretStart); afterSelection = $(child).val().substring(caretEnd, textEnd); - $(child).val(beforeSelection + text + afterSelection); - child.get(0).setSelectionRange(caretStart + text.length, caretEnd + text.length); + $(child).val(beforeSelection + formattedText + afterSelection); + child.get(0).setSelectionRange(caretStart + formattedText.length, caretEnd + formattedText.length); return form_textarea.trigger("input"); }; getFilename = function(e) { diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 094f645a077..ed3826bd46e 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -577,6 +577,15 @@ describe 'Issues', feature: true do expect(page.find_field("issue_description").value).to have_content 'banana_sample' end + + it 'adds double newline to end of attachment markdown' do + drop_in_dropzone test_image_file + + # Wait for the file to upload + sleep 1 + + expect(page.find_field("issue_description").value).to match /\n\n$/ + end end end From 165be6344de51e4db27456f8977da5105f9d33d5 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 19:13:48 +0100 Subject: [PATCH 170/247] Add missing index.md to Pages docs [ci skip] --- doc/user/project/pages/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index 816600964de..276fbd26835 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -444,6 +444,6 @@ For a list of known issues, visit GitLab's [public issue tracker]. [public issue tracker]: https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name=Pages [ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605 [quick start guide]: ../../../ci/quick_start/README.md -[pages-index-guide]: ../../../pages/ +[pages-index-guide]: ../../../pages/index.md [pages-quick]: ../../../pages/getting_started_part_one.md [video-pages-fork]: https://youtu.be/TWqh9MtT4Bg From e2af9d0ab0fb2a5d631c0bbd4425d83a6d1203dc Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 20:14:10 +0100 Subject: [PATCH 171/247] Change Pages redirect [ci skip] --- doc/pages/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pages/README.md b/doc/pages/README.md index c9715eed598..afe62a2ee71 100644 --- a/doc/pages/README.md +++ b/doc/pages/README.md @@ -1 +1 @@ -This document was moved to [user/project/pages](../user/project/pages/index.md). +This document was moved to [index.md](index.md). From 17aae3bd34a467e2aed4c7063bc8bc3619d87e0f Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Feb 2017 20:35:44 +0100 Subject: [PATCH 172/247] Remove Pages readme To prevent a redirect loop in docs.gitlab.com/ce/pages/ [ci skip] --- doc/pages/README.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 doc/pages/README.md diff --git a/doc/pages/README.md b/doc/pages/README.md deleted file mode 100644 index afe62a2ee71..00000000000 --- a/doc/pages/README.md +++ /dev/null @@ -1 +0,0 @@ -This document was moved to [index.md](index.md). From a942240ef5c5bef7e0d1fcf5294209a3a6b69bdf Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 20:42:33 +0000 Subject: [PATCH 173/247] Ignore two Rails CVEs in bundler:audit job --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 433b3119fba..20f410d0b4c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -281,7 +281,7 @@ bundler:audit: - master@gitlab/gitlabhq - master@gitlab/gitlab-ee script: - - "bundle exec bundle-audit check --update --ignore OSVDB-115941" + - "bundle exec bundle-audit check --update --ignore OSVDB-115941 CVE-2016-6316 CVE-2016-6317" migration paths: stage: test From fcb15c5677b5e73590f96f6fbb754b86f0077f93 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Wed, 22 Feb 2017 11:38:10 -0700 Subject: [PATCH 174/247] Update Licensee from 8.0.0 to 8.7.0. Changelog: https://github.com/benbalter/licensee/releases --- Gemfile | 2 +- Gemfile.lock | 6 +++--- .../files/project_owner_creates_license_file_spec.rb | 8 ++++---- ...s_link_to_create_license_file_in_empty_project_spec.rb | 4 ++-- spec/requests/api/templates_spec.rb | 8 ++++---- spec/requests/api/v3/templates_spec.rb | 8 ++++---- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index 01861f1ffac..3fc92abf9a7 100644 --- a/Gemfile +++ b/Gemfile @@ -201,7 +201,7 @@ gem 'babosa', '~> 1.0.2' gem 'loofah', '~> 2.0.3' # Working with license -gem 'licensee', '~> 8.0.0' +gem 'licensee', '~> 8.7.0' # Protect against bruteforcing gem 'rack-attack', '~> 4.4.1' diff --git a/Gemfile.lock b/Gemfile.lock index 2a3be763753..9d6100f66ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -398,8 +398,8 @@ GEM rubyzip thor xml-simple - licensee (8.0.0) - rugged (>= 0.24b) + licensee (8.7.0) + rugged (~> 0.24) little-plugger (1.1.4) logging (2.1.0) little-plugger (~> 1.1) @@ -907,7 +907,7 @@ DEPENDENCIES kubeclient (~> 2.2.0) letter_opener_web (~> 1.3.0) license_finder (~> 2.1.0) - licensee (~> 8.0.0) + licensee (~> 8.7.0) loofah (~> 2.0.3) mail_room (~> 0.9.1) method_source (~> 0.8) diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 64094af29c0..f8ef4577a26 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -25,7 +25,7 @@ feature 'project owner creates a license file', feature: true, js: true do select_template('MIT License') file_content = first('.file-editor') - expect(file_content).to have_content('The MIT License (MIT)') + expect(file_content).to have_content('MIT License') expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true @@ -33,7 +33,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) - expect(page).to have_content('The MIT License (MIT)') + expect(page).to have_content('MIT License') expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end @@ -49,7 +49,7 @@ feature 'project owner creates a license file', feature: true, js: true do select_template('MIT License') file_content = first('.file-editor') - expect(file_content).to have_content('The MIT License (MIT)') + expect(file_content).to have_content('MIT License') expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true @@ -57,7 +57,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) - expect(page).to have_content('The MIT License (MIT)') + expect(page).to have_content('MIT License') expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index 4453b6d485f..420db962318 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -24,7 +24,7 @@ feature 'project owner sees a link to create a license file in empty project', f select_template('MIT License') file_content = first('.file-editor') - expect(file_content).to have_content('The MIT License (MIT)') + expect(file_content).to have_content('MIT License') expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true @@ -34,7 +34,7 @@ feature 'project owner sees a link to create a license file in empty project', f expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) - expect(page).to have_content('The MIT License (MIT)') + expect(page).to have_content('MIT License') expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb index 8506e8fccde..2c83e119065 100644 --- a/spec/requests/api/templates_spec.rb +++ b/spec/requests/api/templates_spec.rb @@ -58,11 +58,11 @@ describe API::Templates, api: true do expect(json_response['popular']).to be true expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/') expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT') - expect(json_response['description']).to include('A permissive license that is short and to the point.') + expect(json_response['description']).to include('A short and simple permissive license with conditions') expect(json_response['conditions']).to eq(%w[include-copyright]) expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use]) expect(json_response['limitations']).to eq(%w[no-liability]) - expect(json_response['content']).to include('The MIT License (MIT)') + expect(json_response['content']).to include('MIT License') end end @@ -73,7 +73,7 @@ describe API::Templates, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response.size).to eq(15) + expect(json_response.size).to eq(12) expect(json_response.map { |l| l['key'] }).to include('agpl-3.0') end @@ -102,7 +102,7 @@ describe API::Templates, api: true do let(:license_type) { 'mit' } it 'returns the license text' do - expect(json_response['content']).to include('The MIT License (MIT)') + expect(json_response['content']).to include('MIT License') end it 'replaces placeholder values' do diff --git a/spec/requests/api/v3/templates_spec.rb b/spec/requests/api/v3/templates_spec.rb index 4fd4e70bedd..f1e554b98cc 100644 --- a/spec/requests/api/v3/templates_spec.rb +++ b/spec/requests/api/v3/templates_spec.rb @@ -56,11 +56,11 @@ describe API::V3::Templates, api: true do expect(json_response['popular']).to be true expect(json_response['html_url']).to eq('http://choosealicense.com/licenses/mit/') expect(json_response['source_url']).to eq('https://opensource.org/licenses/MIT') - expect(json_response['description']).to include('A permissive license that is short and to the point.') + expect(json_response['description']).to include('A short and simple permissive license with conditions') expect(json_response['conditions']).to eq(%w[include-copyright]) expect(json_response['permissions']).to eq(%w[commercial-use modifications distribution private-use]) expect(json_response['limitations']).to eq(%w[no-liability]) - expect(json_response['content']).to include('The MIT License (MIT)') + expect(json_response['content']).to include('MIT License') end end @@ -70,7 +70,7 @@ describe API::V3::Templates, api: true do expect(response).to have_http_status(200) expect(json_response).to be_an Array - expect(json_response.size).to eq(15) + expect(json_response.size).to eq(12) expect(json_response.map { |l| l['key'] }).to include('agpl-3.0') end @@ -98,7 +98,7 @@ describe API::V3::Templates, api: true do let(:license_type) { 'mit' } it 'returns the license text' do - expect(json_response['content']).to include('The MIT License (MIT)') + expect(json_response['content']).to include('MIT License') end it 'replaces placeholder values' do From e6c58aff0f2915e2e17879141924efc7b386fe0d Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 22 Feb 2017 16:56:52 -0600 Subject: [PATCH 175/247] remove require.context from filtered_search_bundle --- .../filtered_search/filtered_search_bundle.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/filtered_search/filtered_search_bundle.js b/app/assets/javascripts/filtered_search/filtered_search_bundle.js index 392f1835966..faaba994f46 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_bundle.js +++ b/app/assets/javascripts/filtered_search/filtered_search_bundle.js @@ -1,3 +1,9 @@ -function requireAll(context) { return context.keys().map(context); } - -requireAll(require.context('./', true, /^\.\/(?!filtered_search_bundle).*\.(js|es6)$/)); +require('./dropdown_hint'); +require('./dropdown_non_user'); +require('./dropdown_user'); +require('./dropdown_utils'); +require('./filtered_search_dropdown_manager'); +require('./filtered_search_dropdown'); +require('./filtered_search_manager'); +require('./filtered_search_token_keys'); +require('./filtered_search_tokenizer'); From 87b19b8cae067bd328c1e6a1cec4fa06a73e8b96 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 22 Feb 2017 17:01:41 -0600 Subject: [PATCH 176/247] remove require.context from graphs_bundle --- app/assets/javascripts/graphs/graphs_bundle.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/graphs/graphs_bundle.js b/app/assets/javascripts/graphs/graphs_bundle.js index 4f7777aa5bc..086dcb34571 100644 --- a/app/assets/javascripts/graphs/graphs_bundle.js +++ b/app/assets/javascripts/graphs/graphs_bundle.js @@ -1,3 +1,4 @@ -// require everything else in this directory -function requireAll(context) { return context.keys().map(context); } -requireAll(require.context('.', false, /^\.\/(?!graphs_bundle).*\.(js|es6)$/)); +require('./stat_graph_contributors_graph'); +require('./stat_graph_contributors_util'); +require('./stat_graph_contributors'); +require('./stat_graph'); From f326e6fb8d806ba443c64965a564d64a2f313a19 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 22 Feb 2017 17:04:53 -0600 Subject: [PATCH 177/247] remove require.context from network_bundle --- app/assets/javascripts/network/network_bundle.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/network/network_bundle.js b/app/assets/javascripts/network/network_bundle.js index aae509caa79..e5947586583 100644 --- a/app/assets/javascripts/network/network_bundle.js +++ b/app/assets/javascripts/network/network_bundle.js @@ -2,9 +2,8 @@ /* global Network */ /* global ShortcutsNetwork */ -// require everything else in this directory -function requireAll(context) { return context.keys().map(context); } -requireAll(require.context('.', false, /^\.\/(?!network_bundle).*\.(js|es6)$/)); +require('./branch_graph'); +require('./network'); (function() { $(function() { From 5600b17de76c8bc93313adc1aa4d9859045de0a9 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Wed, 22 Feb 2017 17:42:11 -0500 Subject: [PATCH 178/247] Code style improvements --- app/views/groups/_head.html.haml | 19 ++++++++++++++++++ app/views/groups/_head_issues.html.haml | 19 ++++++++++++++++++ app/views/groups/activity.html.haml | 3 ++- .../groups/group_members/index.html.haml | 1 + app/views/groups/issues.html.haml | 1 + app/views/groups/labels/index.html.haml | 1 + app/views/groups/milestones/index.html.haml | 1 + app/views/groups/show.html.haml | 1 + app/views/layouts/nav/_group.html.haml | 20 ++----------------- .../26348-cleanup-navigation-order-groups.yml | 4 ++++ features/steps/group/milestones.rb | 4 +--- 11 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 app/views/groups/_head.html.haml create mode 100644 app/views/groups/_head_issues.html.haml create mode 100644 changelogs/unreleased/26348-cleanup-navigation-order-groups.yml diff --git a/app/views/groups/_head.html.haml b/app/views/groups/_head.html.haml new file mode 100644 index 00000000000..6b296ea8dea --- /dev/null +++ b/app/views/groups/_head.html.haml @@ -0,0 +1,19 @@ += content_for :sub_nav do + .scrolling-tabs-container.sub-nav-scroll + = render 'shared/nav_scroll' + .nav-links.sub-nav.scrolling-tabs + %ul{ class: container_class } + = nav_link(path: 'groups#show', html_options: { class: 'home' }) do + = link_to group_path(@group), title: 'Group Home' do + %span + Home + + = nav_link(path: 'groups#activity') do + = link_to activity_group_path(@group), title: 'Activity' do + %span + Activity + + = nav_link(path: 'group_members#index') do + = link_to group_group_members_path(@group), title: 'Members' do + %span + Members diff --git a/app/views/groups/_head_issues.html.haml b/app/views/groups/_head_issues.html.haml new file mode 100644 index 00000000000..d554bc23743 --- /dev/null +++ b/app/views/groups/_head_issues.html.haml @@ -0,0 +1,19 @@ += content_for :sub_nav do + .scrolling-tabs-container.sub-nav-scroll + = render 'shared/nav_scroll' + .nav-links.sub-nav.scrolling-tabs + %ul{ class: container_class } + = nav_link(path: 'groups#issues', html_options: { class: 'home' }) do + = link_to issues_group_path(@group), title: 'List' do + %span + List + + = nav_link(path: 'labels#index') do + = link_to group_labels_path(@group), title: 'Labels' do + %span + Labels + + = nav_link(path: 'milestones#index') do + = link_to group_milestones_path(@group), title: 'Milestones' do + %span + Milestones diff --git a/app/views/groups/activity.html.haml b/app/views/groups/activity.html.haml index aaad265b3ee..d7375b23524 100644 --- a/app/views/groups/activity.html.haml +++ b/app/views/groups/activity.html.haml @@ -2,7 +2,8 @@ - if current_user = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") -- page_title "Activity" +- page_title "Activity" += render 'groups/head' %section.activities = render 'activities' diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index 2e4e4511bb6..8cb56443191 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -1,4 +1,5 @@ - page_title "Members" += render 'groups/head' .project-members-page.prepend-top-default %h4 diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 83edb719692..939bddf3fe9 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -1,4 +1,5 @@ - page_title "Issues" += render "head_issues" = content_for :meta_tags do - if current_user = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues") diff --git a/app/views/groups/labels/index.html.haml b/app/views/groups/labels/index.html.haml index 45325d6bc4b..2bc00fb16c8 100644 --- a/app/views/groups/labels/index.html.haml +++ b/app/views/groups/labels/index.html.haml @@ -1,4 +1,5 @@ - page_title 'Labels' += render "groups/head_issues" .top-area.adjust .nav-text diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index cd5388fe402..644895c56a1 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -1,4 +1,5 @@ - page_title "Milestones" += render "groups/head_issues" .top-area = render 'shared/milestones_filter' diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index b040f404ac4..3d7b469660a 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -4,6 +4,7 @@ - if current_user = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") += render 'groups/head' = render 'groups/home_panel' diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index f3539fd372d..e0742d70fac 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -5,23 +5,11 @@ .fade-right = icon('angle-right') %ul.nav-links.scrolling-tabs - = nav_link(path: 'groups#show', html_options: {class: 'home'}) do + = nav_link(path: ['groups#show', 'groups#activity', 'group_members#index'], html_options: { class: 'home' }) do = link_to group_path(@group), title: 'Home' do %span Group - = nav_link(path: 'groups#activity') do - = link_to activity_group_path(@group), title: 'Activity' do - %span - Activity - = nav_link(controller: [:group, :labels]) do - = link_to group_labels_path(@group), title: 'Labels' do - %span - Labels - = nav_link(controller: [:group, :milestones]) do - = link_to group_milestones_path(@group), title: 'Milestones' do - %span - Milestones - = nav_link(path: 'groups#issues') do + = nav_link(path: ['groups#issues', 'labels#index', 'milestones#index']) do = link_to issues_group_path(@group), title: 'Issues' do %span Issues @@ -33,7 +21,3 @@ Merge Requests - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute %span.badge.count= number_with_delimiter(merge_requests.count) - = nav_link(controller: [:group_members]) do - = link_to group_group_members_path(@group), title: 'Members' do - %span - Members diff --git a/changelogs/unreleased/26348-cleanup-navigation-order-groups.yml b/changelogs/unreleased/26348-cleanup-navigation-order-groups.yml new file mode 100644 index 00000000000..ce888baa32f --- /dev/null +++ b/changelogs/unreleased/26348-cleanup-navigation-order-groups.yml @@ -0,0 +1,4 @@ +--- +title: Clean-up Groups navigation order +merge_request: 9309 +author: diff --git a/features/steps/group/milestones.rb b/features/steps/group/milestones.rb index 70e23098dde..20204ad8654 100644 --- a/features/steps/group/milestones.rb +++ b/features/steps/group/milestones.rb @@ -5,9 +5,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps include SharedUser step 'I click on group milestones' do - page.within('.layout-nav') do - click_link 'Milestones' - end + visit group_milestones_path('owned') end step 'I should see group milestones index page has no milestones' do From ed986806786d0c3fa5794409566e9e18a7916ed9 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 23 Feb 2017 11:44:49 +0100 Subject: [PATCH 179/247] Process skipped jobs in the pipeline when retrying it --- app/services/ci/retry_pipeline_service.rb | 19 +++++++++---------- lib/gitlab/optimistic_locking.rb | 4 +++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index ca19b828e1c..574561adc4c 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -1,22 +1,21 @@ module Ci class RetryPipelineService < ::BaseService + include Gitlab::OptimisticLocking + def execute(pipeline) unless can?(current_user, :update_pipeline, pipeline) raise Gitlab::Access::AccessDeniedError end - pipeline.builds.failed_or_canceled.tap do |builds| - stage_idx = builds.order('stage_idx ASC') - .pluck('DISTINCT stage_idx').first + pipeline.builds.failed_or_canceled.find_each do |build| + next unless build.retryable? - pipeline.mark_as_processable_after_stage(stage_idx) + Ci::RetryBuildService.new(project, current_user) + .reprocess(build) + end - builds.find_each do |build| - next unless build.retryable? - - Ci::RetryBuildService.new(project, current_user) - .reprocess(build) - end + pipeline.builds.skipped.find_each do |skipped| + retry_optimistic_lock(skipped) { |build| build.process } end MergeRequests::AddTodoWhenBuildFailsService diff --git a/lib/gitlab/optimistic_locking.rb b/lib/gitlab/optimistic_locking.rb index 879d46446b3..e0b2286f1dc 100644 --- a/lib/gitlab/optimistic_locking.rb +++ b/lib/gitlab/optimistic_locking.rb @@ -1,6 +1,6 @@ module Gitlab module OptimisticLocking - extend self + module_function def retry_lock(subject, retries = 100, &block) loop do @@ -15,5 +15,7 @@ module Gitlab end end end + + alias :retry_optimistic_lock :retry_lock end end From df97e21c4faffaf14f23c407047cde17f61d95ba Mon Sep 17 00:00:00 2001 From: George Andrinopoulos Date: Tue, 14 Feb 2017 17:51:30 +0200 Subject: [PATCH 180/247] Rebase to master for avoiding failing tests --- .../26875-builds-api-endpoint-skipped-scope.yml | 4 ++++ lib/api/builds.rb | 2 +- spec/requests/api/builds_spec.rb | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml diff --git a/changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml b/changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml new file mode 100644 index 00000000000..3d6400cba76 --- /dev/null +++ b/changelogs/unreleased/26875-builds-api-endpoint-skipped-scope.yml @@ -0,0 +1,4 @@ +--- +title: Add all available statuses to scope filter for project builds endpoint +merge_request: +author: George Andrinopoulos diff --git a/lib/api/builds.rb b/lib/api/builds.rb index 44fe0fc4a95..5b76913fe45 100644 --- a/lib/api/builds.rb +++ b/lib/api/builds.rb @@ -11,7 +11,7 @@ module API helpers do params :optional_scope do optional :scope, types: [String, Array[String]], desc: 'The scope of builds to show', - values: ['pending', 'running', 'failed', 'success', 'canceled'], + values: ::CommitStatus::AVAILABLE_STATUSES, coerce_with: ->(scope) { if scope.is_a?(String) [scope] diff --git a/spec/requests/api/builds_spec.rb b/spec/requests/api/builds_spec.rb index 38aef7f2767..76a10a2374c 100644 --- a/spec/requests/api/builds_spec.rb +++ b/spec/requests/api/builds_spec.rb @@ -16,6 +16,8 @@ describe API::Builds, api: true do let(:query) { '' } before do + create(:ci_build, :skipped, pipeline: pipeline) + get api("/projects/#{project.id}/builds?#{query}", api_user) end @@ -49,6 +51,18 @@ describe API::Builds, api: true do end end + context 'filter project with scope skipped' do + let(:query) { 'scope=skipped' } + let(:json_build) { json_response.first } + + it 'return builds with status skipped' do + expect(response).to have_http_status 200 + expect(json_response).to be_an Array + expect(json_response.length).to eq 1 + expect(json_build['status']).to eq 'skipped' + end + end + context 'filter project with array of scope elements' do let(:query) { 'scope[0]=pending&scope[1]=running' } From 02699f26a4fe067092fdc028738e56048a375453 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 23 Feb 2017 12:07:57 +0100 Subject: [PATCH 181/247] Add basic specs for optimistic locking mixin --- spec/lib/gitlab/optimistic_locking_spec.rb | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/spec/lib/gitlab/optimistic_locking_spec.rb b/spec/lib/gitlab/optimistic_locking_spec.rb index 498dc514c8c..acce2be93f2 100644 --- a/spec/lib/gitlab/optimistic_locking_spec.rb +++ b/spec/lib/gitlab/optimistic_locking_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' describe Gitlab::OptimisticLocking, lib: true do - describe '#retry_lock' do - let!(:pipeline) { create(:ci_pipeline) } - let!(:pipeline2) { Ci::Pipeline.find(pipeline.id) } + let!(:pipeline) { create(:ci_pipeline) } + let!(:pipeline2) { Ci::Pipeline.find(pipeline.id) } + describe '#retry_lock' do it 'does not reload object if state changes' do expect(pipeline).not_to receive(:reload) expect(pipeline).to receive(:succeed).and_call_original @@ -36,4 +36,17 @@ describe Gitlab::OptimisticLocking, lib: true do end.to raise_error(ActiveRecord::StaleObjectError) end end + + describe '#retry_optimistic_lock' do + context 'when locking module is mixed in' do + let(:unlockable) do + Class.new.include(described_class).new + end + + it 'is an alias for retry_lock' do + expect(unlockable.method(:retry_optimistic_lock)) + .to eq unlockable.method(:retry_lock) + end + end + end end From 2f0599b6c851c208b5332f37509df0ada52e6d6a Mon Sep 17 00:00:00 2001 From: Pawel Chojnacki Date: Thu, 23 Feb 2017 12:36:23 +0100 Subject: [PATCH 182/247] Disable unused tags count cache for Projects, Builds and Runners + remove complete leftover when Issues were tagged using acts_as_taggable --- app/models/issue.rb | 2 -- app/models/project.rb | 3 +-- changelogs/unreleased/27989-disable-counting-tags.yml | 4 ++++ config/initializers/acts_as_taggable.rb | 5 +++++ 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 changelogs/unreleased/27989-disable-counting-tags.yml create mode 100644 config/initializers/acts_as_taggable.rb diff --git a/app/models/issue.rb b/app/models/issue.rb index d8826b65fcc..de90f19f854 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -15,8 +15,6 @@ class Issue < ActiveRecord::Base DueThisWeek = DueDateStruct.new('Due This Week', 'week').freeze DueThisMonth = DueDateStruct.new('Due This Month', 'month').freeze - ActsAsTaggableOn.strict_case_match = true - belongs_to :project belongs_to :moved_to, class_name: 'Issue' diff --git a/app/models/project.rb b/app/models/project.rb index 411299eef63..96ab7fdc99d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -70,8 +70,7 @@ class Project < ActiveRecord::Base after_validation :check_pending_delete - ActsAsTaggableOn.strict_case_match = true - acts_as_taggable_on :tags + acts_as_taggable attr_accessor :new_default_branch attr_accessor :old_path_with_namespace diff --git a/changelogs/unreleased/27989-disable-counting-tags.yml b/changelogs/unreleased/27989-disable-counting-tags.yml new file mode 100644 index 00000000000..988785ac454 --- /dev/null +++ b/changelogs/unreleased/27989-disable-counting-tags.yml @@ -0,0 +1,4 @@ +--- +title: Disable unused tags count cache for Projects, Builds and Runners +merge_request: +author: diff --git a/config/initializers/acts_as_taggable.rb b/config/initializers/acts_as_taggable.rb new file mode 100644 index 00000000000..c564c0cab11 --- /dev/null +++ b/config/initializers/acts_as_taggable.rb @@ -0,0 +1,5 @@ +ActsAsTaggableOn.strict_case_match = true + +# tags_counter enables caching count of tags which results in an update whenever a tag is added or removed +# since the count is not used anywhere its better performance wise to disable this cache +ActsAsTaggableOn.tags_counter = false From 5a2c68811712aecdece01ed203cda2ae2bb32ca9 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Thu, 9 Feb 2017 12:29:56 +0000 Subject: [PATCH 183/247] Fix MR changes tab size count This was wrong when there were over 100 files in the diff, because we did not use the same diff options as subclasses of `Gitlab::Diff::FileCollection::Base` when getting the raw diffs. (The reason we don't use those classes directly is because they may perform highlighting, which isn't needed for just counting the diffs.) --- app/models/merge_request.rb | 6 ++- .../fix-mr-size-with-over-100-files.yml | 4 ++ spec/models/merge_request_spec.rb | 44 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/fix-mr-size-with-over-100-files.yml diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 204d2b153ad..9076179b0b3 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -203,7 +203,11 @@ class MergeRequest < ActiveRecord::Base end def diff_size - opts = diff_options || {} + # The `#diffs` method ends up at an instance of a class inheriting from + # `Gitlab::Diff::FileCollection::Base`, so use those options as defaults + # here too, to get the same diff size without performing highlighting. + # + opts = Gitlab::Diff::FileCollection::Base.default_options.merge(diff_options || {}) raw_diffs(opts).size end diff --git a/changelogs/unreleased/fix-mr-size-with-over-100-files.yml b/changelogs/unreleased/fix-mr-size-with-over-100-files.yml new file mode 100644 index 00000000000..eecf3c99a75 --- /dev/null +++ b/changelogs/unreleased/fix-mr-size-with-over-100-files.yml @@ -0,0 +1,4 @@ +--- +title: Fix MR changes tab size count when there are over 100 files in the diff +merge_request: +author: diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index a01741a9971..fa1b0396bcf 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -209,6 +209,50 @@ describe MergeRequest, models: true do end end + describe '#diff_size' do + let(:merge_request) do + build(:merge_request, source_branch: 'expand-collapse-files', target_branch: 'master') + end + + context 'when there are MR diffs' do + before do + merge_request.save + end + + it 'returns the correct count' do + expect(merge_request.diff_size).to eq(105) + end + + it 'does not perform highlighting' do + expect(Gitlab::Diff::Highlight).not_to receive(:new) + + merge_request.diff_size + end + end + + context 'when there are no MR diffs' do + before do + merge_request.compare = CompareService.new( + merge_request.source_project, + merge_request.source_branch + ).execute( + merge_request.target_project, + merge_request.target_branch + ) + end + + it 'returns the correct count' do + expect(merge_request.diff_size).to eq(105) + end + + it 'does not perform highlighting' do + expect(Gitlab::Diff::Highlight).not_to receive(:new) + + merge_request.diff_size + end + end + end + describe "#related_notes" do let!(:merge_request) { create(:merge_request) } From abbc592ee1e06891d91700988e84b862a55b3e63 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 23 Feb 2017 13:37:19 +0100 Subject: [PATCH 184/247] Use POST in the endpoint description for :ressource/unsubscribe [ci skip] --- doc/api/issues.md | 2 +- doc/api/labels.md | 2 +- doc/api/merge_requests.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/issues.md b/doc/api/issues.md index 6cd701215e9..5266077e098 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -569,7 +569,7 @@ from it. If the user is not subscribed to the issue, the status code `304` is returned. ``` -DELETE /projects/:id/issues/:issue_id/unsubscribe +POST /projects/:id/issues/:issue_id/unsubscribe ``` | Attribute | Type | Required | Description | diff --git a/doc/api/labels.md b/doc/api/labels.md index a1e7eb1a7b1..8e0855fe9e2 100644 --- a/doc/api/labels.md +++ b/doc/api/labels.md @@ -228,7 +228,7 @@ from it. If the user is not subscribed to the label, the status code `304` is returned. ``` -DELETE /projects/:id/labels/:label_id/unsubscribe +POST /projects/:id/labels/:label_id/unsubscribe ``` | Attribute | Type | Required | Description | diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 2a99ae822d7..ea30a163a12 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -741,7 +741,7 @@ notifications from that merge request. If the user is not subscribed to the merge request, the status code `304` is returned. ``` -DELETE /projects/:id/merge_requests/:merge_request_id/unsubscribe +POST /projects/:id/merge_requests/:merge_request_id/unsubscribe ``` | Attribute | Type | Required | Description | From 1d38230a4a609dabacaad12eb7a632c17e8a8073 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 23 Feb 2017 14:15:06 +0100 Subject: [PATCH 185/247] Remove last merge_request endpoint --- lib/api/subscriptions.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb index acf11dbdf26..772b5cca017 100644 --- a/lib/api/subscriptions.rb +++ b/lib/api/subscriptions.rb @@ -3,7 +3,6 @@ module API before { authenticate! } subscribable_types = { - 'merge_request' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, 'merge_requests' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, 'issues' => proc { |id| find_project_issue(id) }, 'labels' => proc { |id| find_project_label(id) }, From 08e4d98cacb12f3d9b80b81ed1f50b9474c8b276 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Mon, 6 Feb 2017 18:59:54 +0200 Subject: [PATCH 186/247] Create master branch first if project is repository-less --- .../projects/branches_controller.rb | 20 +++++++-- app/helpers/projects_helper.rb | 16 +++++++ app/services/create_branch_service.rb | 14 ++++++ .../projects/branches_controller_spec.rb | 45 ++++++++++++++++++- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index 89d84809e3a..f815fa1387e 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -1,8 +1,10 @@ class Projects::BranchesController < Projects::ApplicationController include ActionView::Helpers::SanitizeHelper include SortingHelper + include ProjectsHelper + # Authorize - before_action :require_non_empty_project + before_action :require_non_empty_project, except: :create before_action :authorize_download_code! before_action :authorize_push_code!, only: [:new, :create, :destroy, :destroy_all_merged] @@ -32,6 +34,8 @@ class Projects::BranchesController < Projects::ApplicationController branch_name = sanitize(strip_tags(params[:branch_name])) branch_name = Addressable::URI.unescape(branch_name) + is_redirect_to_autodeploy_needed = project.empty_repo? && project.deployment_services.present? + result = CreateBranchService.new(project, current_user). execute(branch_name, ref) @@ -42,8 +46,16 @@ class Projects::BranchesController < Projects::ApplicationController if result[:status] == :success @branch = result[:branch] - redirect_to namespace_project_tree_path(@project.namespace, @project, - @branch.name) + + if is_redirect_to_autodeploy_needed + redirect_to( + url_to_autodeploy_setup(project, branch_name), + notice: "Branch \"#{sanitize(branch_name)}\" was created. To set up auto deploy, \ + choose a GitLab CI Yaml template and commit your changes. #{view_context.link_to_autodeploy_doc}".html_safe) + else + redirect_to namespace_project_tree_path(@project.namespace, @project, + @branch.name) + end else @error = result[:message] render action: 'new' @@ -76,7 +88,7 @@ class Projects::BranchesController < Projects::ApplicationController ref_escaped = sanitize(strip_tags(params[:ref])) Addressable::URI.unescape(ref_escaped) else - @project.default_branch + @project.default_branch || 'master' end end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index eb98204285d..6684d7c456e 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -150,6 +150,10 @@ module ProjectsHelper ).html_safe end + def link_to_autodeploy_doc + link_to 'About auto deploy', help_page_path('ci/autodeploy/index'), target: '_blank' + end + private def repo_children_classes(field) @@ -268,6 +272,18 @@ module ProjectsHelper ) end + def url_to_autodeploy_setup(project, branch_name) + namespace_project_new_blob_path( + project.namespace, + project, + branch_name, + file_name: '.gitlab-ci.yml', + commit_message: 'Set up auto deploy', + target_branch: branch_name, + context: 'autodeploy' + ) + end + def add_koding_stack_path(project) namespace_project_new_blob_path( project.namespace, diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 77459d8779d..b07338d500a 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -1,5 +1,7 @@ class CreateBranchService < BaseService def execute(branch_name, ref) + create_master_branch if project.empty_repo? + result = ValidateNewBranchService.new(project, current_user) .execute(branch_name) @@ -19,4 +21,16 @@ class CreateBranchService < BaseService def success(branch) super().merge(branch: branch) end + + private + + def create_master_branch + project.repository.commit_file( + current_user, + '/README.md', + '', + message: 'Add README.md', + branch_name: 'master', + update: false) + end end diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 9de03876755..3ab3a0eb3e8 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -68,7 +68,7 @@ describe Projects::BranchesController do describe "created from the new branch button on issues" do let(:branch) { "1-feature-branch" } - let!(:issue) { create(:issue, project: project) } + let(:issue) { create(:issue, project: project) } before do sign_in(user) @@ -95,6 +95,49 @@ describe Projects::BranchesController do issue_iid: issue.iid end + context 'repository-less project' do + let(:project) { create :empty_project } + + it 'redirects to newly created branch' do + result = { status: :success, branch: double(name: branch) } + + expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result) + expect(SystemNoteService).to receive(:new_issue_branch).and_return(true) + + post :create, + namespace_id: project.namespace.to_param, + project_id: project.to_param, + branch_name: branch, + issue_iid: issue.iid + + expect(response).to redirect_to namespace_project_tree_path(project.namespace, project, branch) + end + + it 'redirects to autodeploy setup page' do + result = { status: :success, branch: double(name: branch) } + + project.create_kubernetes_service( + active: true, + properties: { + namespace: project.path, + api_url: 'https://kubernetes.example.com', + token: 'a' * 40, + } + ) + + expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result) + expect(SystemNoteService).to receive(:new_issue_branch).and_return(true) + + post :create, + namespace_id: project.namespace.to_param, + project_id: project.to_param, + branch_name: branch, + issue_iid: issue.iid + + expect(response.location).to include(namespace_project_new_blob_path(project.namespace, project, branch)) + end + end + context 'without issue feature access' do before do project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) From ef27b4beb35745c162df5a4ff8f83ec6ccc91df0 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 7 Feb 2017 15:10:10 +0200 Subject: [PATCH 187/247] update changelog --- changelogs/unreleased/create_branch_repo_less.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changelogs/unreleased/create_branch_repo_less.yml diff --git a/changelogs/unreleased/create_branch_repo_less.yml b/changelogs/unreleased/create_branch_repo_less.yml new file mode 100644 index 00000000000..263c6cb78c4 --- /dev/null +++ b/changelogs/unreleased/create_branch_repo_less.yml @@ -0,0 +1,4 @@ +--- +title: Create new branch from issue for repo-less project using new branch button +merge_request: +author: From d52ef5efd03423006717018d3c3b9d6ff11a378b Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 7 Feb 2017 17:59:38 +0200 Subject: [PATCH 188/247] Fixes after review --- .../projects/branches_controller.rb | 20 ++++++++++++++----- app/helpers/projects_helper.rb | 17 +++++----------- .../unreleased/create_branch_repo_less.yml | 2 +- .../projects/branches_controller_spec.rb | 10 ++-------- spec/factories/services.rb | 10 ++++++++++ 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index f815fa1387e..a01c0caa959 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -1,7 +1,6 @@ class Projects::BranchesController < Projects::ApplicationController include ActionView::Helpers::SanitizeHelper include SortingHelper - include ProjectsHelper # Authorize before_action :require_non_empty_project, except: :create @@ -34,7 +33,7 @@ class Projects::BranchesController < Projects::ApplicationController branch_name = sanitize(strip_tags(params[:branch_name])) branch_name = Addressable::URI.unescape(branch_name) - is_redirect_to_autodeploy_needed = project.empty_repo? && project.deployment_services.present? + redirect_to_autodeploy = project.empty_repo? && project.deployment_services.present? result = CreateBranchService.new(project, current_user). execute(branch_name, ref) @@ -47,11 +46,10 @@ class Projects::BranchesController < Projects::ApplicationController if result[:status] == :success @branch = result[:branch] - if is_redirect_to_autodeploy_needed + if redirect_to_autodeploy redirect_to( url_to_autodeploy_setup(project, branch_name), - notice: "Branch \"#{sanitize(branch_name)}\" was created. To set up auto deploy, \ - choose a GitLab CI Yaml template and commit your changes. #{view_context.link_to_autodeploy_doc}".html_safe) + notice: view_context.autodeploy_flash_notice(branch_name)) else redirect_to namespace_project_tree_path(@project.namespace, @project, @branch.name) @@ -91,4 +89,16 @@ class Projects::BranchesController < Projects::ApplicationController @project.default_branch || 'master' end end + + def url_to_autodeploy_setup(project, branch_name) + namespace_project_new_blob_path( + project.namespace, + project, + branch_name, + file_name: '.gitlab-ci.yml', + commit_message: 'Set up auto deploy', + target_branch: branch_name, + context: 'autodeploy' + ) + end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6684d7c456e..735a355c25a 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -154,6 +154,11 @@ module ProjectsHelper link_to 'About auto deploy', help_page_path('ci/autodeploy/index'), target: '_blank' end + def autodeploy_flash_notice(branch_name) + "Branch #{truncate(sanitize(branch_name))} was created. To set up auto deploy, \ + choose a GitLab CI Yaml template and commit your changes. #{link_to_autodeploy_doc}".html_safe + end + private def repo_children_classes(field) @@ -272,18 +277,6 @@ module ProjectsHelper ) end - def url_to_autodeploy_setup(project, branch_name) - namespace_project_new_blob_path( - project.namespace, - project, - branch_name, - file_name: '.gitlab-ci.yml', - commit_message: 'Set up auto deploy', - target_branch: branch_name, - context: 'autodeploy' - ) - end - def add_koding_stack_path(project) namespace_project_new_blob_path( project.namespace, diff --git a/changelogs/unreleased/create_branch_repo_less.yml b/changelogs/unreleased/create_branch_repo_less.yml index 263c6cb78c4..e8b14fa3b67 100644 --- a/changelogs/unreleased/create_branch_repo_less.yml +++ b/changelogs/unreleased/create_branch_repo_less.yml @@ -1,4 +1,4 @@ --- -title: Create new branch from issue for repo-less project using new branch button +title: Creating a new branch from an issue will automatically initialize a repository if one doesn't already exist. merge_request: author: diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 3ab3a0eb3e8..effd8bcd982 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -116,14 +116,7 @@ describe Projects::BranchesController do it 'redirects to autodeploy setup page' do result = { status: :success, branch: double(name: branch) } - project.create_kubernetes_service( - active: true, - properties: { - namespace: project.path, - api_url: 'https://kubernetes.example.com', - token: 'a' * 40, - } - ) + project.services << build(:kubernetes_service) expect_any_instance_of(CreateBranchService).to receive(:execute).and_return(result) expect(SystemNoteService).to receive(:new_issue_branch).and_return(true) @@ -135,6 +128,7 @@ describe Projects::BranchesController do issue_iid: issue.iid expect(response.location).to include(namespace_project_new_blob_path(project.namespace, project, branch)) + expect(response).to have_http_status(302) end end diff --git a/spec/factories/services.rb b/spec/factories/services.rb index a14a46c803e..51335bdcf1d 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -2,4 +2,14 @@ FactoryGirl.define do factory :service do project factory: :empty_project end + + factory :kubernetes_service do + project factory: :empty_project + active true + properties({ + namespace: 'somepath', + api_url: 'https://kubernetes.example.com', + token: 'a' * 40, + }) + end end From 66bca235c1e4e14037100551706abc127b7bb650 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Thu, 23 Feb 2017 13:44:58 +0000 Subject: [PATCH 189/247] Adds missing tests for all status accepted in scope --- .../projects/pipelines_controller_spec.rb | 15 ++++++---- .../projects/pipelines/pipelines_spec.rb | 29 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 242cf18c42b..9a1e79c281a 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -12,7 +12,10 @@ describe Projects::PipelinesController do describe 'GET index.json' do before do - create_list(:ci_empty_pipeline, 2, project: project) + create(:ci_empty_pipeline, status: 'pending', project: project) + create(:ci_empty_pipeline, status: 'running', project: project) + create(:ci_empty_pipeline, status: 'created', project: project) + create(:ci_empty_pipeline, status: 'success', project: project) get :index, namespace_id: project.namespace.path, project_id: project.path, @@ -23,11 +26,11 @@ describe Projects::PipelinesController do expect(response).to have_http_status(:ok) expect(json_response).to include('pipelines') - expect(json_response['pipelines'].count).to eq 2 - expect(json_response['count']['all']).to eq 2 - expect(json_response['count']['running']).to eq 0 - expect(json_response['count']['pending']).to eq 2 - expect(json_response['count']['finished']).to eq 0 + expect(json_response['pipelines'].count).to eq 4 + expect(json_response['count']['all']).to eq 4 + expect(json_response['count']['running']).to eq 1 + expect(json_response['count']['pending']).to eq 1 + expect(json_response['count']['finished']).to eq 1 end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 289cc36c8b5..592dc4483d2 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -26,18 +26,27 @@ describe 'Pipelines', :feature, :js do ) end - [:all, :running, :branches].each do |scope| - context "when displaying #{scope}" do - before do - visit_project_pipelines(scope: scope) - end + context 'scope' do + before do + create(:ci_empty_pipeline, status: 'pending', project: project, sha: project.commit.id, ref: 'master') + create(:ci_empty_pipeline, status: 'running', project: project, sha: project.commit.id, ref: 'master') + create(:ci_empty_pipeline, status: 'created', project: project, sha: project.commit.id, ref: 'master') + create(:ci_empty_pipeline, status: 'success', project: project, sha: project.commit.id, ref: 'master') + end - it 'contains pipeline commit short SHA' do - expect(page).to have_content(pipeline.short_sha) - end + [:all, :running, :pending, :finished, :branches].each do |scope| + context "when displaying #{scope}" do + before do + visit_project_pipelines(scope: scope) + end - it 'contains branch name' do - expect(page).to have_content(pipeline.ref) + it 'contains pipeline commit short SHA' do + expect(page).to have_content(pipeline.short_sha) + end + + it 'contains branch name' do + expect(page).to have_content(pipeline.ref) + end end end end From 128232fcf4e7ec7786f1ebf9610cf75ef5f76b8c Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Thu, 23 Feb 2017 07:54:26 -0600 Subject: [PATCH 190/247] Fix white square and sidebar animation --- app/assets/stylesheets/framework/sidebar.scss | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 040a7ce0c16..8978e284f55 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -29,16 +29,14 @@ } } -@media (min-width: $screen-sm-min) { - .content-wrapper { - padding-right: $gutter_collapsed_width; - } -} - .right-sidebar-collapsed { padding-right: 0; @media (min-width: $screen-sm-min) { + .content-wrapper { + padding-right: $gutter_collapsed_width; + } + .merge-request-tabs-holder.affix { right: $gutter_collapsed_width; } @@ -56,6 +54,12 @@ .right-sidebar-expanded { padding-right: 0; + @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) { + .content-wrapper { + padding-right: $gutter_collapsed_width; + } + } + @media (min-width: $screen-md-min) { .content-wrapper { padding-right: $gutter_width; From ca378aa34c890db9e8f5031413661827680a0701 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 23 Feb 2017 14:56:27 +0100 Subject: [PATCH 191/247] Fix Rubocop offense in OptimisticLocking module --- lib/gitlab/optimistic_locking.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/optimistic_locking.rb b/lib/gitlab/optimistic_locking.rb index e0b2286f1dc..8c47c807bf9 100644 --- a/lib/gitlab/optimistic_locking.rb +++ b/lib/gitlab/optimistic_locking.rb @@ -16,6 +16,6 @@ module Gitlab end end - alias :retry_optimistic_lock :retry_lock + alias_method :retry_optimistic_lock, :retry_lock end end From ad57fcacd1b499982214117447a96c65dac0c87d Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 23 Feb 2017 14:11:11 +0000 Subject: [PATCH 192/247] Upgrade GitLab Pages to v0.3.2 --- GITLAB_PAGES_VERSION | 2 +- changelogs/unreleased/pages-0-3-2.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/pages-0-3-2.yml diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION index 9e11b32fcaa..d15723fbe8d 100644 --- a/GITLAB_PAGES_VERSION +++ b/GITLAB_PAGES_VERSION @@ -1 +1 @@ -0.3.1 +0.3.2 diff --git a/changelogs/unreleased/pages-0-3-2.yml b/changelogs/unreleased/pages-0-3-2.yml new file mode 100644 index 00000000000..f660379f2e6 --- /dev/null +++ b/changelogs/unreleased/pages-0-3-2.yml @@ -0,0 +1,4 @@ +--- +title: Upgrade GitLab Pages to v0.3.2 +merge_request: +author: From da67dca14b926f09a64a2dc40777105393f572cb Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 23 Feb 2017 14:21:03 +0100 Subject: [PATCH 193/247] Use grape to validate parameters in the members API --- lib/api/members.rb | 7 +++---- lib/api/v3/members.rb | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/api/members.rb b/lib/api/members.rb index d1d78775c6d..8360c007005 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -79,13 +79,12 @@ module API optional :expires_at, type: DateTime, desc: 'Date string in the format YEAR-MONTH-DAY' end put ":id/members/:user_id" do - source = find_source(source_type, params[:id]) + source = find_source(source_type, params.delete(:id)) authorize_admin_source!(source_type, source) - member = source.members.find_by!(user_id: params[:user_id]) - attrs = attributes_for_keys [:access_level, :expires_at] + member = source.members.find_by!(user_id: params.delete(:user_id)) - if member.update_attributes(attrs) + if member.update_attributes(declared_params(include_missing: false)) present member.user, with: Entities::Member, member: member else # This is to ensure back-compatibility but 400 behavior should be used diff --git a/lib/api/v3/members.rb b/lib/api/v3/members.rb index 4e6cb2e3c52..19f276d5484 100644 --- a/lib/api/v3/members.rb +++ b/lib/api/v3/members.rb @@ -86,13 +86,12 @@ module API optional :expires_at, type: DateTime, desc: 'Date string in the format YEAR-MONTH-DAY' end put ":id/members/:user_id" do - source = find_source(source_type, params[:id]) + source = find_source(source_type, params.delete(:id)) authorize_admin_source!(source_type, source) - member = source.members.find_by!(user_id: params[:user_id]) - attrs = attributes_for_keys [:access_level, :expires_at] + member = source.members.find_by!(user_id: params.delete(:user_id)) - if member.update_attributes(attrs) + if member.update_attributes(declared_params(include_missing: false)) present member.user, with: ::API::Entities::Member, member: member else # This is to ensure back-compatibility but 400 behavior should be used From 8b2ea599e3047b24a788dec843ea1d6d36e76d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Thu, 23 Feb 2017 16:04:34 +0100 Subject: [PATCH 194/247] Enable the RSpec/BeEql cop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- .rubocop.yml | 2 +- spec/lib/gitlab/ldap/user_spec.rb | 4 ++-- spec/lib/gitlab/o_auth/user_spec.rb | 4 ++-- spec/lib/gitlab/saml/user_spec.rb | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a836b469cc7..4bcabd18d4d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -784,7 +784,7 @@ RSpec/AnyInstance: # Check for expectations where `be(...)` can replace `eql(...)`. RSpec/BeEql: - Enabled: false + Enabled: true # Check that the first argument to the top level describe is the tested class or # module. diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index 89790c9e1af..2f3bd4393b7 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -95,10 +95,10 @@ describe Gitlab::LDAP::User, lib: true do it 'maintains an identity per provider' do existing_user = create(:omniauth_user, email: 'john@example.com', provider: 'twitter') - expect(existing_user.identities.count).to eql(1) + expect(existing_user.identities.count).to be(1) ldap_user.save - expect(ldap_user.gl_user.identities.count).to eql(2) + expect(ldap_user.gl_user.identities.count).to be(2) # Expect that find_by provider only returns a single instance of an identity and not an Enumerable expect(ldap_user.gl_user.identities.find_by(provider: 'twitter')).to be_instance_of Identity diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index fc9e1cb430a..0d950406c7f 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -148,7 +148,7 @@ describe Gitlab::OAuth::User, lib: true do expect(gl_user).to be_valid expect(gl_user.username).to eql uid expect(gl_user.email).to eql 'johndoe@example.com' - expect(gl_user.identities.length).to eql 2 + expect(gl_user.identities.length).to be 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, @@ -167,7 +167,7 @@ describe Gitlab::OAuth::User, lib: true do expect(gl_user).to be_valid expect(gl_user.username).to eql 'john' expect(gl_user.email).to eql 'john@example.com' - expect(gl_user.identities.length).to eql 2 + expect(gl_user.identities.length).to be 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index 02c139f1a0d..acefb18ff43 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -155,7 +155,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user).to be_valid expect(gl_user.username).to eql uid expect(gl_user.email).to eql 'john@mail.com' - expect(gl_user.identities.length).to eql 2 + expect(gl_user.identities.length).to be 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'saml', extern_uid: uid } @@ -178,7 +178,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user).to be_valid expect(gl_user.username).to eql 'john' expect(gl_user.email).to eql 'john@mail.com' - expect(gl_user.identities.length).to eql 2 + expect(gl_user.identities.length).to be 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'saml', extern_uid: uid } @@ -204,7 +204,7 @@ describe Gitlab::Saml::User, lib: true do local_gl_user = local_saml_user.gl_user expect(local_gl_user).to be_valid - expect(local_gl_user.identities.length).to eql 2 + expect(local_gl_user.identities.length).to be 2 identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } From 485ac92244d75403ab6238278595d9bc15e254bb Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Thu, 23 Feb 2017 15:09:11 +0000 Subject: [PATCH 195/247] Fix GitAccess specs These specs never ran due to incorrect indentation: the `context` blocks were inside the `before`. Additionally, `GitHooksService` now has to yield itself to callers, and `GitAccess` never appears to have had an `allowed?` method. --- spec/lib/gitlab/git_access_spec.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index a55bd4387e0..3bfa3928a07 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -199,7 +199,9 @@ describe Gitlab::GitAccess, lib: true do def stub_git_hooks # Running the `pre-receive` hook is expensive, and not necessary for this test. - allow_any_instance_of(GitHooksService).to receive(:execute).and_yield + allow_any_instance_of(GitHooksService).to receive(:execute) do |service, &block| + block.call(service) + end end def merge_into_protected_branch @@ -232,11 +234,18 @@ describe Gitlab::GitAccess, lib: true do else project.team << [user, role] end + end - permissions_matrix[role].each do |action, allowed| - context action do - subject { access.send(:check_push_access!, changes[action]) } - it { expect(subject.allowed?).to allowed ? be_truthy : be_falsey } + permissions_matrix[role].each do |action, allowed| + context action do + subject { access.send(:check_push_access!, changes[action]) } + + it do + if allowed + expect { subject }.not_to raise_error + else + expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError) + end end end end From 547063b3ac096dff25309b6e0846b0d5f417c128 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:04:05 -0600 Subject: [PATCH 196/247] Update .rubocop_todo.yml --- .rubocop_todo.yml | 555 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 436 insertions(+), 119 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a5b4d2f5b02..6033390d8e6 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,76 +1,103 @@ # This configuration was generated by -# `rubocop --auto-gen-config --exclude-limit 0` -# on 2017-01-11 09:38:25 +0000 using RuboCop version 0.46.0. +# `rubocop --auto-gen-config` +# on 2017-02-21 18:00:50 -0600 using RuboCop version 0.46.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 27 +# Offense count: 28 # Configuration parameters: Include. # Include: **/Gemfile, **/gems.rb Bundler/OrderedGems: - Enabled: false + Exclude: + - 'Gemfile' -# Offense count: 175 +# Offense count: 176 Lint/AmbiguousRegexpLiteral: Enabled: false -# Offense count: 53 +# Offense count: 54 # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: Enabled: false -# Offense count: 20 +# Offense count: 23 Lint/HandleExceptions: Enabled: false # Offense count: 1 Lint/Loop: - Enabled: false + Exclude: + - 'app/mailers/notify.rb' -# Offense count: 27 +# Offense count: 32 Lint/ShadowingOuterLocalVariable: Enabled: false # Offense count: 10 # Cop supports --auto-correct. Lint/UnifiedInteger: - Enabled: false + Exclude: + - 'spec/lib/gitlab/metrics/method_call_spec.rb' + - 'spec/lib/gitlab/metrics/metric_spec.rb' + - 'spec/lib/gitlab/metrics/system_spec.rb' + - 'spec/lib/gitlab/metrics/transaction_spec.rb' + - 'spec/models/repository_spec.rb' -# Offense count: 21 +# Offense count: 23 # Cop supports --auto-correct. Lint/UnneededSplatExpansion: - Enabled: false + Exclude: + - 'app/services/projects/update_pages_service.rb' + - 'config/application.rb' + - 'lib/banzai/filter/gollum_tags_filter.rb' + - 'lib/bitbucket/page.rb' + - 'lib/gitlab/markup_helper.rb' + - 'spec/helpers/auth_helper_spec.rb' + - 'spec/models/project_wiki_spec.rb' + - 'spec/requests/api/projects_spec.rb' + - 'spec/requests/api/tags_spec.rb' + - 'spec/requests/api/v3/projects_spec.rb' + - 'spec/support/seed_helper.rb' + - 'spec/support/test_env.rb' -# Offense count: 82 +# Offense count: 89 # Cop supports --auto-correct. # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. Lint/UnusedBlockArgument: Enabled: false -# Offense count: 173 +# Offense count: 171 # Cop supports --auto-correct. # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods. Lint/UnusedMethodArgument: Enabled: false -# Offense count: 93 +# Offense count: 114 # Configuration parameters: CountComments. Metrics/BlockLength: - Enabled: false + Max: 302 # Offense count: 3 # Cop supports --auto-correct. Performance/RedundantBlockCall: - Enabled: false + Exclude: + - 'app/controllers/application_controller.rb' + - 'lib/gitlab/optimistic_locking.rb' + - 'lib/gitlab/shell.rb' # Offense count: 5 # Cop supports --auto-correct. Performance/RedundantMatch: - Enabled: false + Exclude: + - 'app/models/external_issue.rb' + - 'lib/ci/api/helpers.rb' + - 'lib/extracts_path.rb' + - 'lib/gitlab/diff/highlight.rb' + - 'lib/gitlab/diff/parser.rb' -# Offense count: 32 +# Offense count: 25 # Cop supports --auto-correct. # Configuration parameters: MaxKeyValuePairs. Performance/RedundantMerge: @@ -79,9 +106,15 @@ Performance/RedundantMerge: # Offense count: 15 # Configuration parameters: CustomIncludeMethods. RSpec/EmptyExampleGroup: - Enabled: false + Exclude: + - 'spec/features/issues_spec.rb' + - 'spec/features/notes_on_merge_requests_spec.rb' + - 'spec/lib/gitlab/git_access_spec.rb' + - 'spec/models/project_snippet_spec.rb' + - 'spec/models/protected_branch_spec.rb' + - 'spec/routing/routing_spec.rb' -# Offense count: 58 +# Offense count: 63 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: implicit, each, example RSpec/HookArgument: @@ -91,147 +124,223 @@ RSpec/HookArgument: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: is_expected, should RSpec/ImplicitExpect: - Enabled: false + Exclude: + - 'spec/lib/banzai/renderer_spec.rb' + - 'spec/models/project_group_link_spec.rb' + - 'spec/models/project_services/external_wiki_service_spec.rb' + - 'spec/models/project_spec.rb' -# Offense count: 237 +# Offense count: 258 RSpec/LeadingSubject: Enabled: false -# Offense count: 253 +# Offense count: 281 RSpec/LetSetup: Enabled: false # Offense count: 13 RSpec/MessageChain: - Enabled: false + Exclude: + - 'spec/finders/move_to_project_finder_spec.rb' + - 'spec/helpers/issues_helper_spec.rb' + - 'spec/initializers/secret_token_spec.rb' + - 'spec/models/ci/build_spec.rb' + - 'spec/requests/api/internal_spec.rb' + - 'spec/services/ci/retry_build_service_spec.rb' + - 'spec/services/ci/retry_pipeline_service_spec.rb' + - 'spec/services/merge_requests/build_service_spec.rb' + - 'spec/workers/emails_on_push_worker_spec.rb' -# Offense count: 479 +# Offense count: 505 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: have_received, receive RSpec/MessageSpies: Enabled: false -# Offense count: 3036 +# Offense count: 3625 RSpec/MultipleExpectations: - Enabled: false + Max: 37 -# Offense count: 2133 +# Offense count: 2217 RSpec/NamedSubject: Enabled: false -# Offense count: 1974 +# Offense count: 2126 # Configuration parameters: MaxNesting. RSpec/NestedGroups: Enabled: false -# Offense count: 32 +# Offense count: 36 RSpec/RepeatedDescription: - Enabled: false + Exclude: + - 'spec/controllers/projects/todo_controller_spec.rb' + - 'spec/features/boards/boards_spec.rb' + - 'spec/helpers/issuables_helper_spec.rb' + - 'spec/lib/banzai/filter/emoji_filter_spec.rb' + - 'spec/models/commit_range_spec.rb' + - 'spec/models/global_milestone_spec.rb' + - 'spec/models/hooks/system_hook_spec.rb' + - 'spec/requests/api/commits_spec.rb' + - 'spec/requests/api/merge_requests_spec.rb' + - 'spec/requests/api/milestones_spec.rb' + - 'spec/requests/api/users_spec.rb' + - 'spec/requests/api/v3/merge_requests_spec.rb' + - 'spec/requests/lfs_http_spec.rb' + - 'spec/routing/admin_routing_spec.rb' + - 'spec/services/notification_service_spec.rb' # Offense count: 1 RSpec/SingleArgumentMessageChain: - Enabled: false + Exclude: + - 'spec/requests/api/internal_spec.rb' -# Offense count: 133 +# Offense count: 140 RSpec/SubjectStub: Enabled: false -# Offense count: 104 +# Offense count: 126 # Cop supports --auto-correct. # Configuration parameters: Whitelist. # Whitelist: find_by_sql Rails/DynamicFindBy: Enabled: false -# Offense count: 932 +# Offense count: 1162 # Cop supports --auto-correct. # Configuration parameters: Include. # Include: spec/**/*, test/**/* Rails/HttpPositionalArguments: Enabled: false -# Offense count: 55 +# Offense count: 56 Rails/OutputSafety: Enabled: false -# Offense count: 182 +# Offense count: 202 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: strict, flexible Rails/TimeZone: Enabled: false -# Offense count: 15 +# Offense count: 16 # Cop supports --auto-correct. # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/Validation: - Enabled: false + Exclude: + - 'app/models/ci/build.rb' + - 'app/models/ci/pipeline.rb' + - 'app/models/ci/runner_project.rb' + - 'app/models/ci/trigger.rb' + - 'app/models/commit_status.rb' + - 'app/models/members/group_member.rb' + - 'app/models/members/project_member.rb' + - 'app/models/pages_domain.rb' + - 'app/models/project.rb' + - 'app/models/protected_branch.rb' + - 'app/models/user.rb' # Offense count: 8 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect. Security/JSONLoad: - Enabled: false + Exclude: + - 'db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb' + - 'db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb' + - 'db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb' + - 'spec/migrations/migrate_process_commit_worker_jobs_spec.rb' + - 'spec/models/project_services/irker_service_spec.rb' + - 'spec/support/stub_gitlab_calls.rb' -# Offense count: 346 +# Offense count: 431 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: with_first_parameter, with_fixed_indentation Style/AlignParameters: Enabled: false -# Offense count: 54 +# Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: percent_q, bare_percent Style/BarePercentLiterals: Enabled: false -# Offense count: 358 +# Offense count: 399 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: braces, no_braces, context_dependent Style/BracesAroundHashParameters: Enabled: false -# Offense count: 6 +# Offense count: 7 Style/CaseEquality: - Enabled: false + Exclude: + - 'app/helpers/auth_helper.rb' + - 'app/helpers/builds_helper.rb' + - 'app/models/commit.rb' + - 'app/models/protected_branch.rb' + - 'app/services/projects/download_service.rb' + - 'config/initializers/trusted_proxies.rb' + - 'lib/gitlab/route_map.rb' -# Offense count: 37 +# Offense count: 33 # Cop supports --auto-correct. Style/ColonMethodCall: Enabled: false -# Offense count: 4 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: Keywords. # Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW Style/CommentAnnotation: - Enabled: false + Exclude: + - 'config/routes/user.rb' + - 'spec/requests/api/v3/project_snippets_spec.rb' -# Offense count: 29 +# Offense count: 32 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Enabled: false -# Offense count: 1210 +# Offense count: 1304 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: leading, trailing Style/DotPosition: Enabled: false -# Offense count: 18 +# Offense count: 21 Style/DoubleNegation: - Enabled: false + Exclude: + - 'app/controllers/users_controller.rb' + - 'app/models/commit.rb' + - 'app/models/merge_request.rb' + - 'app/models/project.rb' + - 'app/models/project_services/buildkite_service.rb' + - 'app/models/project_services/drone_ci_service.rb' + - 'app/models/project_wiki.rb' + - 'app/models/user.rb' + - 'config/initializers/6_validations.rb' + - 'lib/banzai/filter/abstract_reference_filter.rb' + - 'lib/banzai/filter/relative_link_filter.rb' + - 'lib/gitlab/git/diff_collection.rb' + - 'lib/gitlab/git/repository.rb' + - 'lib/gitlab/sherlock.rb' + - 'lib/gitlab/sherlock/middleware.rb' -# Offense count: 7 +# Offense count: 6 # Cop supports --auto-correct. Style/EachWithObject: - Enabled: false + Exclude: + - 'app/services/merge_requests/get_urls_service.rb' + - 'lib/ci/ansi2html.rb' + - 'lib/expand_variables.rb' + - 'lib/gitlab/ee_compat_check.rb' + - 'lib/gitlab/import_export/members_mapper.rb' + - 'lib/gitlab/import_export/relation_factory.rb' # Offense count: 24 # Cop supports --auto-correct. @@ -243,16 +352,20 @@ Style/EmptyElse: # Offense count: 4 # Cop supports --auto-correct. Style/EmptyLiteral: - Enabled: false + Exclude: + - 'features/steps/project/commits/commits.rb' + - 'lib/gitlab/fogbugz_import/importer.rb' + - 'lib/gitlab/git/diff_collection.rb' + - 'spec/lib/gitlab/workhorse_spec.rb' -# Offense count: 57 +# Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: compact, expanded Style/EmptyMethod: Enabled: false -# Offense count: 147 +# Offense count: 173 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. Style/ExtraSpacing: @@ -262,64 +375,110 @@ Style/ExtraSpacing: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: format, sprintf, percent Style/FormatString: - Enabled: false + Exclude: + - 'app/models/ci/pipeline.rb' + - 'app/services/gravatar_service.rb' + - 'config/initializers/rack_lineprof.rb' + - 'lib/gitlab/version_info.rb' + - 'spec/factories/lfs_objects.rb' + - 'spec/services/issues/move_service_spec.rb' -# Offense count: 238 +# Offense count: 261 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false -# Offense count: 11 +# Offense count: 12 Style/IfInsideElse: - Enabled: false + Exclude: + - 'app/controllers/projects/forks_controller.rb' + - 'app/controllers/projects/imports_controller.rb' + - 'app/helpers/milestones_helper.rb' + - 'app/helpers/projects_helper.rb' + - 'app/services/system_note_service.rb' + - 'config/initializers/1_settings.rb' + - 'lib/gitlab/auth.rb' + - 'lib/gitlab/checks/change_access.rb' + - 'lib/gitlab/database.rb' + - 'spec/controllers/projects/merge_requests_controller_spec.rb' + - 'spec/support/import_export/export_file_helper.rb' -# Offense count: 173 +# Offense count: 178 # Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: Enabled: false -# Offense count: 55 +# Offense count: 61 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_brackets Style/IndentArray: Enabled: false -# Offense count: 101 +# Offense count: 110 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces Style/IndentHash: Enabled: false -# Offense count: 41 +# Offense count: 45 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: line_count_dependent, lambda, literal Style/Lambda: Enabled: false -# Offense count: 5 +# Offense count: 7 # Cop supports --auto-correct. Style/LineEndConcatenation: - Enabled: false + Exclude: + - 'app/helpers/tree_helper.rb' + - 'app/models/merge_request.rb' + - 'app/services/git_operation_service.rb' + - 'spec/lib/gitlab/gfm/reference_rewriter_spec.rb' + - 'spec/lib/gitlab/incoming_email_spec.rb' -# Offense count: 19 +# Offense count: 22 # Cop supports --auto-correct. Style/MethodCallParentheses: - Enabled: false + Exclude: + - 'lib/ci/ansi2html.rb' + - 'spec/controllers/projects/issues_controller_spec.rb' + - 'spec/controllers/projects/merge_requests_controller_spec.rb' + - 'spec/controllers/projects/snippets_controller_spec.rb' + - 'spec/features/dashboard/datetime_on_tooltips_spec.rb' + - 'spec/features/issues/filtered_search/dropdown_assignee_spec.rb' + - 'spec/features/issues/filtered_search/dropdown_author_spec.rb' + - 'spec/features/issues/filtered_search/dropdown_milestone_spec.rb' + - 'spec/features/issues/filtered_search/filter_issues_spec.rb' + - 'spec/helpers/submodule_helper_spec.rb' + - 'spec/lib/gitlab/git/repository_spec.rb' + - 'spec/requests/api/internal_spec.rb' # Offense count: 9 Style/MethodMissing: - Enabled: false + Exclude: + - 'app/controllers/projects/application_controller.rb' + - 'app/models/commit.rb' + - 'app/models/network/commit.rb' + - 'app/models/repository.rb' + - 'config/initializers/gollum.rb' + - 'lib/bitbucket/collection.rb' + - 'lib/gitlab/github_import/client.rb' + - 'lib/gitlab/lazy.rb' + - 'lib/uploaded_file.rb' # Offense count: 3 # Cop supports --auto-correct. Style/MultilineIfModifier: - Enabled: false + Exclude: + - 'app/helpers/snippets_helper.rb' + - 'app/models/project_wiki.rb' + - 'lib/gitlab/workhorse.rb' -# Offense count: 179 +# Offense count: 187 # Cop supports --auto-correct. Style/MutableConstant: Enabled: false @@ -327,35 +486,64 @@ Style/MutableConstant: # Offense count: 8 # Cop supports --auto-correct. Style/NestedParenthesizedCalls: - Enabled: false + Exclude: + - 'app/helpers/commits_helper.rb' + - 'app/workers/irker_worker.rb' + - 'spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb' + - 'spec/lib/gitlab/email/message/repository_push_spec.rb' -# Offense count: 13 +# Offense count: 15 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. # SupportedStyles: skip_modifier_ifs, always Style/Next: - Enabled: false + Exclude: + - 'app/models/namespace.rb' + - 'app/models/user.rb' + - 'app/services/merge_requests/refresh_service.rb' + - 'config/initializers/secret_token.rb' + - 'db/migrate/20161220141214_remove_dot_git_from_group_names.rb' + - 'db/migrate/20161226122833_remove_dot_git_from_usernames.rb' + - 'lib/banzai/filter/math_filter.rb' + - 'lib/banzai/filter/table_of_contents_filter.rb' + - 'lib/gitlab/fogbugz_import/importer.rb' + - 'lib/gitlab/metrics/instrumentation.rb' + - 'lib/gitlab/metrics/sampler.rb' + - 'lib/gitlab/project_search_results.rb' # Offense count: 19 # Cop supports --auto-correct. # Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles. # SupportedOctalStyles: zero_with_o, zero_only Style/NumericLiteralPrefix: - Enabled: false + Exclude: + - 'config/initializers/1_settings.rb' + - 'config/initializers/secret_token.rb' + - 'lib/gitlab/import_export/command_line_util.rb' + - 'lib/gitlab/shell.rb' + - 'lib/gitlab/workhorse.rb' + - 'spec/features/projects/import_export/export_file_spec.rb' + - 'spec/lib/gitlab/git/blob_spec.rb' + - 'spec/lib/gitlab/git/hook_spec.rb' + - 'spec/lib/gitlab/git/repository_spec.rb' + - 'spec/lib/gitlab/workhorse_spec.rb' + - 'spec/support/import_export/export_file_helper.rb' + - 'spec/support/test_env.rb' + - 'spec/tasks/gitlab/backup_rake_spec.rb' -# Offense count: 19 +# Offense count: 68 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles. # SupportedStyles: predicate, comparison Style/NumericPredicate: Enabled: false -# Offense count: 34 +# Offense count: 36 # Cop supports --auto-correct. Style/ParallelAssignment: Enabled: false -# Offense count: 417 +# Offense count: 459 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: @@ -366,14 +554,30 @@ Style/PercentLiteralDelimiters: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: lower_case_q, upper_case_q Style/PercentQLiterals: - Enabled: false + Exclude: + - 'spec/lib/gitlab/diff/highlight_spec.rb' + - 'spec/models/project_services/bamboo_service_spec.rb' + - 'spec/models/project_services/buildkite_service_spec.rb' + - 'spec/models/project_services/drone_ci_service_spec.rb' + - 'spec/models/project_services/teamcity_service_spec.rb' + - 'spec/workers/repository_import_worker_spec.rb' # Offense count: 13 # Cop supports --auto-correct. Style/PerlBackrefs: - Enabled: false + Exclude: + - 'app/controllers/projects/application_controller.rb' + - 'app/helpers/submodule_helper.rb' + - 'lib/banzai/filter/abstract_reference_filter.rb' + - 'lib/banzai/filter/autolink_filter.rb' + - 'lib/banzai/filter/emoji_filter.rb' + - 'lib/banzai/filter/gollum_tags_filter.rb' + - 'lib/expand_variables.rb' + - 'lib/gitlab/diff/highlight.rb' + - 'lib/gitlab/search_results.rb' + - 'lib/gitlab/sherlock/query.rb' -# Offense count: 64 +# Offense count: 72 # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. # NamePrefix: is_, has_, have_ # NamePrefixBlacklist: is_, has_, have_ @@ -381,7 +585,7 @@ Style/PerlBackrefs: Style/PredicateName: Enabled: false -# Offense count: 33 +# Offense count: 39 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: short, verbose @@ -391,44 +595,76 @@ Style/PreferredHashMethods: # Offense count: 8 # Cop supports --auto-correct. Style/Proc: - Enabled: false + Exclude: + - 'app/mailers/base_mailer.rb' + - 'app/models/milestone.rb' + - 'app/models/service.rb' + - 'lib/api/api_guard.rb' + - 'lib/gitlab/ldap/config.rb' + - 'spec/initializers/trusted_proxies_spec.rb' -# Offense count: 50 +# Offense count: 62 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: compact, exploded Style/RaiseArgs: Enabled: false -# Offense count: 4 +# Offense count: 3 # Cop supports --auto-correct. Style/RedundantBegin: - Enabled: false + Exclude: + - 'app/models/merge_request.rb' + - 'app/services/projects/import_service.rb' + - 'lib/gitlab/git/commit.rb' -# Offense count: 29 +# Offense count: 32 # Cop supports --auto-correct. Style/RedundantFreeze: - Enabled: false + Exclude: + - 'app/models/commit.rb' + - 'app/models/merge_request.rb' + - 'app/validators/color_validator.rb' + - 'app/validators/line_code_validator.rb' + - 'lib/api/templates.rb' + - 'lib/api/v3/templates.rb' + - 'lib/banzai/filter/blockquote_fence_filter.rb' + - 'lib/banzai/filter/gollum_tags_filter.rb' + - 'lib/banzai/filter/yaml_front_matter_filter.rb' + - 'lib/gitlab/diff/inline_diff.rb' + - 'lib/gitlab/ee_compat_check.rb' + - 'lib/gitlab/import_export/relation_factory.rb' + - 'lib/gitlab/middleware/static.rb' + - 'lib/gitlab/regex.rb' -# Offense count: 11 +# Offense count: 15 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: - Enabled: false + Exclude: + - 'app/controllers/application_controller.rb' + - 'app/controllers/concerns/issuable_actions.rb' + - 'app/controllers/groups/application_controller.rb' + - 'app/controllers/groups_controller.rb' + - 'app/controllers/omniauth_callbacks_controller.rb' + - 'app/controllers/profiles/keys_controller.rb' + - 'app/controllers/projects/labels_controller.rb' + - 'app/controllers/projects/milestones_controller.rb' + - 'app/services/access_token_validation_service.rb' -# Offense count: 359 +# Offense count: 365 # Cop supports --auto-correct. Style/RedundantSelf: Enabled: false -# Offense count: 105 +# Offense count: 107 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. # SupportedStyles: slashes, percent_r, mixed Style/RegexpLiteral: Enabled: false -# Offense count: 19 +# Offense count: 22 # Cop supports --auto-correct. Style/RescueModifier: Enabled: false @@ -436,21 +672,29 @@ Style/RescueModifier: # Offense count: 7 # Cop supports --auto-correct. Style/SelfAssignment: - Enabled: false + Exclude: + - 'app/models/project_team.rb' + - 'app/services/notification_service.rb' + - 'lib/api/runners.rb' + - 'spec/features/merge_requests/diff_notes_resolve_spec.rb' + - 'spec/support/import_export/configuration_helper.rb' # Offense count: 2 # Configuration parameters: Methods. # Methods: {"reduce"=>["acc", "elem"]}, {"inject"=>["acc", "elem"]} Style/SingleLineBlockParams: - Enabled: false + Exclude: + - 'app/models/commit.rb' + - 'spec/support/services_shared_context.rb' # Offense count: 50 # Cop supports --auto-correct. # Configuration parameters: AllowIfMethodIsEmpty. Style/SingleLineMethods: - Enabled: false + Exclude: + - 'lib/ci/ansi2html.rb' -# Offense count: 138 +# Offense count: 150 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space @@ -461,28 +705,48 @@ Style/SpaceBeforeBlockBraces: # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment. Style/SpaceBeforeFirstArg: - Enabled: false + Exclude: + - 'config/routes/project.rb' + - 'features/steps/project/source/browse_files.rb' + - 'features/steps/project/source/markdown_render.rb' + - 'spec/routing/project_routing_spec.rb' + - 'spec/services/system_note_service_spec.rb' -# Offense count: 37 +# Offense count: 38 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: require_no_space, require_space Style/SpaceInLambdaLiteral: - Enabled: false + Exclude: + - 'app/models/commit_status.rb' + - 'app/models/concerns/mentionable.rb' + - 'app/models/issue.rb' + - 'app/models/member.rb' + - 'lib/api/entities.rb' + - 'lib/file_size_validator.rb' + - 'lib/gitlab/visibility_level.rb' + - 'spec/models/concerns/participable_spec.rb' + - 'spec/models/cycle_analytics/code_spec.rb' + - 'spec/models/cycle_analytics/issue_spec.rb' + - 'spec/models/cycle_analytics/plan_spec.rb' + - 'spec/models/cycle_analytics/production_spec.rb' + - 'spec/models/cycle_analytics/review_spec.rb' + - 'spec/models/cycle_analytics/staging_spec.rb' + - 'spec/models/cycle_analytics/test_spec.rb' -# Offense count: 174 +# Offense count: 205 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space Style/SpaceInsideBlockBraces: Enabled: false -# Offense count: 115 +# Offense count: 120 # Cop supports --auto-correct. Style/SpaceInsideBrackets: Enabled: false -# Offense count: 77 +# Offense count: 90 # Cop supports --auto-correct. Style/SpaceInsideParens: Enabled: false @@ -490,9 +754,10 @@ Style/SpaceInsideParens: # Offense count: 4 # Cop supports --auto-correct. Style/SpaceInsidePercentLiteralDelimiters: - Enabled: false + Exclude: + - 'lib/gitlab/git_access.rb' -# Offense count: 53 +# Offense count: 52 # Cop supports --auto-correct. # Configuration parameters: SupportedStyles. # SupportedStyles: use_perl_names, use_english_names @@ -504,9 +769,23 @@ Style/SpecialGlobalVars: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: single_quotes, double_quotes Style/StringLiteralsInInterpolation: - Enabled: false + Exclude: + - 'app/helpers/labels_helper.rb' + - 'app/helpers/time_helper.rb' + - 'app/helpers/todos_helper.rb' + - 'app/models/application_setting.rb' + - 'app/models/project_services/campfire_service.rb' + - 'app/models/project_services/jira_service.rb' + - 'db/migrate/20161017125927_add_unique_index_to_labels.rb' + - 'features/steps/groups.rb' + - 'features/steps/project/merge_requests.rb' + - 'lib/banzai/filter/abstract_reference_filter.rb' + - 'lib/ci/gitlab_ci_yaml_processor.rb' + - 'lib/gitlab/google_code_import/importer.rb' + - 'spec/lib/banzai/filter/issue_reference_filter_spec.rb' + - 'spec/models/project_services/hipchat_service_spec.rb' -# Offense count: 54 +# Offense count: 57 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. # IgnoredMethods: respond_to, define_method @@ -518,16 +797,21 @@ Style/SymbolProc: # Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment. # SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex Style/TernaryParentheses: - Enabled: false + Exclude: + - 'features/support/capybara.rb' + - 'lib/api/v3/projects.rb' + - 'lib/banzai/filter/table_of_contents_filter.rb' + - 'lib/gitlab/ci/build/artifacts/metadata/entry.rb' + - 'spec/support/capybara.rb' -# Offense count: 36 +# Offense count: 43 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. # SupportedStyles: comma, consistent_comma, no_comma Style/TrailingCommaInArguments: Enabled: false -# Offense count: 150 +# Offense count: 158 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. # SupportedStyles: comma, consistent_comma, no_comma @@ -538,9 +822,15 @@ Style/TrailingCommaInLiteral: # Cop supports --auto-correct. # Configuration parameters: AllowNamedUnderscoreVariables. Style/TrailingUnderscoreVariable: - Enabled: false + Exclude: + - 'app/controllers/admin/background_jobs_controller.rb' + - 'app/controllers/invites_controller.rb' + - 'app/controllers/projects/git_http_client_controller.rb' + - 'app/helpers/tab_helper.rb' + - 'lib/gitlab/git/repository.rb' + - 'lib/gitlab/logger.rb' -# Offense count: 67 +# Offense count: 76 # Cop supports --auto-correct. Style/TrailingWhitespace: Enabled: false @@ -550,19 +840,46 @@ Style/TrailingWhitespace: # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist. # Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym Style/TrivialAccessors: - Enabled: false + Exclude: + - 'app/models/external_issue.rb' + - 'app/serializers/base_serializer.rb' + - 'lib/gitlab/ldap/person.rb' # Offense count: 2 # Cop supports --auto-correct. Style/UnlessElse: - Enabled: false + Exclude: + - 'lib/gitlab/project_search_results.rb' + - 'spec/features/issues/award_emoji_spec.rb' -# Offense count: 17 +# Offense count: 19 # Cop supports --auto-correct. Style/UnneededInterpolation: - Enabled: false + Exclude: + - 'app/helpers/boards_helper.rb' + - 'app/helpers/projects_helper.rb' + - 'app/helpers/search_helper.rb' + - 'app/helpers/time_helper.rb' + - 'app/models/merge_request.rb' + - 'app/models/project_services/pushover_service.rb' + - 'features/steps/project/forked_merge_requests.rb' + - 'spec/controllers/admin/services_controller_spec.rb' + - 'spec/features/admin/admin_projects_spec.rb' + - 'spec/features/issues_spec.rb' + - 'spec/features/projects/branches_spec.rb' + - 'spec/features/projects/issuable_templates_spec.rb' + - 'spec/lib/banzai/filter/issue_reference_filter_spec.rb' + - 'spec/requests/api/issues_spec.rb' + - 'spec/views/projects/commit/_commit_box.html.haml_spec.rb' # Offense count: 8 # Cop supports --auto-correct. Style/ZeroLengthPredicate: - Enabled: false + Exclude: + - 'app/models/deploy_key.rb' + - 'app/models/merge_request.rb' + - 'app/models/network/commit.rb' + - 'app/models/network/graph.rb' + - 'app/models/project_services/asana_service.rb' + - 'app/models/repository.rb' + - 'lib/extracts_path.rb' From 3dadf306ddc81183e74b048bc4119796852ed7ea Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:29:35 -0600 Subject: [PATCH 197/247] Enable Style/DotPosition --- .rubocop.yml | 4 ++ .rubocop_todo.yml | 7 --- .../admin/application_settings_controller.rb | 6 +-- app/controllers/concerns/issues_action.rb | 6 +-- .../concerns/merge_requests_action.rb | 4 +- .../import/bitbucket_controller.rb | 6 +-- app/controllers/projects/badges_controller.rb | 8 +-- .../projects/boards/issues_controller.rb | 8 +-- app/controllers/projects/commit_controller.rb | 6 +-- .../projects/compare_controller.rb | 4 +- .../projects/environments_controller.rb | 22 ++++---- .../projects/merge_requests_controller.rb | 28 +++++----- .../projects/pipelines_controller.rb | 32 ++++++------ app/controllers/projects_controller.rb | 4 +- app/controllers/users_controller.rb | 4 +- app/finders/environments_finder.rb | 10 ++-- app/models/ci/build.rb | 18 +++---- app/models/ci/pipeline.rb | 34 ++++++------ app/models/ci/runner.rb | 4 +- app/models/ci/stage.rb | 6 +-- app/models/commit_status.rb | 10 ++-- app/models/concerns/milestoneish.rb | 4 +- app/models/concerns/presentable.rb | 6 +-- app/models/concerns/subscribable.rb | 8 +-- app/models/generic_commit_status.rb | 6 +-- app/models/global_milestone.rb | 4 +- app/models/group.rb | 6 +-- app/models/label.rb | 6 +-- app/models/lfs_object.rb | 6 +-- app/models/member.rb | 6 +-- app/models/merge_request.rb | 6 +-- app/models/merge_request_diff.rb | 4 +- app/models/namespace.rb | 6 +-- app/models/network/commit.rb | 4 +- app/models/network/graph.rb | 12 ++--- app/serializers/base_serializer.rb | 6 +-- app/serializers/environment_serializer.rb | 6 +-- app/services/after_branch_delete_service.rb | 6 +-- app/services/boards/issues/list_service.rb | 8 +-- app/services/boards/lists/destroy_service.rb | 4 +- app/services/boards/lists/move_service.rb | 12 ++--- app/services/ci/create_pipeline_service.rb | 6 +-- app/services/ci/process_pipeline_service.rb | 6 +-- app/services/ci/retry_build_service.rb | 10 ++-- app/services/ci/retry_pipeline_service.rb | 10 ++-- app/services/commits/change_service.rb | 4 +- app/services/create_branch_service.rb | 4 +- app/services/git_push_service.rb | 10 ++-- app/services/issues/move_service.rb | 4 +- app/services/merge_requests/base_service.rb | 10 ++-- .../merge_requests/refresh_service.rb | 6 +-- app/workers/build_coverage_worker.rb | 4 +- app/workers/build_hooks_worker.rb | 4 +- app/workers/emails_on_push_worker.rb | 8 +-- .../expire_build_instance_artifacts_worker.rb | 8 +-- app/workers/pipeline_hooks_worker.rb | 4 +- app/workers/pipeline_process_worker.rb | 4 +- app/workers/pipeline_success_worker.rb | 6 +-- app/workers/pipeline_update_worker.rb | 4 +- lib/api/merge_requests.rb | 18 +++---- lib/api/pipelines.rb | 4 +- lib/api/v3/merge_requests.rb | 18 +++---- lib/banzai/pipeline/wiki_pipeline.rb | 4 +- lib/banzai/reference_extractor.rb | 4 +- lib/ci/gitlab_ci_yaml_processor.rb | 4 +- lib/gitlab/badge/build/status.rb | 6 +-- lib/gitlab/badge/coverage/report.rb | 6 +-- lib/gitlab/bitbucket_import/importer.rb | 8 +-- lib/gitlab/checks/matching_merge_request.rb | 8 +-- lib/gitlab/ci/config/entry/configurable.rb | 10 ++-- lib/gitlab/ci/config/entry/global.rb | 6 +-- lib/gitlab/ci/config/entry/jobs.rb | 8 +-- lib/gitlab/ci/status/factory.rb | 8 +-- lib/gitlab/ci/trace_reader.rb | 4 +- lib/gitlab/git/encoding_helper.rb | 6 +-- lib/gitlab/github_import/importer.rb | 6 +-- lib/gitlab/github_import/user_formatter.rb | 14 ++--- rubocop/cop/gem_fetcher.rb | 12 ++--- .../ci/projects_controller_spec.rb | 4 +- .../merge_requests_controller_spec.rb | 6 +-- spec/controllers/sessions_controller_spec.rb | 20 +++---- spec/features/environments_spec.rb | 4 +- .../merge_requests/created_from_fork_spec.rb | 4 +- .../projects/pipelines/pipelines_spec.rb | 4 +- spec/finders/environments_finder_spec.rb | 44 ++++++++-------- spec/helpers/issues_helper_spec.rb | 8 +-- spec/helpers/page_layout_helper_spec.rb | 4 +- spec/helpers/visibility_level_helper_spec.rb | 32 ++++++------ spec/lib/api/helpers/pagination_spec.rb | 12 ++--- .../external_issue_reference_filter_spec.rb | 4 +- .../filter/label_reference_filter_spec.rb | 28 +++++----- .../filter/user_reference_filter_spec.rb | 4 +- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 20 +++---- spec/lib/gitlab/asciidoc_spec.rb | 8 +-- spec/lib/gitlab/auth_spec.rb | 8 +-- spec/lib/gitlab/backup/manager_spec.rb | 16 +++--- spec/lib/gitlab/badge/build/status_spec.rb | 4 +- .../gitlab/ci/config/entry/artifacts_spec.rb | 8 +-- .../ci/config/entry/attributable_spec.rb | 12 ++--- .../gitlab/ci/config/entry/boolean_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/cache_spec.rb | 12 ++--- .../gitlab/ci/config/entry/commands_spec.rb | 4 +- .../ci/config/entry/configurable_spec.rb | 4 +- .../ci/config/entry/environment_spec.rb | 16 +++--- .../gitlab/ci/config/entry/factory_spec.rb | 52 +++++++++---------- .../lib/gitlab/ci/config/entry/global_spec.rb | 44 ++++++++-------- spec/lib/gitlab/ci/config/entry/image_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/job_spec.rb | 8 +-- spec/lib/gitlab/ci/config/entry/jobs_spec.rb | 16 +++--- spec/lib/gitlab/ci/config/entry/key_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/paths_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/script_spec.rb | 4 +- .../gitlab/ci/config/entry/services_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/stage_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/stages_spec.rb | 4 +- .../gitlab/ci/config/entry/trigger_spec.rb | 4 +- .../ci/config/entry/validatable_spec.rb | 4 +- .../gitlab/ci/config/entry/validator_spec.rb | 4 +- .../gitlab/ci/config/entry/variables_spec.rb | 4 +- .../lib/gitlab/ci/status/build/common_spec.rb | 6 +-- .../gitlab/ci/status/build/factory_spec.rb | 32 ++++++------ spec/lib/gitlab/ci/status/extended_spec.rb | 4 +- .../gitlab/ci/status/external/common_spec.rb | 6 +-- spec/lib/gitlab/ci/status/factory_spec.rb | 16 +++--- .../gitlab/ci/status/pipeline/common_spec.rb | 10 ++-- .../gitlab/ci/status/pipeline/factory_spec.rb | 8 +-- .../lib/gitlab/ci/status/stage/common_spec.rb | 12 ++--- .../gitlab/ci/status/stage/factory_spec.rb | 4 +- spec/lib/gitlab/data_builder/note_spec.rb | 36 ++++++------- spec/lib/gitlab/database_spec.rb | 4 +- .../import_export/avatar_restorer_spec.rb | 4 +- spec/lib/gitlab/incoming_email_spec.rb | 4 +- spec/lib/gitlab/ldap/adapter_spec.rb | 4 +- spec/lib/gitlab/o_auth/user_spec.rb | 4 +- spec/lib/gitlab/serializer/pagination_spec.rb | 8 +-- spec/models/application_setting_spec.rb | 6 +-- spec/models/ci/build_spec.rb | 16 +++--- spec/models/commit_status_spec.rb | 4 +- spec/models/email_spec.rb | 4 +- spec/models/group_label_spec.rb | 4 +- spec/models/lfs_objects_project_spec.rb | 8 +-- spec/models/merge_request_diff_spec.rb | 8 +-- spec/models/merge_request_spec.rb | 24 ++++----- spec/models/project_label_spec.rb | 12 ++--- spec/models/repository_spec.rb | 4 +- spec/models/user_spec.rb | 8 +-- spec/requests/api/broadcast_messages_spec.rb | 12 ++--- spec/requests/api/commit_statuses_spec.rb | 4 +- spec/requests/api/groups_spec.rb | 8 +-- spec/requests/api/internal_spec.rb | 4 +- spec/requests/api/runners_spec.rb | 8 +-- spec/requests/ci/api/builds_spec.rb | 12 ++--- .../analytics_build_serializer_spec.rb | 4 +- .../analytics_issue_serializer_spec.rb | 6 +-- ...analytics_merge_request_serializer_spec.rb | 6 +-- .../analytics_summary_serializer_spec.rb | 8 +-- .../serializers/build_artifact_entity_spec.rb | 4 +- spec/serializers/commit_entity_spec.rb | 4 +- .../environment_serializer_spec.rb | 32 ++++++------ spec/serializers/pipeline_entity_spec.rb | 12 ++--- spec/serializers/pipeline_serializer_spec.rb | 10 ++-- spec/serializers/request_aware_entity_spec.rb | 4 +- spec/serializers/stage_entity_spec.rb | 8 +-- .../ci/process_pipeline_service_spec.rb | 8 +-- spec/services/ci/retry_build_service_spec.rb | 12 ++--- .../ci/retry_pipeline_service_spec.rb | 8 +-- .../ci/stop_environments_service_spec.rb | 16 +++--- .../ci/update_build_queue_service_spec.rb | 16 +++--- .../issuable/bulk_update_service_spec.rb | 20 +++---- spec/services/issues/move_service_spec.rb | 20 +++---- .../add_todo_when_build_fails_service_spec.rb | 16 +++--- ...rge_when_pipeline_succeeds_service_spec.rb | 20 +++---- spec/services/todo_service_spec.rb | 8 +-- spec/support/ldap_helpers.rb | 8 +-- spec/tasks/gitlab/check_rake_spec.rb | 4 +- spec/tasks/gitlab/shell_rake_spec.rb | 4 +- spec/views/layouts/_head.html.haml_spec.rb | 4 +- .../merge_requests/edit.html.haml_spec.rb | 4 +- spec/workers/build_coverage_worker_spec.rb | 8 +-- spec/workers/build_finished_worker_spec.rb | 20 +++---- spec/workers/build_hooks_worker_spec.rb | 8 +-- spec/workers/build_success_worker_spec.rb | 12 ++--- spec/workers/pipeline_hooks_worker_spec.rb | 8 +-- spec/workers/pipeline_proccess_worker_spec.rb | 4 +- spec/workers/pipeline_success_worker_spec.rb | 4 +- spec/workers/pipeline_update_worker_spec.rb | 4 +- spec/workers/project_cache_worker_spec.rb | 12 ++--- spec/workers/use_key_worker_spec.rb | 4 +- 188 files changed, 868 insertions(+), 871 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a836b469cc7..cb7b86c95e6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -136,6 +136,10 @@ Style/DefWithParentheses: Style/Documentation: Enabled: false +Style/DotPosition: + Enabled: true + EnforcedStyle: trailing + # Align elses and elsifs correctly. Style/ElseAlignment: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6033390d8e6..4831dfe15d9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -305,13 +305,6 @@ Style/CommentAnnotation: Style/ConditionalAssignment: Enabled: false -# Offense count: 1304 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: leading, trailing -Style/DotPosition: - Enabled: false - # Offense count: 21 Style/DoubleNegation: Exclude: diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index b0f5d4a9933..f801fac1839 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -5,9 +5,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end def update - successful = ApplicationSettings::UpdateService - .new(@application_setting, current_user, application_setting_params) - .execute + successful = ApplicationSettings::UpdateService. + new(@application_setting, current_user, application_setting_params). + execute if successful redirect_to admin_application_settings_path, diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index b17c138d5c7..8b985b6d003 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -5,9 +5,9 @@ module IssuesAction def issues @label = issues_finder.labels.first - @issues = issues_collection - .non_archived - .page(params[:page]) + @issues = issues_collection. + non_archived. + page(params[:page]) @collection_type = "Issue" @issuable_meta_data = issuable_meta_data(@issues, @collection_type) diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index d3c8e4888bc..28e34cffc24 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -5,8 +5,8 @@ module MergeRequestsAction def merge_requests @label = merge_requests_finder.labels.first - @merge_requests = merge_requests_collection - .page(params[:page]) + @merge_requests = merge_requests_collection. + page(params[:page]) @collection_type = "MergeRequest" @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index 8e42cdf415f..cd5cef2c20f 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -29,9 +29,9 @@ class Import::BitbucketController < Import::BaseController end def jobs - render json: current_user.created_projects - .where(import_type: 'bitbucket') - .to_json(only: [:id, :import_status]) + render json: current_user.created_projects. + where(import_type: 'bitbucket'). + to_json(only: [:id, :import_status]) end def create diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 6c25cd83a24..c1727d9fa28 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -4,15 +4,15 @@ class Projects::BadgesController < Projects::ApplicationController before_action :no_cache_headers, except: [:index] def build - build_status = Gitlab::Badge::Build::Status - .new(project, params[:ref]) + build_status = Gitlab::Badge::Build::Status. + new(project, params[:ref]) render_badge build_status end def coverage - coverage_report = Gitlab::Badge::Coverage::Report - .new(project, params[:ref], params[:job]) + coverage_report = Gitlab::Badge::Coverage::Report. + new(project, params[:ref], params[:job]) render_badge coverage_report end diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb index 61fef4dc133..8bcf18642cf 100644 --- a/app/controllers/projects/boards/issues_controller.rb +++ b/app/controllers/projects/boards/issues_controller.rb @@ -40,10 +40,10 @@ module Projects def issue @issue ||= - IssuesFinder.new(current_user, project_id: project.id) - .execute - .where(iid: params[:id]) - .first! + IssuesFinder.new(current_user, project_id: project.id). + execute. + where(iid: params[:id]). + first! end def authorize_read_issue! diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index e10d7992db7..23466dda981 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -35,9 +35,9 @@ class Projects::CommitController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: PipelineSerializer - .new(project: @project, user: @current_user) - .represent(@pipelines) + render json: PipelineSerializer. + new(project: @project, user: @current_user). + represent(@pipelines) end end end diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index c6651254d70..99204c82784 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -46,8 +46,8 @@ class Projects::CompareController < Projects::ApplicationController end def define_diff_vars - @compare = CompareService.new(@project, @head_ref) - .execute(@project, @start_ref) + @compare = CompareService.new(@project, @head_ref). + execute(@project, @start_ref) if @compare @commits = @compare.commits diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index fed75396d6e..2bbd8c6d046 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -9,18 +9,18 @@ class Projects::EnvironmentsController < Projects::ApplicationController before_action :verify_api_request!, only: :terminal_websocket_authorize def index - @environments = project.environments - .with_state(params[:scope] || :available) + @environments = project.environments. + with_state(params[:scope] || :available) respond_to do |format| format.html format.json do render json: { - environments: EnvironmentSerializer - .new(project: @project, user: @current_user) - .with_pagination(request, response) - .within_folders - .represent(@environments), + environments: EnvironmentSerializer. + new(project: @project, user: @current_user). + with_pagination(request, response). + within_folders. + represent(@environments), available_count: project.environments.available.count, stopped_count: project.environments.stopped.count } @@ -36,10 +36,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController format.html format.json do render json: { - environments: EnvironmentSerializer - .new(project: @project, user: @current_user) - .with_pagination(request, response) - .represent(@environments), + environments: EnvironmentSerializer. + new(project: @project, user: @current_user). + with_pagination(request, response). + represent(@environments), available_count: folder_environments.available.count, stopped_count: folder_environments.stopped.count } diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 365c49a20d4..c0c71c11dc2 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -232,9 +232,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end format.json do - render json: PipelineSerializer - .new(project: @project, user: @current_user) - .represent(@pipelines) + render json: PipelineSerializer. + new(project: @project, user: @current_user). + represent(@pipelines) end end end @@ -245,9 +245,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController format.json do define_pipelines_vars - render json: PipelineSerializer - .new(project: @project, user: @current_user) - .represent(@pipelines) + render json: PipelineSerializer. + new(project: @project, user: @current_user). + represent(@pipelines) end end end @@ -332,9 +332,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController return access_denied! end - MergeRequests::MergeWhenPipelineSucceedsService - .new(@project, current_user) - .cancel(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService. + new(@project, current_user). + cancel(@merge_request) end def merge @@ -361,9 +361,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end if @merge_request.head_pipeline.active? - MergeRequests::MergeWhenPipelineSucceedsService - .new(@project, current_user, merge_params) - .execute(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService. + new(@project, current_user, merge_params). + execute(@merge_request) @status = :merge_when_build_succeeds elsif @merge_request.head_pipeline.success? @@ -639,8 +639,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_request_params - params.require(:merge_request) - .permit(merge_request_params_ce) + params.require(:merge_request). + permit(merge_request_params_ce) end def merge_request_params_ce diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 8657bc4dfdc..0f2b7b2a4c8 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -7,32 +7,32 @@ class Projects::PipelinesController < Projects::ApplicationController def index @scope = params[:scope] - @pipelines = PipelinesFinder - .new(project) - .execute(scope: @scope) - .page(params[:page]) - .per(30) + @pipelines = PipelinesFinder. + new(project). + execute(scope: @scope). + page(params[:page]). + per(30) - @running_count = PipelinesFinder + @running_count = PipelinesFinder. .new(project).execute(scope: 'running').count - @pending_count = PipelinesFinder + @pending_count = PipelinesFinder. .new(project).execute(scope: 'pending').count - @finished_count = PipelinesFinder + @finished_count = PipelinesFinder. .new(project).execute(scope: 'finished').count - @pipelines_count = PipelinesFinder + @pipelines_count = PipelinesFinder. .new(project).execute.count respond_to do |format| format.html format.json do render json: { - pipelines: PipelineSerializer - .new(project: @project, user: @current_user) - .with_pagination(request, response) - .represent(@pipelines), + pipelines: PipelineSerializer. + new(project: @project, user: @current_user). + with_pagination(request, response). + represent(@pipelines), count: { all: @pipelines_count, running: @running_count, @@ -49,9 +49,9 @@ class Projects::PipelinesController < Projects::ApplicationController end def create - @pipeline = Ci::CreatePipelineService - .new(project, current_user, create_params) - .execute(ignore_skip_ci: true, save_on_errors: false) + @pipeline = Ci::CreatePipelineService. + new(project, current_user, create_params). + execute(ignore_skip_ci: true, save_on_errors: false) unless @pipeline.persisted? render 'new' return diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index acca821782c..9ffb8152e32 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -293,8 +293,8 @@ class ProjectsController < Projects::ApplicationController end def project_params - params.require(:project) - .permit(project_params_ce) + params.require(:project). + permit(project_params_ce) end def project_params_ce diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6e29f1e8a65..c92594d4097 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -118,8 +118,8 @@ class UsersController < ApplicationController def load_projects @projects = - PersonalProjectsFinder.new(user).execute(current_user) - .page(params[:page]) + PersonalProjectsFinder.new(user).execute(current_user). + page(params[:page]) end def load_contributed_projects diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb index a59f8c1efa3..52c73abc31d 100644 --- a/app/finders/environments_finder.rb +++ b/app/finders/environments_finder.rb @@ -17,12 +17,12 @@ class EnvironmentsFinder deployments.none end - environment_ids = deployments - .group(:environment_id) - .select(:environment_id) + environment_ids = deployments. + group(:environment_id). + select(:environment_id) - environments = project.environments.available - .where(id: environment_ids).order_by_last_deployed_at.to_a + environments = project.environments.available. + where(id: environment_ids).order_by_last_deployed_at.to_a environments.select! do |environment| Ability.allowed?(current_user, :read_environment, environment) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index e018f8e7c4e..9a45ef06750 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -63,9 +63,9 @@ module Ci end def retry(build, current_user) - Ci::RetryBuildService - .new(build.project, current_user) - .execute(build) + Ci::RetryBuildService. + new(build.project, current_user). + execute(build) end end @@ -96,9 +96,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Build::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Build::Factory. + new(self, current_user). + fabricate! end def manual? @@ -220,9 +220,9 @@ module Ci end def merge_request - merge_requests = MergeRequest.includes(:merge_request_diff) - .where(source_branch: ref, source_project_id: pipeline.gl_project_id) - .reorder(iid: :asc) + merge_requests = MergeRequest.includes(:merge_request_diff). + where(source_branch: ref, source_project_id: pipeline.gl_project_id). + reorder(iid: :asc) merge_requests.find do |merge_request| merge_request.commits_sha.include?(pipeline.sha) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 6e89b18aee5..ae4759ed2a0 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -89,9 +89,9 @@ module Ci # ref can't be HEAD or SHA, can only be branch/tag name scope :latest, ->(ref = nil) do - max_id = unscope(:select) - .select("max(#{quoted_table_name}.id)") - .group(:ref, :sha) + max_id = unscope(:select). + select("max(#{quoted_table_name}.id)"). + group(:ref, :sha) if ref where(ref: ref, id: max_id.where(ref: ref)) @@ -133,16 +133,16 @@ module Ci def stages # TODO, this needs refactoring, see gitlab-ce#26481. - stages_query = statuses - .group('stage').select(:stage).order('max(stage_idx)') + stages_query = statuses. + group('stage').select(:stage).order('max(stage_idx)') status_sql = statuses.latest.where('stage=sg.stage').status_sql - warnings_sql = statuses.latest.select('COUNT(*) > 0') - .where('stage=sg.stage').failed_but_allowed.to_sql + warnings_sql = statuses.latest.select('COUNT(*) > 0'). + where('stage=sg.stage').failed_but_allowed.to_sql - stages_with_statuses = CommitStatus.from(stages_query, :sg) - .pluck('sg.stage', status_sql, "(#{warnings_sql})") + stages_with_statuses = CommitStatus.from(stages_query, :sg). + pluck('sg.stage', status_sql, "(#{warnings_sql})") stages_with_statuses.map do |stage| Ci::Stage.new(self, Hash[%i[name status warnings].zip(stage)]) @@ -222,8 +222,8 @@ module Ci end def retry_failed(current_user) - Ci::RetryPipelineService.new(project, current_user) - .execute(self) + Ci::RetryPipelineService.new(project, current_user). + execute(self) end def mark_as_processable_after_stage(stage_idx) @@ -355,15 +355,15 @@ module Ci # Merge requests for which the current pipeline is running against # the merge request's latest commit. def merge_requests - @merge_requests ||= project.merge_requests - .where(source_branch: self.ref) - .select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } + @merge_requests ||= project.merge_requests. + where(source_branch: self.ref). + select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } end def detailed_status(current_user) - Gitlab::Ci::Status::Pipeline::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Pipeline::Factory. + new(self, current_user). + fabricate! end private diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 07a086b0aca..9cda008a549 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -23,8 +23,8 @@ module Ci scope :ordered, ->() { order(id: :desc) } scope :owned_or_shared, ->(project_id) do - joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id') - .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) + joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id'). + where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end scope :assignable_for, ->(project) do diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index ca74c91b062..0751ab1b7d8 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -28,9 +28,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Stage::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Stage::Factory. + new(self, current_user). + fabricate! end def statuses diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 99a6326309d..d31a6d81ebd 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -96,8 +96,8 @@ class CommitStatus < ActiveRecord::Base after_transition any => :failed do |commit_status| commit_status.run_after_commit do - MergeRequests::AddTodoWhenBuildFailsService - .new(pipeline.project, nil).execute(self) + MergeRequests::AddTodoWhenBuildFailsService. + new(pipeline.project, nil).execute(self) end end end @@ -133,9 +133,9 @@ class CommitStatus < ActiveRecord::Base end def detailed_status(current_user) - Gitlab::Ci::Status::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Factory. + new(self, current_user). + fabricate! end def sortable_name diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index f449229864d..870a6fbaa90 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -39,8 +39,8 @@ module Milestoneish def issues_visible_to_user(user) memoize_per_user(user, :issues_visible_to_user) do - IssuesFinder.new(user, issues_finder_params) - .execute.where(milestone_id: milestoneish_ids) + IssuesFinder.new(user, issues_finder_params). + execute.where(milestone_id: milestoneish_ids) end end diff --git a/app/models/concerns/presentable.rb b/app/models/concerns/presentable.rb index 7b33b837004..d0f84831d71 100644 --- a/app/models/concerns/presentable.rb +++ b/app/models/concerns/presentable.rb @@ -1,7 +1,7 @@ module Presentable def present(**attributes) - Gitlab::View::Presenter::Factory - .new(self, attributes) - .fabricate! + Gitlab::View::Presenter::Factory. + new(self, attributes). + fabricate! end end diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index 83daa9b1a64..e4f5818d0e3 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -42,15 +42,15 @@ module Subscribable def subscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project) - .update(subscribed: true) + find_or_initialize_subscription(user, project). + update(subscribed: true) end def unsubscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project) - .update(subscribed: false) + find_or_initialize_subscription(user, project). + update(subscribed: false) end private diff --git a/app/models/generic_commit_status.rb b/app/models/generic_commit_status.rb index 8867ba0d2ff..36b8568871b 100644 --- a/app/models/generic_commit_status.rb +++ b/app/models/generic_commit_status.rb @@ -18,8 +18,8 @@ class GenericCommitStatus < CommitStatus end def detailed_status(current_user) - Gitlab::Ci::Status::External::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::External::Factory. + new(self, current_user). + fabricate! end end diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb index b991d78e27f..84deb67ba9b 100644 --- a/app/models/global_milestone.rb +++ b/app/models/global_milestone.rb @@ -76,8 +76,8 @@ class GlobalMilestone end def labels - @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten) - .sort_by!(&:title) + @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten). + sort_by!(&:title) end def due_date diff --git a/app/models/group.rb b/app/models/group.rb index 240a17f1dc1..1835ce118a1 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -71,9 +71,9 @@ class Group < Namespace def select_for_project_authorization if current_scope.joins_values.include?(:shared_projects) - joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id') - .where('project_namespace.share_with_group_lock = ?', false) - .select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") + joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id'). + where('project_namespace.share_with_group_lock = ?', false). + select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") else super end diff --git a/app/models/label.rb b/app/models/label.rb index 5b6b9a7a736..8d76e422c67 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -34,9 +34,9 @@ class Label < ActiveRecord::Base scope :with_title, ->(title) { where(title: title) } def self.prioritized(project) - joins(:priorities) - .where(label_priorities: { project_id: project }) - .reorder('label_priorities.priority ASC, labels.title ASC') + joins(:priorities). + where(label_priorities: { project_id: project }). + reorder('label_priorities.priority ASC, labels.title ASC') end def self.unprioritized(project) diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 7712d5783e0..ee9ac282e39 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -19,8 +19,8 @@ class LfsObject < ActiveRecord::Base end def self.destroy_unreferenced - joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id") - .where(lfs_objects_projects: { id: nil }) - .destroy_all + joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id"). + where(lfs_objects_projects: { id: nil }). + destroy_all end end diff --git a/app/models/member.rb b/app/models/member.rb index d07f270b757..0f6b75b0b93 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -39,9 +39,9 @@ class Member < ActiveRecord::Base is_external_invite = arel_table[:user_id].eq(nil).and(arel_table[:invite_token].not_eq(nil)) user_is_active = User.arel_table[:state].eq(:active) - includes(:user).references(:users) - .where(is_external_invite.or(user_is_active)) - .where(requested_at: nil) + includes(:user).references(:users). + where(is_external_invite.or(user_is_active)). + where(requested_at: nil) end scope :invite, -> { where.not(invite_token: nil) } diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 204d2b153ad..a0b8a63d6ab 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -813,9 +813,9 @@ class MergeRequest < ActiveRecord::Base def all_pipelines return Ci::Pipeline.none unless source_project - @all_pipelines ||= source_project.pipelines - .where(sha: all_commits_sha, ref: source_branch) - .order(id: :desc) + @all_pipelines ||= source_project.pipelines. + where(sha: all_commits_sha, ref: source_branch). + order(id: :desc) end # Note that this could also return SHA from now dangling commits diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 70bad2a4396..e1f172b24bf 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -169,8 +169,8 @@ class MergeRequestDiff < ActiveRecord::Base # When compare merge request versions we want diff A..B instead of A...B # so we handle cases when user does squash and rebase of the commits between versions. # For this reason we set straight to true by default. - CompareService.new(project, head_commit_sha) - .execute(project, sha, straight: straight) + CompareService.new(project, head_commit_sha). + execute(project, sha, straight: straight) end def commits_count diff --git a/app/models/namespace.rb b/app/models/namespace.rb index bd0336c984a..e207ac3db4e 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -48,9 +48,9 @@ class Namespace < ActiveRecord::Base scope :root, -> { where('type IS NULL') } scope :with_statistics, -> do - joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id') - .group('namespaces.id') - .select( + joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id'). + group('namespaces.id'). + select( 'namespaces.*', 'COALESCE(SUM(ps.storage_size), 0) AS storage_size', 'COALESCE(SUM(ps.repository_size), 0) AS repository_size', diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb index 8417f200e36..a48e872ad84 100644 --- a/app/models/network/commit.rb +++ b/app/models/network/commit.rb @@ -28,8 +28,8 @@ module Network if map.include?(p.id) map[p.id] end - end - .compact + end. + compact end end end diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index b524ca50ee8..b16ecc424dd 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -23,12 +23,12 @@ module Network def collect_notes h = Hash.new(0) - @project - .notes - .where('noteable_type = ?', 'Commit') - .group('notes.commit_id') - .select('notes.commit_id, count(notes.id) as note_count') - .each do |item| + @project. + notes. + where('noteable_type = ?', 'Commit'). + group('notes.commit_id'). + select('notes.commit_id, count(notes.id) as note_count'). + each do |item| h[item.commit_id] = item.note_count.to_i end diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb index 311ee9c96be..032c44274ef 100644 --- a/app/serializers/base_serializer.rb +++ b/app/serializers/base_serializer.rb @@ -4,9 +4,9 @@ class BaseSerializer end def represent(resource, opts = {}) - self.class.entity_class - .represent(resource, opts.merge(request: @request)) - .as_json + self.class.entity_class. + represent(resource, opts.merge(request: @request)). + as_json end def self.entity(entity_class) diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index d0a60f134da..ffc4fd34c75 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -36,9 +36,9 @@ class EnvironmentSerializer < BaseSerializer private def itemize(resource) - items = resource.order('folder_name ASC') - .group('COALESCE(environment_type, name)') - .select('COALESCE(environment_type, name) AS folder_name', + items = resource.order('folder_name ASC'). + group('COALESCE(environment_type, name)'). + select('COALESCE(environment_type, name) AS folder_name', 'COUNT(*) AS size', 'MAX(id) AS last_id') # It makes a difference when you call `paginate` method, because diff --git a/app/services/after_branch_delete_service.rb b/app/services/after_branch_delete_service.rb index 227e9ea9c6d..95492f709bb 100644 --- a/app/services/after_branch_delete_service.rb +++ b/app/services/after_branch_delete_service.rb @@ -14,8 +14,8 @@ class AfterBranchDeleteService < BaseService private def stop_environments - Ci::StopEnvironmentsService - .new(project, current_user) - .execute(branch_name) + Ci::StopEnvironmentsService. + new(project, current_user). + execute(branch_name) end end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 8a94c54b6ab..2d664f3f0c8 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -57,15 +57,15 @@ module Boards return issues unless board_label_ids.any? issues.where.not( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") - .where(label_id: board_label_ids).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). + where(label_id: board_label_ids).limit(1).arel.exists ) end def with_list_label(issues) issues.where( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") - .where("label_links.label_id = ?", list.label_id).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). + where("label_links.label_id = ?", list.label_id).limit(1).arel.exists ) end end diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index f986e05944c..6c80dd61873 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -17,8 +17,8 @@ module Boards attr_reader :board def decrement_higher_lists(list) - board.lists.movable.where('position > ?', list.position) - .update_all('position = position - 1') + board.lists.movable.where('position > ?', list.position). + update_all('position = position - 1') end def remove_list(list) diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index f2a68865f7b..2f109934ea9 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -33,15 +33,15 @@ module Boards end def decrement_intermediate_lists - board.lists.movable.where('position > ?', old_position) - .where('position <= ?', new_position) - .update_all('position = position - 1') + board.lists.movable.where('position > ?', old_position). + where('position <= ?', new_position). + update_all('position = position - 1') end def increment_intermediate_lists - board.lists.movable.where('position >= ?', new_position) - .where('position < ?', old_position) - .update_all('position = position + 1') + board.lists.movable.where('position >= ?', new_position). + where('position < ?', old_position). + update_all('position = position + 1') end def update_list_position(list) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 38a85e9fc42..b53a467655f 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -48,9 +48,9 @@ module Ci Ci::Pipeline.transaction do pipeline.save - Ci::CreatePipelineBuildsService - .new(project, current_user) - .execute(pipeline) + Ci::CreatePipelineBuildsService. + new(project, current_user). + execute(pipeline) end pipeline.tap(&:process!) diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 79eb97b7b55..442230abe29 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -78,9 +78,9 @@ module Ci def ensure_created_builds! return if created_builds.any? - Ci::CreatePipelineBuildsService - .new(project, current_user) - .execute(pipeline) + Ci::CreatePipelineBuildsService. + new(project, current_user). + execute(pipeline) end end end diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index 38ef323f6e5..c1fa9278f0f 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -2,8 +2,8 @@ module Ci class RetryBuildService < ::BaseService CLONE_ATTRIBUTES = %i[pipeline project ref tag options commands name allow_failure stage stage_idx trigger_request - yaml_variables when environment coverage_regex] - .freeze + yaml_variables when environment coverage_regex]. + freeze REJECT_ATTRIBUTES = %i[id status user token coverage trace runner artifacts_expire_at artifacts_file @@ -20,9 +20,9 @@ module Ci new_build.enqueue! - MergeRequests::AddTodoWhenBuildFailsService - .new(project, current_user) - .close(new_build) + MergeRequests::AddTodoWhenBuildFailsService. + new(project, current_user). + close(new_build) end end diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 2c5e130e5aa..6e9781ca8cf 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -8,13 +8,13 @@ module Ci pipeline.builds.failed_or_canceled.find_each do |build| next unless build.retryable? - Ci::RetryBuildService.new(project, current_user) - .reprocess(build) + Ci::RetryBuildService.new(project, current_user). + reprocess(build) end - MergeRequests::AddTodoWhenBuildFailsService - .new(project, current_user) - .close_all(pipeline) + MergeRequests::AddTodoWhenBuildFailsService. + new(project, current_user). + close_all(pipeline) pipeline.process! end diff --git a/app/services/commits/change_service.rb b/app/services/commits/change_service.rb index 25e22f14e60..75281837b09 100644 --- a/app/services/commits/change_service.rb +++ b/app/services/commits/change_service.rb @@ -70,8 +70,8 @@ module Commits # Temporary branch exists and contains the change commit return if repository.find_branch(new_branch) - result = ValidateNewBranchService.new(@project, current_user) - .execute(new_branch) + result = ValidateNewBranchService.new(@project, current_user). + execute(new_branch) if result[:status] == :error raise ChangeError, "There was an error creating the source branch: #{result[:message]}" diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 77459d8779d..1b5e504573a 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -1,7 +1,7 @@ class CreateBranchService < BaseService def execute(branch_name, ref) - result = ValidateNewBranchService.new(project, current_user) - .execute(branch_name) + result = ValidateNewBranchService.new(project, current_user). + execute(branch_name) return result if result[:status] == :error diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index dbe2fda27b5..f681f831cbd 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -96,8 +96,8 @@ class GitPushService < BaseService # Update merge requests that may be affected by this push. A new branch # could cause the last commit of a merge request to change. # - UpdateMergeRequestsWorker - .perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) + UpdateMergeRequestsWorker. + perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) EventCreateService.new.push(@project, current_user, build_push_data) @project.execute_hooks(build_push_data.dup, :push_hooks) @@ -105,9 +105,9 @@ class GitPushService < BaseService Ci::CreatePipelineService.new(@project, current_user, build_push_data).execute if push_remove_branch? - AfterBranchDeleteService - .new(project, current_user) - .execute(branch_name) + AfterBranchDeleteService. + new(project, current_user). + execute(branch_name) end end diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb index a2a5f57d069..17b65947468 100644 --- a/app/services/issues/move_service.rb +++ b/app/services/issues/move_service.rb @@ -61,8 +61,8 @@ module Issues end def cloneable_milestone_id - @new_project.milestones - .find_by(title: @old_issue.milestone.try(:title)).try(:id) + @new_project.milestones. + find_by(title: @old_issue.milestone.try(:title)).try(:id) end def rewrite_notes diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index 5a53b973059..fd9d7de35f4 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -40,11 +40,11 @@ module MergeRequests # Returns all origin and fork merge requests from `@project` satisfying passed arguments. def merge_requests_for(source_branch, mr_states: [:opened]) - MergeRequest - .with_state(mr_states) - .where(source_branch: source_branch, source_project_id: @project.id) - .preload(:source_project) # we don't need a #includes since we're just preloading for the #select - .select(&:source_project) + MergeRequest. + with_state(mr_states). + where(source_branch: source_branch, source_project_id: @project.id). + preload(:source_project). # we don't need a #includes since we're just preloading for the #select + select(&:source_project) end def pipeline_merge_requests(pipeline) diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index 581d18032e6..edee3032683 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -60,9 +60,9 @@ module MergeRequests by_source_or_target_branch(@branch_name).to_a # Fork merge requests - merge_requests += MergeRequest.opened - .where(source_branch: @branch_name, source_project: @project) - .where.not(target_project: @project).to_a + merge_requests += MergeRequest.opened. + where(source_branch: @branch_name, source_project: @project). + where.not(target_project: @project).to_a filter_merge_requests(merge_requests).each do |merge_request| if merge_request.source_branch == @branch_name || force_push? diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index def0ab1dde1..31e2dc448da 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -3,7 +3,7 @@ class BuildCoverageWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id) - .try(:update_coverage) + Ci::Build.find_by(id: build_id). + try(:update_coverage) end end diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index 9965af935d4..ff22313c491 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -3,7 +3,7 @@ class BuildHooksWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id) - .try(:execute_hooks) + Ci::Build.find_by(id: build_id). + try(:execute_hooks) end end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index f5ccc84c160..d4c3f14ec06 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -33,15 +33,15 @@ class EmailsOnPushWorker reverse_compare = false if action == :push - compare = CompareService.new(project, after_sha) - .execute(project, before_sha) + compare = CompareService.new(project, after_sha). + execute(project, before_sha) diff_refs = compare.diff_refs return false if compare.same if compare.commits.empty? - compare = CompareService.new(project, before_sha) - .execute(project, after_sha) + compare = CompareService.new(project, before_sha). + execute(project, after_sha) diff_refs = compare.diff_refs reverse_compare = true diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index eb403c134d1..2c29a9a58e1 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -3,10 +3,10 @@ class ExpireBuildInstanceArtifactsWorker include DedicatedSidekiqQueue def perform(build_id) - build = Ci::Build - .with_expired_artifacts - .reorder(nil) - .find_by(id: build_id) + build = Ci::Build. + with_expired_artifacts. + reorder(nil). + find_by(id: build_id) return unless build.try(:project) diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index 7e36eacebf8..7480a055e6a 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -3,7 +3,7 @@ class PipelineHooksWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id) - .try(:execute_hooks) + Ci::Pipeline.find_by(id: pipeline_id). + try(:execute_hooks) end end diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 357e4a9a1c3..5dcb09f553e 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -3,7 +3,7 @@ class PipelineProcessWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id) - .try(:process!) + Ci::Pipeline.find_by(id: pipeline_id). + try(:process!) end end diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb index cc0eb708cf9..ef710f374ca 100644 --- a/app/workers/pipeline_success_worker.rb +++ b/app/workers/pipeline_success_worker.rb @@ -4,9 +4,9 @@ class PipelineSuccessWorker def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| - MergeRequests::MergeWhenPipelineSucceedsService - .new(pipeline.project, nil) - .trigger(pipeline) + MergeRequests::MergeWhenPipelineSucceedsService. + new(pipeline.project, nil). + trigger(pipeline) end end end diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index 96c4152c674..e6d06d0577d 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -3,7 +3,7 @@ class PipelineUpdateWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id) - .try(:update_status) + Ci::Pipeline.find_by(id: pipeline_id). + try(:update_status) end end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index bdd764abfeb..6a2476424a7 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -193,13 +193,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) else - ::MergeRequests::MergeService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) end present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project @@ -213,9 +213,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user) - .cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user). + cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index f59f7959173..ffa73696029 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -36,8 +36,8 @@ module API new_pipeline = Ci::CreatePipelineService.new(user_project, current_user, - declared_params(include_missing: false)) - .execute(ignore_skip_ci: true, save_on_errors: false) + declared_params(include_missing: false)). + execute(ignore_skip_ci: true, save_on_errors: false) if new_pipeline.persisted? present new_pipeline, with: Entities::Pipeline else diff --git a/lib/api/v3/merge_requests.rb b/lib/api/v3/merge_requests.rb index 129f9d850e9..5a8dacc9c44 100644 --- a/lib/api/v3/merge_requests.rb +++ b/lib/api/v3/merge_requests.rb @@ -200,13 +200,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) else - ::MergeRequests::MergeService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) end present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project @@ -220,9 +220,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user) - .cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user). + cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/banzai/pipeline/wiki_pipeline.rb b/lib/banzai/pipeline/wiki_pipeline.rb index c37b8e71cb0..17b460608d7 100644 --- a/lib/banzai/pipeline/wiki_pipeline.rb +++ b/lib/banzai/pipeline/wiki_pipeline.rb @@ -3,8 +3,8 @@ module Banzai class WikiPipeline < FullPipeline def self.filters @filters ||= begin - super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter) - .insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) + super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter). + insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) end end end diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index 8e3b0c4db79..c6426210a92 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -28,8 +28,8 @@ module Banzai # text blobs to parse. return [] if @texts_and_contexts.empty? - @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts) - .map { |html| Nokogiri::HTML.fragment(html) } + @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts). + map { |html| Nokogiri::HTML.fragment(html) } end end end diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 649ee4d018b..04d9756657a 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -115,8 +115,8 @@ module Ci end def yaml_variables(name) - variables = (@variables || {}) - .merge(job_variables(name)) + variables = (@variables || {}). + merge(job_variables(name)) variables.map do |key, value| { key: key.to_s, value: value, public: true } diff --git a/lib/gitlab/badge/build/status.rb b/lib/gitlab/badge/build/status.rb index b762d85b6e5..3c65fd02e4c 100644 --- a/lib/gitlab/badge/build/status.rb +++ b/lib/gitlab/badge/build/status.rb @@ -19,9 +19,9 @@ module Gitlab end def status - @project.pipelines - .where(sha: @sha) - .latest_status(@ref) || 'unknown' + @project.pipelines. + where(sha: @sha). + latest_status(@ref) || 'unknown' end def metadata diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb index 9a0482306b7..8a6564755ab 100644 --- a/lib/gitlab/badge/coverage/report.rb +++ b/lib/gitlab/badge/coverage/report.rb @@ -42,9 +42,9 @@ module Gitlab if @job.blank? @pipeline.coverage else - @pipeline.builds - .find_by(name: @job) - .try(:coverage) + @pipeline.builds. + find_by(name: @job). + try(:coverage) end end end diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb index 44323b47dca..03a7981b1db 100644 --- a/lib/gitlab/bitbucket_import/importer.rb +++ b/lib/gitlab/bitbucket_import/importer.rb @@ -48,10 +48,10 @@ module Gitlab return users[username] if users.key?(username) - users[username] = User.select(:id) - .joins(:identities) - .find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username) - .try(:id) + users[username] = User.select(:id). + joins(:identities). + find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username). + try(:id) end def repo diff --git a/lib/gitlab/checks/matching_merge_request.rb b/lib/gitlab/checks/matching_merge_request.rb index 849848515da..bd295c25194 100644 --- a/lib/gitlab/checks/matching_merge_request.rb +++ b/lib/gitlab/checks/matching_merge_request.rb @@ -8,10 +8,10 @@ module Gitlab end def match? - @project.merge_requests - .with_state(:locked) - .where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name) - .exists? + @project.merge_requests. + with_state(:locked). + where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name). + exists? end end end diff --git a/lib/gitlab/ci/config/entry/configurable.rb b/lib/gitlab/ci/config/entry/configurable.rb index e05aca9881b..deaaf06bbd7 100644 --- a/lib/gitlab/ci/config/entry/configurable.rb +++ b/lib/gitlab/ci/config/entry/configurable.rb @@ -27,9 +27,9 @@ module Gitlab return unless valid? self.class.nodes.each do |key, factory| - factory - .value(@config[key]) - .with(key: key, parent: self) + factory. + value(@config[key]). + with(key: key, parent: self) @entries[key] = factory.create! end @@ -49,8 +49,8 @@ module Gitlab private # rubocop:disable Lint/UselessAccessModifier def entry(key, entry, metadata) - factory = Entry::Factory.new(entry) - .with(description: metadata[:description]) + factory = Entry::Factory.new(entry). + with(description: metadata[:description]) (@nodes ||= {}).merge!(key.to_sym => factory) end diff --git a/lib/gitlab/ci/config/entry/global.rb b/lib/gitlab/ci/config/entry/global.rb index a4ec8f0ff2f..8154beea21f 100644 --- a/lib/gitlab/ci/config/entry/global.rb +++ b/lib/gitlab/ci/config/entry/global.rb @@ -46,9 +46,9 @@ module Gitlab private def compose_jobs! - factory = Entry::Factory.new(Entry::Jobs) - .value(@config.except(*self.class.nodes.keys)) - .with(key: :jobs, parent: self, + factory = Entry::Factory.new(Entry::Jobs). + value(@config.except(*self.class.nodes.keys)). + with(key: :jobs, parent: self, description: 'Jobs definition for this pipeline') @entries[:jobs] = factory.create! diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb index 5671a09480b..41de7dbbb3e 100644 --- a/lib/gitlab/ci/config/entry/jobs.rb +++ b/lib/gitlab/ci/config/entry/jobs.rb @@ -31,10 +31,10 @@ module Gitlab @config.each do |name, config| node = hidden?(name) ? Entry::Hidden : Entry::Job - factory = Entry::Factory.new(node) - .value(config || {}) - .metadata(name: name) - .with(key: name, parent: self, + factory = Entry::Factory.new(node). + value(config || {}). + metadata(name: name). + with(key: name, parent: self, description: "#{name} job definition.") @entries[name] = factory.create! diff --git a/lib/gitlab/ci/status/factory.rb b/lib/gitlab/ci/status/factory.rb index 15836c699c7..efe756cc585 100644 --- a/lib/gitlab/ci/status/factory.rb +++ b/lib/gitlab/ci/status/factory.rb @@ -17,10 +17,10 @@ module Gitlab end def core_status - Gitlab::Ci::Status - .const_get(@status.capitalize) - .new(@subject, @user) - .extend(self.class.common_helpers) + Gitlab::Ci::Status. + const_get(@status.capitalize). + new(@subject, @user). + extend(self.class.common_helpers) end def compound_extended_status diff --git a/lib/gitlab/ci/trace_reader.rb b/lib/gitlab/ci/trace_reader.rb index 1d7ddeb3e0f..dd6a84d7d1c 100644 --- a/lib/gitlab/ci/trace_reader.rb +++ b/lib/gitlab/ci/trace_reader.rb @@ -41,8 +41,8 @@ module Gitlab chunks.unshift(buf) end - chunks.join.lines.last(max_lines).join - .force_encoding(Encoding.default_external) + chunks.join.lines.last(max_lines).join. + force_encoding(Encoding.default_external) end end end diff --git a/lib/gitlab/git/encoding_helper.rb b/lib/gitlab/git/encoding_helper.rb index e57d228e688..874fd8fe6e2 100644 --- a/lib/gitlab/git/encoding_helper.rb +++ b/lib/gitlab/git/encoding_helper.rb @@ -49,9 +49,9 @@ module Gitlab private def clean(message) - message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: "") - .encode("UTF-8") - .gsub("\0".encode("UTF-8"), "") + message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: ""). + encode("UTF-8"). + gsub("\0".encode("UTF-8"), "") end end end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index d95ff4fd104..a631425b3cf 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -178,9 +178,9 @@ module Gitlab def apply_labels(issuable, raw) return unless raw.labels.count > 0 - label_ids = raw.labels - .map { |attrs| @labels[attrs.name] } - .compact + label_ids = raw.labels. + map { |attrs| @labels[attrs.name] }. + compact issuable.update_attribute(:label_ids, label_ids) end diff --git a/lib/gitlab/github_import/user_formatter.rb b/lib/gitlab/github_import/user_formatter.rb index 04c2964da20..7f3bf0052a7 100644 --- a/lib/gitlab/github_import/user_formatter.rb +++ b/lib/gitlab/github_import/user_formatter.rb @@ -25,8 +25,8 @@ module Gitlab def find_by_email return nil unless email - User.find_by_any_email(email) - .try(:id) + User.find_by_any_email(email). + try(:id) end def find_by_external_uid @@ -34,11 +34,11 @@ module Gitlab identities = ::Identity.arel_table - User.select(:id) - .joins(:identities).where(identities[:provider].eq(:github) - .and(identities[:extern_uid].eq(id))) - .first - .try(:id) + User.select(:id). + joins(:identities).where(identities[:provider].eq(:github). + and(identities[:extern_uid].eq(id))). + first. + try(:id) end end end diff --git a/rubocop/cop/gem_fetcher.rb b/rubocop/cop/gem_fetcher.rb index c199f6acab2..4331018fca4 100644 --- a/rubocop/cop/gem_fetcher.rb +++ b/rubocop/cop/gem_fetcher.rb @@ -25,12 +25,12 @@ module RuboCop private def gemfile?(node) - node - .location - .expression - .source_buffer - .name - .end_with?("Gemfile") + node. + location. + expression. + source_buffer. + name. + end_with?("Gemfile") end end end diff --git a/spec/controllers/ci/projects_controller_spec.rb b/spec/controllers/ci/projects_controller_spec.rb index 86f01f437a2..3cd955dc9d4 100644 --- a/spec/controllers/ci/projects_controller_spec.rb +++ b/spec/controllers/ci/projects_controller_spec.rb @@ -33,8 +33,8 @@ describe Ci::ProjectsController do shared_examples 'badge provider' do it 'shows badge' do expect(response.status).to eq 200 - expect(response.headers) - .to include('Content-Type' => 'image/svg+xml') + expect(response.headers). + to include('Content-Type' => 'image/svg+xml') end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index f84f922ba5e..1c5dbda0de2 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -334,9 +334,9 @@ describe Projects::MergeRequestsController do it 'sets the MR to merge when the build succeeds' do service = double(:merge_when_build_succeeds_service) - expect(MergeRequests::MergeWhenPipelineSucceedsService) - .to receive(:new).with(project, anything, anything) - .and_return(service) + expect(MergeRequests::MergeWhenPipelineSucceedsService). + to receive(:new).with(project, anything, anything). + and_return(service) expect(service).to receive(:execute).with(merge_request) merge_when_build_succeeds diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index b56c7880b64..d951325f765 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -11,8 +11,8 @@ describe SessionsController do it 'does not authenticate user' do post(:create, user: { login: 'invalid', password: 'invalid' }) - expect(response) - .to set_flash.now[:alert].to /Invalid Login or password/ + expect(response). + to set_flash.now[:alert].to /Invalid Login or password/ end end @@ -102,8 +102,8 @@ describe SessionsController do end it 'warns about invalid OTP code' do - expect(response).to set_flash.now[:alert] - .to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert]. + to /Invalid two-factor code/ end end end @@ -129,8 +129,8 @@ describe SessionsController do end it 'warns about invalid login' do - expect(response).to set_flash.now[:alert] - .to /Invalid Login or password/ + expect(response).to set_flash.now[:alert]. + to /Invalid Login or password/ end it 'locks the user' do @@ -140,8 +140,8 @@ describe SessionsController do it 'keeps the user locked on future login attempts' do post(:create, user: { login: user.username, password: user.password }) - expect(response) - .to set_flash.now[:alert].to /Invalid Login or password/ + expect(response). + to set_flash.now[:alert].to /Invalid Login or password/ end end end @@ -153,8 +153,8 @@ describe SessionsController do authenticate_2fa(login: another_user.username, otp_attempt: 'invalid') - expect(response).to set_flash.now[:alert] - .to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert]. + to /Invalid two-factor code/ end end end diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index 78be7d36f47..513de297fdf 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -111,8 +111,8 @@ feature 'Environments page', :feature, :js do find('.js-dropdown-play-icon-container').click expect(page).to have_content(manual.name.humanize) - expect { click_link(manual.name.humanize) } - .not_to change { Ci::Pipeline.count } + expect { click_link(manual.name.humanize) }. + not_to change { Ci::Pipeline.count } expect(manual.reload).to be_pending end diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index 73c5ef31edc..9fc5339308c 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -61,8 +61,8 @@ feature 'Merge request created from fork' do expect(page).to have_content pipeline.id end - expect(page.find('a.btn-remove')[:href]) - .to include fork_project.path_with_namespace + expect(page.find('a.btn-remove')[:href]). + to include fork_project.path_with_namespace end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 592dc4483d2..81f5ebf6339 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -366,8 +366,8 @@ describe 'Pipelines', :feature, :js do before { stub_ci_pipeline_to_return_yaml_file } it 'creates a new pipeline' do - expect { click_on 'Create pipeline' } - .to change { Ci::Pipeline.count }.by(1) + expect { click_on 'Create pipeline' }. + to change { Ci::Pipeline.count }.by(1) end end diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb index 0c063f6d5ee..ed60a95deba 100644 --- a/spec/finders/environments_finder_spec.rb +++ b/spec/finders/environments_finder_spec.rb @@ -16,18 +16,18 @@ describe EnvironmentsFinder do end it 'returns environment when with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute). + to contain_exactly(environment) end it 'does not return environment when no with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). + to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). + to be_empty end end @@ -37,23 +37,23 @@ describe EnvironmentsFinder do end it 'returns environment when ref is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). + to contain_exactly(environment) end it 'does not environment when ref is different' do - expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute). + to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). + to be_empty end it 'returns environment when commit constraint is not set' do - expect(described_class.new(project, user, ref: 'master').execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master').execute). + to contain_exactly(environment) end end @@ -63,8 +63,8 @@ describe EnvironmentsFinder do end it 'returns environment' do - expect(described_class.new(project, user, commit: project.commit).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, commit: project.commit).execute). + to contain_exactly(environment) end end @@ -75,8 +75,8 @@ describe EnvironmentsFinder do end it 'finds recently updated environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). + to contain_exactly(environment) end end @@ -87,8 +87,8 @@ describe EnvironmentsFinder do end it 'does not find environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). + to be_empty end end @@ -101,8 +101,8 @@ describe EnvironmentsFinder do end it 'finds both environments' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) - .to contain_exactly(environment, second_environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). + to contain_exactly(environment, second_environment) end end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 13fb9c1f1a7..e1e56582425 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -67,8 +67,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Joe') awards = Array.new(3, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)) - .to eq('Joe, Joe, and Joe') + expect(award_user_list(awards, nil, limit: 3)). + to eq('Joe, Joe, and Joe') end it "displays the current user's name as 'You'" do @@ -83,8 +83,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Jane') awards = Array.new(5, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)) - .to eq('Jane, Jane, Jane, and 2 more.') + expect(award_user_list(awards, nil, limit: 3)). + to eq('Jane, Jane, Jane, and 2 more.') end it "displays the current user in front of other users" do diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index 2cc0b40b2d0..9d7a39d3721 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -111,8 +111,8 @@ describe PageLayoutHelper do end it 'escapes content' do - allow(helper).to receive(:page_card_attributes) - .and_return(foo: %q{foo" http-equiv="refresh}.html_safe) + allow(helper).to receive(:page_card_attributes). + and_return(foo: %q{foo" http-equiv="refresh}.html_safe) tags = helper.page_card_meta_tags diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index 8942b00b128..387279b2031 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -9,52 +9,52 @@ describe VisibilityLevelHelper do describe 'visibility_level_description' do context 'used with a Project' do it 'delegates projects to #project_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)) - .to match /project/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)). + to match /project/i end end context 'used with a Group' do it 'delegates groups to #group_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)) - .to match /group/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)). + to match /group/i end end context 'called with a Snippet' do it 'delegates snippets to #snippet_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)) - .to match /snippet/i + expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)). + to match /snippet/i end end end describe "#project_visibility_level_description" do it "describes private projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) - .to eq "Project access must be granted explicitly to each user." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). + to eq "Project access must be granted explicitly to each user." end it "describes public projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)) - .to eq "The project can be cloned without any authentication." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)). + to eq "The project can be cloned without any authentication." end end describe "#snippet_visibility_level_description" do it 'describes visibility only for me' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)) - .to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)). + to eq "The snippet is visible only to me." end it 'describes visibility for project members' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)) - .to eq "The snippet is visible only to project members." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)). + to eq "The snippet is visible only to project members." end it 'defaults to personal snippet' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) - .to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). + to eq "The snippet is visible only to me." end end diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb index 267318faed4..152c36a3ae6 100644 --- a/spec/lib/api/helpers/pagination_spec.rb +++ b/spec/lib/api/helpers/pagination_spec.rb @@ -37,8 +37,8 @@ describe API::Helpers::Pagination do describe 'first page' do before do - allow(subject).to receive(:params) - .and_return({ page: 1, per_page: 2 }) + allow(subject).to receive(:params). + and_return({ page: 1, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -60,8 +60,8 @@ describe API::Helpers::Pagination do describe 'second page' do before do - allow(subject).to receive(:params) - .and_return({ page: 2, per_page: 2 }) + allow(subject).to receive(:params). + and_return({ page: 2, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -87,8 +87,8 @@ describe API::Helpers::Pagination do end def expect_message(method) - expect(subject).to receive(method) - .at_least(:once).and_return(value) + expect(subject).to receive(method). + at_least(:once).and_return(value) end end end diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb index fbf7a461fa5..efd145e9452 100644 --- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb @@ -33,8 +33,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do doc = filter("Issue #{reference}") issue_id = doc.css('a').first.attr("data-external-issue") - expect(doc.css('a').first.attr('href')) - .to eq helper.url_for_issue(issue_id, project) + expect(doc.css('a').first.attr('href')). + to eq helper.url_for_issue(issue_id, project) end it 'links to the external tracker' do diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index 284641fb20a..5e16fd10ebe 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -372,8 +372,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -406,8 +406,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -440,8 +440,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -476,8 +476,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(another_project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(another_project.namespace, another_project, label_name: group_label.name) end @@ -549,15 +549,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')) - .to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')). + to match /background-color: #00ff00/ end it 'has valid link text' do @@ -583,8 +583,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index d5d128c1907..e9b7b566806 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -37,8 +37,8 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do doc = reference_filter("Hey #{reference}", author: user) expect(doc.css('a').length).to eq 1 - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_url(project.namespace, project) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_url(project.namespace, project) end it 'includes a data-author attribute when there is an author' do diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 68ad429608d..ce31f8a8432 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -25,8 +25,8 @@ module Ci end it 'includes coverage regexp in build attributes' do - expect(subject) - .to include(coverage_regex: 'Code coverage: \d+\.\d+') + expect(subject). + to include(coverage_regex: 'Code coverage: \d+\.\d+') end end end @@ -584,8 +584,8 @@ module Ci end it 'raises error' do - expect { subject } - .to raise_error(GitlabCiYamlProcessor::ValidationError, + expect { subject }. + to raise_error(GitlabCiYamlProcessor::ValidationError, /jobs:rspec:variables config should be a hash of key value pairs/) end end @@ -1365,8 +1365,8 @@ EOT it "returns an error about invalid configutaion" do content = YAML.dump("invalid: yaml: test") - expect(GitlabCiYamlProcessor.validation_message(content)) - .to eq "Invalid configuration format" + expect(GitlabCiYamlProcessor.validation_message(content)). + to eq "Invalid configuration format" end end @@ -1374,15 +1374,15 @@ EOT it "returns an error about invalid tags" do content = YAML.dump({ rspec: { script: "test", tags: "mysql" } }) - expect(GitlabCiYamlProcessor.validation_message(content)) - .to eq "jobs:rspec tags should be an array of strings" + expect(GitlabCiYamlProcessor.validation_message(content)). + to eq "jobs:rspec tags should be an array of strings" end end context "when YAML content is empty" do it "returns an error about missing content" do - expect(GitlabCiYamlProcessor.validation_message('')) - .to eq "Please provide content of .gitlab-ci.yml" + expect(GitlabCiYamlProcessor.validation_message('')). + to eq "Please provide content of .gitlab-ci.yml" end end diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index bca57105d1d..e193a3b79a6 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -19,8 +19,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS } - expect(Asciidoctor).to receive(:convert) - .with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert). + with(input, expected_asciidoc_opts).and_return(html) expect( render(input, context) ).to eql html end @@ -35,8 +35,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS + ['foo'] } - expect(Asciidoctor).to receive(:convert) - .with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert). + with(input, expected_asciidoc_opts).and_return(html) render(input, context, asciidoc_opts) end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index b234de4c772..57c416fb35a 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -140,8 +140,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) - .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). + to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end it 'falls through oauth authentication when the username is oauth2' do @@ -151,8 +151,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) - .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). + to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end end diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index f84782ab440..e9c69183d00 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -141,8 +141,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('No backups found')) + expect(progress).to have_received(:puts). + with(a_string_matching('No backups found')) end end @@ -158,8 +158,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('Found more than one backup')) + expect(progress).to have_received(:puts). + with(a_string_matching('Found more than one backup')) end end @@ -178,8 +178,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts) - .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress).to have_received(:puts). + with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) end end @@ -200,8 +200,8 @@ describe Backup::Manager, lib: true do it 'unpacks the file' do subject.unpack - expect(Kernel).to have_received(:system) - .with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") + expect(Kernel).to have_received(:system). + with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") expect(progress).to have_received(:puts).with(a_string_matching('done')) end end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb index 3c5414701a7..8a4bf4dc89b 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -20,8 +20,8 @@ describe Gitlab::Badge::Build::Status do describe '#metadata' do it 'returns badge metadata' do - expect(badge.metadata.image_url) - .to include 'badges/master/build.svg' + expect(badge.metadata.image_url). + to include 'badges/master/build.svg' end end diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb index 5c31423fdee..987a0b1f67f 100644 --- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb @@ -26,8 +26,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { name: 10 } } it 'reports error' do - expect(entry.errors) - .to include 'artifacts name should be a string' + expect(entry.errors). + to include 'artifacts name should be a string' end end @@ -35,8 +35,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { test: 100 } } it 'reports error' do - expect(entry.errors) - .to include 'artifacts config contains unknown keys: test' + expect(entry.errors). + to include 'artifacts config contains unknown keys: test' end end end diff --git a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb index fde03c51e2c..efb8c5adab1 100644 --- a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb @@ -14,9 +14,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is a hash' do before do - allow(instance) - .to receive(:config) - .and_return({ name: 'some name', test: 'some test' }) + allow(instance). + to receive(:config). + and_return({ name: 'some name', test: 'some test' }) end it 'returns the value of config' do @@ -31,9 +31,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is not a hash' do before do - allow(instance) - .to receive(:config) - .and_return('some test') + allow(instance). + to receive(:config). + and_return('some test') end it 'returns nil' do diff --git a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb index 5f067cad93c..8987c0549c5 100644 --- a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Boolean do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'boolean config should be a boolean value' + expect(entry.errors). + to include 'boolean config should be a boolean value' end end end diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index 70a327c5183..e91f049ee72 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -32,8 +32,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { 'ls' } it 'reports errors with config value' do - expect(entry.errors) - .to include 'cache config should be a hash' + expect(entry.errors). + to include 'cache config should be a hash' end end @@ -41,8 +41,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { key: 1 } } it 'reports error with descendants' do - expect(entry.errors) - .to include 'key config should be a string or symbol' + expect(entry.errors). + to include 'key config should be a string or symbol' end end @@ -50,8 +50,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { invalid: true } } it 'reports error with descendants' do - expect(entry.errors) - .to include 'cache config contains unknown keys: invalid' + expect(entry.errors). + to include 'cache config contains unknown keys: invalid' end end end diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb index b8b0825a1c7..fa3dbd9bf32 100644 --- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb @@ -40,8 +40,8 @@ describe Gitlab::Ci::Config::Entry::Commands do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'commands config should be a ' \ + expect(entry.errors). + to include 'commands config should be a ' \ 'string or an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb index ae7e628b5b5..490ba9b7df1 100644 --- a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb @@ -52,8 +52,8 @@ describe Gitlab::Ci::Config::Entry::Configurable do end it 'creates a node factory' do - expect(entry.nodes[:object]) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Factory + expect(entry.nodes[:object]). + to be_an_instance_of Gitlab::Ci::Config::Entry::Factory end it 'returns a duplicated factory object' do diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb index 2adbed2154f..fab2825fbb0 100644 --- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb @@ -112,8 +112,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors) - .to include 'environment action should be start or stop' + expect(entry.errors). + to include 'environment action should be start or stop' end end end @@ -143,8 +143,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors) - .to include 'environment on stop should be a string' + expect(entry.errors). + to include 'environment on stop should be a string' end end end @@ -174,8 +174,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid type' do - expect(entry.errors) - .to include 'environment config should be a hash or a string' + expect(entry.errors). + to include 'environment config should be a hash or a string' end end end @@ -191,8 +191,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors?' do it 'contains error about missing environment name' do - expect(entry.errors) - .to include "environment name can't be blank" + expect(entry.errors). + to include "environment name can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/factory_spec.rb b/spec/lib/gitlab/ci/config/entry/factory_spec.rb index 00dad5d9591..281a110071a 100644 --- a/spec/lib/gitlab/ci/config/entry/factory_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/factory_spec.rb @@ -7,19 +7,19 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting a concrete value' do it 'creates entry with valid value' do - entry = factory - .value(['ls', 'pwd']) - .create! + entry = factory. + value(['ls', 'pwd']). + create! expect(entry.value).to eq ['ls', 'pwd'] end context 'when setting description' do it 'creates entry with description' do - entry = factory - .value(['ls', 'pwd']) - .with(description: 'test description') - .create! + entry = factory. + value(['ls', 'pwd']). + with(description: 'test description'). + create! expect(entry.value).to eq ['ls', 'pwd'] expect(entry.description).to eq 'test description' @@ -28,10 +28,10 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting key' do it 'creates entry with custom key' do - entry = factory - .value(['ls', 'pwd']) - .with(key: 'test key') - .create! + entry = factory. + value(['ls', 'pwd']). + with(key: 'test key'). + create! expect(entry.key).to eq 'test key' end @@ -41,10 +41,10 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:object) { Object.new } it 'creates entry with valid parent' do - entry = factory - .value('ls') - .with(parent: object) - .create! + entry = factory. + value('ls'). + with(parent: object). + create! expect(entry.parent).to eq object end @@ -61,12 +61,12 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when creating entry with nil value' do it 'creates an undefined entry' do - entry = factory - .value(nil) - .create! + entry = factory. + value(nil). + create! - expect(entry) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(entry). + to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -74,13 +74,13 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:entry) { spy('entry') } it 'passes metadata as a parameter' do - factory - .value('some value') - .metadata(some: 'hash') - .create! + factory. + value('some value'). + metadata(some: 'hash'). + create! - expect(entry).to have_received(:new) - .with('some value', { some: 'hash' }) + expect(entry).to have_received(:new). + with('some value', { some: 'hash' }) end end end diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 432a99dce33..c3551a149ed 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when filtering all the entry/node names' do it 'contains the expected node names' do - expect(described_class.nodes.keys) - .to match_array(%i[before_script image services + expect(described_class.nodes.keys). + to match_array(%i[before_script image services after_script variables stages types cache]) end @@ -44,17 +44,17 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'creates node object using valid class' do - expect(global.descendants.first) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Script - expect(global.descendants.second) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Image + expect(global.descendants.first). + to be_an_instance_of Gitlab::Ci::Config::Entry::Script + expect(global.descendants.second). + to be_an_instance_of Gitlab::Ci::Config::Entry::Image end it 'sets correct description for nodes' do - expect(global.descendants.first.description) - .to eq 'Script that will be executed before each job.' - expect(global.descendants.second.description) - .to eq 'Docker image that will be used to execute jobs.' + expect(global.descendants.first.description). + to eq 'Script that will be executed before each job.' + expect(global.descendants.second.description). + to eq 'Docker image that will be used to execute jobs.' end describe '#leaf?' do @@ -138,8 +138,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#cache_value' do it 'returns cache configuration' do - expect(global.cache_value) - .to eq(key: 'k', untracked: true, paths: ['public/']) + expect(global.cache_value). + to eq(key: 'k', untracked: true, paths: ['public/']) end end @@ -185,8 +185,8 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'contains unspecified nodes' do - expect(global.descendants.first) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(global.descendants.first). + to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -246,8 +246,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors from child nodes' do - expect(global.errors) - .to include 'before_script config should be an array of strings' + expect(global.errors). + to include 'before_script config should be an array of strings' end end @@ -265,8 +265,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors about missing script' do - expect(global.errors) - .to include "jobs:rspec script can't be blank" + expect(global.errors). + to include "jobs:rspec script can't be blank" end end end @@ -303,16 +303,16 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when entry exists' do it 'returns correct entry' do - expect(global[:cache]) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Cache + expect(global[:cache]). + to be_an_instance_of Gitlab::Ci::Config::Entry::Cache expect(global[:jobs][:rspec][:script].value).to eq ['ls'] end end context 'when entry does not exist' do it 'always return unspecified node' do - expect(global[:some][:unknown][:node]) - .not_to be_specified + expect(global[:some][:unknown][:node]). + not_to be_specified end end end diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb index 3c99cb0a1ee..062817e07fd 100644 --- a/spec/lib/gitlab/ci/config/entry/image_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Image do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'image config should be a string' + expect(entry.errors). + to include 'image config should be a string' end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index d20f4ec207d..b90308a0515 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -44,8 +44,8 @@ describe Gitlab::Ci::Config::Entry::Job do describe '#errors' do it 'reports error about a config type' do - expect(entry.errors) - .to include 'job config should be a hash' + expect(entry.errors). + to include 'job config should be a hash' end end end @@ -138,8 +138,8 @@ describe Gitlab::Ci::Config::Entry::Job do end it 'returns correct value' do - expect(entry.value) - .to eq(name: :rspec, + expect(entry.value). + to eq(name: :rspec, before_script: %w[ls pwd], script: %w[rspec], commands: "ls\npwd\nrspec", diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index aaebf783962..c332b70dc71 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -22,8 +22,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { ['incorrect'] } it 'returns error about incorrect type' do - expect(entry.errors) - .to include 'jobs config should be a hash' + expect(entry.errors). + to include 'jobs config should be a hash' end end @@ -39,8 +39,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { { '.hidden'.to_sym => { script: [] } } } it 'returns error about no visible jobs defined' do - expect(entry.errors) - .to include 'jobs config should contain at least one visible job' + expect(entry.errors). + to include 'jobs config should contain at least one visible job' end end end @@ -73,10 +73,10 @@ describe Gitlab::Ci::Config::Entry::Jobs do describe '#descendants' do it 'creates valid descendant nodes' do expect(entry.descendants.count).to eq 3 - expect(entry.descendants.first(2)) - .to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) - expect(entry.descendants.last) - .to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) + expect(entry.descendants.first(2)). + to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) + expect(entry.descendants.last). + to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) end end diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb index a55e5b4b8ac..b1e563e0786 100644 --- a/spec/lib/gitlab/ci/config/entry/key_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Key do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'key config should be a string or symbol' + expect(entry.errors). + to include 'key config should be a string or symbol' end end end diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb index e60c9aaf661..52f595e4b67 100644 --- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Paths do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'paths config should be an array of strings' + expect(entry.errors). + to include 'paths config should be an array of strings' end end end diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb index aa99cee2690..8c1305f376d 100644 --- a/spec/lib/gitlab/ci/config/entry/script_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Script do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'script config should be an array of strings' + expect(entry.errors). + to include 'script config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb index 66fad3b6b16..c31a7c0ec3e 100644 --- a/spec/lib/gitlab/ci/config/entry/services_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Services do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'services config should be an array of strings' + expect(entry.errors). + to include 'services config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/stage_spec.rb b/spec/lib/gitlab/ci/config/entry/stage_spec.rb index 70c8a0a355a..cefef7a805a 100644 --- a/spec/lib/gitlab/ci/config/entry/stage_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stage_spec.rb @@ -24,8 +24,8 @@ describe Gitlab::Ci::Config::Entry::Stage do let(:config) { { test: true } } it 'reports errors about wrong type' do - expect(stage.errors) - .to include 'stage config should be a string' + expect(stage.errors). + to include 'stage config should be a string' end end end diff --git a/spec/lib/gitlab/ci/config/entry/stages_spec.rb b/spec/lib/gitlab/ci/config/entry/stages_spec.rb index 182c8d867c7..bdcd6c98a85 100644 --- a/spec/lib/gitlab/ci/config/entry/stages_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stages_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Stages do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'stages config should be an array of strings' + expect(entry.errors). + to include 'stages config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb index e4ee44f1274..13b00a98b6a 100644 --- a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Trigger do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'trigger config should be an array of strings or regexps' + expect(entry.errors). + to include 'trigger config should be an array of strings or regexps' end end end diff --git a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb index d1856801827..e31e85538b9 100644 --- a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb @@ -19,8 +19,8 @@ describe Gitlab::Ci::Config::Entry::Validatable do end it 'returns validator' do - expect(entry.validator.superclass) - .to be Gitlab::Ci::Config::Entry::Validator + expect(entry.validator.superclass). + to be Gitlab::Ci::Config::Entry::Validator end it 'returns only one validator to mitigate leaks' do diff --git a/spec/lib/gitlab/ci/config/entry/validator_spec.rb b/spec/lib/gitlab/ci/config/entry/validator_spec.rb index ad7e6f07d3c..c6e21cd67b0 100644 --- a/spec/lib/gitlab/ci/config/entry/validator_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validator_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Validator do it 'returns errors' do validator_instance.validate - expect(validator_instance.messages) - .to include "node test attribute can't be blank" + expect(validator_instance.messages). + to include "node test attribute can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index 58327d08904..60aa510b746 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -33,8 +33,8 @@ describe Gitlab::Ci::Config::Entry::Variables do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include /should be a hash of key value pairs/ + expect(entry.errors). + to include /should be a hash of key value pairs/ end end diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index 40b96b1807b..cd893a09748 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Build::Common do let(:project) { build.project } subject do - Gitlab::Ci::Status::Core - .new(build, user) - .extend(described_class) + Gitlab::Ci::Status::Core. + new(build, user). + extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index 0c40fca0c1a..3d1ebadadcc 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -16,8 +16,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -42,8 +42,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -67,8 +67,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable, + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable, Gitlab::Ci::Status::Build::FailedAllowed] end @@ -96,8 +96,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -121,8 +121,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a canceable build status' do @@ -146,8 +146,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a cancelable build status' do @@ -196,8 +196,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Play] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Play] end it 'fabricates a core skipped status' do @@ -222,8 +222,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Stop] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Stop] end it 'fabricates a core skipped status' do diff --git a/spec/lib/gitlab/ci/status/extended_spec.rb b/spec/lib/gitlab/ci/status/extended_spec.rb index c2d74ca5cde..459044eb968 100644 --- a/spec/lib/gitlab/ci/status/extended_spec.rb +++ b/spec/lib/gitlab/ci/status/extended_spec.rb @@ -6,7 +6,7 @@ describe Gitlab::Ci::Status::Extended do end it 'requires subclass to implement matcher' do - expect { subject.matches?(double, double) } - .to raise_error(NotImplementedError) + expect { subject.matches?(double, double) }. + to raise_error(NotImplementedError) end end diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index 5a97d98b55f..6a564eeb8b7 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -10,9 +10,9 @@ describe Gitlab::Ci::Status::External::Common do end subject do - Gitlab::Ci::Status::Core - .new(external_status, user) - .extend(described_class) + Gitlab::Ci::Status::Core. + new(external_status, user). + extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/factory_spec.rb b/spec/lib/gitlab/ci/status/factory_spec.rb index bbf9c7c83a3..45fd49b91ea 100644 --- a/spec/lib/gitlab/ci/status/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/factory_spec.rb @@ -84,15 +84,15 @@ describe Gitlab::Ci::Status::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [first_extended_status, second_extended_status] + expect(factory.extended_statuses). + to eq [first_extended_status, second_extended_status] end end context 'when exclusive statuses are matches' do before do - allow(described_class).to receive(:extended_statuses) - .and_return([[first_extended_status, second_extended_status]]) + allow(described_class).to receive(:extended_statuses). + and_return([[first_extended_status, second_extended_status]]) end it 'does not fabricate compound decorator' do @@ -116,8 +116,8 @@ describe Gitlab::Ci::Status::Factory do context 'when exclusive statuses are not matched' do before do - allow(described_class).to receive(:extended_statuses) - .and_return([[first_extended_status], [second_extended_status]]) + allow(described_class).to receive(:extended_statuses). + and_return([[first_extended_status], [second_extended_status]]) end it_behaves_like 'compound decorator factory' @@ -125,8 +125,8 @@ describe Gitlab::Ci::Status::Factory do context 'when using simplified status grouping' do before do - allow(described_class).to receive(:extended_statuses) - .and_return([first_extended_status, second_extended_status]) + allow(described_class).to receive(:extended_statuses). + and_return([first_extended_status, second_extended_status]) end it_behaves_like 'compound decorator factory' diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index d665674bf70..35dad60febf 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Pipeline::Common do let(:pipeline) { create(:ci_pipeline, project: project) } subject do - Gitlab::Ci::Status::Core - .new(pipeline, user) - .extend(described_class) + Gitlab::Ci::Status::Core. + new(pipeline, user). + extend(described_class) end describe '#has_action?' do @@ -29,8 +29,8 @@ describe Gitlab::Ci::Status::Pipeline::Common do describe '#details_path' do it 'links to the pipeline details page' do - expect(subject.details_path) - .to include "pipelines/#{pipeline.id}" + expect(subject.details_path). + to include "pipelines/#{pipeline.id}" end end end diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index b10a447c27a..7cee4435931 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do it 'extends core status with common pipeline methods' do expect(status).to have_details expect(status).not_to have_action - expect(status.details_path) - .to include "pipelines/#{pipeline.id}" + expect(status.details_path). + to include "pipelines/#{pipeline.id}" end end end @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::SuccessWarning] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::SuccessWarning] end it 'fabricates extended "success with warnings" status' do diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb index 8814a7614a0..3b25893d8c7 100644 --- a/spec/lib/gitlab/ci/status/stage/common_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Status::Stage::Common do end subject do - Class.new(Gitlab::Ci::Status::Core) - .new(stage, user).extend(described_class) + Class.new(Gitlab::Ci::Status::Core). + new(stage, user).extend(described_class) end it 'does not have action' do @@ -19,10 +19,10 @@ describe Gitlab::Ci::Status::Stage::Common do end it 'links to the pipeline details page' do - expect(subject.details_path) - .to include "pipelines/#{pipeline.id}" - expect(subject.details_path) - .to include "##{stage.name}" + expect(subject.details_path). + to include "pipelines/#{pipeline.id}" + expect(subject.details_path). + to include "##{stage.name}" end context 'when user has permission to read pipeline' do diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index bbb40e2c1ab..c8503392b34 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Stage::Factory do end it 'fabricates extended "success with warnings" status' do - expect(status) - .to be_a Gitlab::Ci::Status::SuccessWarning + expect(status). + to be_a Gitlab::Ci::Status::SuccessWarning end it 'extends core status with common stage method' do diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb index 04ec34492e1..7658153df0b 100644 --- a/spec/lib/gitlab/data_builder/note_spec.rb +++ b/spec/lib/gitlab/data_builder/note_spec.rb @@ -9,8 +9,8 @@ describe Gitlab::DataBuilder::Note, lib: true do before(:each) do expect(data).to have_key(:object_attributes) expect(data[:object_attributes]).to have_key(:url) - expect(data[:object_attributes][:url]) - .to eq(Gitlab::UrlBuilder.build(note)) + expect(data[:object_attributes][:url]). + to eq(Gitlab::UrlBuilder.build(note)) expect(data[:object_kind]).to eq('note') expect(data[:user]).to eq(user.hook_attrs) end @@ -49,10 +49,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and issue-specific data' do expect(data).to have_key(:issue) - expect(data[:issue].except('updated_at')) - .to eq(issue.reload.hook_attrs.except('updated_at')) - expect(data[:issue]['updated_at']) - .to be > issue.hook_attrs['updated_at'] + expect(data[:issue].except('updated_at')). + to eq(issue.reload.hook_attrs.except('updated_at')) + expect(data[:issue]['updated_at']). + to be > issue.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -73,10 +73,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')) - .to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']) - .to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')). + to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']). + to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -96,10 +96,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request diff data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')) - .to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']) - .to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')). + to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']). + to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -119,10 +119,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and project snippet data' do expect(data).to have_key(:snippet) - expect(data[:snippet].except('updated_at')) - .to eq(snippet.reload.hook_attrs.except('updated_at')) - expect(data[:snippet]['updated_at']) - .to be > snippet.hook_attrs['updated_at'] + expect(data[:snippet].except('updated_at')). + to eq(snippet.reload.hook_attrs.except('updated_at')) + expect(data[:snippet]['updated_at']). + to be > snippet.hook_attrs['updated_at'] end include_examples 'project hook data' diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index edd01d032c8..5eff7e8425b 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -120,8 +120,8 @@ describe Gitlab::Database, lib: true do pool = described_class.create_connection_pool(5) begin - expect(pool) - .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) + expect(pool). + to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) expect(pool.spec.config[:pool]).to eq(5) ensure diff --git a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb index 08a42fd27a2..c141762421f 100644 --- a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb @@ -7,8 +7,8 @@ describe Gitlab::ImportExport::AvatarRestorer, lib: true do let(:project) { create(:empty_project) } before do - allow_any_instance_of(described_class).to receive(:avatar_export_file) - .and_return(uploaded_image_temp_path) + allow_any_instance_of(described_class).to receive(:avatar_export_file). + and_return(uploaded_image_temp_path) end after do diff --git a/spec/lib/gitlab/incoming_email_spec.rb b/spec/lib/gitlab/incoming_email_spec.rb index 698bd72d0f8..06d39d5c782 100644 --- a/spec/lib/gitlab/incoming_email_spec.rb +++ b/spec/lib/gitlab/incoming_email_spec.rb @@ -99,8 +99,8 @@ describe Gitlab::IncomingEmail, lib: true do end it 'returns reply key' do - expect(described_class.scan_fallback_references(references)) - .to eq(%w[issue_1@localhost + expect(described_class.scan_fallback_references(references)). + to eq(%w[issue_1@localhost reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost exchange@microsoft.com]) end diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb index 563c074017a..fe3709f30e1 100644 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/ldap/adapter_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::LDAP::Adapter, lib: true do end it 'searches with the proper options when searching with a limit' do - expect(adapter) - .to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) + expect(adapter). + to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) adapter.users('uid', 'johndoe', 100) end diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index fc9e1cb430a..8d9352350f0 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -184,8 +184,8 @@ describe Gitlab::OAuth::User, lib: true do oauth_user.save identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash) - .to match_array( + expect(identities_as_hash). + to match_array( [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'twitter', extern_uid: uid } diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb index 519eb1b274f..e05160da7a6 100644 --- a/spec/lib/gitlab/serializer/pagination_spec.rb +++ b/spec/lib/gitlab/serializer/pagination_spec.rb @@ -6,11 +6,11 @@ describe Gitlab::Serializer::Pagination do let(:headers) { spy('headers') } before do - allow(request).to receive(:query_parameters) - .and_return(params) + allow(request).to receive(:query_parameters). + and_return(params) - allow(response).to receive(:headers) - .and_return(headers) + allow(response).to receive(:headers). + and_return(headers) end let(:pagination) { described_class.new(request, response) } diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index b950fcdd81a..53011008f44 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -32,9 +32,9 @@ describe ApplicationSetting, models: true do it { is_expected.to validate_presence_of(:max_attachment_size) } it do - is_expected.to validate_numericality_of(:max_attachment_size) - .only_integer - .is_greater_than(0) + is_expected.to validate_numericality_of(:max_attachment_size). + only_integer. + is_greater_than(0) end it_behaves_like 'an object with email-formated attributes', :admin_notification_email do diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 2dfca8bcfce..2725c63f13b 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -212,15 +212,15 @@ describe Ci::Build, :models do retried_rspec = Ci::Build.retry(rspec_test, user) - expect(staging.depends_on_builds.map(&:id)) - .to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) + expect(staging.depends_on_builds.map(&:id)). + to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) end end describe '#detailed_status' do it 'returns a detailed status' do - expect(build.detailed_status(user)) - .to be_a Gitlab::Ci::Status::Build::Cancelable + expect(build.detailed_status(user)). + to be_a Gitlab::Ci::Status::Build::Cancelable end end @@ -1151,8 +1151,8 @@ describe Ci::Build, :models do let!(:build) { create(:ci_build, artifacts_size: 23) } it 'updates project statistics when the artifact size changes' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(build.project_id, [], [:build_artifacts_size]) build.artifacts_size = 42 build.save! @@ -1166,8 +1166,8 @@ describe Ci::Build, :models do end it 'updates project statistics when the build is destroyed' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(build.project_id, [], [:build_artifacts_size]) build.destroy end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 36533bdd11e..f770e6a9e34 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -253,8 +253,8 @@ describe CommitStatus, :models do let(:user) { create(:user) } it 'returns a detailed status' do - expect(commit_status.detailed_status(user)) - .to be_a Gitlab::Ci::Status::Success + expect(commit_status.detailed_status(user)). + to be_a Gitlab::Ci::Status::Success end end diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index fe4de1b2afb..4652af1cb97 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -8,7 +8,7 @@ describe Email, models: true do end it 'normalize email value' do - expect(described_class.new(email: ' inFO@exAMPLe.com ').email) - .to eq 'info@example.com' + expect(described_class.new(email: ' inFO@exAMPLe.com ').email). + to eq 'info@example.com' end end diff --git a/spec/models/group_label_spec.rb b/spec/models/group_label_spec.rb index 555a876daeb..c8d88022ec7 100644 --- a/spec/models/group_label_spec.rb +++ b/spec/models/group_label_spec.rb @@ -49,8 +49,8 @@ describe GroupLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) } - .to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) }. + to raise_error StandardError, /Unknown format/ end end end diff --git a/spec/models/lfs_objects_project_spec.rb b/spec/models/lfs_objects_project_spec.rb index 7bc278e350f..a2031beeab2 100644 --- a/spec/models/lfs_objects_project_spec.rb +++ b/spec/models/lfs_objects_project_spec.rb @@ -18,8 +18,8 @@ describe LfsObjectsProject, models: true do describe '#update_project_statistics' do it 'updates project statistics when the object is added' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(project.id, [], [:lfs_objects_size]) subject.save! end @@ -27,8 +27,8 @@ describe LfsObjectsProject, models: true do it 'updates project statistics when the object is removed' do subject.save! - expect(ProjectCacheWorker).to receive(:perform_async) - .with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(project.id, [], [:lfs_objects_size]) subject.destroy end diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index 6d599e148a2..1b7360257e8 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -84,8 +84,8 @@ describe MergeRequestDiff, models: true do end it 'saves overflow state' do - allow(Commit).to receive(:max_diff_options) - .and_return(max_lines: 0, max_files: 0) + allow(Commit).to receive(:max_diff_options). + and_return(max_lines: 0, max_files: 0) mr_diff = create(:merge_request).merge_request_diff @@ -93,8 +93,8 @@ describe MergeRequestDiff, models: true do end it 'saves empty state' do - allow_any_instance_of(MergeRequestDiff).to receive(:commits) - .and_return([]) + allow_any_instance_of(MergeRequestDiff).to receive(:commits). + and_return([]) mr_diff = create(:merge_request).merge_request_diff diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index a01741a9971..810c08256dc 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -412,15 +412,15 @@ describe MergeRequest, models: true do it 'includes merge information as the title' do request = build(:merge_request, source_branch: 'source', target_branch: 'target') - expect(request.merge_commit_message) - .to match("Merge branch 'source' into 'target'\n\n") + expect(request.merge_commit_message). + to match("Merge branch 'source' into 'target'\n\n") end it 'includes its title in the body' do request = build(:merge_request, title: 'Remove all technical debt') - expect(request.merge_commit_message) - .to match("Remove all technical debt\n\n") + expect(request.merge_commit_message). + to match("Remove all technical debt\n\n") end it 'includes its closed issues in the body' do @@ -432,15 +432,15 @@ describe MergeRequest, models: true do allow(subject.project).to receive(:default_branch). and_return(subject.target_branch) - expect(subject.merge_commit_message) - .to match("Closes #{issue.to_reference}") + expect(subject.merge_commit_message). + to match("Closes #{issue.to_reference}") end it 'includes its reference in the body' do request = build_stubbed(:merge_request) - expect(request.merge_commit_message) - .to match("See merge request #{request.to_reference}") + expect(request.merge_commit_message). + to match("See merge request #{request.to_reference}") end it 'excludes multiple linebreak runs when description is blank' do @@ -452,15 +452,15 @@ describe MergeRequest, models: true do it 'includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message(include_description: true)) - .to match("By removing all code\n\n") + expect(request.merge_commit_message(include_description: true)). + to match("By removing all code\n\n") end it 'does not includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message) - .not_to match("By removing all code\n\n") + expect(request.merge_commit_message). + not_to match("By removing all code\n\n") end end diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb index 9cdbfa44e5b..3e9dd3758ed 100644 --- a/spec/models/project_label_spec.rb +++ b/spec/models/project_label_spec.rb @@ -94,8 +94,8 @@ describe ProjectLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) } - .to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) }. + to raise_error StandardError, /Unknown format/ end end @@ -104,15 +104,15 @@ describe ProjectLabel, models: true do context 'using name' do it 'returns cross reference with label name' do - expect(label.to_reference(project, format: :name)) - .to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") + expect(label.to_reference(project, format: :name)). + to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") end end context 'using id' do it 'returns cross reference with label id' do - expect(label.to_reference(project, format: :id)) - .to eq %Q(#{label.project.path_with_namespace}~#{label.id}) + expect(label.to_reference(project, format: :id)). + to eq %Q(#{label.project.path_with_namespace}~#{label.id}) end end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 838fd3754b2..0d1db97cd5b 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -265,8 +265,8 @@ describe Repository, models: true do describe '#commit' do context 'when ref exists' do it 'returns commit object' do - expect(repository.commit('master')) - .to be_an_instance_of Commit + expect(repository.commit('master')). + to be_an_instance_of Commit end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 584a4facd94..42029b15f4e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1148,8 +1148,8 @@ describe User, models: true do user = create(:user) project = create(:empty_project, :private, namespace: user.namespace) - expect(user.authorized_projects(Gitlab::Access::REPORTER)) - .to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)). + to contain_exactly(project) end it 'includes projects for which the user is a master' do @@ -1158,8 +1158,8 @@ describe User, models: true do project.team << [user, Gitlab::Access::MASTER] - expect(user.authorized_projects(Gitlab::Access::REPORTER)) - .to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)). + to contain_exactly(project) end end diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb index 921d8714173..576eb80605b 100644 --- a/spec/requests/api/broadcast_messages_spec.rb +++ b/spec/requests/api/broadcast_messages_spec.rb @@ -27,8 +27,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_kind_of(Array) - expect(json_response.first.keys) - .to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.first.keys). + to match_array(%w(id message starts_at ends_at color font active)) end end @@ -52,8 +52,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(json_response['id']).to eq message.id - expect(json_response.keys) - .to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.keys). + to match_array(%w(id message starts_at ends_at color font active)) end end @@ -174,8 +174,8 @@ describe API::BroadcastMessages, api: true do end it 'deletes the broadcast message for admins' do - expect { delete api("/broadcast_messages/#{message.id}", admin) } - .to change { BroadcastMessage.count }.by(-1) + expect { delete api("/broadcast_messages/#{message.id}", admin) }. + to change { BroadcastMessage.count }.by(-1) end end end diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index 81a8856b8f1..eface28976e 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -207,8 +207,8 @@ describe API::CommitStatuses, api: true do it 'responds with bad request status and validation errors' do expect(response).to have_http_status(400) - expect(json_response['message']['target_url']) - .to include 'must be a valid URL' + expect(json_response['message']['target_url']). + to include 'must be a valid URL' end end end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index a59112579e5..ff2e0d58d2a 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -36,8 +36,8 @@ describe API::Groups, api: true do expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.length).to eq(1) - expect(json_response) - .to satisfy_one { |group| group['name'] == group1.name } + expect(json_response). + to satisfy_one { |group| group['name'] == group1.name } end it "does not include statistics" do @@ -84,8 +84,8 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response) - .to satisfy_one { |group| group['statistics'] == attributes } + expect(json_response). + to satisfy_one { |group| group['statistics'] == attributes } end end diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index ffeacb15f17..d1e765d1fdd 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -74,8 +74,8 @@ describe API::Internal, api: true do context 'when two-factor is enabled' do it 'returns new recovery codes when the user exists' do allow_any_instance_of(User).to receive(:two_factor_enabled?).and_return(true) - allow_any_instance_of(User) - .to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) + allow_any_instance_of(User). + to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) post api('/internal/two_factor_recovery_codes'), secret_token: secret_token, diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 103d6755888..2e596f4197e 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -202,8 +202,8 @@ describe API::Runners, api: true do expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql') expect(shared_runner.run_untagged?).to be(false) expect(shared_runner.locked?).to be(true) - expect(shared_runner.ensure_runner_queue_value) - .not_to eq(runner_queue_value) + expect(shared_runner.ensure_runner_queue_value). + not_to eq(runner_queue_value) end end @@ -218,8 +218,8 @@ describe API::Runners, api: true do expect(response).to have_http_status(200) expect(specific_runner.description).to eq('test') expect(specific_runner.description).not_to eq(description) - expect(specific_runner.ensure_runner_queue_value) - .not_to eq(runner_queue_value) + expect(specific_runner.ensure_runner_queue_value). + not_to eq(runner_queue_value) end end diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index d85afdeab42..03b860ae54e 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -38,8 +38,8 @@ describe Ci::API::Builds do it 'gives 204 and set the same X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']) - .to eq(last_update) + expect(response.header['X-GitLab-Last-Update']). + to eq(last_update) end end @@ -49,8 +49,8 @@ describe Ci::API::Builds do it 'gives 204 and set a new X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']) - .to eq(new_update) + expect(response.header['X-GitLab-Last-Update']). + to eq(new_update) end end @@ -260,8 +260,8 @@ describe Ci::API::Builds do end it 'does not update runner info' do - expect { register_builds } - .not_to change { runner.reload.contacted_at } + expect { register_builds }. + not_to change { runner.reload.contacted_at } end end diff --git a/spec/serializers/analytics_build_serializer_spec.rb b/spec/serializers/analytics_build_serializer_spec.rb index e3b1dd93dc2..c8bad5ef105 100644 --- a/spec/serializers/analytics_build_serializer_spec.rb +++ b/spec/serializers/analytics_build_serializer_spec.rb @@ -7,8 +7,8 @@ describe AnalyticsBuildSerializer do context 'when there is a single object provided' do it 'contains important elements of analyticsBuild' do - expect(subject) - .to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) + expect(subject). + to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) end end end diff --git a/spec/serializers/analytics_issue_serializer_spec.rb b/spec/serializers/analytics_issue_serializer_spec.rb index 2f08958a783..fe26b001740 100644 --- a/spec/serializers/analytics_issue_serializer_spec.rb +++ b/spec/serializers/analytics_issue_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsIssueSerializer do subject do - described_class - .new(project: project, entity: :merge_request) - .represent(resource) + described_class. + new(project: project, entity: :merge_request). + represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_merge_request_serializer_spec.rb b/spec/serializers/analytics_merge_request_serializer_spec.rb index 62067cc0ef2..ee08762d237 100644 --- a/spec/serializers/analytics_merge_request_serializer_spec.rb +++ b/spec/serializers/analytics_merge_request_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsMergeRequestSerializer do subject do - described_class - .new(project: project, entity: :merge_request) - .represent(resource) + described_class. + new(project: project, entity: :merge_request). + represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb index 5d7a94c2d02..3106af0ded7 100644 --- a/spec/serializers/analytics_summary_serializer_spec.rb +++ b/spec/serializers/analytics_summary_serializer_spec.rb @@ -9,13 +9,13 @@ describe AnalyticsSummarySerializer do let(:user) { create(:user) } let(:resource) do - Gitlab::CycleAnalytics::Summary::Issue - .new(project: double, from: 1.day.ago, current_user: user) + Gitlab::CycleAnalytics::Summary::Issue. + new(project: double, from: 1.day.ago, current_user: user) end before do - allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue) - .to receive(:value).and_return(1.12) + allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue). + to receive(:value).and_return(1.12) end it 'it generates payload for single object' do diff --git a/spec/serializers/build_artifact_entity_spec.rb b/spec/serializers/build_artifact_entity_spec.rb index 2fc60aa9de6..6ccea199376 100644 --- a/spec/serializers/build_artifact_entity_spec.rb +++ b/spec/serializers/build_artifact_entity_spec.rb @@ -15,8 +15,8 @@ describe BuildArtifactEntity do end it 'contains path to the artifacts' do - expect(subject[:path]) - .to include "builds/#{build.id}/artifacts/download" + expect(subject[:path]). + to include "builds/#{build.id}/artifacts/download" end end end diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index 0333d73b5b5..895aeb30035 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -42,8 +42,8 @@ describe CommitEntity do end it 'needs to receive project in the request' do - expect(request).to receive(:project) - .and_return(project) + expect(request).to receive(:project). + and_return(project) subject end diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb index 6a6df377b35..61b2fce8e8a 100644 --- a/spec/serializers/environment_serializer_spec.rb +++ b/spec/serializers/environment_serializer_spec.rb @@ -5,9 +5,9 @@ describe EnvironmentSerializer do let(:project) { create(:project) } let(:json) do - described_class - .new(user: user, project: project) - .represent(resource) + described_class. + new(user: user, project: project). + represent(resource) end context 'when there is a single object provided' do @@ -27,15 +27,15 @@ describe EnvironmentSerializer do let(:resource) { deployment.environment } it 'contains important elements of environment' do - expect(json) - .to include(:name, :external_url, :environment_path, :last_deployment) + expect(json). + to include(:name, :external_url, :environment_path, :last_deployment) end it 'contains relevant information about last deployment' do last_deployment = json.fetch(:last_deployment) - expect(last_deployment) - .to include(:ref, :user, :commit, :deployable, :manual_actions) + expect(last_deployment). + to include(:ref, :user, :commit, :deployable, :manual_actions) end end @@ -44,8 +44,8 @@ describe EnvironmentSerializer do let(:resource) { create_list(:environment, 2) } it 'contains important elements of environment' do - expect(json.first) - .to include(:last_deployment, :name, :external_url) + expect(json.first). + to include(:last_deployment, :name, :external_url) end it 'generates payload for collection' do @@ -122,13 +122,13 @@ describe EnvironmentSerializer do let(:pagination) { { page: 1, per_page: 2 } } let(:serializer) do - described_class.new(project: project) - .with_pagination(request, response) + described_class.new(project: project). + with_pagination(request, response) end before do - allow(request).to receive(:query_parameters) - .and_return(pagination) + allow(request).to receive(:query_parameters). + and_return(pagination) end subject { serializer.represent(resource) } @@ -164,9 +164,9 @@ describe EnvironmentSerializer do context 'when grouping environments within folders' do let(:serializer) do - described_class.new(project: project) - .with_pagination(request, response) - .within_folders + described_class.new(project: project). + with_pagination(request, response). + within_folders end before do diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb index ccb72973f9c..96ef1d3c071 100644 --- a/spec/serializers/pipeline_entity_spec.rb +++ b/spec/serializers/pipeline_entity_spec.rb @@ -26,17 +26,17 @@ describe PipelineEntity do it 'contains details' do expect(subject).to include :details - expect(subject[:details]) - .to include :duration, :finished_at - expect(subject[:details]) - .to include :stages, :artifacts, :manual_actions + expect(subject[:details]). + to include :duration, :finished_at + expect(subject[:details]). + to include :stages, :artifacts, :manual_actions expect(subject[:details][:status]).to include :icon, :text, :label end it 'contains flags' do expect(subject).to include :flags - expect(subject[:flags]) - .to include :latest, :triggered, :stuck, + expect(subject[:flags]). + to include :latest, :triggered, :stuck, :yaml_errors, :retryable, :cancelable end end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 2aaef03cb93..5f84a98f06d 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -38,14 +38,14 @@ describe PipelineSerializer do let(:pagination) { {} } before do - allow(request) - .to receive(:query_parameters) - .and_return(pagination) + allow(request). + to receive(:query_parameters). + and_return(pagination) end let(:serializer) do - described_class.new(user: user) - .with_pagination(request, response) + described_class.new(user: user). + with_pagination(request, response) end it 'created a paginated serializer' do diff --git a/spec/serializers/request_aware_entity_spec.rb b/spec/serializers/request_aware_entity_spec.rb index aa666b961dc..94dbf02aee8 100644 --- a/spec/serializers/request_aware_entity_spec.rb +++ b/spec/serializers/request_aware_entity_spec.rb @@ -14,8 +14,8 @@ describe RequestAwareEntity do end it 'fetches request from options' do - expect(subject).to receive(:options) - .and_return({ request: 'some value' }) + expect(subject).to receive(:options). + and_return({ request: 'some value' }) expect(subject.request).to eq 'some value' end diff --git a/spec/serializers/stage_entity_spec.rb b/spec/serializers/stage_entity_spec.rb index 4ab40d08432..42f19935453 100644 --- a/spec/serializers/stage_entity_spec.rb +++ b/spec/serializers/stage_entity_spec.rb @@ -35,13 +35,13 @@ describe StageEntity do end it 'contains path to the stage' do - expect(subject[:path]) - .to include "pipelines/#{pipeline.id}##{stage.name}" + expect(subject[:path]). + to include "pipelines/#{pipeline.id}##{stage.name}" end it 'contains path to the stage dropdown' do - expect(subject[:dropdown_path]) - .to include "pipelines/#{pipeline.id}/stage.json?stage=test" + expect(subject[:dropdown_path]). + to include "pipelines/#{pipeline.id}/stage.json?stage=test" end it 'contains stage title' do diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index ef2ddc4b1d7..ce691004178 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -284,14 +284,14 @@ describe Ci::ProcessPipelineService, :services do pipeline.builds.running_or_pending.each(&:success) - expect(builds.pluck(:name)) - .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)). + to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') pipeline.builds.find_by(name: 'test:1').success pipeline.builds.find_by(name: 'test:2').drop - expect(builds.pluck(:name)) - .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)). + to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') Ci::Build.retry(pipeline.builds.find_by(name: 'test:2'), user).success diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index d03f7505eac..6499c7ad63e 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -61,8 +61,8 @@ describe Ci::RetryBuildService, :services do end it 'resolves todos for old build that failed' do - expect(MergeRequests::AddTodoWhenBuildFailsService) - .to receive_message_chain(:new, :close) + expect(MergeRequests::AddTodoWhenBuildFailsService). + to receive_message_chain(:new, :close) service.execute(build) end @@ -82,8 +82,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.execute(build) } - .to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(build) }. + to raise_error Gitlab::Access::AccessDeniedError end end end @@ -109,8 +109,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.reprocess(build) } - .to raise_error Gitlab::Access::AccessDeniedError + expect { service.reprocess(build) }. + to raise_error Gitlab::Access::AccessDeniedError end end end diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index c0af8b8450a..84915b5f1aa 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -134,8 +134,8 @@ describe Ci::RetryPipelineService, '#execute', :services do end it 'closes all todos about failed jobs for pipeline' do - expect(MergeRequests::AddTodoWhenBuildFailsService) - .to receive_message_chain(:new, :close_all) + expect(MergeRequests::AddTodoWhenBuildFailsService). + to receive_message_chain(:new, :close_all) service.execute(pipeline) end @@ -149,8 +149,8 @@ describe Ci::RetryPipelineService, '#execute', :services do context 'when user is not allowed to retry pipeline' do it 'raises an error' do - expect { service.execute(pipeline) } - .to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(pipeline) }. + to raise_error Gitlab::Access::AccessDeniedError end end diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb index 560f83d94f7..23e0856fecd 100644 --- a/spec/services/ci/stop_environments_service_spec.rb +++ b/spec/services/ci/stop_environments_service_spec.rb @@ -44,8 +44,8 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment is not stopped' do before do - allow_any_instance_of(Environment) - .to receive(:state).and_return(:stopped) + allow_any_instance_of(Environment). + to receive(:state).and_return(:stopped) end it 'does not stop environment' do @@ -83,22 +83,22 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment does not exist' do it 'does not raise error' do - expect { service.execute('master') } - .not_to raise_error + expect { service.execute('master') }. + not_to raise_error end end end def expect_environment_stopped_on(branch) - expect_any_instance_of(Environment) - .to receive(:stop!) + expect_any_instance_of(Environment). + to receive(:stop!) service.execute(branch) end def expect_environment_not_stopped_on(branch) - expect_any_instance_of(Environment) - .not_to receive(:stop!) + expect_any_instance_of(Environment). + not_to receive(:stop!) service.execute(branch) end diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb index f01a388b895..14092d9dcca 100644 --- a/spec/services/ci/update_build_queue_service_spec.rb +++ b/spec/services/ci/update_build_queue_service_spec.rb @@ -12,15 +12,15 @@ describe Ci::UpdateBuildQueueService, :services do before { build.project.runners << runner } it 'ticks runner queue value' do - expect { subject.execute(build) } - .to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + to change { runner.ensure_runner_queue_value } end end context 'when there are no runners that can pick build' do it 'does not tick runner queue value' do - expect { subject.execute(build) } - .not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + not_to change { runner.ensure_runner_queue_value } end end end @@ -30,8 +30,8 @@ describe Ci::UpdateBuildQueueService, :services do context 'when there are runner that can pick build' do it 'ticks runner queue value' do - expect { subject.execute(build) } - .to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + to change { runner.ensure_runner_queue_value } end end @@ -39,8 +39,8 @@ describe Ci::UpdateBuildQueueService, :services do before { build.tag_list = [:docker] } it 'does not tick runner queue value' do - expect { subject.execute(build) } - .not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + not_to change { runner.ensure_runner_queue_value } end end end diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb index 0475f38fe5e..87da8581e68 100644 --- a/spec/services/issuable/bulk_update_service_spec.rb +++ b/spec/services/issuable/bulk_update_service_spec.rb @@ -5,8 +5,8 @@ describe Issuable::BulkUpdateService, services: true do let(:project) { create(:empty_project, namespace: user.namespace) } def bulk_update(issues, extra_params = {}) - bulk_update_params = extra_params - .reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) + bulk_update_params = extra_params. + reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) Issuable::BulkUpdateService.new(project, user, bulk_update_params).execute('issue') end @@ -65,22 +65,22 @@ describe Issuable::BulkUpdateService, services: true do assignee = create(:user) project.team << [assignee, :developer] - expect { bulk_update(issue, assignee_id: assignee.id) } - .to change { issue.reload.assignee }.from(user).to(assignee) + expect { bulk_update(issue, assignee_id: assignee.id) }. + to change { issue.reload.assignee }.from(user).to(assignee) end end context "when the new assignee ID is #{IssuableFinder::NONE}" do it "unassigns the issues" do - expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) } - .to change { issue.reload.assignee }.to(nil) + expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) }. + to change { issue.reload.assignee }.to(nil) end end context 'when the new assignee ID is not present' do it 'does not unassign' do - expect { bulk_update(issue, assignee_id: nil) } - .not_to change { issue.reload.assignee } + expect { bulk_update(issue, assignee_id: nil) }. + not_to change { issue.reload.assignee } end end end @@ -97,8 +97,8 @@ describe Issuable::BulkUpdateService, services: true do end it 'updates the issue milestone' do - expect { bulk_update(issue, milestone_id: milestone.id) } - .to change { issue.reload.milestone }.from(nil).to(milestone) + expect { bulk_update(issue, milestone_id: milestone.id) }. + to change { issue.reload.milestone }.from(nil).to(milestone) end end diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index db196ed5751..59c0fa50994 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -188,8 +188,8 @@ describe Issues::MoveService, services: true do let(:new_note) { new_issue.notes.first } it 'rewrites references using a cross reference to old project' do - expect(new_note.note) - .to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" + expect(new_note.note). + to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" end end @@ -201,8 +201,8 @@ describe Issues::MoveService, services: true do it 'rewrites uploads in description' do expect(new_issue.description).not_to eq description - expect(new_issue.description) - .to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) + expect(new_issue.description). + to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) expect(new_issue.description).not_to include uploader.secret end end @@ -216,8 +216,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{another_issue.to_reference}" } it 'rewrites referenced issues creating cross project reference' do - expect(new_issue.description) - .to eq "Some description #{another_issue.to_reference(new_project)}" + expect(new_issue.description). + to eq "Some description #{another_issue.to_reference(new_project)}" end end @@ -226,8 +226,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{user.to_reference}" } it "doesn't throw any errors for issues containing user references" do - expect(new_issue.description) - .to eq "Some description #{user.to_reference}" + expect(new_issue.description). + to eq "Some description #{user.to_reference}" end end end @@ -236,8 +236,8 @@ describe Issues::MoveService, services: true do let(:new_project) { old_project } it 'raises error' do - expect { move_service.execute(old_issue, new_project) } - .to raise_error(StandardError, /Cannot move issue/) + expect { move_service.execute(old_issue, new_project) }. + to raise_error(StandardError, /Cannot move issue/) end end end diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb index d80fb8a1af1..881458c190f 100644 --- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb +++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb @@ -29,9 +29,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do end before do - allow_any_instance_of(MergeRequest) - .to receive(:head_pipeline) - .and_return(pipeline) + allow_any_instance_of(MergeRequest). + to receive(:head_pipeline). + and_return(pipeline) allow(service).to receive(:todo_service).and_return(todo_service) end @@ -113,9 +113,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'resolves todos about failed builds for pipeline' do service.close_all(pipeline) - expect(todo_service) - .to have_received(:merge_request_build_retried) - .with(merge_request) + expect(todo_service). + to have_received(:merge_request_build_retried). + with(merge_request) end end @@ -125,8 +125,8 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'does not resolve any todos about failed builds' do service.close_all(pipeline) - expect(todo_service) - .not_to have_received(:merge_request_build_retried) + expect(todo_service). + not_to have_received(:merge_request_build_retried) end end end diff --git a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb index f92978a33a3..65c08ce15f7 100644 --- a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb @@ -27,9 +27,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do context 'first time enabling' do before do - allow(merge_request) - .to receive(:head_pipeline) - .and_return(pipeline) + allow(merge_request). + to receive(:head_pipeline). + and_return(pipeline) service.execute(merge_request) end @@ -52,11 +52,11 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) } before do - allow(mr_merge_if_green_enabled).to receive(:head_pipeline) - .and_return(pipeline) + allow(mr_merge_if_green_enabled).to receive(:head_pipeline). + and_return(pipeline) - allow(mr_merge_if_green_enabled).to receive(:mergeable?) - .and_return(true) + allow(mr_merge_if_green_enabled).to receive(:mergeable?). + and_return(true) allow(pipeline).to receive(:success?).and_return(true) end @@ -152,9 +152,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do before do # This behavior of MergeRequest: we instantiate a new object # - allow_any_instance_of(MergeRequest) - .to receive(:head_pipeline) - .and_wrap_original do + allow_any_instance_of(MergeRequest). + to receive(:head_pipeline). + and_wrap_original do Ci::Pipeline.find(pipeline.id) end end diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 9f24cc0f3f2..6dfcb702510 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -768,15 +768,15 @@ describe TodoService, services: true do create(:todo, :mentioned, user: john_doe, target: issue, project: project) todos = TodosFinder.new(john_doe, {}).execute - expect { TodoService.new.mark_todos_as_done(todos, john_doe) } - .to change { john_doe.todos.done.count }.from(0).to(1) + expect { TodoService.new.mark_todos_as_done(todos, john_doe) }. + to change { john_doe.todos.done.count }.from(0).to(1) end it 'marks an array of todos as done' do todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project) - expect { TodoService.new.mark_todos_as_done([todo], john_doe) } - .to change { todo.reload.state }.from('pending').to('done') + expect { TodoService.new.mark_todos_as_done([todo], john_doe) }. + to change { todo.reload.state }.from('pending').to('done') end it 'returns the number of updated todos' do # Needed on API diff --git a/spec/support/ldap_helpers.rb b/spec/support/ldap_helpers.rb index 079f244475c..ab635711cf7 100644 --- a/spec/support/ldap_helpers.rb +++ b/spec/support/ldap_helpers.rb @@ -16,8 +16,8 @@ module LdapHelpers # ) def stub_ldap_config(messages) messages.each do |config, value| - allow_any_instance_of(::Gitlab::LDAP::Config) - .to receive(config.to_sym).and_return(value) + allow_any_instance_of(::Gitlab::LDAP::Config). + to receive(config.to_sym).and_return(value) end end @@ -32,8 +32,8 @@ module LdapHelpers def stub_ldap_person_find_by_uid(uid, entry, provider = 'ldapmain') return_value = ::Gitlab::LDAP::Person.new(entry, provider) if entry.present? - allow(::Gitlab::LDAP::Person) - .to receive(:find_by_uid).with(uid, any_args).and_return(return_value) + allow(::Gitlab::LDAP::Person). + to receive(:find_by_uid).with(uid, any_args).and_return(return_value) end # Create a simple LDAP user entry. diff --git a/spec/tasks/gitlab/check_rake_spec.rb b/spec/tasks/gitlab/check_rake_spec.rb index 538ff952bf4..a808ef7dcc0 100644 --- a/spec/tasks/gitlab/check_rake_spec.rb +++ b/spec/tasks/gitlab/check_rake_spec.rb @@ -23,8 +23,8 @@ describe 'gitlab:ldap:check rake task' do let(:adapter) { ldap_adapter('ldapmain', ldap) } before do - allow(Gitlab::LDAP::Config) - .to receive_messages( + allow(Gitlab::LDAP::Config). + to receive_messages( enabled?: true, providers: ['ldapmain'] ) diff --git a/spec/tasks/gitlab/shell_rake_spec.rb b/spec/tasks/gitlab/shell_rake_spec.rb index 226d34fe2c9..0787894ad2c 100644 --- a/spec/tasks/gitlab/shell_rake_spec.rb +++ b/spec/tasks/gitlab/shell_rake_spec.rb @@ -17,8 +17,8 @@ describe 'gitlab:shell rake tasks' do describe 'create_hooks task' do it 'calls gitlab-shell bin/create_hooks' do - expect_any_instance_of(Object).to receive(:system) - .with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) + expect_any_instance_of(Object).to receive(:system). + with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) run_rake_task('gitlab:shell:create_hooks') end diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb index 8020faa1f9c..254672a5612 100644 --- a/spec/views/layouts/_head.html.haml_spec.rb +++ b/spec/views/layouts/_head.html.haml_spec.rb @@ -26,7 +26,7 @@ describe 'layouts/_head' do end def stub_helper_with_safe_string(method) - allow_any_instance_of(PageLayoutHelper).to receive(method) - .and_return(%q{foo" http-equiv="refresh}.html_safe) + allow_any_instance_of(PageLayoutHelper).to receive(method). + and_return(%q{foo" http-equiv="refresh}.html_safe) end end diff --git a/spec/views/projects/merge_requests/edit.html.haml_spec.rb b/spec/views/projects/merge_requests/edit.html.haml_spec.rb index 3650b22c389..2e4390d6797 100644 --- a/spec/views/projects/merge_requests/edit.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/edit.html.haml_spec.rb @@ -23,8 +23,8 @@ describe 'projects/merge_requests/edit.html.haml' do assign(:merge_request, closed_merge_request) allow(view).to receive(:can?).and_return(true) - allow(view).to receive(:current_user) - .and_return(User.find(closed_merge_request.author_id)) + allow(view).to receive(:current_user). + and_return(User.find(closed_merge_request.author_id)) end context 'when a merge request without fork' do diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index ba20488f663..8ebf00374a1 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildCoverageWorker do let!(:build) { create(:ci_build) } it 'updates code coverage' do - expect_any_instance_of(Ci::Build) - .to receive(:update_coverage) + expect_any_instance_of(Ci::Build). + to receive(:update_coverage) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildCoverageWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index 2868167c7d4..f8119913116 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -6,15 +6,15 @@ describe BuildFinishedWorker do let(:build) { create(:ci_build) } it 'calculates coverage and calls hooks' do - expect(BuildCoverageWorker) - .to receive(:new).ordered.and_call_original - expect(BuildHooksWorker) - .to receive(:new).ordered.and_call_original + expect(BuildCoverageWorker). + to receive(:new).ordered.and_call_original + expect(BuildHooksWorker). + to receive(:new).ordered.and_call_original - expect_any_instance_of(BuildCoverageWorker) - .to receive(:perform) - expect_any_instance_of(BuildHooksWorker) - .to receive(:perform) + expect_any_instance_of(BuildCoverageWorker). + to receive(:perform) + expect_any_instance_of(BuildHooksWorker). + to receive(:perform) described_class.new.perform(build.id) end @@ -22,8 +22,8 @@ describe BuildFinishedWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index 97654a93f5c..51abc1d89a1 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildHooksWorker do let!(:build) { create(:ci_build) } it 'calls build hooks' do - expect_any_instance_of(Ci::Build) - .to receive(:execute_hooks) + expect_any_instance_of(Ci::Build). + to receive(:execute_hooks) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildHooksWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb index dba70883130..d016ecbb738 100644 --- a/spec/workers/build_success_worker_spec.rb +++ b/spec/workers/build_success_worker_spec.rb @@ -7,8 +7,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, environment: 'production') } it 'executes deployment service' do - expect_any_instance_of(CreateDeploymentService) - .to receive(:execute) + expect_any_instance_of(CreateDeploymentService). + to receive(:execute) described_class.new.perform(build.id) end @@ -18,8 +18,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, project: nil) } it 'does not create deployment' do - expect_any_instance_of(CreateDeploymentService) - .not_to receive(:execute) + expect_any_instance_of(CreateDeploymentService). + not_to receive(:execute) described_class.new.perform(build.id) end @@ -28,8 +28,8 @@ describe BuildSuccessWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index 035e329839f..061f4bda36c 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe PipelineHooksWorker do let(:pipeline) { create(:ci_pipeline) } it 'executes hooks for the pipeline' do - expect_any_instance_of(Ci::Pipeline) - .to receive(:execute_hooks) + expect_any_instance_of(Ci::Pipeline). + to receive(:execute_hooks) described_class.new.perform(pipeline.id) end @@ -15,8 +15,8 @@ describe PipelineHooksWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_proccess_worker_spec.rb b/spec/workers/pipeline_proccess_worker_spec.rb index 86e9d7f6684..fd6ee0714ea 100644 --- a/spec/workers/pipeline_proccess_worker_spec.rb +++ b/spec/workers/pipeline_proccess_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineProcessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_success_worker_spec.rb b/spec/workers/pipeline_success_worker_spec.rb index d1c84adda6f..f6c56465feb 100644 --- a/spec/workers/pipeline_success_worker_spec.rb +++ b/spec/workers/pipeline_success_worker_spec.rb @@ -16,8 +16,8 @@ describe PipelineSuccessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index 0b456cfd0da..24d78aae112 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineUpdateWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index f4f63b57a5f..0fc274f1a01 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -31,9 +31,9 @@ describe ProjectCacheWorker do context 'with an existing project' do it 'updates the project statistics' do - expect(worker).to receive(:update_statistics) - .with(kind_of(Project), %i(repository_size)) - .and_call_original + expect(worker).to receive(:update_statistics). + with(kind_of(Project), %i(repository_size)). + and_call_original worker.perform(project.id, [], %w(repository_size)) end @@ -67,9 +67,9 @@ describe ProjectCacheWorker do with(project.id, :update_statistics). and_return(true) - expect(statistics).to receive(:refresh!) - .with(only: %i(repository_size)) - .and_call_original + expect(statistics).to receive(:refresh!). + with(only: %i(repository_size)). + and_call_original worker.update_statistics(project, %i(repository_size)) end diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb index e50c788b82a..f8752c42a49 100644 --- a/spec/workers/use_key_worker_spec.rb +++ b/spec/workers/use_key_worker_spec.rb @@ -8,8 +8,8 @@ describe UseKeyWorker do current_time = Time.zone.now Timecop.freeze(current_time) do - expect { worker.perform(key.id) } - .to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) + expect { worker.perform(key.id) }. + to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) end end From b7d8df503cf35b3048b273dc0cadb5ec39aac5e1 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:32:18 -0600 Subject: [PATCH 198/247] Enable Style/MutableConstant --- .rubocop.yml | 3 + .rubocop_todo.yml | 5 -- .../admin/system_info_controller.rb | 4 +- app/controllers/concerns/service_params.rb | 4 +- app/controllers/jwt_controller.rb | 2 +- app/finders/issuable_finder.rb | 2 +- app/finders/todos_finder.rb | 2 +- app/helpers/issuables_helper.rb | 2 +- app/models/application_setting.rb | 2 +- app/models/ci/runner.rb | 4 +- app/models/commit.rb | 2 +- app/models/concerns/cache_markdown_field.rb | 2 +- app/models/concerns/has_status.rb | 12 +-- app/models/label.rb | 2 +- app/models/members/group_member.rb | 2 +- app/models/members/project_member.rb | 2 +- app/models/merge_request_diff.rb | 2 +- app/models/notification_setting.rb | 4 +- app/models/project.rb | 2 +- app/models/project_feature.rb | 2 +- .../project_services/buildkite_service.rb | 2 +- .../project_services/hipchat_service.rb | 2 +- .../pivotaltracker_service.rb | 2 +- app/models/project_statistics.rb | 2 +- app/models/project_wiki.rb | 2 +- app/models/repository.rb | 4 +- app/models/todo.rb | 2 +- ...ntainer_registry_authentication_service.rb | 2 +- app/services/members/destroy_service.rb | 2 +- app/services/notes/slash_commands_service.rb | 2 +- app/services/projects/destroy_service.rb | 2 +- app/services/projects/download_service.rb | 2 +- app/services/projects/update_pages_service.rb | 2 +- app/uploaders/uploader_helper.rb | 6 +- app/validators/addressable_url_validator.rb | 2 +- config/initializers/gollum.rb | 2 +- config/initializers/workhorse_multipart.rb | 2 +- config/routes/wiki.rb | 2 +- ...erge_to_protected_branches_merge_access.rb | 2 +- ..._push_to_protected_branches_push_access.rb | 2 +- ...173930_remove_project_id_from_spam_logs.rb | 2 +- ...160823081327_change_merge_error_to_text.rb | 2 +- .../20160824124900_add_table_issue_metrics.rb | 2 +- ...5052008_add_table_merge_request_metrics.rb | 2 +- ...160829114652_add_markdown_cache_columns.rb | 2 +- ...20160831214543_migrate_project_features.rb | 2 +- ...0_remove_features_enabled_from_projects.rb | 2 +- ...3162434_remove_projects_pushes_since_gc.rb | 2 +- ...0913212128_change_artifacts_size_column.rb | 2 +- ...21_create_merge_requests_closing_issues.rb | 2 +- .../20160919144305_add_type_to_labels.rb | 2 +- .../20161014173530_create_label_priorities.rb | 2 +- ...161017125927_add_unique_index_to_labels.rb | 2 +- .../20161018024215_migrate_labels_priority.rb | 2 +- ...61018024550_remove_priority_from_labels.rb | 2 +- ...736_migrate_sidekiq_queues_from_default.rb | 4 +- ...5_generate_project_feature_for_projects.rb | 2 +- ...dd_pipeline_id_to_merge_request_metrics.rb | 2 +- ...317_migrate_mailroom_queue_from_default.rb | 4 +- .../20161025231710_migrate_jira_to_gem.rb | 2 +- ...174110_migrate_subscriptions_project_id.rb | 2 +- ...81638_add_unique_index_to_subscriptions.rb | 2 +- ...171205_rename_repository_storage_column.rb | 2 +- ...1322_migrate_process_commit_worker_jobs.rb | 2 +- .../20161130095245_fill_routes_table.rb | 2 +- ...161130101252_fill_projects_routes_table.rb | 2 +- ...161201160452_migrate_project_statistics.rb | 2 +- ...31620_fixup_environment_name_uniqueness.rb | 2 +- ...21_create_environment_name_unique_index.rb | 2 +- .../20161207231626_add_environment_slug.rb | 2 +- ...0_add_unique_index_for_environment_slug.rb | 2 +- ...0124174637_add_foreign_keys_to_timelogs.rb | 2 +- ...remove_inactive_jira_service_properties.rb | 2 +- ...221153951_rename_reserved_project_names.rb | 2 +- lib/api/api_guard.rb | 2 +- lib/api/award_emoji.rb | 2 +- lib/api/helpers.rb | 2 +- lib/api/notes.rb | 2 +- lib/api/todos.rb | 2 +- lib/banzai/filter/autolink_filter.rb | 2 +- lib/bitbucket/connection.rb | 6 +- lib/ci/ansi2html.rb | 6 +- lib/ci/api/helpers.rb | 2 +- lib/container_registry/client.rb | 2 +- lib/gitlab/auth.rb | 4 +- lib/gitlab/badge/build/template.rb | 2 +- lib/gitlab/badge/coverage/template.rb | 2 +- lib/gitlab/ci/config/entry/artifacts.rb | 2 +- lib/gitlab/ci/config/entry/cache.rb | 2 +- lib/gitlab/ci/config/entry/environment.rb | 2 +- lib/gitlab/ci/config/entry/job.rb | 2 +- lib/gitlab/diff/inline_diff_marker.rb | 2 +- lib/gitlab/downtime_check/message.rb | 4 +- lib/gitlab/email/handler.rb | 2 +- lib/gitlab/exclusive_lease.rb | 2 +- lib/gitlab/file_detector.rb | 2 +- lib/gitlab/git_access.rb | 6 +- lib/gitlab/import_export.rb | 2 +- lib/gitlab/metrics/rack_middleware.rb | 6 +- lib/gitlab/metrics/subscribers/action_view.rb | 2 +- lib/gitlab/metrics/transaction.rb | 2 +- lib/gitlab/middleware/multipart.rb | 2 +- lib/gitlab/redis.rb | 10 +-- lib/gitlab/reference_extractor.rb | 2 +- lib/gitlab/request_profiler.rb | 2 +- lib/gitlab/workhorse.rb | 8 +- rubocop/cop/gem_fetcher.rb | 4 +- rubocop/cop/migration/add_column.rb | 4 +- .../cop/migration/add_column_with_default.rb | 2 +- .../migration/add_concurrent_foreign_key.rb | 2 +- rubocop/cop/migration/add_index.rb | 2 +- .../features/merge_requests/conflicts_spec.rb | 2 +- spec/models/environment_spec.rb | 2 +- spec/support/javascript_fixtures_helpers.rb | 2 +- spec/support/jira_service_helper.rb | 2 +- spec/support/seed_helper.rb | 2 +- spec/support/seed_repo.rb | 76 +++++++++---------- spec/support/test_env.rb | 4 +- 118 files changed, 190 insertions(+), 192 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index cb7b86c95e6..b453f4a1dc2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -308,6 +308,9 @@ Style/MultilineOperationIndentation: Style/MultilineTernaryOperator: Enabled: true +Style/MutableConstant: + Enabled: true + # Favor unless over if for negative conditions (or control flow or). Style/NegatedIf: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4831dfe15d9..8d75c99d5a6 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -471,11 +471,6 @@ Style/MultilineIfModifier: - 'app/models/project_wiki.rb' - 'lib/gitlab/workhorse.rb' -# Offense count: 187 -# Cop supports --auto-correct. -Style/MutableConstant: - Enabled: false - # Offense count: 8 # Cop supports --auto-correct. Style/NestedParenthesizedCalls: diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb index 1330399a836..99039724521 100644 --- a/app/controllers/admin/system_info_controller.rb +++ b/app/controllers/admin/system_info_controller.rb @@ -3,7 +3,7 @@ class Admin::SystemInfoController < Admin::ApplicationController 'nobrowse', 'read-only', 'ro' - ] + ].freeze EXCLUDED_MOUNT_TYPES = [ 'autofs', @@ -27,7 +27,7 @@ class Admin::SystemInfoController < Admin::ApplicationController 'tmpfs', 'tracefs', 'vfat' - ] + ].freeze def show @cpus = Vmstat.cpu rescue nil diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb index d7f5a4e4682..e610ccaec96 100644 --- a/app/controllers/concerns/service_params.rb +++ b/app/controllers/concerns/service_params.rb @@ -59,10 +59,10 @@ module ServiceParams :user_key, :username, :webhook - ] + ].freeze # Parameters to ignore if no value is specified - FILTER_BLANK_PARAMS = [:password] + FILTER_BLANK_PARAMS = [:password].freeze def service_params dynamic_params = @service.event_channel_names + @service.event_names diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index c2e4d62b50b..cc3df3bd127 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -5,7 +5,7 @@ class JwtController < ApplicationController SERVICES = { Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService, - } + }.freeze def auth service = SERVICES[params[:service]] diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 206c92fe82a..f49301e2631 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -19,7 +19,7 @@ # iids: integer[] # class IssuableFinder - NONE = '0' + NONE = '0'.freeze attr_accessor :current_user, :params diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb index a93a63bdb9b..10a1f948f93 100644 --- a/app/finders/todos_finder.rb +++ b/app/finders/todos_finder.rb @@ -13,7 +13,7 @@ # class TodosFinder - NONE = '0' + NONE = '0'.freeze attr_accessor :current_user, :params diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 03354c235eb..b65edb4049c 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -198,7 +198,7 @@ module IssuablesHelper @counts[issuable_type][state] end - IRRELEVANT_PARAMS_FOR_CACHE_KEY = %i[utf8 sort page] + IRRELEVANT_PARAMS_FOR_CACHE_KEY = %i[utf8 sort page].freeze private_constant :IRRELEVANT_PARAMS_FOR_CACHE_KEY def issuables_state_counter_cache_key(issuable_type, state) diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 74b358d8c40..4212f1247cc 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -5,7 +5,7 @@ class ApplicationSetting < ActiveRecord::Base add_authentication_token_field :runners_registration_token add_authentication_token_field :health_check_access_token - CACHE_KEY = 'application_setting.last' + CACHE_KEY = 'application_setting.last'.freeze DOMAIN_LIST_SEPARATOR = %r{\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace | # or \s # any whitespace character diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 9cda008a549..a120112e882 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -4,8 +4,8 @@ module Ci RUNNER_QUEUE_EXPIRY_TIME = 60.minutes LAST_CONTACT_TIME = 1.hour.ago - AVAILABLE_SCOPES = %w[specific shared active paused online] - FORM_EDITABLE = %i[description tag_list active run_untagged locked] + AVAILABLE_SCOPES = %w[specific shared active paused online].freeze + FORM_EDITABLE = %i[description tag_list active run_untagged locked].freeze has_many :builds has_many :runner_projects, dependent: :destroy diff --git a/app/models/commit.rb b/app/models/commit.rb index 46f06733da1..ec759762977 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -22,7 +22,7 @@ class Commit DIFF_HARD_LIMIT_LINES = 50000 # The SHA can be between 7 and 40 hex characters. - COMMIT_SHA_PATTERN = '\h{7,40}' + COMMIT_SHA_PATTERN = '\h{7,40}'.freeze class << self def decorate(commits, project) diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb index a600f9c14c5..6dc8c88a14d 100644 --- a/app/models/concerns/cache_markdown_field.rb +++ b/app/models/concerns/cache_markdown_field.rb @@ -45,7 +45,7 @@ module CacheMarkdownField Project Release Snippet - ] + ].freeze def self.caching_classes CACHING_CLASSES.map(&:constantize) diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb index 431c0354969..aea359e70bb 100644 --- a/app/models/concerns/has_status.rb +++ b/app/models/concerns/has_status.rb @@ -1,12 +1,12 @@ module HasStatus extend ActiveSupport::Concern - DEFAULT_STATUS = 'created' - AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped] - STARTED_STATUSES = %w[running success failed skipped] - ACTIVE_STATUSES = %w[pending running] - COMPLETED_STATUSES = %w[success failed canceled skipped] - ORDERED_STATUSES = %w[failed pending running canceled success skipped] + DEFAULT_STATUS = 'created'.freeze + AVAILABLE_STATUSES = %w[created pending running success failed canceled skipped].freeze + STARTED_STATUSES = %w[running success failed skipped].freeze + ACTIVE_STATUSES = %w[pending running].freeze + COMPLETED_STATUSES = %w[success failed canceled skipped].freeze + ORDERED_STATUSES = %w[failed pending running canceled success skipped].freeze class_methods do def status_sql diff --git a/app/models/label.rb b/app/models/label.rb index 8d76e422c67..27429e60e4a 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -11,7 +11,7 @@ class Label < ActiveRecord::Base cache_markdown_field :description, pipeline: :single_line - DEFAULT_COLOR = '#428BCA' + DEFAULT_COLOR = '#428BCA'.freeze default_value_for :color, DEFAULT_COLOR diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index 204f34f0269..4043fde5301 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -1,5 +1,5 @@ class GroupMember < Member - SOURCE_TYPE = 'Namespace' + SOURCE_TYPE = 'Namespace'.freeze belongs_to :group, foreign_key: 'source_id' diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index 008fff0857c..06f8fd39c99 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -1,5 +1,5 @@ class ProjectMember < Member - SOURCE_TYPE = 'Project' + SOURCE_TYPE = 'Project'.freeze include Gitlab::ShellAdapter diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index e1f172b24bf..53d08488788 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -7,7 +7,7 @@ class MergeRequestDiff < ActiveRecord::Base COMMITS_SAFE_SIZE = 100 # Valid types of serialized diffs allowed by Gitlab::Git::Diff - VALID_CLASSES = [Hash, Rugged::Patch, Rugged::Diff::Delta] + VALID_CLASSES = [Hash, Rugged::Patch, Rugged::Diff::Delta].freeze belongs_to :merge_request diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index 58f6214bea7..52577bd52ea 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -35,11 +35,11 @@ class NotificationSetting < ActiveRecord::Base :merge_merge_request, :failed_pipeline, :success_pipeline - ] + ].freeze EXCLUDED_WATCHER_EVENTS = [ :success_pipeline - ] + ].freeze store :events, accessors: EMAIL_EVENTS, coder: JSON diff --git a/app/models/project.rb b/app/models/project.rb index 411299eef63..3a1a724b987 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -22,7 +22,7 @@ class Project < ActiveRecord::Base class BoardLimitExceeded < StandardError; end NUMBER_OF_PERMITTED_BOARDS = 1 - UNKNOWN_IMPORT_URL = 'http://unknown.git' + UNKNOWN_IMPORT_URL = 'http://unknown.git'.freeze cache_markdown_field :description, pipeline: :description diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb index 03194fc2141..e3ef4919b28 100644 --- a/app/models/project_feature.rb +++ b/app/models/project_feature.rb @@ -18,7 +18,7 @@ class ProjectFeature < ActiveRecord::Base PRIVATE = 10 ENABLED = 20 - FEATURES = %i(issues merge_requests wiki snippets builds repository) + FEATURES = %i(issues merge_requests wiki snippets builds repository).freeze class << self def access_level_attribute(feature) diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb index 0956c4a4ede..5fb95050b83 100644 --- a/app/models/project_services/buildkite_service.rb +++ b/app/models/project_services/buildkite_service.rb @@ -3,7 +3,7 @@ require "addressable/uri" class BuildkiteService < CiService include ReactiveService - ENDPOINT = "https://buildkite.com" + ENDPOINT = "https://buildkite.com".freeze prop_accessor :project_url, :token boolean_accessor :enable_ssl_verification diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 72da219df28..3fdcee26bf3 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -6,7 +6,7 @@ class HipchatService < Service a b i strong em br img pre code table th tr td caption colgroup col thead tbody tfoot ul ol li dl dt dd - ] + ].freeze prop_accessor :token, :room, :server, :color, :api_version boolean_accessor :notify_only_broken_builds, :notify diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb index 9cc642591f4..d86f4f6f448 100644 --- a/app/models/project_services/pivotaltracker_service.rb +++ b/app/models/project_services/pivotaltracker_service.rb @@ -1,7 +1,7 @@ class PivotaltrackerService < Service include HTTParty - API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits' + API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'.freeze prop_accessor :token, :restrict_to_branch validates :token, presence: true, if: :activated? diff --git a/app/models/project_statistics.rb b/app/models/project_statistics.rb index 06abd406523..aeaf63abab9 100644 --- a/app/models/project_statistics.rb +++ b/app/models/project_statistics.rb @@ -4,7 +4,7 @@ class ProjectStatistics < ActiveRecord::Base before_save :update_storage_size - STORAGE_COLUMNS = [:repository_size, :lfs_objects_size, :build_artifacts_size] + STORAGE_COLUMNS = [:repository_size, :lfs_objects_size, :build_artifacts_size].freeze STATISTICS_COLUMNS = [:commit_count] + STORAGE_COLUMNS def total_repository_size diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index d0b991db112..de36fd3b252 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -5,7 +5,7 @@ class ProjectWiki 'Markdown' => :markdown, 'RDoc' => :rdoc, 'AsciiDoc' => :asciidoc - } unless defined?(MARKUPS) + }.freeze unless defined?(MARKUPS) class CouldNotCreateWikiError < StandardError; end diff --git a/app/models/repository.rb b/app/models/repository.rb index 56c582cd9be..e2a4f458c50 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -18,7 +18,7 @@ class Repository CACHED_METHODS = %i(size commit_count readme version contribution_guide changelog license_blob license_key gitignore koding_yml gitlab_ci_yml branch_names tag_names branch_count - tag_count avatar exists? empty? root_ref) + tag_count avatar exists? empty? root_ref).freeze # Certain method caches should be refreshed when certain types of files are # changed. This Hash maps file types (as returned by Gitlab::FileDetector) to @@ -33,7 +33,7 @@ class Repository koding: :koding_yml, gitlab_ci: :gitlab_ci_yml, avatar: :avatar - } + }.freeze # Wraps around the given method and caches its output in Redis and an instance # variable. diff --git a/app/models/todo.rb b/app/models/todo.rb index 3dda7948d0b..47789a21133 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -17,7 +17,7 @@ class Todo < ActiveRecord::Base APPROVAL_REQUIRED => :approval_required, UNMERGEABLE => :unmergeable, DIRECTLY_ADDRESSED => :directly_addressed - } + }.freeze belongs_to :author, class_name: "User" belongs_to :note diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb index 5cb7a86a5ee..db82b8f6c30 100644 --- a/app/services/auth/container_registry_authentication_service.rb +++ b/app/services/auth/container_registry_authentication_service.rb @@ -2,7 +2,7 @@ module Auth class ContainerRegistryAuthenticationService < BaseService include Gitlab::CurrentSettings - AUDIENCE = 'container_registry' + AUDIENCE = 'container_registry'.freeze def execute(authentication_abilities:) @authentication_abilities = authentication_abilities diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb index 431da8372c9..2e089149ca8 100644 --- a/app/services/members/destroy_service.rb +++ b/app/services/members/destroy_service.rb @@ -4,7 +4,7 @@ module Members attr_accessor :source - ALLOWED_SCOPES = %i[members requesters all] + ALLOWED_SCOPES = %i[members requesters all].freeze def initialize(source, current_user, params = {}) @source = source diff --git a/app/services/notes/slash_commands_service.rb b/app/services/notes/slash_commands_service.rb index 56913568cae..ad1e6f6774a 100644 --- a/app/services/notes/slash_commands_service.rb +++ b/app/services/notes/slash_commands_service.rb @@ -3,7 +3,7 @@ module Notes UPDATE_SERVICES = { 'Issue' => Issues::UpdateService, 'MergeRequest' => MergeRequests::UpdateService - } + }.freeze def self.noteable_update_service(note) UPDATE_SERVICES[note.noteable_type] diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 9716a1780a9..2e06826c311 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -4,7 +4,7 @@ module Projects class DestroyError < StandardError; end - DELETED_FLAG = '+deleted' + DELETED_FLAG = '+deleted'.freeze def async_execute project.transaction do diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb index f06a3d44c17..4e95653417b 100644 --- a/app/services/projects/download_service.rb +++ b/app/services/projects/download_service.rb @@ -2,7 +2,7 @@ module Projects class DownloadService < BaseService WHITELIST = [ /^[^.]+\.fogbugz.com$/ - ] + ].freeze def initialize(project, url) @project, @url = project, url diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index f5f9ee88912..2d42c4fc04a 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -2,7 +2,7 @@ module Projects class UpdatePagesService < BaseService BLOCK_SIZE = 32.kilobytes MAX_SIZE = 1.terabyte - SITE_PATH = 'public/' + SITE_PATH = 'public/'.freeze attr_reader :build diff --git a/app/uploaders/uploader_helper.rb b/app/uploaders/uploader_helper.rb index 35fd1ed23f8..bee311583ea 100644 --- a/app/uploaders/uploader_helper.rb +++ b/app/uploaders/uploader_helper.rb @@ -1,15 +1,15 @@ # Extra methods for uploader module UploaderHelper - IMAGE_EXT = %w[png jpg jpeg gif bmp tiff] + IMAGE_EXT = %w[png jpg jpeg gif bmp tiff].freeze # We recommend using the .mp4 format over .mov. Videos in .mov format can # still be used but you really need to make sure they are served with the # proper MIME type video/mp4 and not video/quicktime or your videos won't play # on IE >= 9. # http://archive.sublimevideo.info/20150912/docs.sublimevideo.net/troubleshooting.html - VIDEO_EXT = %w[mp4 m4v mov webm ogv] + VIDEO_EXT = %w[mp4 m4v mov webm ogv].freeze # These extension types can contain dangerous code and should only be embedded inline with # proper filtering. They should always be tagged as "Content-Disposition: attachment", not "inline". - DANGEROUS_EXT = %w[svg] + DANGEROUS_EXT = %w[svg].freeze def image? extension_match?(IMAGE_EXT) diff --git a/app/validators/addressable_url_validator.rb b/app/validators/addressable_url_validator.rb index 09bfa613cbe..94542125d43 100644 --- a/app/validators/addressable_url_validator.rb +++ b/app/validators/addressable_url_validator.rb @@ -18,7 +18,7 @@ # end # class AddressableUrlValidator < ActiveModel::EachValidator - DEFAULT_OPTIONS = { protocols: %w(http https ssh git) } + DEFAULT_OPTIONS = { protocols: %w(http https ssh git) }.freeze def validate_each(record, attribute, value) unless valid_url?(value) diff --git a/config/initializers/gollum.rb b/config/initializers/gollum.rb index 703f24f93b2..1ebe3c7a742 100644 --- a/config/initializers/gollum.rb +++ b/config/initializers/gollum.rb @@ -1,5 +1,5 @@ module Gollum - GIT_ADAPTER = "rugged" + GIT_ADAPTER = "rugged".freeze end require "gollum-lib" diff --git a/config/initializers/workhorse_multipart.rb b/config/initializers/workhorse_multipart.rb index 84d809741c4..064e5964f09 100644 --- a/config/initializers/workhorse_multipart.rb +++ b/config/initializers/workhorse_multipart.rb @@ -10,7 +10,7 @@ end # module Gitlab module StrongParameterScalars - GITLAB_PERMITTED_SCALAR_TYPES = [::UploadedFile] + GITLAB_PERMITTED_SCALAR_TYPES = [::UploadedFile].freeze def permitted_scalar?(value) super || GITLAB_PERMITTED_SCALAR_TYPES.any? { |type| value.is_a?(type) } diff --git a/config/routes/wiki.rb b/config/routes/wiki.rb index dad746d59a1..a6b3f5d4693 100644 --- a/config/routes/wiki.rb +++ b/config/routes/wiki.rb @@ -1,4 +1,4 @@ -WIKI_SLUG_ID = { id: /\S+/ } unless defined? WIKI_SLUG_ID +WIKI_SLUG_ID = { id: /\S+/ }.freeze unless defined? WIKI_SLUG_ID scope(controller: :wikis) do scope(path: 'wikis', as: :wikis) do diff --git a/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb b/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb index 1db0df92bec..cd5d4286b31 100644 --- a/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb +++ b/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb @@ -3,7 +3,7 @@ class MoveFromDevelopersCanMergeToProtectedBranchesMergeAccess < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC + DOWNTIME_REASON = <<-HEREDOC.freeze We're creating a `merge_access_level` for each `protected_branch`. If a user creates a `protected_branch` while this is running, we might be left with a `protected_branch` _without_ an associated `merge_access_level`. The `protected_branches` table must not change while this is running, so downtime is required. diff --git a/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb b/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb index 5c3e189bb5b..45e3368fa9b 100644 --- a/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb +++ b/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb @@ -3,7 +3,7 @@ class MoveFromDevelopersCanPushToProtectedBranchesPushAccess < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC + DOWNTIME_REASON = <<-HEREDOC.freeze We're creating a `push_access_level` for each `protected_branch`. If a user creates a `protected_branch` while this is running, we might be left with a `protected_branch` _without_ an associated `push_access_level`. The `protected_branches` table must not change while this is running, so downtime is required. diff --git a/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb b/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb index e28ab31d629..9995191ed9b 100644 --- a/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb +++ b/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb @@ -10,7 +10,7 @@ class RemoveProjectIdFromSpamLogs < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Removing a column that contains data that is not used anywhere.' + DOWNTIME_REASON = 'Removing a column that contains data that is not used anywhere.'.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160823081327_change_merge_error_to_text.rb b/db/migrate/20160823081327_change_merge_error_to_text.rb index 7920389cd83..6dbf8a8d5e5 100644 --- a/db/migrate/20160823081327_change_merge_error_to_text.rb +++ b/db/migrate/20160823081327_change_merge_error_to_text.rb @@ -2,7 +2,7 @@ class ChangeMergeErrorToText < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration requires downtime because it alters a column from varchar(255) to text.' + DOWNTIME_REASON = 'This migration requires downtime because it alters a column from varchar(255) to text.'.freeze def change change_column :merge_requests, :merge_error, :text, limit: 65535 diff --git a/db/migrate/20160824124900_add_table_issue_metrics.rb b/db/migrate/20160824124900_add_table_issue_metrics.rb index e9bb79b3c62..9e52c54a35b 100644 --- a/db/migrate/20160824124900_add_table_issue_metrics.rb +++ b/db/migrate/20160824124900_add_table_issue_metrics.rb @@ -10,7 +10,7 @@ class AddTableIssueMetrics < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding foreign key' + DOWNTIME_REASON = 'Adding foreign key'.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160825052008_add_table_merge_request_metrics.rb b/db/migrate/20160825052008_add_table_merge_request_metrics.rb index e01cc5038b9..195baf5f45b 100644 --- a/db/migrate/20160825052008_add_table_merge_request_metrics.rb +++ b/db/migrate/20160825052008_add_table_merge_request_metrics.rb @@ -10,7 +10,7 @@ class AddTableMergeRequestMetrics < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding foreign key' + DOWNTIME_REASON = 'Adding foreign key'.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160829114652_add_markdown_cache_columns.rb b/db/migrate/20160829114652_add_markdown_cache_columns.rb index 8753e55e058..9cb44dfa9f9 100644 --- a/db/migrate/20160829114652_add_markdown_cache_columns.rb +++ b/db/migrate/20160829114652_add_markdown_cache_columns.rb @@ -26,7 +26,7 @@ class AddMarkdownCacheColumns < ActiveRecord::Migration projects: [:description], releases: [:description], snippets: [:title, :content], - } + }.freeze def change COLUMNS.each do |table, columns| diff --git a/db/migrate/20160831214543_migrate_project_features.rb b/db/migrate/20160831214543_migrate_project_features.rb index 93f9821bc76..79a5fb29d64 100644 --- a/db/migrate/20160831214543_migrate_project_features.rb +++ b/db/migrate/20160831214543_migrate_project_features.rb @@ -3,7 +3,7 @@ class MigrateProjectFeatures < ActiveRecord::Migration DOWNTIME = true DOWNTIME_REASON = - <<-EOT + <<-EOT.freeze Migrating issues_enabled, merge_requests_enabled, wiki_enabled, builds_enabled, snippets_enabled fields from projects to a new table called project_features. EOT diff --git a/db/migrate/20160831223750_remove_features_enabled_from_projects.rb b/db/migrate/20160831223750_remove_features_enabled_from_projects.rb index a2c207b49ea..8202c6a7b79 100644 --- a/db/migrate/20160831223750_remove_features_enabled_from_projects.rb +++ b/db/migrate/20160831223750_remove_features_enabled_from_projects.rb @@ -7,7 +7,7 @@ class RemoveFeaturesEnabledFromProjects < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = true - DOWNTIME_REASON = "Removing fields from database requires downtine." + DOWNTIME_REASON = "Removing fields from database requires downtine.".freeze def up remove_column :projects, :issues_enabled diff --git a/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb b/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb index 18ea9d43a43..919bfcdd86e 100644 --- a/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb +++ b/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb @@ -5,7 +5,7 @@ class RemoveProjectsPushesSinceGc < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration removes an existing column' + DOWNTIME_REASON = 'This migration removes an existing column'.freeze disable_ddl_transaction! diff --git a/db/migrate/20160913212128_change_artifacts_size_column.rb b/db/migrate/20160913212128_change_artifacts_size_column.rb index 063bbca537c..8cda4b66c5a 100644 --- a/db/migrate/20160913212128_change_artifacts_size_column.rb +++ b/db/migrate/20160913212128_change_artifacts_size_column.rb @@ -3,7 +3,7 @@ class ChangeArtifactsSizeColumn < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = 'Changing an integer column size requires a full table rewrite.' + DOWNTIME_REASON = 'Changing an integer column size requires a full table rewrite.'.freeze def up change_column :ci_builds, :artifacts_size, :integer, limit: 8 diff --git a/db/migrate/20160915042921_create_merge_requests_closing_issues.rb b/db/migrate/20160915042921_create_merge_requests_closing_issues.rb index 94874a853da..105278d49f7 100644 --- a/db/migrate/20160915042921_create_merge_requests_closing_issues.rb +++ b/db/migrate/20160915042921_create_merge_requests_closing_issues.rb @@ -10,7 +10,7 @@ class CreateMergeRequestsClosingIssues < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding foreign keys' + DOWNTIME_REASON = 'Adding foreign keys'.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160919144305_add_type_to_labels.rb b/db/migrate/20160919144305_add_type_to_labels.rb index 66172bda6ff..f028c9460d1 100644 --- a/db/migrate/20160919144305_add_type_to_labels.rb +++ b/db/migrate/20160919144305_add_type_to_labels.rb @@ -2,7 +2,7 @@ class AddTypeToLabels < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.' + DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.'.freeze def change add_column :labels, :type, :string diff --git a/db/migrate/20161014173530_create_label_priorities.rb b/db/migrate/20161014173530_create_label_priorities.rb index 2c22841c28a..73c9897631c 100644 --- a/db/migrate/20161014173530_create_label_priorities.rb +++ b/db/migrate/20161014173530_create_label_priorities.rb @@ -2,7 +2,7 @@ class CreateLabelPriorities < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration adds foreign keys' + DOWNTIME_REASON = 'This migration adds foreign keys'.freeze disable_ddl_transaction! diff --git a/db/migrate/20161017125927_add_unique_index_to_labels.rb b/db/migrate/20161017125927_add_unique_index_to_labels.rb index f2b56ebfb7b..5571160ccb4 100644 --- a/db/migrate/20161017125927_add_unique_index_to_labels.rb +++ b/db/migrate/20161017125927_add_unique_index_to_labels.rb @@ -2,7 +2,7 @@ class AddUniqueIndexToLabels < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration removes duplicated labels.' + DOWNTIME_REASON = 'This migration removes duplicated labels.'.freeze disable_ddl_transaction! diff --git a/db/migrate/20161018024215_migrate_labels_priority.rb b/db/migrate/20161018024215_migrate_labels_priority.rb index 22bec2382f4..9529bd3d494 100644 --- a/db/migrate/20161018024215_migrate_labels_priority.rb +++ b/db/migrate/20161018024215_migrate_labels_priority.rb @@ -2,7 +2,7 @@ class MigrateLabelsPriority < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Prioritized labels will not work as expected until this migration is complete.' + DOWNTIME_REASON = 'Prioritized labels will not work as expected until this migration is complete.'.freeze disable_ddl_transaction! diff --git a/db/migrate/20161018024550_remove_priority_from_labels.rb b/db/migrate/20161018024550_remove_priority_from_labels.rb index b7416cca664..4415a2e91af 100644 --- a/db/migrate/20161018024550_remove_priority_from_labels.rb +++ b/db/migrate/20161018024550_remove_priority_from_labels.rb @@ -2,7 +2,7 @@ class RemovePriorityFromLabels < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration removes an existing column' + DOWNTIME_REASON = 'This migration removes an existing column'.freeze disable_ddl_transaction! diff --git a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb index e875213ab96..9730ebb8f8a 100644 --- a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb +++ b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb @@ -8,7 +8,7 @@ class MigrateSidekiqQueuesFromDefault < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-EOF + DOWNTIME_REASON = <<-EOF.freeze Moving Sidekiq jobs from queues requires Sidekiq to be stopped. Not stopping Sidekiq will result in the loss of jobs that are scheduled after this migration completes. @@ -71,7 +71,7 @@ class MigrateSidekiqQueuesFromDefault < ActiveRecord::Migration 'StuckCiBuildsWorker' => :cronjob, 'UpdateMergeRequestsWorker' => :update_merge_requests } - } + }.freeze def up Sidekiq.redis do |redis| diff --git a/db/migrate/20161019213545_generate_project_feature_for_projects.rb b/db/migrate/20161019213545_generate_project_feature_for_projects.rb index 4554e14b0df..6486181575d 100644 --- a/db/migrate/20161019213545_generate_project_feature_for_projects.rb +++ b/db/migrate/20161019213545_generate_project_feature_for_projects.rb @@ -1,7 +1,7 @@ class GenerateProjectFeatureForProjects < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC + DOWNTIME_REASON = <<-HEREDOC.freeze Application was eager loading project_feature for all projects generating an extra query everytime a project was fetched. We removed that behavior to avoid the extra query, this migration makes sure all projects have a project_feature record associated. diff --git a/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb b/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb index 2abfe47b776..b396c03ecbf 100644 --- a/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb +++ b/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb @@ -12,7 +12,7 @@ class AddPipelineIdToMergeRequestMetrics < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding a foreign key' + DOWNTIME_REASON = 'Adding a foreign key'.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb index 06d07bdb835..4167ccae39b 100644 --- a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb +++ b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb @@ -8,7 +8,7 @@ class MigrateMailroomQueueFromDefault < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-EOF + DOWNTIME_REASON = <<-EOF.freeze Moving Sidekiq jobs from queues requires Sidekiq to be stopped. Not stopping Sidekiq will result in the loss of jobs that are scheduled after this migration completes. @@ -25,7 +25,7 @@ class MigrateMailroomQueueFromDefault < ActiveRecord::Migration incoming_email: { 'EmailReceiverWorker' => :email_receiver } - } + }.freeze def up Sidekiq.redis do |redis| diff --git a/db/migrate/20161025231710_migrate_jira_to_gem.rb b/db/migrate/20161025231710_migrate_jira_to_gem.rb index 870b00411d2..38824ba9fe5 100644 --- a/db/migrate/20161025231710_migrate_jira_to_gem.rb +++ b/db/migrate/20161025231710_migrate_jira_to_gem.rb @@ -1,7 +1,7 @@ class MigrateJiraToGem < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC + DOWNTIME_REASON = <<-HEREDOC.freeze Refactor all Jira services properties(serialized field) to use new jira-ruby gem. There were properties on old Jira service that are not needed anymore after the service refactoring: api_url, project_url, new_issue_url, issues_url. diff --git a/db/migrate/20161031174110_migrate_subscriptions_project_id.rb b/db/migrate/20161031174110_migrate_subscriptions_project_id.rb index 549145a0a65..130b5f556ff 100644 --- a/db/migrate/20161031174110_migrate_subscriptions_project_id.rb +++ b/db/migrate/20161031174110_migrate_subscriptions_project_id.rb @@ -2,7 +2,7 @@ class MigrateSubscriptionsProjectId < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Subscriptions will not work as expected until this migration is complete.' + DOWNTIME_REASON = 'Subscriptions will not work as expected until this migration is complete.'.freeze def up execute <<-EOF.strip_heredoc diff --git a/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb b/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb index 4b1b29e1265..1b675a36db7 100644 --- a/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb +++ b/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb @@ -2,7 +2,7 @@ class AddUniqueIndexToSubscriptions < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration requires downtime because it changes a column to not accept null values.' + DOWNTIME_REASON = 'This migration requires downtime because it changes a column to not accept null values.'.freeze disable_ddl_transaction! diff --git a/db/migrate/20161103171205_rename_repository_storage_column.rb b/db/migrate/20161103171205_rename_repository_storage_column.rb index 93280573939..32d22e630d8 100644 --- a/db/migrate/20161103171205_rename_repository_storage_column.rb +++ b/db/migrate/20161103171205_rename_repository_storage_column.rb @@ -10,7 +10,7 @@ class RenameRepositoryStorageColumn < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Renaming the application_settings.repository_storage column' + DOWNTIME_REASON = 'Renaming the application_settings.repository_storage column'.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb index 77e0c40d850..633f57ef600 100644 --- a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb +++ b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb @@ -25,7 +25,7 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration end DOWNTIME = true - DOWNTIME_REASON = 'Existing workers will error until they are using a newer version of the code' + DOWNTIME_REASON = 'Existing workers will error until they are using a newer version of the code'.freeze disable_ddl_transaction! diff --git a/db/migrate/20161130095245_fill_routes_table.rb b/db/migrate/20161130095245_fill_routes_table.rb index c3536d6d911..ccd2cceee0c 100644 --- a/db/migrate/20161130095245_fill_routes_table.rb +++ b/db/migrate/20161130095245_fill_routes_table.rb @@ -5,7 +5,7 @@ class FillRoutesTable < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'No new namespaces should be created during data copy' + DOWNTIME_REASON = 'No new namespaces should be created during data copy'.freeze def up execute <<-EOF diff --git a/db/migrate/20161130101252_fill_projects_routes_table.rb b/db/migrate/20161130101252_fill_projects_routes_table.rb index 56ba6fcdbe3..5e7d0e75ad8 100644 --- a/db/migrate/20161130101252_fill_projects_routes_table.rb +++ b/db/migrate/20161130101252_fill_projects_routes_table.rb @@ -5,7 +5,7 @@ class FillProjectsRoutesTable < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'No new projects should be created during data copy' + DOWNTIME_REASON = 'No new projects should be created during data copy'.freeze def up if Gitlab::Database.postgresql? diff --git a/db/migrate/20161201160452_migrate_project_statistics.rb b/db/migrate/20161201160452_migrate_project_statistics.rb index 3ae3f2c159b..afd5ce95068 100644 --- a/db/migrate/20161201160452_migrate_project_statistics.rb +++ b/db/migrate/20161201160452_migrate_project_statistics.rb @@ -2,7 +2,7 @@ class MigrateProjectStatistics < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Removes two columns from the projects table' + DOWNTIME_REASON = 'Removes two columns from the projects table'.freeze def up # convert repository_size in float (megabytes) to integer (bytes), diff --git a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb index b74552e762d..57f28e809de 100644 --- a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb +++ b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb @@ -2,7 +2,7 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Renaming non-unique environments' + DOWNTIME_REASON = 'Renaming non-unique environments'.freeze def up environments = Arel::Table.new(:environments) diff --git a/db/migrate/20161207231621_create_environment_name_unique_index.rb b/db/migrate/20161207231621_create_environment_name_unique_index.rb index ac680c8d10f..94fa3b6838c 100644 --- a/db/migrate/20161207231621_create_environment_name_unique_index.rb +++ b/db/migrate/20161207231621_create_environment_name_unique_index.rb @@ -4,7 +4,7 @@ class CreateEnvironmentNameUniqueIndex < ActiveRecord::Migration disable_ddl_transaction! DOWNTIME = true - DOWNTIME_REASON = 'Making a non-unique index into a unique index' + DOWNTIME_REASON = 'Making a non-unique index into a unique index'.freeze def up remove_index :environments, [:project_id, :name] diff --git a/db/migrate/20161207231626_add_environment_slug.rb b/db/migrate/20161207231626_add_environment_slug.rb index 8e98ee5b9ba..aec08dc79f2 100644 --- a/db/migrate/20161207231626_add_environment_slug.rb +++ b/db/migrate/20161207231626_add_environment_slug.rb @@ -5,7 +5,7 @@ class AddEnvironmentSlug < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Adding NOT NULL column environments.slug with dependent data' + DOWNTIME_REASON = 'Adding NOT NULL column environments.slug with dependent data'.freeze # Used to generate random suffixes for the slug LETTERS = 'a'..'z' diff --git a/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb b/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb index e9fcef1cd45..fbf6e4c2a45 100644 --- a/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb +++ b/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb @@ -5,7 +5,7 @@ class AddUniqueIndexForEnvironmentSlug < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Adding a *unique* index to environments.slug' + DOWNTIME_REASON = 'Adding a *unique* index to environments.slug'.freeze disable_ddl_transaction! diff --git a/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb b/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb index 69bfa2d3fc4..2b2b7ab27ce 100644 --- a/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb +++ b/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb @@ -9,7 +9,7 @@ class AddForeignKeysToTimelogs < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = '' + DOWNTIME_REASON = ''.freeze # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb b/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb index 319d86ac159..eacc6d1b033 100644 --- a/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb +++ b/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb @@ -2,7 +2,7 @@ class RemoveInactiveJiraServiceProperties < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = "Removes all inactive jira_service properties" + DOWNTIME_REASON = "Removes all inactive jira_service properties".freeze def up execute("UPDATE services SET properties = '{}' WHERE services.type = 'JiraService' and services.active = false") diff --git a/db/post_migrate/20161221153951_rename_reserved_project_names.rb b/db/post_migrate/20161221153951_rename_reserved_project_names.rb index 282837be1fa..49a6bc884a8 100644 --- a/db/post_migrate/20161221153951_rename_reserved_project_names.rb +++ b/db/post_migrate/20161221153951_rename_reserved_project_names.rb @@ -37,7 +37,7 @@ class RenameReservedProjectNames < ActiveRecord::Migration unsubscribes update users - wikis) + wikis).freeze def up queues = Array.new(THREAD_COUNT) { Queue.new } diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index df6db140d0e..dad588debf0 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -6,7 +6,7 @@ module API module APIGuard extend ActiveSupport::Concern - PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" + PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN".freeze PRIVATE_TOKEN_PARAM = :private_token included do |base| diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index 2ef327217ea..a5394cf61d5 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -3,7 +3,7 @@ module API include PaginationParams before { authenticate! } - AWARDABLES = %w[issue merge_request snippet] + AWARDABLES = %w[issue merge_request snippet].freeze resource :projects do AWARDABLES.each do |awardable_type| diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index a1db2099693..d0efa7b993b 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -3,7 +3,7 @@ module API include Gitlab::Utils include Helpers::Pagination - SUDO_HEADER = "HTTP_SUDO" + SUDO_HEADER = "HTTP_SUDO".freeze SUDO_PARAM = :sudo def declared_params(options = {}) diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 8beccaaabd1..c680b77f3d9 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -4,7 +4,7 @@ module API before { authenticate! } - NOTEABLE_TYPES = [Issue, MergeRequest, Snippet] + NOTEABLE_TYPES = [Issue, MergeRequest, Snippet].freeze params do requires :id, type: String, desc: 'The ID of a project' diff --git a/lib/api/todos.rb b/lib/api/todos.rb index 0b9650b296c..e59030428da 100644 --- a/lib/api/todos.rb +++ b/lib/api/todos.rb @@ -7,7 +7,7 @@ module API ISSUABLE_TYPES = { 'merge_requests' => ->(id) { find_merge_request_with_access(id) }, 'issues' => ->(id) { find_project_issue(id) } - } + }.freeze params do requires :id, type: String, desc: 'The ID of a project' diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index 80c844baecd..b8d2673c1a6 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -37,7 +37,7 @@ module Banzai and contains(., '://') and not(starts-with(., 'http')) and not(starts-with(., 'ftp')) - ]) + ]).freeze def call return doc if context[:autolink] == false diff --git a/lib/bitbucket/connection.rb b/lib/bitbucket/connection.rb index 7e55cf4deab..287410bf46f 100644 --- a/lib/bitbucket/connection.rb +++ b/lib/bitbucket/connection.rb @@ -1,8 +1,8 @@ module Bitbucket class Connection - DEFAULT_API_VERSION = '2.0' - DEFAULT_BASE_URI = 'https://api.bitbucket.org/' - DEFAULT_QUERY = {} + DEFAULT_API_VERSION = '2.0'.freeze + DEFAULT_BASE_URI = 'https://api.bitbucket.org/'.freeze + DEFAULT_QUERY = {}.freeze attr_reader :expires_at, :expires_in, :refresh_token, :token diff --git a/lib/ci/ansi2html.rb b/lib/ci/ansi2html.rb index 158a33f26fe..bab02268139 100644 --- a/lib/ci/ansi2html.rb +++ b/lib/ci/ansi2html.rb @@ -13,7 +13,7 @@ module Ci 5 => 'magenta', 6 => 'cyan', 7 => 'white', # not that this is gray in the dark (aka default) color table - } + }.freeze STYLE_SWITCHES = { bold: 0x01, @@ -21,7 +21,7 @@ module Ci underline: 0x04, conceal: 0x08, cross: 0x10, - } + }.freeze def self.convert(ansi, state = nil) Converter.new.convert(ansi, state) @@ -86,7 +86,7 @@ module Ci attr_accessor :offset, :n_open_tags, :fg_color, :bg_color, :style_mask - STATE_PARAMS = [:offset, :n_open_tags, :fg_color, :bg_color, :style_mask] + STATE_PARAMS = [:offset, :n_open_tags, :fg_color, :bg_color, :style_mask].freeze def convert(raw, new_state) reset_state diff --git a/lib/ci/api/helpers.rb b/lib/ci/api/helpers.rb index 5ff25a3a9b2..654bddf7d18 100644 --- a/lib/ci/api/helpers.rb +++ b/lib/ci/api/helpers.rb @@ -1,7 +1,7 @@ module Ci module API module Helpers - BUILD_TOKEN_HEADER = "HTTP_BUILD_TOKEN" + BUILD_TOKEN_HEADER = "HTTP_BUILD_TOKEN".freeze BUILD_TOKEN_PARAM = :token UPDATE_RUNNER_EVERY = 10 * 60 diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb index 2edddb84fc3..7f5f6d9ddb6 100644 --- a/lib/container_registry/client.rb +++ b/lib/container_registry/client.rb @@ -5,7 +5,7 @@ module ContainerRegistry class Client attr_accessor :uri - MANIFEST_VERSION = 'application/vnd.docker.distribution.manifest.v2+json' + MANIFEST_VERSION = 'application/vnd.docker.distribution.manifest.v2+json'.freeze # Taken from: FaradayMiddleware::FollowRedirects REDIRECT_CODES = Set.new [301, 302, 303, 307] diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index f638905a1e0..89db6c3da46 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -2,8 +2,8 @@ module Gitlab module Auth class MissingPersonalTokenError < StandardError; end - SCOPES = [:api, :read_user] - DEFAULT_SCOPES = [:api] + SCOPES = [:api, :read_user].freeze + DEFAULT_SCOPES = [:api].freeze OPTIONAL_SCOPES = SCOPES - DEFAULT_SCOPES class << self diff --git a/lib/gitlab/badge/build/template.rb b/lib/gitlab/badge/build/template.rb index 2b95ddfcb53..bc0e0cd441d 100644 --- a/lib/gitlab/badge/build/template.rb +++ b/lib/gitlab/badge/build/template.rb @@ -15,7 +15,7 @@ module Gitlab canceled: '#9f9f9f', skipped: '#9f9f9f', unknown: '#9f9f9f' - } + }.freeze def initialize(badge) @entity = badge.entity diff --git a/lib/gitlab/badge/coverage/template.rb b/lib/gitlab/badge/coverage/template.rb index 06e0d084e9f..fcecb1d9665 100644 --- a/lib/gitlab/badge/coverage/template.rb +++ b/lib/gitlab/badge/coverage/template.rb @@ -13,7 +13,7 @@ module Gitlab medium: '#dfb317', low: '#e05d44', unknown: '#9f9f9f' - } + }.freeze def initialize(badge) @entity = badge.entity diff --git a/lib/gitlab/ci/config/entry/artifacts.rb b/lib/gitlab/ci/config/entry/artifacts.rb index b756b0d4555..8275aacee9b 100644 --- a/lib/gitlab/ci/config/entry/artifacts.rb +++ b/lib/gitlab/ci/config/entry/artifacts.rb @@ -9,7 +9,7 @@ module Gitlab include Validatable include Attributable - ALLOWED_KEYS = %i[name untracked paths when expire_in] + ALLOWED_KEYS = %i[name untracked paths when expire_in].freeze attributes ALLOWED_KEYS diff --git a/lib/gitlab/ci/config/entry/cache.rb b/lib/gitlab/ci/config/entry/cache.rb index 7653cab668b..066643ccfcc 100644 --- a/lib/gitlab/ci/config/entry/cache.rb +++ b/lib/gitlab/ci/config/entry/cache.rb @@ -8,7 +8,7 @@ module Gitlab class Cache < Node include Configurable - ALLOWED_KEYS = %i[key untracked paths] + ALLOWED_KEYS = %i[key untracked paths].freeze validations do validates :config, allowed_keys: ALLOWED_KEYS diff --git a/lib/gitlab/ci/config/entry/environment.rb b/lib/gitlab/ci/config/entry/environment.rb index f7c530c7d9f..940333b92ef 100644 --- a/lib/gitlab/ci/config/entry/environment.rb +++ b/lib/gitlab/ci/config/entry/environment.rb @@ -8,7 +8,7 @@ module Gitlab class Environment < Node include Validatable - ALLOWED_KEYS = %i[name url action on_stop] + ALLOWED_KEYS = %i[name url action on_stop].freeze validations do validate do diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb index 69a5e6f433d..7f7662f2776 100644 --- a/lib/gitlab/ci/config/entry/job.rb +++ b/lib/gitlab/ci/config/entry/job.rb @@ -11,7 +11,7 @@ module Gitlab ALLOWED_KEYS = %i[tags script only except type image services allow_failure type stage when artifacts cache dependencies before_script - after_script variables environment coverage] + after_script variables environment coverage].freeze validations do validates :config, allowed_keys: ALLOWED_KEYS diff --git a/lib/gitlab/diff/inline_diff_marker.rb b/lib/gitlab/diff/inline_diff_marker.rb index 87a9b1e23ac..736933b1c4b 100644 --- a/lib/gitlab/diff/inline_diff_marker.rb +++ b/lib/gitlab/diff/inline_diff_marker.rb @@ -4,7 +4,7 @@ module Gitlab MARKDOWN_SYMBOLS = { addition: "+", deletion: "-" - } + }.freeze attr_accessor :raw_line, :rich_line diff --git a/lib/gitlab/downtime_check/message.rb b/lib/gitlab/downtime_check/message.rb index 40a4815a9a0..543e62794c5 100644 --- a/lib/gitlab/downtime_check/message.rb +++ b/lib/gitlab/downtime_check/message.rb @@ -3,8 +3,8 @@ module Gitlab class Message attr_reader :path, :offline - OFFLINE = "\e[31moffline\e[0m" - ONLINE = "\e[32monline\e[0m" + OFFLINE = "\e[31moffline\e[0m".freeze + ONLINE = "\e[32monline\e[0m".freeze # path - The file path of the migration. # offline - When set to `true` the migration will require downtime. diff --git a/lib/gitlab/email/handler.rb b/lib/gitlab/email/handler.rb index bd2f5d3615e..35ea2e0ef59 100644 --- a/lib/gitlab/email/handler.rb +++ b/lib/gitlab/email/handler.rb @@ -5,7 +5,7 @@ require 'gitlab/email/handler/unsubscribe_handler' module Gitlab module Email module Handler - HANDLERS = [UnsubscribeHandler, CreateNoteHandler, CreateIssueHandler] + HANDLERS = [UnsubscribeHandler, CreateNoteHandler, CreateIssueHandler].freeze def self.for(mail, mail_key) HANDLERS.find do |klass| diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb index 2dd42704396..62ddd45785d 100644 --- a/lib/gitlab/exclusive_lease.rb +++ b/lib/gitlab/exclusive_lease.rb @@ -10,7 +10,7 @@ module Gitlab # ExclusiveLease. # class ExclusiveLease - LUA_CANCEL_SCRIPT = <<-EOS + LUA_CANCEL_SCRIPT = <<-EOS.freeze local key, uuid = KEYS[1], ARGV[1] if redis.call("get", key) == uuid then redis.call("del", key) diff --git a/lib/gitlab/file_detector.rb b/lib/gitlab/file_detector.rb index 1d93a67dc56..c9ca4cadd1c 100644 --- a/lib/gitlab/file_detector.rb +++ b/lib/gitlab/file_detector.rb @@ -14,7 +14,7 @@ module Gitlab koding: '.koding.yml', gitlab_ci: '.gitlab-ci.yml', avatar: /\Alogo\.(png|jpg|gif)\z/ - } + }.freeze # Returns an Array of file types based on the given paths. # diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 7e1484613f2..ffb178334bc 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -10,10 +10,10 @@ module Gitlab deploy_key_upload: 'This deploy key does not have write access to this project.', no_repo: 'A repository for this project does not exist yet.' - } + }.freeze - DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } - PUSH_COMMANDS = %w{ git-receive-pack } + DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }.freeze + PUSH_COMMANDS = %w{ git-receive-pack }.freeze ALL_COMMANDS = DOWNLOAD_COMMANDS + PUSH_COMMANDS attr_reader :actor, :project, :protocol, :user_access, :authentication_abilities diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index a46a41bc56e..f1d1af8eee5 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -3,7 +3,7 @@ module Gitlab extend self # For every version update, the version history in import_export.md has to be kept up to date. - VERSION = '0.1.6' + VERSION = '0.1.6'.freeze FILENAME_LIMIT = 50 def export_path(relative_path:) diff --git a/lib/gitlab/metrics/rack_middleware.rb b/lib/gitlab/metrics/rack_middleware.rb index 47f88727fc8..adc0db1a874 100644 --- a/lib/gitlab/metrics/rack_middleware.rb +++ b/lib/gitlab/metrics/rack_middleware.rb @@ -2,8 +2,8 @@ module Gitlab module Metrics # Rack middleware for tracking Rails and Grape requests. class RackMiddleware - CONTROLLER_KEY = 'action_controller.instance' - ENDPOINT_KEY = 'api.endpoint' + CONTROLLER_KEY = 'action_controller.instance'.freeze + ENDPOINT_KEY = 'api.endpoint'.freeze CONTENT_TYPES = { 'text/html' => :html, 'text/plain' => :txt, @@ -14,7 +14,7 @@ module Gitlab 'image/jpeg' => :jpeg, 'image/gif' => :gif, 'image/svg+xml' => :svg - } + }.freeze def initialize(app) @app = app diff --git a/lib/gitlab/metrics/subscribers/action_view.rb b/lib/gitlab/metrics/subscribers/action_view.rb index 2e9dd4645e3..d435a33e9c7 100644 --- a/lib/gitlab/metrics/subscribers/action_view.rb +++ b/lib/gitlab/metrics/subscribers/action_view.rb @@ -5,7 +5,7 @@ module Gitlab class ActionView < ActiveSupport::Subscriber attach_to :action_view - SERIES = 'views' + SERIES = 'views'.freeze def render_template(event) track(event) if current_transaction diff --git a/lib/gitlab/metrics/transaction.rb b/lib/gitlab/metrics/transaction.rb index 7bc16181be6..4f9fb1c7853 100644 --- a/lib/gitlab/metrics/transaction.rb +++ b/lib/gitlab/metrics/transaction.rb @@ -5,7 +5,7 @@ module Gitlab THREAD_KEY = :_gitlab_metrics_transaction # The series to store events (e.g. Git pushes) in. - EVENT_SERIES = 'events' + EVENT_SERIES = 'events'.freeze attr_reader :tags, :values, :method, :metrics diff --git a/lib/gitlab/middleware/multipart.rb b/lib/gitlab/middleware/multipart.rb index dd99f9bb7d7..fee741b47be 100644 --- a/lib/gitlab/middleware/multipart.rb +++ b/lib/gitlab/middleware/multipart.rb @@ -26,7 +26,7 @@ module Gitlab module Middleware class Multipart - RACK_ENV_KEY = 'HTTP_GITLAB_WORKHORSE_MULTIPART_FIELDS' + RACK_ENV_KEY = 'HTTP_GITLAB_WORKHORSE_MULTIPART_FIELDS'.freeze class Handler def initialize(env, message) diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb index 9384102acec..53665c8375e 100644 --- a/lib/gitlab/redis.rb +++ b/lib/gitlab/redis.rb @@ -4,11 +4,11 @@ require 'active_support/core_ext/hash/keys' module Gitlab class Redis - CACHE_NAMESPACE = 'cache:gitlab' - SESSION_NAMESPACE = 'session:gitlab' - SIDEKIQ_NAMESPACE = 'resque:gitlab' - MAILROOM_NAMESPACE = 'mail_room:gitlab' - DEFAULT_REDIS_URL = 'redis://localhost:6379' + CACHE_NAMESPACE = 'cache:gitlab'.freeze + SESSION_NAMESPACE = 'session:gitlab'.freeze + SIDEKIQ_NAMESPACE = 'resque:gitlab'.freeze + MAILROOM_NAMESPACE = 'mail_room:gitlab'.freeze + DEFAULT_REDIS_URL = 'redis://localhost:6379'.freeze CONFIG_FILE = File.expand_path('../../config/resque.yml', __dir__) class << self diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 437a339dd2b..7668ecacc4b 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -1,7 +1,7 @@ module Gitlab # Extract possible GFM references from an arbitrary String for further processing. class ReferenceExtractor < Banzai::ReferenceExtractor - REFERABLES = %i(user issue label milestone merge_request snippet commit commit_range directly_addressed_user) + REFERABLES = %i(user issue label milestone merge_request snippet commit commit_range directly_addressed_user).freeze attr_accessor :project, :current_user, :author def initialize(project, current_user = nil) diff --git a/lib/gitlab/request_profiler.rb b/lib/gitlab/request_profiler.rb index 8130e55351e..0c9ab759e81 100644 --- a/lib/gitlab/request_profiler.rb +++ b/lib/gitlab/request_profiler.rb @@ -2,7 +2,7 @@ require 'fileutils' module Gitlab module RequestProfiler - PROFILES_DIR = "#{Gitlab.config.shared.path}/tmp/requests_profiles" + PROFILES_DIR = "#{Gitlab.config.shared.path}/tmp/requests_profiles".freeze def profile_token Rails.cache.fetch('profile-token') do diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb index c8872df8a93..3ff9f9eb5e7 100644 --- a/lib/gitlab/workhorse.rb +++ b/lib/gitlab/workhorse.rb @@ -4,10 +4,10 @@ require 'securerandom' module Gitlab class Workhorse - SEND_DATA_HEADER = 'Gitlab-Workhorse-Send-Data' - VERSION_FILE = 'GITLAB_WORKHORSE_VERSION' - INTERNAL_API_CONTENT_TYPE = 'application/vnd.gitlab-workhorse+json' - INTERNAL_API_REQUEST_HEADER = 'Gitlab-Workhorse-Api-Request' + SEND_DATA_HEADER = 'Gitlab-Workhorse-Send-Data'.freeze + VERSION_FILE = 'GITLAB_WORKHORSE_VERSION'.freeze + INTERNAL_API_CONTENT_TYPE = 'application/vnd.gitlab-workhorse+json'.freeze + INTERNAL_API_REQUEST_HEADER = 'Gitlab-Workhorse-Api-Request'.freeze # Supposedly the effective key size for HMAC-SHA256 is 256 bits, i.e. 32 # bytes https://tools.ietf.org/html/rfc4868#section-2.6 diff --git a/rubocop/cop/gem_fetcher.rb b/rubocop/cop/gem_fetcher.rb index 4331018fca4..6a951f5f91a 100644 --- a/rubocop/cop/gem_fetcher.rb +++ b/rubocop/cop/gem_fetcher.rb @@ -4,9 +4,9 @@ module RuboCop # `Gemfile` in order to avoid additional points of failure beyond # rubygems.org. class GemFetcher < RuboCop::Cop::Cop - MSG = 'Do not use gems from git repositories, only use gems from RubyGems.' + MSG = 'Do not use gems from git repositories, only use gems from RubyGems.'.freeze - GIT_KEYS = [:git, :github] + GIT_KEYS = [:git, :github].freeze def on_send(node) return unless gemfile?(node) diff --git a/rubocop/cop/migration/add_column.rb b/rubocop/cop/migration/add_column.rb index 1490fcdd814..d2cf36c454a 100644 --- a/rubocop/cop/migration/add_column.rb +++ b/rubocop/cop/migration/add_column.rb @@ -8,10 +8,10 @@ module RuboCop class AddColumn < RuboCop::Cop::Cop include MigrationHelpers - WHITELISTED_TABLES = [:application_settings] + WHITELISTED_TABLES = [:application_settings].freeze MSG = '`add_column` with a default value requires downtime, ' \ - 'use `add_column_with_default` instead' + 'use `add_column_with_default` instead'.freeze def on_send(node) return unless in_migration?(node) diff --git a/rubocop/cop/migration/add_column_with_default.rb b/rubocop/cop/migration/add_column_with_default.rb index 747d7caf1ef..54a920d4b49 100644 --- a/rubocop/cop/migration/add_column_with_default.rb +++ b/rubocop/cop/migration/add_column_with_default.rb @@ -9,7 +9,7 @@ module RuboCop include MigrationHelpers MSG = '`add_column_with_default` is not reversible so you must manually define ' \ - 'the `up` and `down` methods in your migration class, using `remove_column` in `down`' + 'the `up` and `down` methods in your migration class, using `remove_column` in `down`'.freeze def on_send(node) return unless in_migration?(node) diff --git a/rubocop/cop/migration/add_concurrent_foreign_key.rb b/rubocop/cop/migration/add_concurrent_foreign_key.rb index e40a7087a47..d1fc94d55be 100644 --- a/rubocop/cop/migration/add_concurrent_foreign_key.rb +++ b/rubocop/cop/migration/add_concurrent_foreign_key.rb @@ -8,7 +8,7 @@ module RuboCop class AddConcurrentForeignKey < RuboCop::Cop::Cop include MigrationHelpers - MSG = '`add_foreign_key` requires downtime, use `add_concurrent_foreign_key` instead' + MSG = '`add_foreign_key` requires downtime, use `add_concurrent_foreign_key` instead'.freeze def on_send(node) return unless in_migration?(node) diff --git a/rubocop/cop/migration/add_index.rb b/rubocop/cop/migration/add_index.rb index 5e6766f6994..fa21a0d6555 100644 --- a/rubocop/cop/migration/add_index.rb +++ b/rubocop/cop/migration/add_index.rb @@ -7,7 +7,7 @@ module RuboCop class AddIndex < RuboCop::Cop::Cop include MigrationHelpers - MSG = '`add_index` requires downtime, use `add_concurrent_index` instead' + MSG = '`add_index` requires downtime, use `add_concurrent_index` instead'.freeze def on_def(node) return unless in_migration?(node) diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index d710a780111..18508a44184 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -154,7 +154,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do 'conflict-binary-file' => 'when the conflicts contain a binary file', 'conflict-missing-side' => 'when the conflicts contain a file edited in one branch and deleted in another', 'conflict-non-utf8' => 'when the conflicts contain a non-UTF-8 file', - } + }.freeze UNRESOLVABLE_CONFLICTS.each do |source_branch, description| context description do diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index f0ed0c679d5..503e5b3eed8 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -311,7 +311,7 @@ describe Environment, models: true do end describe '#generate_slug' do - SUFFIX = "-[a-z0-9]{6}" + SUFFIX = "-[a-z0-9]{6}".freeze { "staging-12345678901234567" => "staging-123456789" + SUFFIX, "9-staging-123456789012345" => "env-9-staging-123" + SUFFIX, diff --git a/spec/support/javascript_fixtures_helpers.rb b/spec/support/javascript_fixtures_helpers.rb index 0b8729db0f9..a982b159b48 100644 --- a/spec/support/javascript_fixtures_helpers.rb +++ b/spec/support/javascript_fixtures_helpers.rb @@ -5,7 +5,7 @@ require 'gitlab/popen' module JavaScriptFixturesHelpers include Gitlab::Popen - FIXTURE_PATH = 'spec/javascripts/fixtures' + FIXTURE_PATH = 'spec/javascripts/fixtures'.freeze # Public: Removes all fixture files from given directory # diff --git a/spec/support/jira_service_helper.rb b/spec/support/jira_service_helper.rb index 929fc0c5182..97ae0b6afc5 100644 --- a/spec/support/jira_service_helper.rb +++ b/spec/support/jira_service_helper.rb @@ -1,5 +1,5 @@ module JiraServiceHelper - JIRA_URL = "http://jira.example.net" + JIRA_URL = "http://jira.example.net".freeze JIRA_API = JIRA_URL + "/rest/api/2" def jira_service_settings diff --git a/spec/support/seed_helper.rb b/spec/support/seed_helper.rb index 03fa0a66b9a..07f81e9c4f3 100644 --- a/spec/support/seed_helper.rb +++ b/spec/support/seed_helper.rb @@ -7,7 +7,7 @@ TEST_MUTABLE_REPO_PATH = File.join(SEED_REPOSITORY_PATH, "mutable-repo.git") TEST_BROKEN_REPO_PATH = File.join(SEED_REPOSITORY_PATH, "broken-repo.git") module SeedHelper - GITLAB_URL = "https://gitlab.com/gitlab-org/gitlab-git-test.git" + GITLAB_URL = "https://gitlab.com/gitlab-org/gitlab-git-test.git".freeze def ensure_seeds if File.exist?(SEED_REPOSITORY_PATH) diff --git a/spec/support/seed_repo.rb b/spec/support/seed_repo.rb index 9f2cd7c67c5..99a500bbbb1 100644 --- a/spec/support/seed_repo.rb +++ b/spec/support/seed_repo.rb @@ -25,64 +25,64 @@ module SeedRepo module BigCommit - ID = "913c66a37b4a45b9769037c55c2d238bd0942d2e" - PARENT_ID = "cfe32cf61b73a0d5e9f13e774abde7ff789b1660" - MESSAGE = "Files, encoding and much more" - AUTHOR_FULL_NAME = "Dmitriy Zaporozhets" + ID = "913c66a37b4a45b9769037c55c2d238bd0942d2e".freeze + PARENT_ID = "cfe32cf61b73a0d5e9f13e774abde7ff789b1660".freeze + MESSAGE = "Files, encoding and much more".freeze + AUTHOR_FULL_NAME = "Dmitriy Zaporozhets".freeze FILES_COUNT = 2 end module Commit - ID = "570e7b2abdd848b95f2f578043fc23bd6f6fd24d" - PARENT_ID = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" - MESSAGE = "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \n" - AUTHOR_FULL_NAME = "Dmitriy Zaporozhets" - FILES = ["files/ruby/popen.rb", "files/ruby/regex.rb"] + ID = "570e7b2abdd848b95f2f578043fc23bd6f6fd24d".freeze + PARENT_ID = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9".freeze + MESSAGE = "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \n".freeze + AUTHOR_FULL_NAME = "Dmitriy Zaporozhets".freeze + FILES = ["files/ruby/popen.rb", "files/ruby/regex.rb"].freeze FILES_COUNT = 2 - C_FILE_PATH = "files/ruby" - C_FILES = ["popen.rb", "regex.rb", "version_info.rb"] - BLOB_FILE = %{%h3= @key.title\n%hr\n%pre= @key.key\n.actions\n = link_to 'Remove', @key, :confirm => 'Are you sure?', :method => :delete, :class => \"btn danger delete-key\"\n\n\n} - BLOB_FILE_PATH = "app/views/keys/show.html.haml" + C_FILE_PATH = "files/ruby".freeze + C_FILES = ["popen.rb", "regex.rb", "version_info.rb"].freeze + BLOB_FILE = %{%h3= @key.title\n%hr\n%pre= @key.key\n.actions\n = link_to 'Remove', @key, :confirm => 'Are you sure?', :method => :delete, :class => \"btn danger delete-key\"\n\n\n}.freeze + BLOB_FILE_PATH = "app/views/keys/show.html.haml".freeze end module EmptyCommit - ID = "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9" - PARENT_ID = "40f4a7a617393735a95a0bb67b08385bc1e7c66d" - MESSAGE = "Empty commit" - AUTHOR_FULL_NAME = "Rémy Coutable" - FILES = [] + ID = "b0e52af38d7ea43cf41d8a6f2471351ac036d6c9".freeze + PARENT_ID = "40f4a7a617393735a95a0bb67b08385bc1e7c66d".freeze + MESSAGE = "Empty commit".freeze + AUTHOR_FULL_NAME = "Rémy Coutable".freeze + FILES = [].freeze FILES_COUNT = FILES.count end module EncodingCommit - ID = "40f4a7a617393735a95a0bb67b08385bc1e7c66d" - PARENT_ID = "66028349a123e695b589e09a36634d976edcc5e8" - MESSAGE = "Add ISO-8859-encoded file" - AUTHOR_FULL_NAME = "Stan Hu" - FILES = ["encoding/iso8859.txt"] + ID = "40f4a7a617393735a95a0bb67b08385bc1e7c66d".freeze + PARENT_ID = "66028349a123e695b589e09a36634d976edcc5e8".freeze + MESSAGE = "Add ISO-8859-encoded file".freeze + AUTHOR_FULL_NAME = "Stan Hu".freeze + FILES = ["encoding/iso8859.txt"].freeze FILES_COUNT = FILES.count end module FirstCommit - ID = "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863" + ID = "1a0b36b3cdad1d2ee32457c102a8c0b7056fa863".freeze PARENT_ID = nil - MESSAGE = "Initial commit" - AUTHOR_FULL_NAME = "Dmitriy Zaporozhets" - FILES = ["LICENSE", ".gitignore", "README.md"] + MESSAGE = "Initial commit".freeze + AUTHOR_FULL_NAME = "Dmitriy Zaporozhets".freeze + FILES = ["LICENSE", ".gitignore", "README.md"].freeze FILES_COUNT = 3 end module LastCommit - ID = "4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6" - PARENT_ID = "0e1b353b348f8477bdbec1ef47087171c5032cd9" - MESSAGE = "Merge branch 'master' into 'master'" - AUTHOR_FULL_NAME = "Stan Hu" - FILES = ["bin/executable"] + ID = "4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6".freeze + PARENT_ID = "0e1b353b348f8477bdbec1ef47087171c5032cd9".freeze + MESSAGE = "Merge branch 'master' into 'master'".freeze + AUTHOR_FULL_NAME = "Stan Hu".freeze + FILES = ["bin/executable"].freeze FILES_COUNT = FILES.count end module Repo - HEAD = "master" + HEAD = "master".freeze BRANCHES = %w[ feature fix @@ -93,14 +93,14 @@ module SeedRepo gitattributes-updated master merge-test - ] - TAGS = %w[v1.0.0 v1.1.0 v1.2.0 v1.2.1] + ].freeze + TAGS = %w[v1.0.0 v1.1.0 v1.2.0 v1.2.1].freeze end module RubyBlob - ID = "7e3e39ebb9b2bf433b4ad17313770fbe4051649c" - NAME = "popen.rb" - CONTENT = <<-eos + ID = "7e3e39ebb9b2bf433b4ad17313770fbe4051649c".freeze + NAME = "popen.rb".freeze + CONTENT = <<-eos.freeze require 'fileutils' require 'open3' diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index b87232a350b..4e63a4cd537 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -38,7 +38,7 @@ module TestEnv 'deleted-image-test' => '6c17798', 'wip' => 'b9238ee', 'csv' => '3dd0896' - } + }.freeze # gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily # need to keep all the branches in sync. @@ -48,7 +48,7 @@ module TestEnv 'master' => '5937ac0', 'remove-submodule' => '2a33e0c', 'conflict-resolvable-fork' => '404fa3f' - } + }.freeze # Test environment # From c10064aad5d0e4ca1981fd898a6688e42ea8c9d0 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:33:53 -0600 Subject: [PATCH 199/247] Enable Style/SpaceInsideBrackets --- .rubocop.yml | 3 ++ .rubocop_todo.yml | 5 --- app/helpers/submodule_helper.rb | 8 ++-- app/models/concerns/issuable.rb | 2 +- app/models/concerns/reactive_service.rb | 2 +- .../project_services/kubernetes_service.rb | 4 +- config/initializers/1_settings.rb | 4 +- config/initializers/devise.rb | 8 ++-- config/initializers/trusted_proxies.rb | 2 +- lib/api/api_guard.rb | 2 +- lib/api/award_emoji.rb | 2 +- lib/api/projects.rb | 2 +- lib/api/repositories.rb | 2 +- lib/api/v3/projects.rb | 2 +- spec/helpers/issues_helper_spec.rb | 2 +- spec/helpers/submodule_helper_spec.rb | 44 +++++++++---------- spec/initializers/trusted_proxies_spec.rb | 4 +- .../lib/bitbucket/representation/repo_spec.rb | 2 +- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 2 +- spec/lib/gitlab/ci/config/entry/key_spec.rb | 2 +- spec/lib/gitlab/ci/config/entry/paths_spec.rb | 2 +- .../gitlab/ci/config/entry/variables_spec.rb | 2 +- spec/lib/gitlab/git/diff_collection_spec.rb | 2 +- spec/lib/gitlab/o_auth/user_spec.rb | 4 +- spec/lib/gitlab/saml/user_spec.rb | 6 +-- spec/models/ci/build_spec.rb | 4 +- spec/models/cycle_analytics/staging_spec.rb | 2 +- spec/models/members/project_member_spec.rb | 8 ++-- .../kubernetes_service_spec.rb | 4 +- spec/requests/api/groups_spec.rb | 6 +-- .../protected_branches/create_service_spec.rb | 4 +- spec/support/kubernetes_helpers.rb | 2 +- ..._service_slash_commands_shared_examples.rb | 2 +- 33 files changed, 75 insertions(+), 77 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b453f4a1dc2..cd120e8581c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -413,6 +413,9 @@ Style/SpaceBeforeComment: Style/SpaceBeforeSemicolon: Enabled: true +Style/SpaceInsideBrackets: + Enabled: true + # Use spaces inside hash literal braces - or don't. Style/SpaceInsideHashLiteralBraces: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 8d75c99d5a6..4da79899831 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -729,11 +729,6 @@ Style/SpaceInLambdaLiteral: Style/SpaceInsideBlockBraces: Enabled: false -# Offense count: 120 -# Cop supports --auto-correct. -Style/SpaceInsideBrackets: - Enabled: false - # Offense count: 90 # Cop supports --auto-correct. Style/SpaceInsideParens: diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb index 9a748aaaf33..97d8cde4b3d 100644 --- a/app/helpers/submodule_helper.rb +++ b/app/helpers/submodule_helper.rb @@ -37,8 +37,8 @@ module SubmoduleHelper end def self_url?(url, namespace, project) - return true if url == [ Gitlab.config.gitlab.url, '/', namespace, '/', - project, '.git' ].join('') + return true if url == [Gitlab.config.gitlab.url, '/', namespace, '/', + project, '.git'].join('') url == gitlab_shell.url_to_repo([namespace, '/', project].join('')) end @@ -48,8 +48,8 @@ module SubmoduleHelper end def standard_links(host, namespace, project, commit) - base = [ 'https://', host, '/', namespace, '/', project ].join('') - [base, [ base, '/tree/', commit ].join('')] + base = ['https://', host, '/', namespace, '/', project].join('') + [base, [base, '/tree/', commit].join('')] end def relative_self_links(url, commit) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index c9c6bd24d75..e07ae9d1660 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -68,7 +68,7 @@ module Issuable scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) } scope :join_project, -> { joins(:project) } - scope :inc_notes_with_associations, -> { includes(notes: [ :project, :author, :award_emoji ]) } + scope :inc_notes_with_associations, -> { includes(notes: [:project, :author, :award_emoji]) } scope :references_project, -> { references(:project) } scope :non_archived, -> { join_project.where(projects: { archived: false }) } diff --git a/app/models/concerns/reactive_service.rb b/app/models/concerns/reactive_service.rb index e1f868a299b..713246039c1 100644 --- a/app/models/concerns/reactive_service.rb +++ b/app/models/concerns/reactive_service.rb @@ -5,6 +5,6 @@ module ReactiveService include ReactiveCaching # Default cache key: class name + project_id - self.reactive_cache_key = ->(service) { [ service.class.model_name.singular, service.project_id ] } + self.reactive_cache_key = ->(service) { [service.class.model_name.singular, service.project_id] } end end diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index f2f019c43bb..eb5019c08b5 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -3,7 +3,7 @@ class KubernetesService < DeploymentService include Gitlab::Kubernetes include ReactiveCaching - self.reactive_cache_key = ->(service) { [ service.class.model_name.singular, service.project_id ] } + self.reactive_cache_key = ->(service) { [service.class.model_name.singular, service.project_id] } # Namespace defaults to the project path, but can be overridden in case that # is an invalid or inappropriate name @@ -167,7 +167,7 @@ class KubernetesService < DeploymentService url = URI.parse(api_url) prefix = url.path.sub(%r{/+\z}, '') - url.path = [ prefix, *parts ].join("/") + url.path = [prefix, *parts].join("/") url.to_s end diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 3f716dd8833..680deee6d46 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -19,7 +19,7 @@ class Settings < Settingslogic else custom_port = ":#{gitlab.port}" end - [ gitlab.protocol, + [gitlab.protocol, "://", gitlab.host, custom_port, @@ -80,7 +80,7 @@ class Settings < Settingslogic def base_url(config) custom_port = on_standard_port?(config) ? nil : ":#{config.port}" - [ config.protocol, + [config.protocol, "://", config.host, custom_port diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 738dbeefc11..3b1317030bc 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -24,7 +24,7 @@ Devise.setup do |config| # session. If you need permissions, you should implement that in a before filter. # You can also supply a hash where the value is a boolean determining whether # or not authentication should be aborted when the value is not present. - config.authentication_keys = [ :login ] + config.authentication_keys = [:login] # Configure parameters from the request object used for authentication. Each entry # given should be a request method and it will automatically be passed to the @@ -36,12 +36,12 @@ Devise.setup do |config| # Configure which authentication keys should be case-insensitive. # These keys will be downcased upon creating or modifying a user and when used # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [ :email ] + config.case_insensitive_keys = [:email] # Configure which authentication keys should have whitespace stripped. # These keys will have whitespace before and after removed upon creating or # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [ :email ] + config.strip_whitespace_keys = [:email] # Tell if authentication through request.params is enabled. True by default. # config.params_authenticatable = true @@ -124,7 +124,7 @@ Devise.setup do |config| config.lock_strategy = :failed_attempts # Defines which key will be used when locking and unlocking an account - config.unlock_keys = [ :email ] + config.unlock_keys = [:email] # Defines which strategy will be used to unlock an account. # :email = Sends an unlock link to the user email diff --git a/config/initializers/trusted_proxies.rb b/config/initializers/trusted_proxies.rb index cd869657c53..fc4f02453d7 100644 --- a/config/initializers/trusted_proxies.rb +++ b/config/initializers/trusted_proxies.rb @@ -21,4 +21,4 @@ gitlab_trusted_proxies = Array(Gitlab.config.gitlab.trusted_proxies).map do |pro end.compact Rails.application.config.action_dispatch.trusted_proxies = ( - [ '127.0.0.1', '::1' ] + gitlab_trusted_proxies) + ['127.0.0.1', '::1'] + gitlab_trusted_proxies) diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index dad588debf0..a955d17c9d1 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -114,7 +114,7 @@ module API private def install_error_responders(base) - error_classes = [ MissingTokenError, TokenNotFoundError, + error_classes = [MissingTokenError, TokenNotFoundError, ExpiredError, RevokedError, InsufficientScopeError] base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index a5394cf61d5..f54ba232608 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -15,7 +15,7 @@ module API requires :"#{awardable_id_string}", type: Integer, desc: "The ID of an Issue, Merge Request or Snippet" end - [ ":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", + [":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji" ].each do |endpoint| diff --git a/lib/api/projects.rb b/lib/api/projects.rb index f1cb1b22143..b2ea2ab0b99 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -19,7 +19,7 @@ module API optional :visibility_level, type: Integer, values: [ Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL, - Gitlab::VisibilityLevel::PUBLIC ], desc: 'Create a public project. The same as visibility_level = 20.' + Gitlab::VisibilityLevel::PUBLIC], desc: 'Create a public project. The same as visibility_level = 20.' optional :public_builds, type: Boolean, desc: 'Perform public builds' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :only_allow_merge_if_build_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed' diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index bfda6f45b0a..36166780149 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -45,7 +45,7 @@ module API requires :sha, type: String, desc: 'The commit, branch name, or tag name' requires :filepath, type: String, desc: 'The path to the file to display' end - get [ ":id/repository/blobs/:sha", ":id/repository/commits/:sha/blob" ] do + get [":id/repository/blobs/:sha", ":id/repository/commits/:sha/blob"] do repo = user_project.repository commit = repo.commit(params[:sha]) diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index 4bc836f2a3a..f84f2ce5d42 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -20,7 +20,7 @@ module API optional :visibility_level, type: Integer, values: [ Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL, - Gitlab::VisibilityLevel::PUBLIC ], desc: 'Create a public project. The same as visibility_level = 20.' + Gitlab::VisibilityLevel::PUBLIC], desc: 'Create a public project. The same as visibility_level = 20.' optional :public_builds, type: Boolean, desc: 'Perform public builds' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :only_allow_merge_if_build_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed' diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index e1e56582425..372546e92a5 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -55,7 +55,7 @@ describe IssuesHelper do describe "merge_requests_sentence" do subject { merge_requests_sentence(merge_requests)} let(:merge_requests) do - [ build(:merge_request, iid: 1), build(:merge_request, iid: 2), + [build(:merge_request, iid: 1), build(:merge_request, iid: 2), build(:merge_request, iid: 3)] end diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb index 4da1569e59f..28b8def331d 100644 --- a/spec/helpers/submodule_helper_spec.rb +++ b/spec/helpers/submodule_helper_spec.rb @@ -20,97 +20,97 @@ describe SubmoduleHelper do it 'detects ssh on standard port' do allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(22) # set this just to be sure allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix)) - stub_url([ config.user, '@', config.host, ':gitlab-org/gitlab-ce.git' ].join('')) - expect(submodule_links(submodule_item)).to eq([ namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash') ]) + stub_url([config.user, '@', config.host, ':gitlab-org/gitlab-ce.git'].join('')) + expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')]) end it 'detects ssh on non-standard port' do allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(2222) allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix)) - stub_url([ 'ssh://', config.user, '@', config.host, ':2222/gitlab-org/gitlab-ce.git' ].join('')) - expect(submodule_links(submodule_item)).to eq([ namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash') ]) + stub_url(['ssh://', config.user, '@', config.host, ':2222/gitlab-org/gitlab-ce.git'].join('')) + expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')]) end it 'detects http on standard port' do allow(Gitlab.config.gitlab).to receive(:port).and_return(80) allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url)) - stub_url([ 'http://', config.host, '/gitlab-org/gitlab-ce.git' ].join('')) - expect(submodule_links(submodule_item)).to eq([ namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash') ]) + stub_url(['http://', config.host, '/gitlab-org/gitlab-ce.git'].join('')) + expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')]) end it 'detects http on non-standard port' do allow(Gitlab.config.gitlab).to receive(:port).and_return(3000) allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url)) - stub_url([ 'http://', config.host, ':3000/gitlab-org/gitlab-ce.git' ].join('')) - expect(submodule_links(submodule_item)).to eq([ namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash') ]) + stub_url(['http://', config.host, ':3000/gitlab-org/gitlab-ce.git'].join('')) + expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')]) end it 'works with relative_url_root' do allow(Gitlab.config.gitlab).to receive(:port).and_return(80) # set this just to be sure allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return('/gitlab/root') allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url)) - stub_url([ 'http://', config.host, '/gitlab/root/gitlab-org/gitlab-ce.git' ].join('')) - expect(submodule_links(submodule_item)).to eq([ namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash') ]) + stub_url(['http://', config.host, '/gitlab/root/gitlab-org/gitlab-ce.git'].join('')) + expect(submodule_links(submodule_item)).to eq([namespace_project_path('gitlab-org', 'gitlab-ce'), namespace_project_tree_path('gitlab-org', 'gitlab-ce', 'hash')]) end end context 'submodule on github.com' do it 'detects ssh' do stub_url('git@github.com:gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ 'https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash' ]) + expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash']) end it 'detects http' do stub_url('http://github.com/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ 'https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash' ]) + expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash']) end it 'detects https' do stub_url('https://github.com/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ 'https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash' ]) + expect(submodule_links(submodule_item)).to eq(['https://github.com/gitlab-org/gitlab-ce', 'https://github.com/gitlab-org/gitlab-ce/tree/hash']) end it 'returns original with non-standard url' do stub_url('http://github.com/gitlab-org/gitlab-ce') - expect(submodule_links(submodule_item)).to eq([ repo.submodule_url_for, nil ]) + expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil]) stub_url('http://github.com/another/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ repo.submodule_url_for, nil ]) + expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil]) end end context 'submodule on gitlab.com' do it 'detects ssh' do stub_url('git@gitlab.com:gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ 'https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash' ]) + expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash']) end it 'detects http' do stub_url('http://gitlab.com/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ 'https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash' ]) + expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash']) end it 'detects https' do stub_url('https://gitlab.com/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ 'https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash' ]) + expect(submodule_links(submodule_item)).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash']) end it 'returns original with non-standard url' do stub_url('http://gitlab.com/gitlab-org/gitlab-ce') - expect(submodule_links(submodule_item)).to eq([ repo.submodule_url_for, nil ]) + expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil]) stub_url('http://gitlab.com/another/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ repo.submodule_url_for, nil ]) + expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil]) end end context 'submodule on unsupported' do it 'returns original' do stub_url('http://mygitserver.com/gitlab-org/gitlab-ce') - expect(submodule_links(submodule_item)).to eq([ repo.submodule_url_for, nil ]) + expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil]) stub_url('http://mygitserver.com/gitlab-org/gitlab-ce.git') - expect(submodule_links(submodule_item)).to eq([ repo.submodule_url_for, nil ]) + expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil]) end end diff --git a/spec/initializers/trusted_proxies_spec.rb b/spec/initializers/trusted_proxies_spec.rb index 290e47763eb..ff8b8daa347 100644 --- a/spec/initializers/trusted_proxies_spec.rb +++ b/spec/initializers/trusted_proxies_spec.rb @@ -27,7 +27,7 @@ describe 'trusted_proxies', lib: true do context 'with private IP ranges added' do before do - set_trusted_proxies([ "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" ]) + set_trusted_proxies(["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]) end it 'filters out private and local IPs' do @@ -39,7 +39,7 @@ describe 'trusted_proxies', lib: true do context 'with proxy IP added' do before do - set_trusted_proxies([ "60.98.25.47" ]) + set_trusted_proxies(["60.98.25.47"]) end it 'filters out proxy IP' do diff --git a/spec/lib/bitbucket/representation/repo_spec.rb b/spec/lib/bitbucket/representation/repo_spec.rb index adcd978e1b3..d9228230145 100644 --- a/spec/lib/bitbucket/representation/repo_spec.rb +++ b/spec/lib/bitbucket/representation/repo_spec.rb @@ -42,7 +42,7 @@ describe Bitbucket::Representation::Repo do describe '#clone_url' do it 'builds url' do - data = { 'links' => { 'clone' => [ { 'name' => 'https', 'href' => 'https://bibucket.org/test/test.git' }] } } + data = { 'links' => { 'clone' => [{ 'name' => 'https', 'href' => 'https://bibucket.org/test/test.git' }] } } expect(described_class.new(data).clone_url('abc')).to eq('https://x-token-auth:abc@bibucket.org/test/test.git') end end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index ce31f8a8432..86eec3d6392 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -580,7 +580,7 @@ module Ci context 'when syntax is incorrect' do context 'when variables defined but invalid' do let(:variables) do - [ 'VAR1', 'value1', 'VAR2', 'value2' ] + ['VAR1', 'value1', 'VAR2', 'value2'] end it 'raises error' do diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb index b1e563e0786..cd7b03ffb11 100644 --- a/spec/lib/gitlab/ci/config/entry/key_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb @@ -21,7 +21,7 @@ describe Gitlab::Ci::Config::Entry::Key do end context 'when entry value is not correct' do - let(:config) { [ 'incorrect' ] } + let(:config) { ['incorrect'] } describe '#errors' do it 'saves errors' do diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb index 52f595e4b67..b0ac90f1d94 100644 --- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb @@ -21,7 +21,7 @@ describe Gitlab::Ci::Config::Entry::Paths do end context 'when entry value is not valid' do - let(:config) { [ 1 ] } + let(:config) { [1] } describe '#errors' do it 'saves errors' do diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index 60aa510b746..c117f35c906 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -29,7 +29,7 @@ describe Gitlab::Ci::Config::Entry::Variables do end context 'when entry value is not correct' do - let(:config) { [ :VAR, 'test' ] } + let(:config) { [:VAR, 'test'] } describe '#errors' do it 'saves errors' do diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb index 4fa72c565ae..47bdd7310d5 100644 --- a/spec/lib/gitlab/git/diff_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_collection_spec.rb @@ -365,7 +365,7 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do end context 'when go over safe limits on files' do - let(:iterator) { [ fake_diff(1, 1) ] * 4 } + let(:iterator) { [fake_diff(1, 1)] * 4 } before(:each) do stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: 2, max_lines: max_lines }) diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 8d9352350f0..0575b95fd30 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -151,7 +151,7 @@ describe Gitlab::OAuth::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( - [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + [{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'twitter', extern_uid: uid } ]) end @@ -170,7 +170,7 @@ describe Gitlab::OAuth::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( - [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + [{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'twitter', extern_uid: uid } ]) end diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index 02c139f1a0d..844b9446603 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -157,7 +157,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user.email).to eql 'john@mail.com' expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'saml', extern_uid: uid } ]) end @@ -180,7 +180,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user.email).to eql 'john@mail.com' expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'saml', extern_uid: uid } ]) end @@ -206,7 +206,7 @@ describe Gitlab::Saml::User, lib: true do expect(local_gl_user).to be_valid expect(local_gl_user.identities.length).to eql 2 identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } ]) end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 2725c63f13b..2611a0be92f 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1262,8 +1262,8 @@ describe Ci::Build, :models do context 'when build has user' do let(:user_variables) do - [ { key: 'GITLAB_USER_ID', value: user.id.to_s, public: true }, - { key: 'GITLAB_USER_EMAIL', value: user.email, public: true } ] + [{ key: 'GITLAB_USER_ID', value: user.id.to_s, public: true }, + { key: 'GITLAB_USER_EMAIL', value: user.email, public: true }] end before do diff --git a/spec/models/cycle_analytics/staging_spec.rb b/spec/models/cycle_analytics/staging_spec.rb index 9a024d533a1..78ec518ac86 100644 --- a/spec/models/cycle_analytics/staging_spec.rb +++ b/spec/models/cycle_analytics/staging_spec.rb @@ -18,7 +18,7 @@ describe 'CycleAnalytics#staging', feature: true do start_time_conditions: [["merge request that closes issue is merged", -> (context, data) do context.merge_merge_requests_closing_issue(data[:issue]) - end ]], + end]], end_time_conditions: [["merge request that closes issue is deployed to production", -> (context, data) do context.deploy_master diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index e4be0aba7a6..87ea2e70680 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -89,8 +89,8 @@ describe ProjectMember, models: true do @user_1 = create :user @user_2 = create :user - @project_1.team << [ @user_1, :developer ] - @project_2.team << [ @user_2, :reporter ] + @project_1.team << [@user_1, :developer] + @project_2.team << [@user_2, :reporter] @status = @project_2.team.import(@project_1) end @@ -137,8 +137,8 @@ describe ProjectMember, models: true do @user_1 = create :user @user_2 = create :user - @project_1.team << [ @user_1, :developer] - @project_2.team << [ @user_2, :reporter] + @project_1.team << [@user_1, :developer] + @project_2.team << [@user_2, :reporter] ProjectMember.truncate_teams([@project_1.id, @project_2.id]) end diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 9052479d35e..24356447fed 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -171,7 +171,7 @@ describe KubernetesService, models: true, caching: true do context 'with invalid pods' do it 'returns no terminals' do - stub_reactive_cache(service, pods: [ { "bad" => "pod" } ]) + stub_reactive_cache(service, pods: [{ "bad" => "pod" }]) is_expected.to be_empty end @@ -184,7 +184,7 @@ describe KubernetesService, models: true, caching: true do before do stub_reactive_cache( service, - pods: [ pod, pod, kube_pod(app: "should-be-filtered-out") ] + pods: [pod, pod, kube_pod(app: "should-be-filtered-out")] ) end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index ff2e0d58d2a..b82372b1b60 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -303,7 +303,7 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response.length).to eq(2) - project_names = json_response.map { |proj| proj['name' ] } + project_names = json_response.map { |proj| proj['name'] } expect(project_names).to match_array([project1.name, project3.name]) expect(json_response.first['visibility_level']).to be_present end @@ -314,7 +314,7 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response.length).to eq(2) - project_names = json_response.map { |proj| proj['name' ] } + project_names = json_response.map { |proj| proj['name'] } expect(project_names).to match_array([project1.name, project3.name]) expect(json_response.first['visibility_level']).not_to be_present end @@ -398,7 +398,7 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers - project_names = json_response.map { |proj| proj['name' ] } + project_names = json_response.map { |proj| proj['name'] } expect(project_names).to match_array([project1.name, project3.name]) end diff --git a/spec/services/protected_branches/create_service_spec.rb b/spec/services/protected_branches/create_service_spec.rb index 7d4eff3b6ef..6ea8f309981 100644 --- a/spec/services/protected_branches/create_service_spec.rb +++ b/spec/services/protected_branches/create_service_spec.rb @@ -6,8 +6,8 @@ describe ProtectedBranches::CreateService, services: true do let(:params) do { name: 'master', - merge_access_levels_attributes: [ { access_level: Gitlab::Access::MASTER } ], - push_access_levels_attributes: [ { access_level: Gitlab::Access::MASTER } ] + merge_access_levels_attributes: [{ access_level: Gitlab::Access::MASTER }], + push_access_levels_attributes: [{ access_level: Gitlab::Access::MASTER }] } end diff --git a/spec/support/kubernetes_helpers.rb b/spec/support/kubernetes_helpers.rb index 444612cf871..41c40eb5084 100644 --- a/spec/support/kubernetes_helpers.rb +++ b/spec/support/kubernetes_helpers.rb @@ -11,7 +11,7 @@ module KubernetesHelpers def kube_pods_body(*pods) { "kind" => "PodList", - "items" => [ kube_pod ], + "items" => [kube_pod], } end diff --git a/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb b/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb index c64574679b6..81d06dc2a3d 100644 --- a/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb +++ b/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb @@ -11,7 +11,7 @@ shared_examples 'new issuable record that supports slash commands' do let(:params) { base_params.merge(defined?(default_params) ? default_params : {}).merge(example_params) } let(:issuable) { described_class.new(project, user, params).execute } - before { project.team << [assignee, :master ] } + before { project.team << [assignee, :master] } context 'with labels in command only' do let(:example_params) do From b664a542042fc9b31849bb074f821bc0d1ff5d92 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:34:50 -0600 Subject: [PATCH 200/247] Disable Style/TrailingCommaInLiteral --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index cd120e8581c..5d89b73fe2b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -452,6 +452,9 @@ Style/Tab: Style/TrailingBlankLines: Enabled: true +Style/TrailingCommaInLiteral: + Enabled: false + # Checks for %W when interpolation is not needed. Style/UnneededCapitalW: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4da79899831..d065b246050 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -794,13 +794,6 @@ Style/TernaryParentheses: Style/TrailingCommaInArguments: Enabled: false -# Offense count: 158 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma -Style/TrailingCommaInLiteral: - Enabled: false - # Offense count: 7 # Cop supports --auto-correct. # Configuration parameters: AllowNamedUnderscoreVariables. From 7a81a41f178dfdf582835854c0358a2ffddaefba Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:35:12 -0600 Subject: [PATCH 201/247] Disable Lint/UnusedMethodArgument --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 5d89b73fe2b..a55ad5f01c7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -683,6 +683,9 @@ Lint/UnneededDisable: Lint/UnreachableCode: Enabled: true +Lint/UnusedMethodArgument: + Enabled: false + # Checks for useless assignment to a local variable. Lint/UselessAssignment: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d065b246050..31569250877 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -68,12 +68,6 @@ Lint/UnneededSplatExpansion: Lint/UnusedBlockArgument: Enabled: false -# Offense count: 171 -# Cop supports --auto-correct. -# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods. -Lint/UnusedMethodArgument: - Enabled: false - # Offense count: 114 # Configuration parameters: CountComments. Metrics/BlockLength: From 73382c2feac59a2fe8ec773b16b8cfb3a884fe38 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:37:54 -0600 Subject: [PATCH 202/247] =?UTF-8?q?Custom=20cops=20don=E2=80=99t=20need=20?= =?UTF-8?q?to=20be=20mentioned=20in=20.rubocop.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .rubocop.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a55ad5f01c7..6622e213617 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -861,9 +861,3 @@ RSpec/NotToNot: # Prefer using verifying doubles over normal doubles. RSpec/VerifiedDoubles: Enabled: false - -# Custom ###################################################################### - -# Disallow the `git` and `github` arguments in the Gemfile. -GemFetcher: - Enabled: true From 378ad332dd9fc84bb85af2300ae4e6ce828818ab Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:41:04 -0600 Subject: [PATCH 203/247] Disable a few RSpec cops --- .rubocop.yml | 27 ++++++++++++++++++++ .rubocop_todo.yml | 63 ----------------------------------------------- 2 files changed, 27 insertions(+), 63 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6622e213617..6151d6c570c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -861,3 +861,30 @@ RSpec/NotToNot: # Prefer using verifying doubles over normal doubles. RSpec/VerifiedDoubles: Enabled: false + +RSpec/MultipleExpectations: + Enabled: false + +RSpec/NamedSubject: + Enabled: false + +RSpec/NestedGroups: + Enabled: false + +RSpec/LeadingSubject: + Enabled: false + +RSpec/LetSetup: + Enabled: false + +RSpec/MessageChain: + Enabled: false + +RSpec/MessageSpies: + Enabled: false + +RSpec/RepeatedDescription: + Enabled: false + +RSpec/SubjectStub: + Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 31569250877..085e593c6b9 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -124,74 +124,11 @@ RSpec/ImplicitExpect: - 'spec/models/project_services/external_wiki_service_spec.rb' - 'spec/models/project_spec.rb' -# Offense count: 258 -RSpec/LeadingSubject: - Enabled: false - -# Offense count: 281 -RSpec/LetSetup: - Enabled: false - -# Offense count: 13 -RSpec/MessageChain: - Exclude: - - 'spec/finders/move_to_project_finder_spec.rb' - - 'spec/helpers/issues_helper_spec.rb' - - 'spec/initializers/secret_token_spec.rb' - - 'spec/models/ci/build_spec.rb' - - 'spec/requests/api/internal_spec.rb' - - 'spec/services/ci/retry_build_service_spec.rb' - - 'spec/services/ci/retry_pipeline_service_spec.rb' - - 'spec/services/merge_requests/build_service_spec.rb' - - 'spec/workers/emails_on_push_worker_spec.rb' - -# Offense count: 505 -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: have_received, receive -RSpec/MessageSpies: - Enabled: false - -# Offense count: 3625 -RSpec/MultipleExpectations: - Max: 37 - -# Offense count: 2217 -RSpec/NamedSubject: - Enabled: false - -# Offense count: 2126 -# Configuration parameters: MaxNesting. -RSpec/NestedGroups: - Enabled: false - -# Offense count: 36 -RSpec/RepeatedDescription: - Exclude: - - 'spec/controllers/projects/todo_controller_spec.rb' - - 'spec/features/boards/boards_spec.rb' - - 'spec/helpers/issuables_helper_spec.rb' - - 'spec/lib/banzai/filter/emoji_filter_spec.rb' - - 'spec/models/commit_range_spec.rb' - - 'spec/models/global_milestone_spec.rb' - - 'spec/models/hooks/system_hook_spec.rb' - - 'spec/requests/api/commits_spec.rb' - - 'spec/requests/api/merge_requests_spec.rb' - - 'spec/requests/api/milestones_spec.rb' - - 'spec/requests/api/users_spec.rb' - - 'spec/requests/api/v3/merge_requests_spec.rb' - - 'spec/requests/lfs_http_spec.rb' - - 'spec/routing/admin_routing_spec.rb' - - 'spec/services/notification_service_spec.rb' - # Offense count: 1 RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 140 -RSpec/SubjectStub: - Enabled: false - # Offense count: 126 # Cop supports --auto-correct. # Configuration parameters: Whitelist. From c5a49cc3c56283ae5f015c808327b1a29ca09ed9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:45:20 -0600 Subject: [PATCH 204/247] Disable some more cops --- .rubocop.yml | 42 +++++++++++++++++++ .rubocop_todo.yml | 104 ---------------------------------------------- 2 files changed, 42 insertions(+), 104 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6151d6c570c..88264d046ae 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -874,6 +874,21 @@ RSpec/NestedGroups: RSpec/LeadingSubject: Enabled: false +Lint/AmbiguousRegexpLiteral: + Enabled: false + +Bundler/OrderedGems: + Enabled: false + +Lint/HandleExceptions: + Enabled: false + +Lint/Loop: + Enabled: false + +Metrics/BlockLength: + Enabled: false + RSpec/LetSetup: Enabled: false @@ -888,3 +903,30 @@ RSpec/RepeatedDescription: RSpec/SubjectStub: Enabled: false +Lint/ShadowingOuterLocalVariable: + Enabled: false + +Lint/AssignmentInCondition: + Enabled: false + + +Lint/UnusedBlockArgument: + Enabled: false + +Rails/HttpPositionalArguments: + Enabled: false + +Rails/TimeZone: + Enabled: false + +Style/AlignParameters: + Enabled: false + +Style/CaseEquality: + Enabled: false + +Style/CommentAnnotation: + Enabled: false + +Style/DoubleNegation: + Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 085e593c6b9..29453cb4981 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,35 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 28 -# Configuration parameters: Include. -# Include: **/Gemfile, **/gems.rb -Bundler/OrderedGems: - Exclude: - - 'Gemfile' - -# Offense count: 176 -Lint/AmbiguousRegexpLiteral: - Enabled: false - -# Offense count: 54 -# Configuration parameters: AllowSafeAssignment. -Lint/AssignmentInCondition: - Enabled: false - -# Offense count: 23 -Lint/HandleExceptions: - Enabled: false - -# Offense count: 1 -Lint/Loop: - Exclude: - - 'app/mailers/notify.rb' - -# Offense count: 32 -Lint/ShadowingOuterLocalVariable: - Enabled: false - # Offense count: 10 # Cop supports --auto-correct. Lint/UnifiedInteger: @@ -62,17 +33,6 @@ Lint/UnneededSplatExpansion: - 'spec/support/seed_helper.rb' - 'spec/support/test_env.rb' -# Offense count: 89 -# Cop supports --auto-correct. -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. -Lint/UnusedBlockArgument: - Enabled: false - -# Offense count: 114 -# Configuration parameters: CountComments. -Metrics/BlockLength: - Max: 302 - # Offense count: 3 # Cop supports --auto-correct. Performance/RedundantBlockCall: @@ -136,24 +96,6 @@ RSpec/SingleArgumentMessageChain: Rails/DynamicFindBy: Enabled: false -# Offense count: 1162 -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: spec/**/*, test/**/* -Rails/HttpPositionalArguments: - Enabled: false - -# Offense count: 56 -Rails/OutputSafety: - Enabled: false - -# Offense count: 202 -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: strict, flexible -Rails/TimeZone: - Enabled: false - -# Offense count: 16 # Cop supports --auto-correct. # Configuration parameters: Include. # Include: app/models/**/*.rb @@ -183,13 +125,6 @@ Security/JSONLoad: - 'spec/models/project_services/irker_service_spec.rb' - 'spec/support/stub_gitlab_calls.rb' -# Offense count: 431 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: with_first_parameter, with_fixed_indentation -Style/AlignParameters: - Enabled: false - # Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. @@ -204,31 +139,11 @@ Style/BarePercentLiterals: Style/BracesAroundHashParameters: Enabled: false -# Offense count: 7 -Style/CaseEquality: - Exclude: - - 'app/helpers/auth_helper.rb' - - 'app/helpers/builds_helper.rb' - - 'app/models/commit.rb' - - 'app/models/protected_branch.rb' - - 'app/services/projects/download_service.rb' - - 'config/initializers/trusted_proxies.rb' - - 'lib/gitlab/route_map.rb' - # Offense count: 33 # Cop supports --auto-correct. Style/ColonMethodCall: Enabled: false -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: Keywords. -# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW -Style/CommentAnnotation: - Exclude: - - 'config/routes/user.rb' - - 'spec/requests/api/v3/project_snippets_spec.rb' - # Offense count: 32 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. @@ -236,25 +151,6 @@ Style/CommentAnnotation: Style/ConditionalAssignment: Enabled: false -# Offense count: 21 -Style/DoubleNegation: - Exclude: - - 'app/controllers/users_controller.rb' - - 'app/models/commit.rb' - - 'app/models/merge_request.rb' - - 'app/models/project.rb' - - 'app/models/project_services/buildkite_service.rb' - - 'app/models/project_services/drone_ci_service.rb' - - 'app/models/project_wiki.rb' - - 'app/models/user.rb' - - 'config/initializers/6_validations.rb' - - 'lib/banzai/filter/abstract_reference_filter.rb' - - 'lib/banzai/filter/relative_link_filter.rb' - - 'lib/gitlab/git/diff_collection.rb' - - 'lib/gitlab/git/repository.rb' - - 'lib/gitlab/sherlock.rb' - - 'lib/gitlab/sherlock/middleware.rb' - # Offense count: 6 # Cop supports --auto-correct. Style/EachWithObject: From 030baf70d25a666b660b0024f000586631ee3daf Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:50:22 -0600 Subject: [PATCH 205/247] Enable Performance/RedundantMerge --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 6 ------ app/helpers/sorting_helper.rb | 2 +- app/models/concerns/issuable.rb | 2 +- app/models/merge_request.rb | 2 +- app/models/project_services/pushover_service.rb | 2 +- app/services/protected_branches/api_update_service.rb | 8 ++++---- app/services/system_hooks_service.rb | 4 +--- app/services/system_note_service.rb | 2 +- features/steps/shared/issuable.rb | 2 +- lib/api/users.rb | 2 +- lib/gitlab/github_import/importer.rb | 2 +- spec/finders/notes_finder_spec.rb | 2 +- spec/services/projects/create_service_spec.rb | 4 ++-- 14 files changed, 20 insertions(+), 24 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 88264d046ae..4c6438f8b0d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -889,6 +889,10 @@ Lint/Loop: Metrics/BlockLength: Enabled: false +Performance/RedundantMerge: + Enabled: true + MaxKeyValuePairs: 1 + RSpec/LetSetup: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 29453cb4981..ca80e9c3f20 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -51,12 +51,6 @@ Performance/RedundantMatch: - 'lib/gitlab/diff/highlight.rb' - 'lib/gitlab/diff/parser.rb' -# Offense count: 25 -# Cop supports --auto-correct. -# Configuration parameters: MaxKeyValuePairs. -Performance/RedundantMerge: - Enabled: false - # Offense count: 15 # Configuration parameters: CustomIncludeMethods. RSpec/EmptyExampleGroup: diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index ff787fb4131..8ad3851fb9a 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -30,7 +30,7 @@ module SortingHelper } if current_controller?('admin/projects') - options.merge!(sort_value_largest_repo => sort_title_largest_repo) + options[sort_value_largest_repo] = sort_title_largest_repo end options diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index e07ae9d1660..768baa80c01 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -235,7 +235,7 @@ module Issuable # DEPRECATED repository: project.hook_attrs.slice(:name, :url, :description, :homepage) } - hook_data.merge!(assignee: assignee.hook_attrs) if assignee + hook_data[:assignee] = assignee.hook_attrs if assignee hook_data end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index a0b8a63d6ab..ea784f77015 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -527,7 +527,7 @@ class MergeRequest < ActiveRecord::Base } if diff_head_commit - attrs.merge!(last_commit: diff_head_commit.hook_attrs) + attrs[:last_commit] = diff_head_commit.hook_attrs end attributes.merge!(attrs) diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index a963d27a376..f623bf9851b 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -97,7 +97,7 @@ class PushoverService < Service # Sound parameter MUST NOT be sent to API if not selected if sound - pushover_data.merge!(sound: sound) + pushover_data[:sound] = sound end PushoverService.post('/messages.json', body: pushover_data) diff --git a/app/services/protected_branches/api_update_service.rb b/app/services/protected_branches/api_update_service.rb index 050cb3b738b..bdb0e0cc8bf 100644 --- a/app/services/protected_branches/api_update_service.rb +++ b/app/services/protected_branches/api_update_service.rb @@ -15,16 +15,16 @@ module ProtectedBranches case @developers_can_push when true - params.merge!(push_access_levels_attributes: [{ access_level: Gitlab::Access::DEVELOPER }]) + params[:push_access_levels_attributes] = [{ access_level: Gitlab::Access::DEVELOPER }] when false - params.merge!(push_access_levels_attributes: [{ access_level: Gitlab::Access::MASTER }]) + params[:push_access_levels_attributes] = [{ access_level: Gitlab::Access::MASTER }] end case @developers_can_merge when true - params.merge!(merge_access_levels_attributes: [{ access_level: Gitlab::Access::DEVELOPER }]) + params[:merge_access_levels_attributes] = [{ access_level: Gitlab::Access::DEVELOPER }] when false - params.merge!(merge_access_levels_attributes: [{ access_level: Gitlab::Access::MASTER }]) + params[:merge_access_levels_attributes] = [{ access_level: Gitlab::Access::MASTER }] end service = ProtectedBranches::UpdateService.new(@project, @current_user, @params) diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index a2bfa422c9d..9b6dd013e3a 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -33,9 +33,7 @@ class SystemHooksService data.merge!(project_data(model)) if event == :rename || event == :transfer - data.merge!({ - old_path_with_namespace: model.old_path_with_namespace - }) + data[:old_path_with_namespace] = model.old_path_with_namespace end data diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 87ba72cf991..71b4f8605a4 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -359,7 +359,7 @@ module SystemNoteService if noteable.kind_of?(Commit) note_options.merge!(noteable_type: 'Commit', commit_id: noteable.id) else - note_options.merge!(noteable: noteable) + note_options[:noteable] = noteable end if noteable.is_a?(ExternalIssue) diff --git a/features/steps/shared/issuable.rb b/features/steps/shared/issuable.rb index 79dde620265..3d9cedf5c2d 100644 --- a/features/steps/shared/issuable.rb +++ b/features/steps/shared/issuable.rb @@ -153,7 +153,7 @@ module SharedIssuable case type when :issue - attrs.merge!(project: project) + attrs[:project] = project when :merge_request attrs.merge!( source_project: project, diff --git a/lib/api/users.rb b/lib/api/users.rb index fbc17953691..94b2b6653d2 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -172,7 +172,7 @@ module API end end - user_params.merge!(password_expires_at: Time.now) if user_params[:password].present? + user_params[:password_expires_at] = Time.now if user_params[:password].present? if user.update_attributes(user_params.except(:extern_uid, :provider)) present user, with: Entities::UserPublic diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index a631425b3cf..a160869541a 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -285,7 +285,7 @@ module Gitlab def fetch_resources(resource_type, *opts) return if imported?(resource_type) - opts.last.merge!(page: current_page(resource_type)) + opts.last[:page] = current_page(resource_type) client.public_send(resource_type, *opts) do |resources| yield resources diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb index f8b05d4e9bc..77a04507be1 100644 --- a/spec/finders/notes_finder_spec.rb +++ b/spec/finders/notes_finder_spec.rb @@ -111,7 +111,7 @@ describe NotesFinder do end it 'raises an exception for an invalid target_type' do - params.merge!(target_type: 'invalid') + params[:target_type] = 'invalid' expect { described_class.new(project, user, params).execute }.to raise_error('invalid target_type') end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index af515ad2e0e..62f21049b0b 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -50,7 +50,7 @@ describe Projects::CreateService, '#execute', services: true do context 'error handling' do it 'handles invalid options' do - opts.merge!({ default_branch: 'master' } ) + opts[:default_branch] = 'master' expect(create_project(user, opts)).to eq(nil) end end @@ -67,7 +67,7 @@ describe Projects::CreateService, '#execute', services: true do context 'wiki_enabled false does not create wiki repository directory' do it do - opts.merge!(wiki_enabled: false) + opts[:wiki_enabled] = false project = create_project(user, opts) path = ProjectWiki.new(project, user).send(:path_to_repo) From 3a8128f199f171d674be2acd48222b1e6b3c6604 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:54:03 -0600 Subject: [PATCH 206/247] Enable Lint/UnifiedInteger --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 10 ---------- spec/lib/gitlab/metrics/method_call_spec.rb | 2 +- spec/lib/gitlab/metrics/metric_spec.rb | 2 +- spec/lib/gitlab/metrics/system_spec.rb | 6 +++--- spec/lib/gitlab/metrics/transaction_spec.rb | 4 ++-- spec/models/repository_spec.rb | 6 +++--- 7 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 4c6438f8b0d..c674cfbcf51 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -907,6 +907,10 @@ RSpec/RepeatedDescription: RSpec/SubjectStub: Enabled: false + +Lint/UnifiedInteger: + Enabled: true + Lint/ShadowingOuterLocalVariable: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ca80e9c3f20..b18adcc8b2f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,16 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 10 -# Cop supports --auto-correct. -Lint/UnifiedInteger: - Exclude: - - 'spec/lib/gitlab/metrics/method_call_spec.rb' - - 'spec/lib/gitlab/metrics/metric_spec.rb' - - 'spec/lib/gitlab/metrics/system_spec.rb' - - 'spec/lib/gitlab/metrics/transaction_spec.rb' - - 'spec/models/repository_spec.rb' - # Offense count: 23 # Cop supports --auto-correct. Lint/UnneededSplatExpansion: diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb index 8d05081eecb..16c6de0bee6 100644 --- a/spec/lib/gitlab/metrics/method_call_spec.rb +++ b/spec/lib/gitlab/metrics/method_call_spec.rb @@ -23,7 +23,7 @@ describe Gitlab::Metrics::MethodCall do expect(metric.values[:duration]).to be_a_kind_of(Numeric) expect(metric.values[:cpu_duration]).to be_a_kind_of(Numeric) - expect(metric.values[:call_count]).to an_instance_of(Fixnum) + expect(metric.values[:call_count]).to an_instance_of(Integer) expect(metric.tags).to eq({ method: 'Foo#bar' }) end diff --git a/spec/lib/gitlab/metrics/metric_spec.rb b/spec/lib/gitlab/metrics/metric_spec.rb index f26fca52c50..b4d29ebe05f 100644 --- a/spec/lib/gitlab/metrics/metric_spec.rb +++ b/spec/lib/gitlab/metrics/metric_spec.rb @@ -62,7 +62,7 @@ describe Gitlab::Metrics::Metric do end it 'includes the timestamp' do - expect(hash[:timestamp]).to be_an_instance_of(Fixnum) + expect(hash[:timestamp]).to be_an_instance_of(Integer) end end end diff --git a/spec/lib/gitlab/metrics/system_spec.rb b/spec/lib/gitlab/metrics/system_spec.rb index 9e2ea89a712..a7b129e2827 100644 --- a/spec/lib/gitlab/metrics/system_spec.rb +++ b/spec/lib/gitlab/metrics/system_spec.rb @@ -29,19 +29,19 @@ describe Gitlab::Metrics::System do describe '.cpu_time' do it 'returns a Fixnum' do - expect(described_class.cpu_time).to be_an_instance_of(Fixnum) + expect(described_class.cpu_time).to be_an_instance_of(Integer) end end describe '.real_time' do it 'returns a Fixnum' do - expect(described_class.real_time).to be_an_instance_of(Fixnum) + expect(described_class.real_time).to be_an_instance_of(Integer) end end describe '.monotonic_time' do it 'returns a Fixnum' do - expect(described_class.monotonic_time).to be_an_instance_of(Fixnum) + expect(described_class.monotonic_time).to be_an_instance_of(Integer) end end end diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb index 3887c04c832..83bd862d146 100644 --- a/spec/lib/gitlab/metrics/transaction_spec.rb +++ b/spec/lib/gitlab/metrics/transaction_spec.rb @@ -134,7 +134,7 @@ describe Gitlab::Metrics::Transaction do series: 'rails_transactions', tags: { action: 'Foo#bar' }, values: { duration: 0.0, allocated_memory: a_kind_of(Numeric) }, - timestamp: an_instance_of(Fixnum) + timestamp: an_instance_of(Integer) } expect(Gitlab::Metrics).to receive(:submit_metrics). @@ -151,7 +151,7 @@ describe Gitlab::Metrics::Transaction do series: 'events', tags: { event: :meow }, values: { count: 1 }, - timestamp: an_instance_of(Fixnum) + timestamp: an_instance_of(Integer) } expect(Gitlab::Metrics).to receive(:submit_metrics). diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 0d1db97cd5b..c3d4365639d 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1382,13 +1382,13 @@ describe Repository, models: true do describe '#branch_count' do it 'returns the number of branches' do - expect(repository.branch_count).to be_an_instance_of(Fixnum) + expect(repository.branch_count).to be_an_instance_of(Integer) end end describe '#tag_count' do it 'returns the number of tags' do - expect(repository.tag_count).to be_an_instance_of(Fixnum) + expect(repository.tag_count).to be_an_instance_of(Integer) end end @@ -1738,7 +1738,7 @@ describe Repository, models: true do context 'with an existing repository' do it 'returns the commit count' do - expect(repository.commit_count).to be_an_instance_of(Fixnum) + expect(repository.commit_count).to be_an_instance_of(Integer) end end end From 8924594a3e84f03c363031d0831960ad5ab822dd Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:56:27 -0600 Subject: [PATCH 207/247] Disable Lint/UnneededSplatExpansion --- .rubocop.yml | 2 ++ .rubocop_todo.yml | 17 ----------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c674cfbcf51..7bcd09bef1b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -917,6 +917,8 @@ Lint/ShadowingOuterLocalVariable: Lint/AssignmentInCondition: Enabled: false +Lint/UnneededSplatExpansion: + Enabled: false Lint/UnusedBlockArgument: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b18adcc8b2f..f4497e5ac25 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,23 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 23 -# Cop supports --auto-correct. -Lint/UnneededSplatExpansion: - Exclude: - - 'app/services/projects/update_pages_service.rb' - - 'config/application.rb' - - 'lib/banzai/filter/gollum_tags_filter.rb' - - 'lib/bitbucket/page.rb' - - 'lib/gitlab/markup_helper.rb' - - 'spec/helpers/auth_helper_spec.rb' - - 'spec/models/project_wiki_spec.rb' - - 'spec/requests/api/projects_spec.rb' - - 'spec/requests/api/tags_spec.rb' - - 'spec/requests/api/v3/projects_spec.rb' - - 'spec/support/seed_helper.rb' - - 'spec/support/test_env.rb' - # Offense count: 3 # Cop supports --auto-correct. Performance/RedundantBlockCall: From 215228b477e9dae8cf3ba36af767ae12d4328e28 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 17:59:42 -0600 Subject: [PATCH 208/247] Enable Performance/RedundantBlockCall --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 8 -------- app/controllers/application_controller.rb | 2 +- lib/gitlab/optimistic_locking.rb | 2 +- lib/gitlab/shell.rb | 2 +- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 7bcd09bef1b..9087b626bb9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -923,6 +923,9 @@ Lint/UnneededSplatExpansion: Lint/UnusedBlockArgument: Enabled: false +Performance/RedundantBlockCall: + Enabled: true + Rails/HttpPositionalArguments: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f4497e5ac25..abd7be72b46 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,14 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 3 -# Cop supports --auto-correct. -Performance/RedundantBlockCall: - Exclude: - - 'app/controllers/application_controller.rb' - - 'lib/gitlab/optimistic_locking.rb' - - 'lib/gitlab/shell.rb' - # Offense count: 5 # Cop supports --auto-correct. Performance/RedundantMatch: diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5e7af3bff0d..e42e48f87d2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -181,7 +181,7 @@ class ApplicationController < ActionController::Base end def gitlab_ldap_access(&block) - Gitlab::LDAP::Access.open { |access| block.call(access) } + Gitlab::LDAP::Access.open { |access| yield(access) } end # JSON for infinite scroll via Pager object diff --git a/lib/gitlab/optimistic_locking.rb b/lib/gitlab/optimistic_locking.rb index 879d46446b3..76634ea0abf 100644 --- a/lib/gitlab/optimistic_locking.rb +++ b/lib/gitlab/optimistic_locking.rb @@ -6,7 +6,7 @@ module Gitlab loop do begin ActiveRecord::Base.transaction do - return block.call(subject) + return yield(subject) end rescue ActiveRecord::StaleObjectError retries -= 1 diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 3faa336f142..330dfd866cb 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -145,7 +145,7 @@ module Gitlab # batch_add_keys { |adder| adder.add_key("key-42", "sha-rsa ...") } def batch_add_keys(&block) IO.popen(%W(#{gitlab_shell_path}/bin/gitlab-keys batch-add-keys), 'w') do |io| - block.call(KeyAdder.new(io)) + yield(KeyAdder.new(io)) end end From ccbebbdfeb9ce78c0a386ae08ae88aeb7dc5ad86 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:16:48 -0600 Subject: [PATCH 209/247] Enable Performance/RedundantMatch --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 10 ---------- app/models/external_issue.rb | 2 +- lib/ci/api/helpers.rb | 2 +- lib/extracts_path.rb | 2 +- lib/gitlab/diff/highlight.rb | 2 +- lib/gitlab/diff/parser.rb | 2 +- 7 files changed, 8 insertions(+), 15 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9087b626bb9..3aae3a0261b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -926,6 +926,9 @@ Lint/UnusedBlockArgument: Performance/RedundantBlockCall: Enabled: true +Performance/RedundantMatch: + Enabled: true + Rails/HttpPositionalArguments: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index abd7be72b46..a7b89d3dba2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,16 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 5 -# Cop supports --auto-correct. -Performance/RedundantMatch: - Exclude: - - 'app/models/external_issue.rb' - - 'lib/ci/api/helpers.rb' - - 'lib/extracts_path.rb' - - 'lib/gitlab/diff/highlight.rb' - - 'lib/gitlab/diff/parser.rb' - # Offense count: 15 # Configuration parameters: CustomIncludeMethods. RSpec/EmptyExampleGroup: diff --git a/app/models/external_issue.rb b/app/models/external_issue.rb index 26712c19b5a..b973bbcd8da 100644 --- a/app/models/external_issue.rb +++ b/app/models/external_issue.rb @@ -43,7 +43,7 @@ class ExternalIssue end def reference_link_text(from_project = nil) - return "##{id}" if /^\d+$/.match(id) + return "##{id}" if id =~ /^\d+$/ id end diff --git a/lib/ci/api/helpers.rb b/lib/ci/api/helpers.rb index 654bddf7d18..a2e6387dbe5 100644 --- a/lib/ci/api/helpers.rb +++ b/lib/ci/api/helpers.rb @@ -60,7 +60,7 @@ module Ci end def build_not_found! - if headers['User-Agent'].to_s.match(/gitlab-ci-multi-runner \d+\.\d+\.\d+(~beta\.\d+\.g[0-9a-f]+)? /) + if headers['User-Agent'].to_s =~ /gitlab-ci-multi-runner \d+\.\d+\.\d+(~beta\.\d+\.g[0-9a-f]+)? / no_content! else not_found! diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index 82551f1f222..1a6ad039bc0 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -42,7 +42,7 @@ module ExtractsPath return pair unless @project - if id.match(/^([[:alnum:]]{40})(.+)/) + if id =~ /^([[:alnum:]]{40})(.+)/ # If the ref appears to be a SHA, we're done, just split the string pair = $~.captures else diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb index 9ea976e18fa..7db896522a9 100644 --- a/lib/gitlab/diff/highlight.rb +++ b/lib/gitlab/diff/highlight.rb @@ -50,7 +50,7 @@ module Gitlab # Only update text if line is found. This will prevent # issues with submodules given the line only exists in diff content. if rich_line - line_prefix = diff_line.text.match(/\A(.)/) ? $1 : ' ' + line_prefix = diff_line.text =~ /\A(.)/ ? $1 : ' ' "#{line_prefix}#{rich_line}".html_safe end end diff --git a/lib/gitlab/diff/parser.rb b/lib/gitlab/diff/parser.rb index 89320f5d9dc..8f844224a7a 100644 --- a/lib/gitlab/diff/parser.rb +++ b/lib/gitlab/diff/parser.rb @@ -20,7 +20,7 @@ module Gitlab full_line = line.delete("\n") - if line.match(/^@@ -/) + if line =~ /^@@ -/ type = "match" line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0 From b3c514eed9d1914fbeb63a616f70b657054d0531 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:33:39 -0600 Subject: [PATCH 210/247] Disable Rails/DynamicFindBy --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 3aae3a0261b..c10a46d344b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -929,6 +929,9 @@ Performance/RedundantBlockCall: Performance/RedundantMatch: Enabled: true +Rails/DynamicFindBy: + Enabled: false + Rails/HttpPositionalArguments: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a7b89d3dba2..f24c74547e8 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,13 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 126 -# Cop supports --auto-correct. -# Configuration parameters: Whitelist. -# Whitelist: find_by_sql -Rails/DynamicFindBy: - Enabled: false - # Cop supports --auto-correct. # Configuration parameters: Include. # Include: app/models/**/*.rb From 8df3eb6648a561e6f4695bbd78077a369aa4b48f Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:35:45 -0600 Subject: [PATCH 211/247] Disable Rails/OutputSafety --- .rubocop.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index c10a46d344b..c81e7eb37b6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -935,6 +935,9 @@ Rails/DynamicFindBy: Rails/HttpPositionalArguments: Enabled: false +Rails/OutputSafety: + Enabled: false + Rails/TimeZone: Enabled: false From 5cd9c7c6ea1ba5c6ad40799b9476145803dccba5 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:40:04 -0600 Subject: [PATCH 212/247] Enable Rails/Validation --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 17 ----------------- app/models/ci/build.rb | 2 +- app/models/ci/pipeline.rb | 6 +++--- app/models/ci/runner_project.rb | 2 +- app/models/ci/trigger.rb | 4 ++-- app/models/commit_status.rb | 2 +- app/models/members/group_member.rb | 2 +- app/models/members/project_member.rb | 2 +- app/models/pages_domain.rb | 2 +- app/models/project.rb | 4 ++-- app/models/protected_branch.rb | 4 ++-- app/models/user.rb | 2 +- 13 files changed, 19 insertions(+), 33 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index c81e7eb37b6..e0d65533bb5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -941,6 +941,9 @@ Rails/OutputSafety: Rails/TimeZone: Enabled: false +Rails/Validation: + Enabled: true + Style/AlignParameters: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f24c74547e8..37d05ac4509 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,23 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Cop supports --auto-correct. -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/Validation: - Exclude: - - 'app/models/ci/build.rb' - - 'app/models/ci/pipeline.rb' - - 'app/models/ci/runner_project.rb' - - 'app/models/ci/trigger.rb' - - 'app/models/commit_status.rb' - - 'app/models/members/group_member.rb' - - 'app/models/members/project_member.rb' - - 'app/models/pages_domain.rb' - - 'app/models/project.rb' - - 'app/models/protected_branch.rb' - - 'app/models/user.rb' - # Offense count: 8 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect. diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 9a45ef06750..f9592873ea0 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -23,7 +23,7 @@ module Ci serialize :yaml_variables, Gitlab::Serializer::Ci::Variables validates :coverage, numericality: true, allow_blank: true - validates_presence_of :ref + validates :ref, presence: true scope :unstarted, ->() { where(runner_id: nil) } scope :ignore_failures, ->() { where(allow_failure: false) } diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index ae4759ed2a0..673647f284a 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -14,9 +14,9 @@ module Ci has_many :builds, foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id - validates_presence_of :sha, unless: :importing? - validates_presence_of :ref, unless: :importing? - validates_presence_of :status, unless: :importing? + validates :sha, presence: { unless: :importing? } + validates :ref, presence: { unless: :importing? } + validates :status, presence: { unless: :importing? } validate :valid_commit_sha, unless: :importing? after_create :keep_around_commits, unless: :importing? diff --git a/app/models/ci/runner_project.rb b/app/models/ci/runner_project.rb index 1f9baeca5b1..234376a7e4c 100644 --- a/app/models/ci/runner_project.rb +++ b/app/models/ci/runner_project.rb @@ -5,6 +5,6 @@ module Ci belongs_to :runner belongs_to :project, foreign_key: :gl_project_id - validates_uniqueness_of :runner_id, scope: :gl_project_id + validates :runner_id, uniqueness: { scope: :gl_project_id } end end diff --git a/app/models/ci/trigger.rb b/app/models/ci/trigger.rb index 62889fe80d8..39a1dd86241 100644 --- a/app/models/ci/trigger.rb +++ b/app/models/ci/trigger.rb @@ -7,8 +7,8 @@ module Ci belongs_to :project, foreign_key: :gl_project_id has_many :trigger_requests, dependent: :destroy - validates_presence_of :token - validates_uniqueness_of :token + validates :token, presence: true + validates :token, uniqueness: true before_validation :set_default_values diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index d31a6d81ebd..ef5e6202519 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -13,7 +13,7 @@ class CommitStatus < ActiveRecord::Base validates :pipeline, presence: true, unless: :importing? - validates_presence_of :name + validates :name, presence: true alias_attribute :author, :user diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index 4043fde5301..446f9f8f8a7 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -5,7 +5,7 @@ class GroupMember < Member # Make sure group member points only to group as it source default_value_for :source_type, SOURCE_TYPE - validates_format_of :source_type, with: /\ANamespace\z/ + validates :source_type, format: { with: /\ANamespace\z/ } default_scope { where(source_type: SOURCE_TYPE) } def self.access_level_roles diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index 06f8fd39c99..912820b51ac 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -7,7 +7,7 @@ class ProjectMember < Member # Make sure project member points only to project as it source default_value_for :source_type, SOURCE_TYPE - validates_format_of :source_type, with: /\AProject\z/ + validates :source_type, format: { with: /\AProject\z/ } validates :access_level, inclusion: { in: Gitlab::Access.values } default_scope { where(source_type: SOURCE_TYPE) } diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb index 0b9ebf1ffe2..f2f2fc1e32a 100644 --- a/app/models/pages_domain.rb +++ b/app/models/pages_domain.rb @@ -2,7 +2,7 @@ class PagesDomain < ActiveRecord::Base belongs_to :project validates :domain, hostname: true - validates_uniqueness_of :domain, case_sensitive: false + validates :domain, uniqueness: { case_sensitive: false } validates :certificate, certificate: true, allow_nil: true, allow_blank: true validates :key, certificate_key: true, allow_nil: true, allow_blank: true diff --git a/app/models/project.rb b/app/models/project.rb index 3a1a724b987..0da21be8351 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -191,8 +191,8 @@ class Project < ActiveRecord::Base format: { with: Gitlab::Regex.project_path_regex, message: Gitlab::Regex.project_path_regex_message } validates :namespace, presence: true - validates_uniqueness_of :name, scope: :namespace_id - validates_uniqueness_of :path, scope: :namespace_id + validates :name, uniqueness: { scope: :namespace_id } + validates :path, uniqueness: { scope: :namespace_id } validates :import_url, addressable_url: true, if: :external_import? validates :star_count, numericality: { greater_than_or_equal_to: 0 } validate :check_limit, on: :create diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index 6240912a6e1..39e979ef15b 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -8,8 +8,8 @@ class ProtectedBranch < ActiveRecord::Base has_many :merge_access_levels, dependent: :destroy has_many :push_access_levels, dependent: :destroy - validates_length_of :merge_access_levels, is: 1, message: "are restricted to a single instance per protected branch." - validates_length_of :push_access_levels, is: 1, message: "are restricted to a single instance per protected branch." + validates :merge_access_levels, length: { is: 1, message: "are restricted to a single instance per protected branch." } + validates :push_access_levels, length: { is: 1, message: "are restricted to a single instance per protected branch." } accepts_nested_attributes_for :push_access_levels accepts_nested_attributes_for :merge_access_levels diff --git a/app/models/user.rb b/app/models/user.rb index f614eb66e1f..f37735c5eba 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -104,7 +104,7 @@ class User < ActiveRecord::Base # # Note: devise :validatable above adds validations for :email and :password validates :name, presence: true - validates_confirmation_of :email + validates :email, confirmation: true validates :notification_email, presence: true validates :notification_email, email: true, if: ->(user) { user.notification_email != user.email } validates :public_email, presence: true, uniqueness: true, email: true, allow_blank: true From d78513cb6ccfe10976cc433e2b421c30d06d19be Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:42:22 -0600 Subject: [PATCH 213/247] Enable Security/JSONLoad --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 12 ------------ ...1019190736_migrate_sidekiq_queues_from_default.rb | 2 +- ...1024042317_migrate_mailroom_queue_from_default.rb | 2 +- ...61124141322_migrate_process_commit_worker_jobs.rb | 4 ++-- .../migrate_process_commit_worker_jobs_spec.rb | 4 ++-- spec/models/project_services/irker_service_spec.rb | 2 +- spec/support/stub_gitlab_calls.rb | 2 +- 8 files changed, 11 insertions(+), 20 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e0d65533bb5..f48ad41243f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -944,6 +944,9 @@ Rails/TimeZone: Rails/Validation: Enabled: true +Security/JSONLoad: + Enabled: true + Style/AlignParameters: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 37d05ac4509..ec9bd29f4ca 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,18 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect. -Security/JSONLoad: - Exclude: - - 'db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb' - - 'db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb' - - 'db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb' - - 'spec/migrations/migrate_process_commit_worker_jobs_spec.rb' - - 'spec/models/project_services/irker_service_spec.rb' - - 'spec/support/stub_gitlab_calls.rb' - # Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb index 9730ebb8f8a..3a7acc84028 100644 --- a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb +++ b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb @@ -93,7 +93,7 @@ class MigrateSidekiqQueuesFromDefault < ActiveRecord::Migration def migrate_from_queue(redis, queue, job_mapping) while job = redis.lpop("queue:#{queue}") - payload = JSON.load(job) + payload = JSON.parse(job) new_queue = job_mapping[payload['class']] # If we have no target queue to migrate to we're probably dealing with diff --git a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb index 4167ccae39b..91d078f6293 100644 --- a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb +++ b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb @@ -47,7 +47,7 @@ class MigrateMailroomQueueFromDefault < ActiveRecord::Migration def migrate_from_queue(redis, queue, job_mapping) while job = redis.lpop("queue:#{queue}") - payload = JSON.load(job) + payload = JSON.parse(job) new_queue = job_mapping[payload['class']] # If we have no target queue to migrate to we're probably dealing with diff --git a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb index 633f57ef600..35697aab207 100644 --- a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb +++ b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb @@ -34,7 +34,7 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration new_jobs = [] while job = redis.lpop('queue:process_commit') - payload = JSON.load(job) + payload = JSON.parse(job) project = Project.find_including_path(payload['args'][0]) next unless project @@ -75,7 +75,7 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration new_jobs = [] while job = redis.lpop('queue:process_commit') - payload = JSON.load(job) + payload = JSON.parse(job) payload['args'][2] = payload['args'][2]['id'] diff --git a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb index 6a93deb5412..b6d678bac18 100644 --- a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb +++ b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb @@ -62,7 +62,7 @@ describe MigrateProcessCommitWorkerJobs do end def pop_job - JSON.load(Sidekiq.redis { |r| r.lpop('queue:process_commit') }) + JSON.parse(Sidekiq.redis { |r| r.lpop('queue:process_commit') }) end before do @@ -198,7 +198,7 @@ describe MigrateProcessCommitWorkerJobs do let(:job) do migration.down - JSON.load(Sidekiq.redis { |r| r.lpop('queue:process_commit') }) + JSON.parse(Sidekiq.redis { |r| r.lpop('queue:process_commit') }) end it 'includes the project ID' do diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb index b9fb6f3f6f4..dd5400f937b 100644 --- a/spec/models/project_services/irker_service_spec.rb +++ b/spec/models/project_services/irker_service_spec.rb @@ -59,7 +59,7 @@ describe IrkerService, models: true do conn = @irker_server.accept conn.readlines.each do |line| - msg = JSON.load(line.chomp("\n")) + msg = JSON.parse(line.chomp("\n")) expect(msg.keys).to match_array(['to', 'privmsg']) expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits", "irc://test.net/#test"]) diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 93f96cacc00..a01ef576234 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -35,7 +35,7 @@ module StubGitlabCalls { "tags" => tags } ) allow_any_instance_of(ContainerRegistry::Client).to receive(:repository_manifest).and_return( - JSON.load(File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest.json')) + JSON.parse(File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest.json')) ) allow_any_instance_of(ContainerRegistry::Client).to receive(:blob).and_return( File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json') From baafd8de26507ebd76177b5c65b5da921445ddc9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:47:39 -0600 Subject: [PATCH 214/247] Enable Style/BarePercentLiterals --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 7 ------- app/helpers/commits_helper.rb | 2 +- app/models/commit.rb | 2 +- ...0160610201627_migrate_users_notification_level.rb | 4 ++-- .../20160831214543_migrate_project_features.rb | 4 ++-- features/steps/project/badges/build.rb | 2 +- lib/banzai/filter/autolink_filter.rb | 2 +- lib/banzai/filter/reference_filter.rb | 4 ++-- lib/banzai/filter/table_of_contents_filter.rb | 6 +++--- lib/gitlab/database/median.rb | 4 ++-- spec/features/projects/badges/coverage_spec.rb | 2 +- spec/features/projects/issuable_templates_spec.rb | 2 +- spec/features/projects/pipelines/pipelines_spec.rb | 2 +- spec/helpers/blob_helper_spec.rb | 2 +- spec/helpers/gitlab_markdown_helper_spec.rb | 4 ++-- spec/lib/banzai/filter/external_link_filter_spec.rb | 6 +++--- .../lib/banzai/filter/label_reference_filter_spec.rb | 2 +- .../banzai/filter/milestone_reference_filter_spec.rb | 2 +- spec/lib/banzai/filter/user_reference_filter_spec.rb | 2 +- spec/lib/banzai/pipeline/full_pipeline_spec.rb | 2 +- spec/lib/gitlab/diff/highlight_spec.rb | 12 ++++++------ spec/lib/gitlab/gfm/reference_rewriter_spec.rb | 8 ++++---- spec/lib/gitlab/highlight_spec.rb | 6 +++--- spec/lib/gitlab/reference_extractor_spec.rb | 2 +- spec/lib/gitlab/url_sanitizer_spec.rb | 2 +- spec/models/project_label_spec.rb | 4 ++-- spec/models/project_services/bamboo_service_spec.rb | 4 ++-- .../project_services/buildkite_service_spec.rb | 4 ++-- .../models/project_services/drone_ci_service_spec.rb | 4 ++-- .../models/project_services/teamcity_service_spec.rb | 6 +++--- spec/workers/repository_import_worker_spec.rb | 2 +- 32 files changed, 59 insertions(+), 62 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index f48ad41243f..396a760da91 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -950,6 +950,10 @@ Security/JSONLoad: Style/AlignParameters: Enabled: false +Style/BarePercentLiterals: + Enabled: true + EnforcedStyle: bare_percent + Style/CaseEquality: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ec9bd29f4ca..12439d7bff6 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,13 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 55 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: percent_q, bare_percent -Style/BarePercentLiterals: - Enabled: false - # Offense count: 399 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 8aad39e148b..4e1fbc57575 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -155,7 +155,7 @@ module CommitsHelper text = if options[:avatar] - %Q{#{person_name}} + %{#{person_name}} else person_name end diff --git a/app/models/commit.rb b/app/models/commit.rb index ec759762977..20be3c9cba7 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -255,7 +255,7 @@ class Commit end def revert_message(user) - %Q{Revert "#{title.strip}"\n\n#{revert_description(user)}} + %{Revert "#{title.strip}"\n\n#{revert_description(user)}} end def reverts_commit?(commit, user) diff --git a/db/migrate/20160610201627_migrate_users_notification_level.rb b/db/migrate/20160610201627_migrate_users_notification_level.rb index 760b766828e..798e315102e 100644 --- a/db/migrate/20160610201627_migrate_users_notification_level.rb +++ b/db/migrate/20160610201627_migrate_users_notification_level.rb @@ -3,7 +3,7 @@ class MigrateUsersNotificationLevel < ActiveRecord::Migration # creating a new record on notification settings table def up - execute(%Q{ + execute(%{ INSERT INTO notification_settings (user_id, level, created_at, updated_at) (SELECT id, notification_level, created_at, updated_at FROM users WHERE notification_level != 1) @@ -13,7 +13,7 @@ class MigrateUsersNotificationLevel < ActiveRecord::Migration # Migrates from notification settings back to user notification_level # If no value is found the default level of 1 will be used def down - execute(%Q{ + execute(%{ UPDATE users u SET notification_level = COALESCE((SELECT level FROM notification_settings WHERE user_id = u.id AND source_type IS NULL), 1) }) diff --git a/db/migrate/20160831214543_migrate_project_features.rb b/db/migrate/20160831214543_migrate_project_features.rb index 79a5fb29d64..a2f2267773c 100644 --- a/db/migrate/20160831214543_migrate_project_features.rb +++ b/db/migrate/20160831214543_migrate_project_features.rb @@ -10,7 +10,7 @@ class MigrateProjectFeatures < ActiveRecord::Migration def up sql = - %Q{ + %{ INSERT INTO project_features(project_id, issues_access_level, merge_requests_access_level, wiki_access_level, builds_access_level, snippets_access_level, created_at, updated_at) SELECT @@ -29,7 +29,7 @@ class MigrateProjectFeatures < ActiveRecord::Migration end def down - sql = %Q{ + sql = %{ UPDATE projects SET issues_enabled = COALESCE((SELECT CASE WHEN issues_access_level = 20 THEN true ELSE false END AS issues_enabled FROM project_features WHERE project_features.project_id = projects.id), true), diff --git a/features/steps/project/badges/build.rb b/features/steps/project/badges/build.rb index 96c59322f9b..12a49779edb 100644 --- a/features/steps/project/badges/build.rb +++ b/features/steps/project/badges/build.rb @@ -27,6 +27,6 @@ class Spinach::Features::ProjectBadgesBuild < Spinach::FeatureSteps def expect_badge(status) svg = Nokogiri::XML.parse(page.body) expect(page.response_headers['Content-Type']).to include('image/svg+xml') - expect(svg.at(%Q{text:contains("#{status}")})).to be_truthy + expect(svg.at(%{text:contains("#{status}")})).to be_truthy end end diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index b8d2673c1a6..e84b7c2c0c3 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -32,7 +32,7 @@ module Banzai IGNORE_PARENTS = %w(a code kbd pre script style).to_set # The XPath query to use for finding text nodes to parse. - TEXT_QUERY = %Q(descendant-or-self::text()[ + TEXT_QUERY = %(descendant-or-self::text()[ not(#{IGNORE_PARENTS.map { |p| "ancestor::#{p}" }.join(' or ')}) and contains(., '://') and not(starts-with(., 'http')) diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb index 6640168bfa2..6281fa7e401 100644 --- a/lib/banzai/filter/reference_filter.rb +++ b/lib/banzai/filter/reference_filter.rb @@ -32,7 +32,7 @@ module Banzai attributes[:reference_type] ||= self.class.reference_type attributes.delete(:original) if context[:no_original_data] attributes.map do |key, value| - %Q(data-#{key.to_s.dasherize}="#{escape_once(value)}") + %(data-#{key.to_s.dasherize}="#{escape_once(value)}") end.join(' ') end @@ -76,7 +76,7 @@ module Banzai def each_node return to_enum(__method__) unless block_given? - query = %Q{descendant-or-self::text()[not(#{ignore_ancestor_query})] + query = %{descendant-or-self::text()[not(#{ignore_ancestor_query})] | descendant-or-self::a[ not(contains(concat(" ", @class, " "), " gfm ")) and not(@href = "") ]} diff --git a/lib/banzai/filter/table_of_contents_filter.rb b/lib/banzai/filter/table_of_contents_filter.rb index 8e7084f2543..d460110b974 100644 --- a/lib/banzai/filter/table_of_contents_filter.rb +++ b/lib/banzai/filter/table_of_contents_filter.rb @@ -43,7 +43,7 @@ module Banzai end end - result[:toc] = %Q{
    \n#{result[:toc]}
} unless result[:toc].empty? + result[:toc] = %{
    \n#{result[:toc]}
} unless result[:toc].empty? doc end @@ -51,11 +51,11 @@ module Banzai private def anchor_tag(id, href) - %Q{} + %{} end def push_toc(href, text) - result[:toc] << %Q{
  • #{text}
  • \n} + result[:toc] << %{
  • #{text}
  • \n} end end end diff --git a/lib/gitlab/database/median.rb b/lib/gitlab/database/median.rb index 08607c27c09..e46c551098d 100644 --- a/lib/gitlab/database/median.rb +++ b/lib/gitlab/database/median.rb @@ -100,13 +100,13 @@ module Gitlab end def extract_epoch(arel_attribute) - Arel.sql(%Q{EXTRACT(EPOCH FROM "#{arel_attribute.relation.name}"."#{arel_attribute.name}")}) + Arel.sql(%{EXTRACT(EPOCH FROM "#{arel_attribute.relation.name}"."#{arel_attribute.name}")}) end def extract_diff_epoch(diff) return diff unless Gitlab::Database.postgresql? - Arel.sql(%Q{EXTRACT(EPOCH FROM (#{diff.to_sql}))}) + Arel.sql(%{EXTRACT(EPOCH FROM (#{diff.to_sql}))}) end # Need to cast '0' to an INTERVAL before we can check if the interval is positive def zero_interval diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb index 01a95bf49ac..1fefcb916f6 100644 --- a/spec/features/projects/badges/coverage_spec.rb +++ b/spec/features/projects/badges/coverage_spec.rb @@ -77,6 +77,6 @@ feature 'test coverage badge' do def expect_coverage_badge(coverage) svg = Nokogiri::XML.parse(page.body) expect(page.response_headers['Content-Type']).to include('image/svg+xml') - expect(svg.at(%Q{text:contains("#{coverage}")})).to be_truthy + expect(svg.at(%{text:contains("#{coverage}")})).to be_truthy end end diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb index e90a033b8c4..3fe5a6ec818 100644 --- a/spec/features/projects/issuable_templates_spec.rb +++ b/spec/features/projects/issuable_templates_spec.rb @@ -13,7 +13,7 @@ feature 'issuable templates', feature: true, js: true do context 'user creates an issue using templates' do let(:template_content) { 'this is a test "bug" template' } - let(:longtemplate_content) { %Q(this\n\n\n\n\nis\n\n\n\n\na\n\n\n\n\nbug\n\n\n\n\ntemplate) } + let(:longtemplate_content) { %(this\n\n\n\n\nis\n\n\n\n\na\n\n\n\n\nbug\n\n\n\n\ntemplate) } let(:issue) { create(:issue, author: user, assignee: user, project: project) } let(:description_addition) { ' appending to description' } diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 81f5ebf6339..845490badd4 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -154,7 +154,7 @@ describe 'Pipelines', :feature, :js do it 'contains badge with tooltip which contains error' do expect(pipeline).to have_yaml_errors expect(page).to have_selector( - %Q{span[data-original-title="#{pipeline.yaml_errors}"]}) + %{span[data-original-title="#{pipeline.yaml_errors}"]}) end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index fa516f9903e..3e1b29dde75 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -23,7 +23,7 @@ describe BlobHelper do end it 'highlights single block' do - expected = %Q[
    (make-pathname :defaults name
    +      expected = %[
    (make-pathname :defaults name
     :type "assem"))
    ] expect(helper.highlight(blob_name, blob_content)).to eq(expected) diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index b8ec3521edb..520b6afddc3 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -107,13 +107,13 @@ describe GitlabMarkdownHelper do it 'ignores reference links when they are the entire body' do text = issues[0].to_reference act = helper.link_to_gfm(text, '/foo') - expect(act).to eq %Q(#{issues[0].to_reference}) + expect(act).to eq %(#{issues[0].to_reference}) end it 'replaces commit message with emoji to link' do actual = link_to_gfm(':book:Book', '/foo') expect(actual). - to eq %Q(:book:Book) + to eq %(:book:Book) end end diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb index d9e4525cb28..5ffbab0f12f 100644 --- a/spec/lib/banzai/filter/external_link_filter_spec.rb +++ b/spec/lib/banzai/filter/external_link_filter_spec.rb @@ -15,7 +15,7 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do it 'skips internal links' do internal = Gitlab.config.gitlab.url - exp = act = %Q(Login) + exp = act = %(Login) expect(filter(act).to_html).to eq exp end @@ -70,8 +70,8 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do it 'skips internal links' do internal_link = Gitlab.config.gitlab.url + "/sign_in" url = internal_link.gsub(/\Ahttp/, 'HtTp') - act = %Q(Login) - exp = %Q(Login) + act = %(Login) + exp = %(Login) expect(filter(act).to_html).to eq(exp) end diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index 5e16fd10ebe..e72d9935bd4 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -282,7 +282,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do end describe 'referencing a label in a link href' do - let(:reference) { %Q{Label} } + let(:reference) { %{Label} } it 'links to a valid reference' do doc = reference_filter("See #{reference}") diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index a317c751d32..cd94729b442 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -117,7 +117,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do end describe 'referencing a milestone in a link href' do - let(:reference) { %Q{Milestone} } + let(:reference) { %{Milestone} } it 'links to a valid reference' do doc = reference_filter("See #{reference}") diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index e9b7b566806..6afeee4d76d 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -144,7 +144,7 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do end context 'referencing a user in a link href' do - let(:reference) { %Q{User} } + let(:reference) { %{User} } it 'links to a User' do doc = reference_filter("Hey #{reference}") diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb index 2501b638774..c24a0e4d2b6 100644 --- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb @@ -20,7 +20,7 @@ describe Banzai::Pipeline::FullPipeline do end it 'escapes the data-original attribute on a reference' do - markdown = %Q{[">bad things](#{issue.to_reference})} + markdown = %{[">bad things](#{issue.to_reference})} result = described_class.to_html(markdown, project: project) expect(result).to include(%{data-original='\">bad things'}) end diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb index 5893485634d..1cb6f66ced5 100644 --- a/spec/lib/gitlab/diff/highlight_spec.rb +++ b/spec/lib/gitlab/diff/highlight_spec.rb @@ -22,19 +22,19 @@ describe Gitlab::Diff::Highlight, lib: true do end it 'highlights and marks unchanged lines' do - code = %Q{ def popen(cmd, path=nil)\n} + code = %{ def popen(cmd, path=nil)\n} expect(subject[2].text).to eq(code) end it 'highlights and marks removed lines' do - code = %Q{- raise "System commands must be given as an array of strings"\n} + code = %{- raise "System commands must be given as an array of strings"\n} expect(subject[4].text).to eq(code) end it 'highlights and marks added lines' do - code = %Q{+ raise RuntimeError, "System commands must be given as an array of strings"\n} + code = %{+ raise RuntimeError, "System commands must be given as an array of strings"\n} expect(subject[5].text).to eq(code) end @@ -53,21 +53,21 @@ describe Gitlab::Diff::Highlight, lib: true do end it 'marks unchanged lines' do - code = %Q{ def popen(cmd, path=nil)} + code = %{ def popen(cmd, path=nil)} expect(subject[2].text).to eq(code) expect(subject[2].text).not_to be_html_safe end it 'marks removed lines' do - code = %Q{- raise "System commands must be given as an array of strings"} + code = %{- raise "System commands must be given as an array of strings"} expect(subject[4].text).to eq(code) expect(subject[4].text).not_to be_html_safe end it 'marks added lines' do - code = %Q{+ raise RuntimeError, "System commands must be given as an array of strings"} + code = %{+ raise RuntimeError, "System commands must be given as an array of strings"} expect(subject[5].text).to eq(code) expect(subject[5].text).to be_html_safe diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb index 5d416c9eec3..8625dd7b711 100644 --- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb @@ -68,12 +68,12 @@ describe Gitlab::Gfm::ReferenceRewriter do context 'label referenced by id' do let(:text) { '#1 and ~123' } - it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~123} } + it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~123} } end context 'label referenced by text' do let(:text) { '#1 and ~"test"' } - it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~123} } + it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~123} } end end @@ -88,12 +88,12 @@ describe Gitlab::Gfm::ReferenceRewriter do context 'label referenced by id' do let(:text) { '#1 and ~321' } - it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~321} } + it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~321} } end context 'label referenced by text' do let(:text) { '#1 and ~"group label"' } - it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~321} } + it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~321} } end end end diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb index e177d883158..fc2733691be 100644 --- a/spec/lib/gitlab/highlight_spec.rb +++ b/spec/lib/gitlab/highlight_spec.rb @@ -13,9 +13,9 @@ describe Gitlab::Highlight, lib: true do end it 'highlights all the lines properly' do - expect(lines[4]).to eq(%Q{ extend self\n}) - expect(lines[21]).to eq(%Q{ unless File.directory?(path)\n}) - expect(lines[26]).to eq(%Q{ @cmd_status = 0\n}) + expect(lines[4]).to eq(%{ extend self\n}) + expect(lines[21]).to eq(%{ unless File.directory?(path)\n}) + expect(lines[26]).to eq(%{ @cmd_status = 0\n}) end describe 'with CRLF' do diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 84cfd934fa0..0a2cab6888d 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -29,7 +29,7 @@ describe Gitlab::ReferenceExtractor, lib: true do project.team << [@u_foo, :reporter] project.team << [@u_bar, :guest] - subject.analyze(%Q{ + subject.analyze(%{ Inline code: `@foo` Code block: diff --git a/spec/lib/gitlab/url_sanitizer_spec.rb b/spec/lib/gitlab/url_sanitizer_spec.rb index 2cb74629da8..f3533947c1c 100644 --- a/spec/lib/gitlab/url_sanitizer_spec.rb +++ b/spec/lib/gitlab/url_sanitizer_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::UrlSanitizer, lib: true do describe '.sanitize' do def sanitize_url(url) # We want to try with multi-line content because is how error messages are formatted - described_class.sanitize(%Q{ + described_class.sanitize(%{ remote: Not Found fatal: repository '#{url}' not found }) diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb index 3e9dd3758ed..5bfa9fffba9 100644 --- a/spec/models/project_label_spec.rb +++ b/spec/models/project_label_spec.rb @@ -105,14 +105,14 @@ describe ProjectLabel, models: true do context 'using name' do it 'returns cross reference with label name' do expect(label.to_reference(project, format: :name)). - to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") + to eq %(#{label.project.path_with_namespace}~"#{label.name}") end end context 'using id' do it 'returns cross reference with label id' do expect(label.to_reference(project, format: :id)). - to eq %Q(#{label.project.path_with_namespace}~#{label.id}) + to eq %(#{label.project.path_with_namespace}~#{label.id}) end end end diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb index 497a626a418..e30b62ddb61 100644 --- a/spec/models/project_services/bamboo_service_spec.rb +++ b/spec/models/project_services/bamboo_service_spec.rb @@ -181,7 +181,7 @@ describe BambooService, models: true, caching: true do end it 'sets commit status to "pending" when response has no results' do - stub_request(body: %Q({"results":{"results":{"size":"0"}}})) + stub_request(body: %({"results":{"results":{"size":"0"}}})) is_expected.to eq('pending') end @@ -223,6 +223,6 @@ describe BambooService, models: true, caching: true do end def bamboo_response(result_key: 42, build_state: 'success', size: 1) - %Q({"results":{"results":{"size":"#{size}","result":{"buildState":"#{build_state}","planResultKey":{"key":"#{result_key}"}}}}}) + %({"results":{"results":{"size":"#{size}","result":{"buildState":"#{build_state}","planResultKey":{"key":"#{result_key}"}}}}}) end end diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb index dbd23ff5491..59c04c32cf0 100644 --- a/spec/models/project_services/buildkite_service_spec.rb +++ b/spec/models/project_services/buildkite_service_spec.rb @@ -92,7 +92,7 @@ describe BuildkiteService, models: true, caching: true do end it 'passes through build status untouched when status is 200' do - stub_request(body: %Q({"status":"Great Success"})) + stub_request(body: %({"status":"Great Success"})) is_expected.to eq('Great Success') end @@ -101,7 +101,7 @@ describe BuildkiteService, models: true, caching: true do end def stub_request(status: 200, body: nil) - body ||= %Q({"status":"success"}) + body ||= %({"status":"success"}) buildkite_full_url = 'https://gitlab.buildkite.com/status/secret-sauce-status-token.json?commit=123' WebMock.stub_request(:get, buildkite_full_url).to_return( diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb index f9307d6de7b..3b5b215513d 100644 --- a/spec/models/project_services/drone_ci_service_spec.rb +++ b/spec/models/project_services/drone_ci_service_spec.rb @@ -50,7 +50,7 @@ describe DroneCiService, models: true, caching: true do end def stub_request(status: 200, body: nil) - body ||= %Q({"status":"success"}) + body ||= %({"status":"success"}) WebMock.stub_request(:get, commit_status_path).to_return( status: status, @@ -102,7 +102,7 @@ describe DroneCiService, models: true, caching: true do }.each do |drone_status, our_status| it "sets commit status to #{our_status.inspect} when returned status is #{drone_status.inspect}" do - stub_request(body: %Q({"status":"#{drone_status}"})) + stub_request(body: %({"status":"#{drone_status}"})) is_expected.to eq(our_status) end diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb index a1edd083aa1..2b76897e4eb 100644 --- a/spec/models/project_services/teamcity_service_spec.rb +++ b/spec/models/project_services/teamcity_service_spec.rb @@ -143,7 +143,7 @@ describe TeamcityService, models: true, caching: true do end it 'returns a build URL when teamcity_url has no trailing slash' do - stub_request(body: %Q({"build":{"id":"666"}})) + stub_request(body: %({"build":{"id":"666"}})) is_expected.to eq('http://gitlab.com/teamcity/viewLog.html?buildId=666&buildTypeId=foo') end @@ -152,7 +152,7 @@ describe TeamcityService, models: true, caching: true do let(:teamcity_url) { 'http://gitlab.com/teamcity/' } it 'returns a build URL' do - stub_request(body: %Q({"build":{"id":"666"}})) + stub_request(body: %({"build":{"id":"666"}})) is_expected.to eq('http://gitlab.com/teamcity/viewLog.html?buildId=666&buildTypeId=foo') end @@ -202,7 +202,7 @@ describe TeamcityService, models: true, caching: true do def stub_request(status: 200, body: nil, build_status: 'success') teamcity_full_url = 'http://mic:password@gitlab.com/teamcity/httpAuth/app/rest/builds/branch:unspecified:any,number:123' - body ||= %Q({"build":{"status":"#{build_status}","id":"666"}}) + body ||= %({"build":{"status":"#{build_status}","id":"666"}}) WebMock.stub_request(:get, teamcity_full_url).to_return( status: status, diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb index f1b1574abf4..9b0e6635844 100644 --- a/spec/workers/repository_import_worker_spec.rb +++ b/spec/workers/repository_import_worker_spec.rb @@ -20,7 +20,7 @@ describe RepositoryImportWorker do context 'when the import has failed' do it 'hide the credentials that were used in the import URL' do - error = %Q{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found } + error = %{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found } expect_any_instance_of(Projects::ImportService).to receive(:execute). and_return({ status: :error, message: error }) From b2da4623089e4c7c53526436bd7c0a8f516910a3 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:50:26 -0600 Subject: [PATCH 215/247] Disable Style/BracesAroundHashParameters --- .rubocop.yml | 4 +++- .rubocop_todo.yml | 7 ------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 396a760da91..219dcf0375d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -952,7 +952,9 @@ Style/AlignParameters: Style/BarePercentLiterals: Enabled: true - EnforcedStyle: bare_percent + +Style/BracesAroundHashParameters: + Enabled: false Style/CaseEquality: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 12439d7bff6..92c0934b05b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,13 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 399 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: braces, no_braces, context_dependent -Style/BracesAroundHashParameters: - Enabled: false - # Offense count: 33 # Cop supports --auto-correct. Style/ColonMethodCall: From 7ea641b6d0882fc782a7eb493daf8b66d076924b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 18:51:36 -0600 Subject: [PATCH 216/247] Enable Style/ColonMethodCall --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 5 ----- app/controllers/profiles/two_factor_auths_controller.rb | 2 +- app/models/commit.rb | 2 +- app/models/project_services/drone_ci_service.rb | 4 ++-- app/models/repository.rb | 2 +- app/services/projects/download_service.rb | 2 +- app/workers/irker_worker.rb | 6 +++--- lib/api/notes.rb | 2 +- lib/bitbucket/representation/repo.rb | 2 +- lib/gitlab/gon_helper.rb | 2 +- lib/gitlab/shell.rb | 2 +- spec/features/atom/dashboard_issues_spec.rb | 2 +- spec/features/atom/issues_spec.rb | 4 ++-- spec/features/dashboard_issues_spec.rb | 4 ++-- spec/features/projects/import_export/export_file_spec.rb | 2 +- spec/features/projects/import_export/import_file_spec.rb | 2 +- .../projects/import_export/namespace_export_file_spec.rb | 2 +- spec/lib/gitlab/git/blob_spec.rb | 2 +- spec/lib/gitlab/git_spec.rb | 6 +++--- spec/lib/gitlab/import_export/avatar_saver_spec.rb | 2 +- spec/lib/gitlab/import_export/file_importer_spec.rb | 2 +- spec/lib/gitlab/import_export/project_tree_saver_spec.rb | 2 +- spec/lib/gitlab/import_export/repo_bundler_spec.rb | 2 +- spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb | 2 +- spec/lib/gitlab/kubernetes_spec.rb | 2 +- spec/workers/git_garbage_collect_worker_spec.rb | 4 ++-- 27 files changed, 36 insertions(+), 38 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 219dcf0375d..1b2e3010ea0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -959,6 +959,9 @@ Style/BracesAroundHashParameters: Style/CaseEquality: Enabled: false +Style/ColonMethodCall: + Enabled: true + Style/CommentAnnotation: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 92c0934b05b..72930fa51c1 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,11 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 33 -# Cop supports --auto-correct. -Style/ColonMethodCall: - Enabled: false - # Offense count: 32 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 18044ca78e2..26e7e93533e 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -80,7 +80,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController def build_qr_code uri = current_user.otp_provisioning_uri(account_string, issuer: issuer_host) - RQRCode::render_qrcode(uri, :svg, level: :m, unit: 3) + RQRCode.render_qrcode(uri, :svg, level: :m, unit: 3) end def account_string diff --git a/app/models/commit.rb b/app/models/commit.rb index 20be3c9cba7..7afc8f4add8 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -105,7 +105,7 @@ class Commit end def diff_line_count - @diff_line_count ||= Commit::diff_line_count(raw_diffs) + @diff_line_count ||= Commit.diff_line_count(raw_diffs) @diff_line_count end diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb index 1ad9efac196..cd55194e291 100644 --- a/app/models/project_services/drone_ci_service.rb +++ b/app/models/project_services/drone_ci_service.rb @@ -39,7 +39,7 @@ class DroneCiService < CiService def commit_status_path(sha, ref) url = [drone_url, "gitlab/#{project.full_path}/commits/#{sha}", - "?branch=#{URI::encode(ref.to_s)}&access_token=#{token}"] + "?branch=#{URI.encode(ref.to_s)}&access_token=#{token}"] URI.join(*url).to_s end @@ -74,7 +74,7 @@ class DroneCiService < CiService def build_page(sha, ref) url = [drone_url, "gitlab/#{project.full_path}/redirect/commits/#{sha}", - "?branch=#{URI::encode(ref.to_s)}"] + "?branch=#{URI.encode(ref.to_s)}"] URI.join(*url).to_s end diff --git a/app/models/repository.rb b/app/models/repository.rb index e2a4f458c50..32252957a84 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -892,7 +892,7 @@ class Repository def get_committer_and_author(user, email: nil, name: nil) committer = user_to_committer(user) - author = Gitlab::Git::committer_hash(email: email, name: name) || committer + author = Gitlab::Git.committer_hash(email: email, name: name) || committer { author: author, diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb index 4e95653417b..3948df955ed 100644 --- a/app/services/projects/download_service.rb +++ b/app/services/projects/download_service.rb @@ -25,7 +25,7 @@ module Projects end def http?(url) - url =~ /\A#{URI::regexp(['http', 'https'])}\z/ + url =~ /\A#{URI.regexp(['http', 'https'])}\z/ end def valid_domain?(url) diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb index 7e44b241743..c9658b3fe17 100644 --- a/app/workers/irker_worker.rb +++ b/app/workers/irker_worker.rb @@ -120,8 +120,8 @@ class IrkerWorker end def compare_url(data, repo_path) - sha1 = Commit::truncate_sha(data['before']) - sha2 = Commit::truncate_sha(data['after']) + sha1 = Commit.truncate_sha(data['before']) + sha2 = Commit.truncate_sha(data['after']) compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/compare" compare_url += "/#{sha1}...#{sha2}" colorize_url compare_url @@ -129,7 +129,7 @@ class IrkerWorker def send_one_commit(project, hook_attrs, repo_name, branch) commit = commit_from_id project, hook_attrs['id'] - sha = colorize_sha Commit::truncate_sha(hook_attrs['id']) + sha = colorize_sha Commit.truncate_sha(hook_attrs['id']) author = hook_attrs['author']['name'] files = colorize_nb_files(files_count commit) title = commit.title diff --git a/lib/api/notes.rb b/lib/api/notes.rb index c680b77f3d9..f559a7f74a0 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -85,7 +85,7 @@ module API note = ::Notes::CreateService.new(user_project, current_user, opts).execute if note.valid? - present note, with: Entities::const_get(note.class.name) + present note, with: Entities.const_get(note.class.name) else not_found!("Note #{note.errors.messages}") end diff --git a/lib/bitbucket/representation/repo.rb b/lib/bitbucket/representation/repo.rb index 423eff8f2a5..59b0fda8e14 100644 --- a/lib/bitbucket/representation/repo.rb +++ b/lib/bitbucket/representation/repo.rb @@ -23,7 +23,7 @@ module Bitbucket url = raw['links']['clone'].find { |link| link['name'] == 'https' }.fetch('href') if token.present? - clone_url = URI::parse(url) + clone_url = URI.parse(url) clone_url.user = "x-token-auth:#{token}" clone_url.to_s else diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb index b8a5ac907a4..101b1b80c1e 100644 --- a/lib/gitlab/gon_helper.rb +++ b/lib/gitlab/gon_helper.rb @@ -2,7 +2,7 @@ module Gitlab module GonHelper def add_gon_variables gon.api_version = API::API.version - gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s + gon.default_avatar_url = URI.join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s gon.max_file_size = current_application_settings.max_attachment_size gon.relative_url_root = Gitlab.config.gitlab.relative_url_root gon.shortcuts_path = help_page_path('shortcuts') diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 330dfd866cb..3be8d3aec9c 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -82,7 +82,7 @@ module Gitlab def import_repository(storage, name, url) # Timeout should be less than 900 ideally, to prevent the memory killer # to silently kill the process without knowing we are timing out here. - output, status = Popen::popen([gitlab_shell_projects_path, 'import-project', + output, status = Popen.popen([gitlab_shell_projects_path, 'import-project', storage, "#{name}.git", url, '800']) raise Error, output unless status.zero? true diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb index 21ee6cedbae..a7c22615b89 100644 --- a/spec/features/atom/dashboard_issues_spec.rb +++ b/spec/features/atom/dashboard_issues_spec.rb @@ -23,7 +23,7 @@ describe "Dashboard Issues Feed", feature: true do visit issues_dashboard_path(:atom, private_token: user.private_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') - params = CGI::parse(URI.parse(link[:href]).query) + params = CGI.parse(URI.parse(link[:href]).query) expect(params).to include('private_token' => [user.private_token]) expect(params).to include('state' => ['opened']) diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index 863412d18eb..a01a050a013 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -43,7 +43,7 @@ describe 'Issues Feed', feature: true do :atom, private_token: user.private_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') - params = CGI::parse(URI.parse(link[:href]).query) + params = CGI.parse(URI.parse(link[:href]).query) expect(params).to include('private_token' => [user.private_token]) expect(params).to include('state' => ['opened']) @@ -54,7 +54,7 @@ describe 'Issues Feed', feature: true do visit issues_group_path(group, :atom, private_token: user.private_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') - params = CGI::parse(URI.parse(link[:href]).query) + params = CGI.parse(URI.parse(link[:href]).query) expect(params).to include('private_token' => [user.private_token]) expect(params).to include('state' => ['opened']) diff --git a/spec/features/dashboard_issues_spec.rb b/spec/features/dashboard_issues_spec.rb index b898f9bc64f..aa75e1140f6 100644 --- a/spec/features/dashboard_issues_spec.rb +++ b/spec/features/dashboard_issues_spec.rb @@ -49,9 +49,9 @@ describe "Dashboard Issues filtering", feature: true, js: true do visit_issues(milestone_title: '', assignee_id: user.id) link = find('.nav-controls a', text: 'Subscribe') - params = CGI::parse(URI.parse(link[:href]).query) + params = CGI.parse(URI.parse(link[:href]).query) auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) - auto_discovery_params = CGI::parse(URI.parse(auto_discovery_link[:href]).query) + auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) expect(params).to include('private_token' => [user.private_token]) expect(params).to include('milestone_title' => ['']) diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 16dddb2a86b..40caf89dd54 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -9,7 +9,7 @@ feature 'Import/Export - project export integration test', feature: true, js: tr include ExportFileHelper let(:user) { create(:admin) } - let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } + let(:export_path) { "#{Dir.tmpdir}/import_file_spec" } let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } let(:sensitive_words) { %w[pass secret token key] } diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 3015576f6f8..2d1106ea3e8 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -4,7 +4,7 @@ feature 'Import/Export - project import integration test', feature: true, js: tr include Select2Helper let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') } - let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } + let(:export_path) { "#{Dir.tmpdir}/import_file_spec" } background do allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) diff --git a/spec/features/projects/import_export/namespace_export_file_spec.rb b/spec/features/projects/import_export/namespace_export_file_spec.rb index d0bafc6168c..cb399ea55df 100644 --- a/spec/features/projects/import_export/namespace_export_file_spec.rb +++ b/spec/features/projects/import_export/namespace_export_file_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' feature 'Import/Export - Namespace export file cleanup', feature: true, js: true do - let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } + let(:export_path) { "#{Dir.tmpdir}/import_file_spec" } let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } let(:project) { create(:empty_project) } diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb index 84f79ec2391..0c321f0343c 100644 --- a/spec/lib/gitlab/git/blob_spec.rb +++ b/spec/lib/gitlab/git/blob_spec.rb @@ -292,7 +292,7 @@ describe Gitlab::Git::Blob, seed_helper: true do it 'should preserve file modes with commit' do commit_options[:file][:path] = 'files/executables/ls' - entry = Gitlab::Git::Blob::find_entry_by_path(repository, commit.tree.oid, commit_options[:file][:path]) + entry = Gitlab::Git::Blob.find_entry_by_path(repository, commit.tree.oid, commit_options[:file][:path]) expect(entry[:filemode]).to eq(0100755) end end diff --git a/spec/lib/gitlab/git_spec.rb b/spec/lib/gitlab/git_spec.rb index 219198eff60..8eaf7aac264 100644 --- a/spec/lib/gitlab/git_spec.rb +++ b/spec/lib/gitlab/git_spec.rb @@ -19,7 +19,7 @@ describe Gitlab::Git, lib: true do describe 'committer_hash' do it "returns a hash containing the given email and name" do - committer_hash = Gitlab::Git::committer_hash(email: committer_email, name: committer_name) + committer_hash = Gitlab::Git.committer_hash(email: committer_email, name: committer_name) expect(committer_hash[:email]).to eq(committer_email) expect(committer_hash[:name]).to eq(committer_name) @@ -28,7 +28,7 @@ describe Gitlab::Git, lib: true do context 'when email is nil' do it "returns nil" do - committer_hash = Gitlab::Git::committer_hash(email: nil, name: committer_name) + committer_hash = Gitlab::Git.committer_hash(email: nil, name: committer_name) expect(committer_hash).to be_nil end @@ -36,7 +36,7 @@ describe Gitlab::Git, lib: true do context 'when name is nil' do it "returns nil" do - committer_hash = Gitlab::Git::committer_hash(email: committer_email, name: nil) + committer_hash = Gitlab::Git.committer_hash(email: committer_email, name: nil) expect(committer_hash).to be_nil end diff --git a/spec/lib/gitlab/import_export/avatar_saver_spec.rb b/spec/lib/gitlab/import_export/avatar_saver_spec.rb index d6ee94442cb..579a31ead58 100644 --- a/spec/lib/gitlab/import_export/avatar_saver_spec.rb +++ b/spec/lib/gitlab/import_export/avatar_saver_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::ImportExport::AvatarSaver, lib: true do let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: 'test') } - let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" } let(:project_with_avatar) { create(:empty_project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) } let(:project) { create(:empty_project) } diff --git a/spec/lib/gitlab/import_export/file_importer_spec.rb b/spec/lib/gitlab/import_export/file_importer_spec.rb index a88ddd17aca..b88b9c18c15 100644 --- a/spec/lib/gitlab/import_export/file_importer_spec.rb +++ b/spec/lib/gitlab/import_export/file_importer_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::ImportExport::FileImporter, lib: true do let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: 'test') } - let(:export_path) { "#{Dir::tmpdir}/file_importer_spec" } + let(:export_path) { "#{Dir.tmpdir}/file_importer_spec" } let(:valid_file) { "#{shared.export_path}/valid.json" } let(:symlink_file) { "#{shared.export_path}/invalid.json" } let(:subfolder_symlink_file) { "#{shared.export_path}/subfolder/invalid.json" } diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb index 3628adefc0c..8579239f225 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do describe 'saves the project tree into a json object' do let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared) } - let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" } let(:user) { create(:user) } let(:project) { setup_project } diff --git a/spec/lib/gitlab/import_export/repo_bundler_spec.rb b/spec/lib/gitlab/import_export/repo_bundler_spec.rb index d39ea60ff7f..a7f4e11271e 100644 --- a/spec/lib/gitlab/import_export/repo_bundler_spec.rb +++ b/spec/lib/gitlab/import_export/repo_bundler_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::ImportExport::RepoSaver, services: true do describe 'bundle a project Git repo' do let(:user) { create(:user) } let!(:project) { create(:empty_project, :public, name: 'searchable_project') } - let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" } let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } let(:bundler) { described_class.new(project: project, shared: shared) } diff --git a/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb b/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb index 47d5d2fc150..071e5fac3f0 100644 --- a/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb +++ b/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::ImportExport::WikiRepoSaver, services: true do describe 'bundle a wiki Git repo' do let(:user) { create(:user) } let!(:project) { create(:empty_project, :public, name: 'searchable_project') } - let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" } let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } let(:wiki_bundler) { described_class.new(project: project, shared: shared) } let!(:project_wiki) { ProjectWiki.new(project, user) } diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb index c9bd52a3b8f..91f9d06b85a 100644 --- a/spec/lib/gitlab/kubernetes_spec.rb +++ b/spec/lib/gitlab/kubernetes_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::Kubernetes do let(:pod_name) { 'pod1' } let(:container_name) { 'container1' } - subject(:result) { URI::parse(container_exec_url(api_url, namespace, pod_name, container_name)) } + subject(:result) { URI.parse(container_exec_url(api_url, namespace, pod_name, container_name)) } it { expect(result.scheme).to eq('wss') } it { expect(result.host).to eq('example.com') } diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb index 5ef8cf1105b..a60af574a08 100644 --- a/spec/workers/git_garbage_collect_worker_spec.rb +++ b/spec/workers/git_garbage_collect_worker_spec.rb @@ -102,8 +102,8 @@ describe GitGarbageCollectWorker do new_commit_sha = Rugged::Commit.create( rugged, message: "hello world #{SecureRandom.hex(6)}", - author: Gitlab::Git::committer_hash(email: 'foo@bar', name: 'baz'), - committer: Gitlab::Git::committer_hash(email: 'foo@bar', name: 'baz'), + author: Gitlab::Git.committer_hash(email: 'foo@bar', name: 'baz'), + committer: Gitlab::Git.committer_hash(email: 'foo@bar', name: 'baz'), tree: old_commit.tree, parents: [old_commit], ) From 8a4d68c53e9c58ad7f8dce1494f7976292b2f929 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 21 Feb 2017 19:02:23 -0600 Subject: [PATCH 217/247] Enable Style/ConditionalAssignment --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 7 ------- app/controllers/concerns/creates_commit.rb | 6 +++--- .../projects/git_http_client_controller.rb | 6 +++--- .../projects/merge_requests_controller.rb | 6 +++--- app/controllers/sessions_controller.rb | 6 +++--- app/finders/notes_finder.rb | 6 +++--- app/helpers/application_helper.rb | 6 +++--- app/helpers/blob_helper.rb | 6 +++--- app/mailers/repository_check_mailer.rb | 6 +++--- app/models/commit.rb | 6 +++--- app/models/concerns/case_sensitivity.rb | 6 +++--- app/models/concerns/sortable.rb | 6 +++--- app/models/network/graph.rb | 6 +++--- app/models/project.rb | 6 +++--- app/models/project_services/pushover_service.rb | 8 ++++---- app/services/system_note_service.rb | 6 +++--- config/initializers/1_settings.rb | 12 ++++++------ lib/banzai/filter/abstract_reference_filter.rb | 6 +++--- lib/banzai/filter/gollum_tags_filter.rb | 6 +++--- lib/banzai/filter/issue_reference_filter.rb | 6 +++--- lib/gitlab/award_emoji.rb | 6 +++--- lib/gitlab/conflict/file.rb | 6 +++--- lib/gitlab/diff/position.rb | 6 +++--- lib/gitlab/email/reply_parser.rb | 6 +++--- lib/gitlab/metrics/instrumentation.rb | 6 +++--- lib/gitlab/saml/user.rb | 6 +++--- lib/gitlab/search_results.rb | 12 ++++++------ lib/gitlab/sherlock/query.rb | 6 +++--- spec/features/issuables/issuable_list_spec.rb | 6 +++--- .../issuables_list_metadata_shared_examples.rb | 6 +++--- spec/support/login_helpers.rb | 6 +++--- 32 files changed, 100 insertions(+), 104 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1b2e3010ea0..70e11be29cf 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -965,5 +965,8 @@ Style/ColonMethodCall: Style/CommentAnnotation: Enabled: false +Style/ConditionalAssignment: + Enabled: true + Style/DoubleNegation: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 72930fa51c1..78fceb74881 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -38,13 +38,6 @@ RSpec/SingleArgumentMessageChain: Exclude: - 'spec/requests/api/internal_spec.rb' -# Offense count: 32 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. -# SupportedStyles: assign_to_condition, assign_inside_condition -Style/ConditionalAssignment: - Enabled: false - # Offense count: 6 # Cop supports --auto-correct. Style/EachWithObject: diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 88d180fcc2e..a6cf2b274a2 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -101,12 +101,12 @@ module CreatesCommit # TODO: We should really clean this up def set_commit_variables - if can?(current_user, :push_code, @project) + @mr_source_project = if can?(current_user, :push_code, @project) # Edit file in this project - @mr_source_project = @project + @project else # Merge request from fork to this project - @mr_source_project = current_user.fork_of(@project) + current_user.fork_of(@project) end # Merge request to this project diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb index 216c158e41e..0305dafe8da 100644 --- a/app/controllers/projects/git_http_client_controller.rb +++ b/app/controllers/projects/git_http_client_controller.rb @@ -76,10 +76,10 @@ class Projects::GitHttpClientController < Projects::ApplicationController return @project if defined?(@project) project_id, _ = project_id_with_suffix - if project_id.blank? - @project = nil + @project = if project_id.blank? + nil else - @project = Project.find_by_full_path("#{params[:namespace_id]}/#{project_id}") + Project.find_by_full_path("#{params[:namespace_id]}/#{project_id}") end end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index c0c71c11dc2..ff77c2b5e01 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -381,13 +381,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_widget_refresh - if merge_request.merge_when_build_succeeds - @status = :merge_when_build_succeeds + @status = if merge_request.merge_when_build_succeeds + :merge_when_build_succeeds else # Only MRs that can be merged end in this action # MR can be already picked up for merge / merged already or can be waiting for worker to be picked up # in last case it does not have any special status. Possible error is handled inside widget js function - @status = :success + :success end render 'merge' diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 93a180b9036..529a8c9b4b4 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -15,10 +15,10 @@ class SessionsController < Devise::SessionsController def new set_minimum_password_length - if Gitlab.config.ldap.enabled - @ldap_servers = Gitlab::LDAP::Config.servers + @ldap_servers = if Gitlab.config.ldap.enabled + Gitlab::LDAP::Config.servers else - @ldap_servers = [] + [] end super diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb index 4bd8c83081a..3279cd4a941 100644 --- a/app/finders/notes_finder.rb +++ b/app/finders/notes_finder.rb @@ -28,10 +28,10 @@ class NotesFinder private def init_collection - if @params[:target_id] - @notes = on_target(@params[:target_type], @params[:target_id]) + @notes = if @params[:target_id] + on_target(@params[:target_type], @params[:target_id]) else - @notes = notes_of_any_type + notes_of_any_type end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6db813d4a02..ed4be180f04 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -69,10 +69,10 @@ module ApplicationHelper end def avatar_icon(user_or_email = nil, size = nil, scale = 2) - if user_or_email.is_a?(User) - user = user_or_email + user = if user_or_email.is_a?(User) + user_or_email else - user = User.find_by_any_email(user_or_email.try(:downcase)) + User.find_by_any_email(user_or_email.try(:downcase)) end if user diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 311a70725ab..6cba11f1b63 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -153,15 +153,15 @@ module BlobHelper # Because we are opionated we set the cache headers ourselves. response.cache_control[:public] = @project.public? - if @ref && @commit && @ref == @commit.id + response.cache_control[:max_age] = if @ref && @commit && @ref == @commit.id # This is a link to a commit by its commit SHA. That means that the blob # is immutable. The only reason to invalidate the cache is if the commit # was deleted or if the user lost access to the repository. - response.cache_control[:max_age] = Blob::CACHE_TIME_IMMUTABLE + Blob::CACHE_TIME_IMMUTABLE else # A branch or tag points at this blob. That means that the expected blob # value may change over time. - response.cache_control[:max_age] = Blob::CACHE_TIME + Blob::CACHE_TIME end response.etag = @blob.id diff --git a/app/mailers/repository_check_mailer.rb b/app/mailers/repository_check_mailer.rb index 21db2fe04a0..11a0c0b7700 100644 --- a/app/mailers/repository_check_mailer.rb +++ b/app/mailers/repository_check_mailer.rb @@ -1,9 +1,9 @@ class RepositoryCheckMailer < BaseMailer def notify(failed_count) - if failed_count == 1 - @message = "One project failed its last repository check" + @message = if failed_count == 1 + "One project failed its last repository check" else - @message = "#{failed_count} projects failed their last repository check" + "#{failed_count} projects failed their last repository check" end mail( diff --git a/app/models/commit.rb b/app/models/commit.rb index 7afc8f4add8..feb35bb3e92 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -122,10 +122,10 @@ class Commit def full_title return @full_title if @full_title - if safe_message.blank? - @full_title = no_commit_message + @full_title = if safe_message.blank? + no_commit_message else - @full_title = safe_message.split("\n", 2).first + safe_message.split("\n", 2).first end end diff --git a/app/models/concerns/case_sensitivity.rb b/app/models/concerns/case_sensitivity.rb index fe0cea8465f..2cfb6127c96 100644 --- a/app/models/concerns/case_sensitivity.rb +++ b/app/models/concerns/case_sensitivity.rb @@ -13,10 +13,10 @@ module CaseSensitivity params.each do |key, value| column = ActiveRecord::Base.connection.quote_table_name(key) - if cast_lower - condition = "LOWER(#{column}) = LOWER(:value)" + condition = if cast_lower + "LOWER(#{column}) = LOWER(:value)" else - condition = "#{column} = :value" + "#{column} = :value" end criteria = criteria.where(condition, value: value) diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index 7edb0acd56c..fdcb4f3ba64 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -46,10 +46,10 @@ module Sortable where("label_links.target_id = #{target_column}"). reorder(nil) - if target_type_column - query = query.where("label_links.target_type = #{target_type_column}") + query = if target_type_column + query.where("label_links.target_type = #{target_type_column}") else - query = query.where(label_links: { target_type: target_type }) + query.where(label_links: { target_type: target_type }) end query = query.where.not(title: excluded_labels) if excluded_labels.present? diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index b16ecc424dd..b859d40da24 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -188,10 +188,10 @@ module Network end # and mark it as reserved - if parent_time.nil? - min_time = leaves.first.time + min_time = if parent_time.nil? + leaves.first.time else - min_time = parent_time + 1 + parent_time + 1 end max_time = leaves.last.time diff --git a/app/models/project.rb b/app/models/project.rb index 0da21be8351..a0bc82af7d5 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -453,12 +453,12 @@ class Project < ActiveRecord::Base end def add_import_job - if forked? - job_id = RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path, + job_id = if forked? + RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path, forked_from_project.path_with_namespace, self.namespace.full_path) else - job_id = RepositoryImportWorker.perform_async(self.id) + RepositoryImportWorker.perform_async(self.id) end if job_id diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index f623bf9851b..cd185f6e120 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -72,12 +72,12 @@ class PushoverService < Service before = data[:before] after = data[:after] - if Gitlab::Git.blank_ref?(before) - message = "#{data[:user_name]} pushed new branch \"#{ref}\"." + message = if Gitlab::Git.blank_ref?(before) + "#{data[:user_name]} pushed new branch \"#{ref}\"." elsif Gitlab::Git.blank_ref?(after) - message = "#{data[:user_name]} deleted branch \"#{ref}\"." + "#{data[:user_name]} deleted branch \"#{ref}\"." else - message = "#{data[:user_name]} push to branch \"#{ref}\"." + "#{data[:user_name]} push to branch \"#{ref}\"." end if data[:total_commits_count] > 0 diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 71b4f8605a4..3e362bb2ca9 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -408,11 +408,11 @@ module SystemNoteService # Initial scope should be system notes of this noteable type notes = Note.system.where(noteable_type: noteable.class) - if noteable.is_a?(Commit) + notes = if noteable.is_a?(Commit) # Commits have non-integer IDs, so they're stored in `commit_id` - notes = notes.where(commit_id: noteable.id) + notes.where(commit_id: noteable.id) else - notes = notes.where(noteable_id: noteable.id) + notes.where(noteable_id: noteable.id) end notes_for_mentioner(mentioner, noteable, notes).exists? diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 680deee6d46..ecae5453736 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -14,10 +14,10 @@ class Settings < Settingslogic end def build_gitlab_ci_url - if on_standard_port?(gitlab) - custom_port = nil + custom_port = if on_standard_port?(gitlab) + nil else - custom_port = ":#{gitlab.port}" + ":#{gitlab.port}" end [gitlab.protocol, "://", @@ -160,10 +160,10 @@ if github_settings github_settings["args"] ||= Settingslogic.new({}) - if github_settings["url"].include?(github_default_url) - github_settings["args"]["client_options"] = OmniAuth::Strategies::GitHub.default_options[:client_options] + github_settings["args"]["client_options"] = if github_settings["url"].include?(github_default_url) + OmniAuth::Strategies::GitHub.default_options[:client_options] else - github_settings["args"]["client_options"] = { + { "site" => File.join(github_settings["url"], "api/v3"), "authorize_url" => File.join(github_settings["url"], "login/oauth/authorize"), "token_url" => File.join(github_settings["url"], "login/oauth/access_token") diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb index 3b15ff6566f..1c42ae3363d 100644 --- a/lib/banzai/filter/abstract_reference_filter.rb +++ b/lib/banzai/filter/abstract_reference_filter.rb @@ -160,10 +160,10 @@ module Banzai data = data_attributes_for(link_content || match, project, object, link: !!link_content) - if matches.names.include?("url") && matches[:url] - url = matches[:url] + url = if matches.names.include?("url") && matches[:url] + matches[:url] else - url = url_for_object_cached(object, project) + url_for_object_cached(object, project) end content = link_content || object_link_text(object, matches) diff --git a/lib/banzai/filter/gollum_tags_filter.rb b/lib/banzai/filter/gollum_tags_filter.rb index d08267a9d6c..35d21733967 100644 --- a/lib/banzai/filter/gollum_tags_filter.rb +++ b/lib/banzai/filter/gollum_tags_filter.rb @@ -149,10 +149,10 @@ module Banzai name, reference = *parts.compact.map(&:strip) end - if url?(reference) - href = reference + href = if url?(reference) + reference else - href = ::File.join(project_wiki_base_path, reference) + ::File.join(project_wiki_base_path, reference) end content_tag(:a, name || reference, href: href, class: 'gfm') diff --git a/lib/banzai/filter/issue_reference_filter.rb b/lib/banzai/filter/issue_reference_filter.rb index fd6b9704132..e5082895e82 100644 --- a/lib/banzai/filter/issue_reference_filter.rb +++ b/lib/banzai/filter/issue_reference_filter.rb @@ -39,10 +39,10 @@ module Banzai projects_per_reference.each do |path, project| issue_ids = references_per_project[path] - if project.default_issues_tracker? - issues = project.issues.where(iid: issue_ids.to_a) + issues = if project.default_issues_tracker? + project.issues.where(iid: issue_ids.to_a) else - issues = issue_ids.map { |id| ExternalIssue.new(id, project) } + issue_ids.map { |id| ExternalIssue.new(id, project) } end issues.each do |issue| diff --git a/lib/gitlab/award_emoji.rb b/lib/gitlab/award_emoji.rb index 39b43ab5489..fcb3542d181 100644 --- a/lib/gitlab/award_emoji.rb +++ b/lib/gitlab/award_emoji.rb @@ -69,10 +69,10 @@ module Gitlab end JSON.parse(File.read(path)).map do |hash| - if digest - fname = "#{hash['unicode']}-#{hash['digest']}" + fname = if digest + "#{hash['unicode']}-#{hash['digest']}" else - fname = hash['unicode'] + hash['unicode'] end { name: hash['name'], path: File.join(base, prefix, "#{fname}.png") } diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index c843315782d..fd43a224b3d 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -91,10 +91,10 @@ module Gitlab our_highlight = Gitlab::Highlight.highlight(our_path, our_file, repository: repository).lines lines.each do |line| - if line.type == 'old' - line.rich_text = their_highlight[line.old_line - 1].try(:html_safe) + line.rich_text = if line.type == 'old' + their_highlight[line.old_line - 1].try(:html_safe) else - line.rich_text = our_highlight[line.new_line - 1].try(:html_safe) + our_highlight[line.new_line - 1].try(:html_safe) end end end diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb index ecf62dead35..81c93f1aab5 100644 --- a/lib/gitlab/diff/position.rb +++ b/lib/gitlab/diff/position.rb @@ -140,10 +140,10 @@ module Gitlab def find_diff_file(repository) # We're at the initial commit, so just get that as we can't compare to anything. - if Gitlab::Git.blank_ref?(start_sha) - compare = Gitlab::Git::Commit.find(repository.raw_repository, head_sha) + compare = if Gitlab::Git.blank_ref?(start_sha) + Gitlab::Git::Commit.find(repository.raw_repository, head_sha) else - compare = Gitlab::Git::Compare.new( + Gitlab::Git::Compare.new( repository.raw_repository, start_sha, head_sha diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 8c8dd1b9cef..4ddfd78130e 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -31,10 +31,10 @@ module Gitlab private def select_body(message) - if message.multipart? - part = message.text_part || message.html_part || message + part = if message.multipart? + message.text_part || message.html_part || message else - part = message + message end decoded = fix_charset(part) diff --git a/lib/gitlab/metrics/instrumentation.rb b/lib/gitlab/metrics/instrumentation.rb index 4b7a791e497..9a07abfed06 100644 --- a/lib/gitlab/metrics/instrumentation.rb +++ b/lib/gitlab/metrics/instrumentation.rb @@ -143,10 +143,10 @@ module Gitlab # signature this would break things. As a result we'll make sure the # generated method _only_ accepts regular arguments if the underlying # method also accepts them. - if method.arity == 0 - args_signature = '' + args_signature = if method.arity == 0 + '' else - args_signature = '*args' + '*args' end proxy_module.class_eval <<-EOF, __FILE__, __LINE__ + 1 diff --git a/lib/gitlab/saml/user.rb b/lib/gitlab/saml/user.rb index f253dc7477e..abde05d9b68 100644 --- a/lib/gitlab/saml/user.rb +++ b/lib/gitlab/saml/user.rb @@ -28,10 +28,10 @@ module Gitlab if external_users_enabled? && @user # Check if there is overlap between the user's groups and the external groups # setting then set user as external or internal. - if (auth_hash.groups & Gitlab::Saml::Config.external_groups).empty? - @user.external = false + @user.external = if (auth_hash.groups & Gitlab::Saml::Config.external_groups).empty? + false else - @user.external = true + true end end diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index c9c65f76f4b..a1a6929103b 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -56,10 +56,10 @@ module Gitlab def issues issues = IssuesFinder.new(current_user).execute.where(project_id: project_ids_relation) - if query =~ /#(\d+)\z/ - issues = issues.where(iid: $1) + issues = if query =~ /#(\d+)\z/ + issues.where(iid: $1) else - issues = issues.full_search(query) + issues.full_search(query) end issues.order('updated_at DESC') @@ -73,10 +73,10 @@ module Gitlab def merge_requests merge_requests = MergeRequestsFinder.new(current_user).execute.in_projects(project_ids_relation) - if query =~ /[#!](\d+)\z/ - merge_requests = merge_requests.where(iid: $1) + merge_requests = if query =~ /[#!](\d+)\z/ + merge_requests.where(iid: $1) else - merge_requests = merge_requests.full_search(query) + merge_requests.full_search(query) end merge_requests.order('updated_at DESC') end diff --git a/lib/gitlab/sherlock/query.rb b/lib/gitlab/sherlock/query.rb index 4917c4ae2ac..086fcddf721 100644 --- a/lib/gitlab/sherlock/query.rb +++ b/lib/gitlab/sherlock/query.rb @@ -94,10 +94,10 @@ module Gitlab private def raw_explain(query) - if Gitlab::Database.postgresql? - explain = "EXPLAIN ANALYZE #{query};" + explain = if Gitlab::Database.postgresql? + "EXPLAIN ANALYZE #{query};" else - explain = "EXPLAIN #{query};" + "EXPLAIN #{query};" end ActiveRecord::Base.connection.execute(explain) diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index 0bf7977fb02..2867fcf8819 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -47,10 +47,10 @@ describe 'issuable list', feature: true do def create_issuables(issuable_type) 3.times do - if issuable_type == :issue - issuable = create(:issue, project: project, author: user) + issuable = if issuable_type == :issue + create(:issue, project: project, author: user) else - issuable = create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) + create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) end 2.times do diff --git a/spec/support/issuables_list_metadata_shared_examples.rb b/spec/support/issuables_list_metadata_shared_examples.rb index dac94dfc31e..c61f3e05cea 100644 --- a/spec/support/issuables_list_metadata_shared_examples.rb +++ b/spec/support/issuables_list_metadata_shared_examples.rb @@ -3,10 +3,10 @@ shared_examples 'issuables list meta-data' do |issuable_type, action = nil| @issuable_ids = [] 2.times do - if issuable_type == :issue - issuable = create(issuable_type, project: project) + issuable = if issuable_type == :issue + create(issuable_type, project: project) else - issuable = create(issuable_type, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) + create(issuable_type, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) end @issuable_ids << issuable.id diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index ad1eed5b369..b94ffa30736 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -15,10 +15,10 @@ module LoginHelpers # user = create(:user) # login_as(user) def login_as(user_or_role) - if user_or_role.kind_of?(User) - @user = user_or_role + @user = if user_or_role.kind_of?(User) + user_or_role else - @user = create(user_or_role) + create(user_or_role) end login_with(@user) From 02494f7ce86fbf1276b384f45f58558c427eff63 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 08:10:38 -0600 Subject: [PATCH 218/247] Fix specs --- spec/lib/gitlab/metrics/metric_spec.rb | 2 +- spec/lib/gitlab/metrics/system_spec.rb | 6 +++--- spec/lib/gitlab/metrics/transaction_spec.rb | 4 ++-- spec/models/concerns/cache_markdown_field_spec.rb | 5 +++-- spec/models/repository_spec.rb | 6 +++--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/spec/lib/gitlab/metrics/metric_spec.rb b/spec/lib/gitlab/metrics/metric_spec.rb index b4d29ebe05f..d240b8a01fd 100644 --- a/spec/lib/gitlab/metrics/metric_spec.rb +++ b/spec/lib/gitlab/metrics/metric_spec.rb @@ -62,7 +62,7 @@ describe Gitlab::Metrics::Metric do end it 'includes the timestamp' do - expect(hash[:timestamp]).to be_an_instance_of(Integer) + expect(hash[:timestamp]).to be_an(Integer) end end end diff --git a/spec/lib/gitlab/metrics/system_spec.rb b/spec/lib/gitlab/metrics/system_spec.rb index a7b129e2827..4d94d8705fb 100644 --- a/spec/lib/gitlab/metrics/system_spec.rb +++ b/spec/lib/gitlab/metrics/system_spec.rb @@ -29,19 +29,19 @@ describe Gitlab::Metrics::System do describe '.cpu_time' do it 'returns a Fixnum' do - expect(described_class.cpu_time).to be_an_instance_of(Integer) + expect(described_class.cpu_time).to be_an(Integer) end end describe '.real_time' do it 'returns a Fixnum' do - expect(described_class.real_time).to be_an_instance_of(Integer) + expect(described_class.real_time).to be_an(Integer) end end describe '.monotonic_time' do it 'returns a Fixnum' do - expect(described_class.monotonic_time).to be_an_instance_of(Integer) + expect(described_class.monotonic_time).to be_an(Integer) end end end diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb index 83bd862d146..0c5a6246d85 100644 --- a/spec/lib/gitlab/metrics/transaction_spec.rb +++ b/spec/lib/gitlab/metrics/transaction_spec.rb @@ -134,7 +134,7 @@ describe Gitlab::Metrics::Transaction do series: 'rails_transactions', tags: { action: 'Foo#bar' }, values: { duration: 0.0, allocated_memory: a_kind_of(Numeric) }, - timestamp: an_instance_of(Integer) + timestamp: a_kind_of(Integer) } expect(Gitlab::Metrics).to receive(:submit_metrics). @@ -151,7 +151,7 @@ describe Gitlab::Metrics::Transaction do series: 'events', tags: { event: :meow }, values: { count: 1 }, - timestamp: an_instance_of(Integer) + timestamp: a_kind_of(Integer) } expect(Gitlab::Metrics).to receive(:submit_metrics). diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb index 2e3702f7520..6151d53cd91 100644 --- a/spec/models/concerns/cache_markdown_field_spec.rb +++ b/spec/models/concerns/cache_markdown_field_spec.rb @@ -1,7 +1,8 @@ require 'spec_helper' describe CacheMarkdownField do - CacheMarkdownField::CACHING_CLASSES << "ThingWithMarkdownFields" + caching_classes = CacheMarkdownField::CACHING_CLASSES + CacheMarkdownField::CACHING_CLASSES = ["ThingWithMarkdownFields"].freeze # The minimum necessary ActiveModel to test this concern class ThingWithMarkdownFields @@ -54,7 +55,7 @@ describe CacheMarkdownField do end end - CacheMarkdownField::CACHING_CLASSES.delete("ThingWithMarkdownFields") + CacheMarkdownField::CACHING_CLASSES = caching_classes def thing_subclass(new_attr) Class.new(ThingWithMarkdownFields) { add_attr(new_attr) } diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index c3d4365639d..a3fe412b229 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1382,13 +1382,13 @@ describe Repository, models: true do describe '#branch_count' do it 'returns the number of branches' do - expect(repository.branch_count).to be_an_instance_of(Integer) + expect(repository.branch_count).to be_an(Integer) end end describe '#tag_count' do it 'returns the number of tags' do - expect(repository.tag_count).to be_an_instance_of(Integer) + expect(repository.tag_count).to be_an(Integer) end end @@ -1738,7 +1738,7 @@ describe Repository, models: true do context 'with an existing repository' do it 'returns the commit count' do - expect(repository.commit_count).to be_an_instance_of(Integer) + expect(repository.commit_count).to be_an(Integer) end end end From 5c7f9d69e3db27921acf6d8259245f2b4babcc2b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 09:10:32 -0600 Subject: [PATCH 219/247] Fix code for cops --- app/controllers/concerns/creates_commit.rb | 15 ++++--- .../projects/git_http_client_controller.rb | 11 ++--- .../projects/merge_requests_controller.rb | 17 +++---- app/controllers/sessions_controller.rb | 11 ++--- app/finders/notes_finder.rb | 11 ++--- app/helpers/application_helper.rb | 11 ++--- app/helpers/blob_helper.rb | 21 ++++----- app/helpers/submodule_helper.rb | 2 +- app/mailers/repository_check_mailer.rb | 11 ++--- app/models/commit.rb | 11 ++--- app/models/concerns/case_sensitivity.rb | 11 ++--- app/models/concerns/sortable.rb | 11 ++--- app/models/network/graph.rb | 11 ++--- app/models/project.rb | 15 ++++--- .../project_services/pushover_service.rb | 15 ++++--- app/services/system_note_service.rb | 13 +++--- config/initializers/1_settings.rb | 44 ++++++++++--------- lib/api/api_guard.rb | 2 +- lib/api/award_emoji.rb | 2 +- .../filter/abstract_reference_filter.rb | 11 ++--- lib/banzai/filter/gollum_tags_filter.rb | 11 ++--- lib/banzai/filter/issue_reference_filter.rb | 11 ++--- lib/gitlab/award_emoji.rb | 11 ++--- lib/gitlab/ci/config/entry/global.rb | 2 +- lib/gitlab/ci/config/entry/jobs.rb | 2 +- lib/gitlab/conflict/file.rb | 11 ++--- lib/gitlab/diff/position.rb | 19 ++++---- lib/gitlab/email/reply_parser.rb | 11 ++--- lib/gitlab/metrics/instrumentation.rb | 11 ++--- lib/gitlab/saml/user.rb | 11 ++--- lib/gitlab/search_results.rb | 22 +++++----- lib/gitlab/shell.rb | 2 +- lib/gitlab/sherlock/query.rb | 11 ++--- spec/features/issuables/issuable_list_spec.rb | 11 ++--- spec/helpers/issues_helper_spec.rb | 2 +- .../lib/gitlab/ci/config/entry/global_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/job_spec.rb | 10 ++--- .../gitlab/ci/status/build/factory_spec.rb | 2 +- spec/lib/gitlab/incoming_email_spec.rb | 4 +- spec/lib/gitlab/o_auth/user_spec.rb | 4 +- spec/lib/gitlab/saml/user_spec.rb | 6 +-- spec/models/ci/build_spec.rb | 2 +- ...issuables_list_metadata_shared_examples.rb | 11 ++--- spec/support/login_helpers.rb | 11 ++--- 44 files changed, 245 insertions(+), 213 deletions(-) diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index a6cf2b274a2..2fe03020d2d 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -101,13 +101,14 @@ module CreatesCommit # TODO: We should really clean this up def set_commit_variables - @mr_source_project = if can?(current_user, :push_code, @project) - # Edit file in this project - @project - else - # Merge request from fork to this project - current_user.fork_of(@project) - end + @mr_source_project = + if can?(current_user, :push_code, @project) + # Edit file in this project + @project + else + # Merge request from fork to this project + current_user.fork_of(@project) + end # Merge request to this project @mr_target_project = @project diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb index 0305dafe8da..9a1bf037a95 100644 --- a/app/controllers/projects/git_http_client_controller.rb +++ b/app/controllers/projects/git_http_client_controller.rb @@ -76,11 +76,12 @@ class Projects::GitHttpClientController < Projects::ApplicationController return @project if defined?(@project) project_id, _ = project_id_with_suffix - @project = if project_id.blank? - nil - else - Project.find_by_full_path("#{params[:namespace_id]}/#{project_id}") - end + @project = + if project_id.blank? + nil + else + Project.find_by_full_path("#{params[:namespace_id]}/#{project_id}") + end end # This method returns two values so that we can parse diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index ff77c2b5e01..5ee7972e29e 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -381,14 +381,15 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_widget_refresh - @status = if merge_request.merge_when_build_succeeds - :merge_when_build_succeeds - else - # Only MRs that can be merged end in this action - # MR can be already picked up for merge / merged already or can be waiting for worker to be picked up - # in last case it does not have any special status. Possible error is handled inside widget js function - :success - end + @status = + if merge_request.merge_when_build_succeeds + :merge_when_build_succeeds + else + # Only MRs that can be merged end in this action + # MR can be already picked up for merge / merged already or can be waiting for worker to be picked up + # in last case it does not have any special status. Possible error is handled inside widget js function + :success + end render 'merge' end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 529a8c9b4b4..7d81c96262f 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -15,11 +15,12 @@ class SessionsController < Devise::SessionsController def new set_minimum_password_length - @ldap_servers = if Gitlab.config.ldap.enabled - Gitlab::LDAP::Config.servers - else - [] - end + @ldap_servers = + if Gitlab.config.ldap.enabled + Gitlab::LDAP::Config.servers + else + [] + end super end diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb index 3279cd4a941..6630c6384f2 100644 --- a/app/finders/notes_finder.rb +++ b/app/finders/notes_finder.rb @@ -28,11 +28,12 @@ class NotesFinder private def init_collection - @notes = if @params[:target_id] - on_target(@params[:target_type], @params[:target_id]) - else - notes_of_any_type - end + @notes = + if @params[:target_id] + on_target(@params[:target_type], @params[:target_id]) + else + notes_of_any_type + end end def notes_of_any_type diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ed4be180f04..70419eb4bde 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -69,11 +69,12 @@ module ApplicationHelper end def avatar_icon(user_or_email = nil, size = nil, scale = 2) - user = if user_or_email.is_a?(User) - user_or_email - else - User.find_by_any_email(user_or_email.try(:downcase)) - end + user = + if user_or_email.is_a?(User) + user_or_email + else + User.find_by_any_email(user_or_email.try(:downcase)) + end if user user.avatar_url(size) || default_avatar diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 6cba11f1b63..7f32c1b5300 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -153,16 +153,17 @@ module BlobHelper # Because we are opionated we set the cache headers ourselves. response.cache_control[:public] = @project.public? - response.cache_control[:max_age] = if @ref && @commit && @ref == @commit.id - # This is a link to a commit by its commit SHA. That means that the blob - # is immutable. The only reason to invalidate the cache is if the commit - # was deleted or if the user lost access to the repository. - Blob::CACHE_TIME_IMMUTABLE - else - # A branch or tag points at this blob. That means that the expected blob - # value may change over time. - Blob::CACHE_TIME - end + response.cache_control[:max_age] = + if @ref && @commit && @ref == @commit.id + # This is a link to a commit by its commit SHA. That means that the blob + # is immutable. The only reason to invalidate the cache is if the commit + # was deleted or if the user lost access to the repository. + Blob::CACHE_TIME_IMMUTABLE + else + # A branch or tag points at this blob. That means that the expected blob + # value may change over time. + Blob::CACHE_TIME + end response.etag = @blob.id !stale diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb index 97d8cde4b3d..fb95f2b565e 100644 --- a/app/helpers/submodule_helper.rb +++ b/app/helpers/submodule_helper.rb @@ -38,7 +38,7 @@ module SubmoduleHelper def self_url?(url, namespace, project) return true if url == [Gitlab.config.gitlab.url, '/', namespace, '/', - project, '.git'].join('') + project, '.git'].join('') url == gitlab_shell.url_to_repo([namespace, '/', project].join('')) end diff --git a/app/mailers/repository_check_mailer.rb b/app/mailers/repository_check_mailer.rb index 11a0c0b7700..22a9f5da646 100644 --- a/app/mailers/repository_check_mailer.rb +++ b/app/mailers/repository_check_mailer.rb @@ -1,10 +1,11 @@ class RepositoryCheckMailer < BaseMailer def notify(failed_count) - @message = if failed_count == 1 - "One project failed its last repository check" - else - "#{failed_count} projects failed their last repository check" - end + @message = + if failed_count == 1 + "One project failed its last repository check" + else + "#{failed_count} projects failed their last repository check" + end mail( to: User.admins.pluck(:email), diff --git a/app/models/commit.rb b/app/models/commit.rb index feb35bb3e92..8f6179f183e 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -122,11 +122,12 @@ class Commit def full_title return @full_title if @full_title - @full_title = if safe_message.blank? - no_commit_message - else - safe_message.split("\n", 2).first - end + @full_title = + if safe_message.blank? + no_commit_message + else + safe_message.split("\n", 2).first + end end # Returns the commits description diff --git a/app/models/concerns/case_sensitivity.rb b/app/models/concerns/case_sensitivity.rb index 2cfb6127c96..034e9f40ff0 100644 --- a/app/models/concerns/case_sensitivity.rb +++ b/app/models/concerns/case_sensitivity.rb @@ -13,11 +13,12 @@ module CaseSensitivity params.each do |key, value| column = ActiveRecord::Base.connection.quote_table_name(key) - condition = if cast_lower - "LOWER(#{column}) = LOWER(:value)" - else - "#{column} = :value" - end + condition = + if cast_lower + "LOWER(#{column}) = LOWER(:value)" + else + "#{column} = :value" + end criteria = criteria.where(condition, value: value) end diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index fdcb4f3ba64..b9a2d812edd 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -46,11 +46,12 @@ module Sortable where("label_links.target_id = #{target_column}"). reorder(nil) - query = if target_type_column - query.where("label_links.target_type = #{target_type_column}") - else - query.where(label_links: { target_type: target_type }) - end + query = + if target_type_column + query.where("label_links.target_type = #{target_type_column}") + else + query.where(label_links: { target_type: target_type }) + end query = query.where.not(title: excluded_labels) if excluded_labels.present? diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index b859d40da24..2a7fa7d0607 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -188,11 +188,12 @@ module Network end # and mark it as reserved - min_time = if parent_time.nil? - leaves.first.time - else - parent_time + 1 - end + min_time = + if parent_time.nil? + leaves.first.time + else + parent_time + 1 + end max_time = leaves.last.time leaves.last.parents(@map).each do |parent| diff --git a/app/models/project.rb b/app/models/project.rb index a0bc82af7d5..e75ba3abb98 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -453,13 +453,14 @@ class Project < ActiveRecord::Base end def add_import_job - job_id = if forked? - RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path, - forked_from_project.path_with_namespace, - self.namespace.full_path) - else - RepositoryImportWorker.perform_async(self.id) - end + job_id = + if forked? + RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path, + forked_from_project.path_with_namespace, + self.namespace.full_path) + else + RepositoryImportWorker.perform_async(self.id) + end if job_id Rails.logger.info "Import job started for #{path_with_namespace} with job ID #{job_id}" diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index cd185f6e120..f4106048345 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -72,13 +72,14 @@ class PushoverService < Service before = data[:before] after = data[:after] - message = if Gitlab::Git.blank_ref?(before) - "#{data[:user_name]} pushed new branch \"#{ref}\"." - elsif Gitlab::Git.blank_ref?(after) - "#{data[:user_name]} deleted branch \"#{ref}\"." - else - "#{data[:user_name]} push to branch \"#{ref}\"." - end + message = + if Gitlab::Git.blank_ref?(before) + "#{data[:user_name]} pushed new branch \"#{ref}\"." + elsif Gitlab::Git.blank_ref?(after) + "#{data[:user_name]} deleted branch \"#{ref}\"." + else + "#{data[:user_name]} push to branch \"#{ref}\"." + end if data[:total_commits_count] > 0 message << "\nTotal commits count: #{data[:total_commits_count]}" diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 3e362bb2ca9..5cb4401d69d 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -408,12 +408,13 @@ module SystemNoteService # Initial scope should be system notes of this noteable type notes = Note.system.where(noteable_type: noteable.class) - notes = if noteable.is_a?(Commit) - # Commits have non-integer IDs, so they're stored in `commit_id` - notes.where(commit_id: noteable.id) - else - notes.where(noteable_id: noteable.id) - end + notes = + if noteable.is_a?(Commit) + # Commits have non-integer IDs, so they're stored in `commit_id` + notes.where(commit_id: noteable.id) + else + notes.where(noteable_id: noteable.id) + end notes_for_mentioner(mentioner, noteable, notes).exists? end diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index ecae5453736..ac89fb9e9cf 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -14,16 +14,17 @@ class Settings < Settingslogic end def build_gitlab_ci_url - custom_port = if on_standard_port?(gitlab) - nil - else - ":#{gitlab.port}" - end + custom_port = + if on_standard_port?(gitlab) + nil + else + ":#{gitlab.port}" + end [gitlab.protocol, - "://", - gitlab.host, - custom_port, - gitlab.relative_url_root + "://", + gitlab.host, + custom_port, + gitlab.relative_url_root ].join('') end @@ -81,9 +82,9 @@ class Settings < Settingslogic def base_url(config) custom_port = on_standard_port?(config) ? nil : ":#{config.port}" [config.protocol, - "://", - config.host, - custom_port + "://", + config.host, + custom_port ] end @@ -160,15 +161,16 @@ if github_settings github_settings["args"] ||= Settingslogic.new({}) - github_settings["args"]["client_options"] = if github_settings["url"].include?(github_default_url) - OmniAuth::Strategies::GitHub.default_options[:client_options] - else - { - "site" => File.join(github_settings["url"], "api/v3"), - "authorize_url" => File.join(github_settings["url"], "login/oauth/authorize"), - "token_url" => File.join(github_settings["url"], "login/oauth/access_token") - } - end + github_settings["args"]["client_options"] = + if github_settings["url"].include?(github_default_url) + OmniAuth::Strategies::GitHub.default_options[:client_options] + else + { + "site" => File.join(github_settings["url"], "api/v3"), + "authorize_url" => File.join(github_settings["url"], "login/oauth/authorize"), + "token_url" => File.join(github_settings["url"], "login/oauth/access_token") + } + end end Settings['shared'] ||= Settingslogic.new({}) diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index a955d17c9d1..c11f8529183 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -115,7 +115,7 @@ module API def install_error_responders(base) error_classes = [MissingTokenError, TokenNotFoundError, - ExpiredError, RevokedError, InsufficientScopeError] + ExpiredError, RevokedError, InsufficientScopeError] base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler end diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index f54ba232608..d6352920f57 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -16,7 +16,7 @@ module API end [":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", - ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji" + ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji" ].each do |endpoint| desc 'Get a list of project +awardable+ award emoji' do diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb index 1c42ae3363d..02d5ad70fa7 100644 --- a/lib/banzai/filter/abstract_reference_filter.rb +++ b/lib/banzai/filter/abstract_reference_filter.rb @@ -160,11 +160,12 @@ module Banzai data = data_attributes_for(link_content || match, project, object, link: !!link_content) - url = if matches.names.include?("url") && matches[:url] - matches[:url] - else - url_for_object_cached(object, project) - end + url = + if matches.names.include?("url") && matches[:url] + matches[:url] + else + url_for_object_cached(object, project) + end content = link_content || object_link_text(object, matches) diff --git a/lib/banzai/filter/gollum_tags_filter.rb b/lib/banzai/filter/gollum_tags_filter.rb index 35d21733967..0ea4eeaed5b 100644 --- a/lib/banzai/filter/gollum_tags_filter.rb +++ b/lib/banzai/filter/gollum_tags_filter.rb @@ -149,11 +149,12 @@ module Banzai name, reference = *parts.compact.map(&:strip) end - href = if url?(reference) - reference - else - ::File.join(project_wiki_base_path, reference) - end + href = + if url?(reference) + reference + else + ::File.join(project_wiki_base_path, reference) + end content_tag(:a, name || reference, href: href, class: 'gfm') end diff --git a/lib/banzai/filter/issue_reference_filter.rb b/lib/banzai/filter/issue_reference_filter.rb index e5082895e82..044d18ff824 100644 --- a/lib/banzai/filter/issue_reference_filter.rb +++ b/lib/banzai/filter/issue_reference_filter.rb @@ -39,11 +39,12 @@ module Banzai projects_per_reference.each do |path, project| issue_ids = references_per_project[path] - issues = if project.default_issues_tracker? - project.issues.where(iid: issue_ids.to_a) - else - issue_ids.map { |id| ExternalIssue.new(id, project) } - end + issues = + if project.default_issues_tracker? + project.issues.where(iid: issue_ids.to_a) + else + issue_ids.map { |id| ExternalIssue.new(id, project) } + end issues.each do |issue| hash[project][issue.iid.to_i] = issue diff --git a/lib/gitlab/award_emoji.rb b/lib/gitlab/award_emoji.rb index fcb3542d181..7555326d384 100644 --- a/lib/gitlab/award_emoji.rb +++ b/lib/gitlab/award_emoji.rb @@ -69,11 +69,12 @@ module Gitlab end JSON.parse(File.read(path)).map do |hash| - fname = if digest - "#{hash['unicode']}-#{hash['digest']}" - else - hash['unicode'] - end + fname = + if digest + "#{hash['unicode']}-#{hash['digest']}" + else + hash['unicode'] + end { name: hash['name'], path: File.join(base, prefix, "#{fname}.png") } end diff --git a/lib/gitlab/ci/config/entry/global.rb b/lib/gitlab/ci/config/entry/global.rb index 8154beea21f..0a404331225 100644 --- a/lib/gitlab/ci/config/entry/global.rb +++ b/lib/gitlab/ci/config/entry/global.rb @@ -49,7 +49,7 @@ module Gitlab factory = Entry::Factory.new(Entry::Jobs). value(@config.except(*self.class.nodes.keys)). with(key: :jobs, parent: self, - description: 'Jobs definition for this pipeline') + description: 'Jobs definition for this pipeline') @entries[:jobs] = factory.create! end diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb index 41de7dbbb3e..7b83f0f1b69 100644 --- a/lib/gitlab/ci/config/entry/jobs.rb +++ b/lib/gitlab/ci/config/entry/jobs.rb @@ -35,7 +35,7 @@ module Gitlab value(config || {}). metadata(name: name). with(key: name, parent: self, - description: "#{name} job definition.") + description: "#{name} job definition.") @entries[name] = factory.create! end diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index fd43a224b3d..d80bc748209 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -91,11 +91,12 @@ module Gitlab our_highlight = Gitlab::Highlight.highlight(our_path, our_file, repository: repository).lines lines.each do |line| - line.rich_text = if line.type == 'old' - their_highlight[line.old_line - 1].try(:html_safe) - else - our_highlight[line.new_line - 1].try(:html_safe) - end + line.rich_text = + if line.type == 'old' + their_highlight[line.old_line - 1].try(:html_safe) + else + our_highlight[line.new_line - 1].try(:html_safe) + end end end diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb index 81c93f1aab5..fc728123c97 100644 --- a/lib/gitlab/diff/position.rb +++ b/lib/gitlab/diff/position.rb @@ -140,15 +140,16 @@ module Gitlab def find_diff_file(repository) # We're at the initial commit, so just get that as we can't compare to anything. - compare = if Gitlab::Git.blank_ref?(start_sha) - Gitlab::Git::Commit.find(repository.raw_repository, head_sha) - else - Gitlab::Git::Compare.new( - repository.raw_repository, - start_sha, - head_sha - ) - end + compare = + if Gitlab::Git.blank_ref?(start_sha) + Gitlab::Git::Commit.find(repository.raw_repository, head_sha) + else + Gitlab::Git::Compare.new( + repository.raw_repository, + start_sha, + head_sha + ) + end diff = compare.diffs(paths: paths).first diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 4ddfd78130e..558df87f36d 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -31,11 +31,12 @@ module Gitlab private def select_body(message) - part = if message.multipart? - message.text_part || message.html_part || message - else - message - end + part = + if message.multipart? + message.text_part || message.html_part || message + else + message + end decoded = fix_charset(part) diff --git a/lib/gitlab/metrics/instrumentation.rb b/lib/gitlab/metrics/instrumentation.rb index 9a07abfed06..6aa38542cb4 100644 --- a/lib/gitlab/metrics/instrumentation.rb +++ b/lib/gitlab/metrics/instrumentation.rb @@ -143,11 +143,12 @@ module Gitlab # signature this would break things. As a result we'll make sure the # generated method _only_ accepts regular arguments if the underlying # method also accepts them. - args_signature = if method.arity == 0 - '' - else - '*args' - end + args_signature = + if method.arity == 0 + '' + else + '*args' + end proxy_module.class_eval <<-EOF, __FILE__, __LINE__ + 1 def #{name}(#{args_signature}) diff --git a/lib/gitlab/saml/user.rb b/lib/gitlab/saml/user.rb index abde05d9b68..8a7cc690046 100644 --- a/lib/gitlab/saml/user.rb +++ b/lib/gitlab/saml/user.rb @@ -28,11 +28,12 @@ module Gitlab if external_users_enabled? && @user # Check if there is overlap between the user's groups and the external groups # setting then set user as external or internal. - @user.external = if (auth_hash.groups & Gitlab::Saml::Config.external_groups).empty? - false - else - true - end + @user.external = + if (auth_hash.groups & Gitlab::Saml::Config.external_groups).empty? + false + else + true + end end @user diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index a1a6929103b..ccfa517e04b 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -56,11 +56,12 @@ module Gitlab def issues issues = IssuesFinder.new(current_user).execute.where(project_id: project_ids_relation) - issues = if query =~ /#(\d+)\z/ - issues.where(iid: $1) - else - issues.full_search(query) - end + issues = + if query =~ /#(\d+)\z/ + issues.where(iid: $1) + else + issues.full_search(query) + end issues.order('updated_at DESC') end @@ -73,11 +74,12 @@ module Gitlab def merge_requests merge_requests = MergeRequestsFinder.new(current_user).execute.in_projects(project_ids_relation) - merge_requests = if query =~ /[#!](\d+)\z/ - merge_requests.where(iid: $1) - else - merge_requests.full_search(query) - end + merge_requests = + if query =~ /[#!](\d+)\z/ + merge_requests.where(iid: $1) + else + merge_requests.full_search(query) + end merge_requests.order('updated_at DESC') end diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 3be8d3aec9c..7374d2bc8b8 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -83,7 +83,7 @@ module Gitlab # Timeout should be less than 900 ideally, to prevent the memory killer # to silently kill the process without knowing we are timing out here. output, status = Popen.popen([gitlab_shell_projects_path, 'import-project', - storage, "#{name}.git", url, '800']) + storage, "#{name}.git", url, '800']) raise Error, output unless status.zero? true end diff --git a/lib/gitlab/sherlock/query.rb b/lib/gitlab/sherlock/query.rb index 086fcddf721..99e56e923eb 100644 --- a/lib/gitlab/sherlock/query.rb +++ b/lib/gitlab/sherlock/query.rb @@ -94,11 +94,12 @@ module Gitlab private def raw_explain(query) - explain = if Gitlab::Database.postgresql? - "EXPLAIN ANALYZE #{query};" - else - "EXPLAIN #{query};" - end + explain = + if Gitlab::Database.postgresql? + "EXPLAIN ANALYZE #{query};" + else + "EXPLAIN #{query};" + end ActiveRecord::Base.connection.execute(explain) end diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index 2867fcf8819..b90bf6268fd 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -47,11 +47,12 @@ describe 'issuable list', feature: true do def create_issuables(issuable_type) 3.times do - issuable = if issuable_type == :issue - create(:issue, project: project, author: user) - else - create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) - end + issuable = + if issuable_type == :issue + create(:issue, project: project, author: user) + else + create(:merge_request, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) + end 2.times do create(:note_on_issue, noteable: issuable, project: project, note: 'Test note') diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 372546e92a5..4a9cbba69f9 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -56,7 +56,7 @@ describe IssuesHelper do subject { merge_requests_sentence(merge_requests)} let(:merge_requests) do [build(:merge_request, iid: 1), build(:merge_request, iid: 2), - build(:merge_request, iid: 3)] + build(:merge_request, iid: 3)] end it { is_expected.to eq("!1, !2, or !3") } diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index c3551a149ed..3b2d043301e 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::Ci::Config::Entry::Global do it 'contains the expected node names' do expect(described_class.nodes.keys). to match_array(%i[before_script image services - after_script variables stages - types cache]) + after_script variables stages + types cache]) end end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index b90308a0515..82feff0af1c 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -140,11 +140,11 @@ describe Gitlab::Ci::Config::Entry::Job do it 'returns correct value' do expect(entry.value). to eq(name: :rspec, - before_script: %w[ls pwd], - script: %w[rspec], - commands: "ls\npwd\nrspec", - stage: 'test', - after_script: %w[cleanup]) + before_script: %w[ls pwd], + script: %w[rspec], + commands: "ls\npwd\nrspec", + stage: 'test', + after_script: %w[cleanup]) end end end diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index 3d1ebadadcc..aa026a66460 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -69,7 +69,7 @@ describe Gitlab::Ci::Status::Build::Factory do it 'matches correct extended statuses' do expect(factory.extended_statuses). to eq [Gitlab::Ci::Status::Build::Retryable, - Gitlab::Ci::Status::Build::FailedAllowed] + Gitlab::Ci::Status::Build::FailedAllowed] end it 'fabricates a failed but allowed build status' do diff --git a/spec/lib/gitlab/incoming_email_spec.rb b/spec/lib/gitlab/incoming_email_spec.rb index 06d39d5c782..d54753ccf90 100644 --- a/spec/lib/gitlab/incoming_email_spec.rb +++ b/spec/lib/gitlab/incoming_email_spec.rb @@ -101,8 +101,8 @@ describe Gitlab::IncomingEmail, lib: true do it 'returns reply key' do expect(described_class.scan_fallback_references(references)). to eq(%w[issue_1@localhost - reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost - exchange@microsoft.com]) + reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost + exchange@microsoft.com]) end end end diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 0575b95fd30..2c07c37b0ea 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -152,7 +152,7 @@ describe Gitlab::OAuth::User, lib: true do identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( [{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'twitter', extern_uid: uid } + { provider: 'twitter', extern_uid: uid } ]) end end @@ -171,7 +171,7 @@ describe Gitlab::OAuth::User, lib: true do identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( [{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'twitter', extern_uid: uid } + { provider: 'twitter', extern_uid: uid } ]) end end diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index 844b9446603..00dd29f3e5d 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -158,7 +158,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'saml', extern_uid: uid } + { provider: 'saml', extern_uid: uid } ]) end end @@ -181,7 +181,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'saml', extern_uid: uid } + { provider: 'saml', extern_uid: uid } ]) end @@ -207,7 +207,7 @@ describe Gitlab::Saml::User, lib: true do expect(local_gl_user.identities.length).to eql 2 identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } + { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } ]) end end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 2611a0be92f..eaff27efd5d 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1263,7 +1263,7 @@ describe Ci::Build, :models do context 'when build has user' do let(:user_variables) do [{ key: 'GITLAB_USER_ID', value: user.id.to_s, public: true }, - { key: 'GITLAB_USER_EMAIL', value: user.email, public: true }] + { key: 'GITLAB_USER_EMAIL', value: user.email, public: true }] end before do diff --git a/spec/support/issuables_list_metadata_shared_examples.rb b/spec/support/issuables_list_metadata_shared_examples.rb index c61f3e05cea..4644c7a6b86 100644 --- a/spec/support/issuables_list_metadata_shared_examples.rb +++ b/spec/support/issuables_list_metadata_shared_examples.rb @@ -3,11 +3,12 @@ shared_examples 'issuables list meta-data' do |issuable_type, action = nil| @issuable_ids = [] 2.times do - issuable = if issuable_type == :issue - create(issuable_type, project: project) - else - create(issuable_type, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) - end + issuable = + if issuable_type == :issue + create(issuable_type, project: project) + else + create(issuable_type, title: FFaker::Lorem.sentence, source_project: project, source_branch: FFaker::Name.name) + end @issuable_ids << issuable.id diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index b94ffa30736..dd4c7287655 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -15,11 +15,12 @@ module LoginHelpers # user = create(:user) # login_as(user) def login_as(user_or_role) - @user = if user_or_role.kind_of?(User) - user_or_role - else - create(user_or_role) - end + @user = + if user_or_role.kind_of?(User) + user_or_role + else + create(user_or_role) + end login_with(@user) end From 0b27d63359cdc6968cbb48b56bd168bddc09950e Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 09:13:02 -0600 Subject: [PATCH 220/247] =?UTF-8?q?Old=20migration=20doesn=E2=80=99t=20req?= =?UTF-8?q?uire=20downtime?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/20160610201627_migrate_users_notification_level.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/migrate/20160610201627_migrate_users_notification_level.rb b/db/migrate/20160610201627_migrate_users_notification_level.rb index 798e315102e..9da67b59dd1 100644 --- a/db/migrate/20160610201627_migrate_users_notification_level.rb +++ b/db/migrate/20160610201627_migrate_users_notification_level.rb @@ -2,6 +2,8 @@ class MigrateUsersNotificationLevel < ActiveRecord::Migration # Migrates only users who changed their default notification level :participating # creating a new record on notification settings table + DOWNTIME = false + def up execute(%{ INSERT INTO notification_settings From f72a65603db4dfdb41f327ab03892eed5dadb57e Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 10:50:04 -0600 Subject: [PATCH 221/247] Fix another spec --- spec/lib/gitlab/metrics/method_call_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb index 16c6de0bee6..a247f03b2da 100644 --- a/spec/lib/gitlab/metrics/method_call_spec.rb +++ b/spec/lib/gitlab/metrics/method_call_spec.rb @@ -23,7 +23,7 @@ describe Gitlab::Metrics::MethodCall do expect(metric.values[:duration]).to be_a_kind_of(Numeric) expect(metric.values[:cpu_duration]).to be_a_kind_of(Numeric) - expect(metric.values[:call_count]).to an_instance_of(Integer) + expect(metric.values[:call_count]).to be_an(Integer) expect(metric.tags).to eq({ method: 'Foo#bar' }) end From 206953a430e442fbbd06984b1120890dbf8d3f79 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 10:55:08 -0600 Subject: [PATCH 222/247] Prefer leading style for Style/DotPosition --- .rubocop.yml | 2 +- .../admin/application_settings_controller.rb | 6 +- app/controllers/concerns/creates_commit.rb | 4 +- app/controllers/concerns/issues_action.rb | 6 +- .../concerns/membership_actions.rb | 4 +- .../concerns/merge_requests_action.rb | 4 +- .../import/bitbucket_controller.rb | 6 +- app/controllers/jwt_controller.rb | 4 +- .../omniauth_callbacks_controller.rb | 4 +- app/controllers/profiles_controller.rb | 6 +- app/controllers/projects/badges_controller.rb | 8 +- app/controllers/projects/blob_controller.rb | 4 +- .../projects/boards/issues_controller.rb | 8 +- .../projects/branches_controller.rb | 4 +- app/controllers/projects/builds_controller.rb | 4 +- app/controllers/projects/commit_controller.rb | 6 +- .../projects/commits_controller.rb | 8 +- .../projects/compare_controller.rb | 8 +- .../projects/environments_controller.rb | 22 +-- app/controllers/projects/issues_controller.rb | 10 +- .../projects/merge_requests_controller.rb | 36 ++-- .../projects/pipelines_controller.rb | 24 +-- .../projects/project_members_controller.rb | 4 +- .../projects/settings/ci_cd_controller.rb | 4 +- .../projects/settings/members_controller.rb | 8 +- app/controllers/projects/tags_controller.rb | 4 +- .../projects/uploads_controller.rb | 4 +- app/controllers/projects_controller.rb | 4 +- app/controllers/sessions_controller.rb | 4 +- .../sherlock/application_controller.rb | 4 +- app/controllers/snippets_controller.rb | 8 +- app/controllers/users_controller.rb | 14 +- app/finders/environments_finder.rb | 10 +- app/finders/group_members_finder.rb | 6 +- app/helpers/form_helper.rb | 8 +- app/helpers/search_helper.rb | 4 +- app/helpers/wiki_helper.rb | 6 +- app/models/award_emoji.rb | 6 +- app/models/ci/build.rb | 22 +-- app/models/ci/pipeline.rb | 44 ++--- app/models/ci/runner.rb | 8 +- app/models/ci/stage.rb | 6 +- app/models/commit_status.rb | 10 +- app/models/concerns/issuable.rb | 6 +- app/models/concerns/mentionable.rb | 4 +- app/models/concerns/milestoneish.rb | 4 +- app/models/concerns/presentable.rb | 6 +- app/models/concerns/routable.rb | 8 +- app/models/concerns/sortable.rb | 12 +- app/models/concerns/subscribable.rb | 26 +-- app/models/deployment.rb | 22 +-- app/models/environment.rb | 6 +- app/models/event.rb | 6 +- app/models/generic_commit_status.rb | 6 +- app/models/global_milestone.rb | 4 +- app/models/group.rb | 10 +- app/models/issue_collection.rb | 6 +- app/models/label.rb | 18 +- app/models/lfs_object.rb | 6 +- app/models/member.rb | 12 +- app/models/merge_request.rb | 18 +- app/models/merge_request_diff.rb | 4 +- app/models/merge_requests_closing_issues.rb | 6 +- app/models/milestone.rb | 14 +- app/models/namespace.rb | 14 +- app/models/network/commit.rb | 4 +- app/models/network/graph.rb | 12 +- app/models/note.rb | 10 +- app/models/project.rb | 22 +-- .../project_services/kubernetes_service.rb | 6 +- .../mattermost_slash_commands_service.rb | 4 +- app/models/project_team.rb | 8 +- app/models/repository.rb | 12 +- app/models/todo.rb | 6 +- app/models/user.rb | 54 +++--- app/models/wiki_page.rb | 10 +- app/serializers/base_serializer.rb | 6 +- app/serializers/environment_serializer.rb | 6 +- app/services/after_branch_delete_service.rb | 6 +- app/services/boards/issues/list_service.rb | 8 +- app/services/boards/lists/destroy_service.rb | 4 +- app/services/boards/lists/move_service.rb | 12 +- .../ci/create_pipeline_builds_service.rb | 4 +- app/services/ci/create_pipeline_service.rb | 6 +- .../ci/create_trigger_request_service.rb | 4 +- app/services/ci/process_pipeline_service.rb | 6 +- app/services/ci/register_build_service.rb | 14 +- app/services/ci/retry_build_service.rb | 10 +- app/services/ci/retry_pipeline_service.rb | 10 +- app/services/commits/change_service.rb | 4 +- app/services/create_branch_service.rb | 4 +- app/services/files/base_service.rb | 4 +- app/services/files/update_service.rb | 4 +- app/services/git_push_service.rb | 14 +- app/services/issuable_base_service.rb | 4 +- app/services/issues/create_service.rb | 4 +- app/services/issues/move_service.rb | 4 +- app/services/labels/promote_service.rb | 28 +-- app/services/labels/transfer_service.rb | 20 +- app/services/merge_requests/base_service.rb | 10 +- app/services/merge_requests/merge_service.rb | 4 +- .../merge_requests/refresh_service.rb | 16 +- app/services/notes/slash_commands_service.rb | 4 +- app/services/tags/create_service.rb | 4 +- .../refresh_authorized_projects_service.rb | 10 +- app/workers/build_coverage_worker.rb | 4 +- app/workers/build_hooks_worker.rb | 4 +- app/workers/emails_on_push_worker.rb | 8 +- .../expire_build_instance_artifacts_worker.rb | 8 +- app/workers/merge_worker.rb | 4 +- app/workers/pipeline_hooks_worker.rb | 4 +- app/workers/pipeline_process_worker.rb | 4 +- app/workers/pipeline_success_worker.rb | 6 +- app/workers/pipeline_update_worker.rb | 4 +- app/workers/process_commit_worker.rb | 8 +- app/workers/project_cache_worker.rb | 6 +- app/workers/prune_old_events_worker.rb | 8 +- app/workers/repository_check/batch_worker.rb | 8 +- config/initializers/metrics.rb | 4 +- ...1322_migrate_process_commit_worker_jobs.rb | 6 +- ...31620_fixup_environment_name_uniqueness.rb | 32 ++-- .../20161207231626_add_environment_slug.rb | 8 +- ...project_records_with_invalid_visibility.rb | 22 +-- ...221153951_rename_reserved_project_names.rb | 12 +- ...4150317_requeue_pending_delete_projects.rb | 12 +- ...20170106142508_fill_authorized_projects.rb | 4 +- lib/api/access_requests.rb | 4 +- lib/api/branches.rb | 8 +- lib/api/entities.rb | 6 +- lib/api/issues.rb | 6 +- lib/api/merge_requests.rb | 18 +- lib/api/notes.rb | 4 +- lib/api/pipelines.rb | 4 +- lib/api/tags.rb | 16 +- lib/api/users.rb | 30 +-- lib/api/v3/issues.rb | 6 +- lib/api/v3/merge_requests.rb | 18 +- lib/banzai/pipeline/wiki_pipeline.rb | 4 +- lib/banzai/reference_extractor.rb | 8 +- lib/banzai/reference_parser/issue_parser.rb | 4 +- lib/banzai/reference_parser/user_parser.rb | 4 +- lib/ci/charts.rb | 26 +-- lib/ci/gitlab_ci_yaml_processor.rb | 4 +- lib/gitlab/badge/build/status.rb | 6 +- lib/gitlab/badge/coverage/report.rb | 6 +- lib/gitlab/bitbucket_import/importer.rb | 8 +- lib/gitlab/checks/matching_merge_request.rb | 8 +- lib/gitlab/ci/config/entry/configurable.rb | 10 +- lib/gitlab/ci/config/entry/global.rb | 6 +- lib/gitlab/ci/config/entry/jobs.rb | 8 +- lib/gitlab/ci/pipeline_duration.rb | 4 +- lib/gitlab/ci/status/factory.rb | 8 +- lib/gitlab/ci/trace_reader.rb | 4 +- lib/gitlab/contributions_calendar.rb | 46 ++--- lib/gitlab/cycle_analytics/base_query.rb | 18 +- lib/gitlab/database/median.rb | 22 +-- lib/gitlab/database/migration_helpers.rb | 18 +- lib/gitlab/downtime_check.rb | 4 +- lib/gitlab/git/encoding_helper.rb | 6 +- lib/gitlab/github_import/importer.rb | 6 +- lib/gitlab/github_import/user_formatter.rb | 14 +- lib/gitlab/highlight.rb | 4 +- lib/gitlab/ldap/user.rb | 6 +- lib/gitlab/metrics.rb | 4 +- lib/gitlab/metrics/system.rb | 8 +- lib/gitlab/other_markup.rb | 4 +- lib/gitlab/shell.rb | 4 +- lib/gitlab/sherlock/line_profiler.rb | 4 +- lib/gitlab/sherlock/query.rb | 8 +- rubocop/cop/gem_fetcher.rb | 12 +- rubocop/migration_helpers.rb | 4 +- .../admin/users_controller_spec.rb | 4 +- spec/controllers/blob_controller_spec.rb | 4 +- .../ci/projects_controller_spec.rb | 4 +- .../import/bitbucket_controller_spec.rb | 46 ++--- .../import/github_controller_spec.rb | 8 +- .../import/gitlab_controller_spec.rb | 46 ++--- .../projects/branches_controller_spec.rb | 12 +- .../projects/commit_controller_spec.rb | 4 +- .../projects/environments_controller_spec.rb | 14 +- .../projects/issues_controller_spec.rb | 12 +- .../projects/mattermosts_controller_spec.rb | 4 +- .../merge_requests_controller_spec.rb | 24 +-- .../projects/raw_controller_spec.rb | 4 +- .../projects/snippets_controller_spec.rb | 32 ++-- .../projects/tree_controller_spec.rb | 12 +- .../sent_notifications_controller_spec.rb | 8 +- spec/controllers/sessions_controller_spec.rb | 28 +-- spec/controllers/snippets_controller_spec.rb | 32 ++-- spec/factories/projects.rb | 4 +- spec/features/admin/admin_projects_spec.rb | 4 +- spec/features/admin/admin_users_spec.rb | 8 +- spec/features/atom/dashboard_spec.rb | 4 +- spec/features/atom/issues_spec.rb | 8 +- spec/features/atom/users_spec.rb | 4 +- spec/features/environments_spec.rb | 4 +- .../features/gitlab_flavored_markdown_spec.rb | 4 +- spec/features/login_spec.rb | 4 +- spec/features/markdown_spec.rb | 16 +- .../merge_requests/created_from_fork_spec.rb | 4 +- spec/features/notes_on_merge_requests_spec.rb | 12 +- .../projects/pipelines/pipelines_spec.rb | 4 +- spec/finders/environments_finder_spec.rb | 44 ++--- spec/helpers/application_helper_spec.rb | 32 ++-- .../helpers/broadcast_messages_helper_spec.rb | 4 +- spec/helpers/commits_helper_spec.rb | 8 +- spec/helpers/form_helper_spec.rb | 12 +- spec/helpers/gitlab_markdown_helper_spec.rb | 16 +- spec/helpers/groups_helper_spec.rb | 4 +- spec/helpers/import_helper_spec.rb | 20 +- spec/helpers/issuables_helper_spec.rb | 40 ++-- spec/helpers/issues_helper_spec.rb | 12 +- spec/helpers/labels_helper_spec.rb | 4 +- spec/helpers/merge_requests_helper_spec.rb | 4 +- spec/helpers/page_layout_helper_spec.rb | 8 +- spec/helpers/preferences_helper_spec.rb | 16 +- spec/helpers/visibility_level_helper_spec.rb | 32 ++-- spec/lib/api/helpers/pagination_spec.rb | 12 +- .../banzai/cross_project_reference_spec.rb | 4 +- .../filter/abstract_reference_filter_spec.rb | 28 +-- .../commit_range_reference_filter_spec.rb | 36 ++-- .../filter/commit_reference_filter_spec.rb | 8 +- .../external_issue_reference_filter_spec.rb | 8 +- .../filter/issue_reference_filter_spec.rb | 70 +++---- .../filter/label_reference_filter_spec.rb | 104 +++++------ .../merge_request_reference_filter_spec.rb | 20 +- .../filter/milestone_reference_filter_spec.rb | 68 +++---- .../lib/banzai/filter/redactor_filter_spec.rb | 6 +- .../banzai/filter/reference_filter_spec.rb | 4 +- .../filter/relative_link_filter_spec.rb | 48 ++--- .../banzai/filter/sanitization_filter_spec.rb | 4 +- .../filter/snippet_reference_filter_spec.rb | 20 +- .../banzai/filter/upload_link_filter_spec.rb | 24 +-- .../filter/user_reference_filter_spec.rb | 4 +- spec/lib/banzai/note_renderer_spec.rb | 12 +- spec/lib/banzai/object_renderer_spec.rb | 20 +- spec/lib/banzai/redactor_spec.rb | 22 +-- .../reference_parser/base_parser_spec.rb | 110 +++++------ .../reference_parser/commit_parser_spec.rb | 32 ++-- .../commit_range_parser_spec.rb | 24 +-- .../reference_parser/issue_parser_spec.rb | 12 +- .../reference_parser/user_parser_spec.rb | 24 +-- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 20 +- spec/lib/container_registry/blob_spec.rb | 20 +- .../lib/container_registry/repository_spec.rb | 6 +- spec/lib/container_registry/tag_spec.rb | 40 ++-- spec/lib/extracts_path_spec.rb | 4 +- spec/lib/gitlab/asciidoc_spec.rb | 8 +- spec/lib/gitlab/auth_spec.rb | 8 +- spec/lib/gitlab/backup/manager_spec.rb | 16 +- spec/lib/gitlab/badge/build/status_spec.rb | 4 +- .../gitlab/bitbucket_import/importer_spec.rb | 6 +- .../ci/build/artifacts/metadata_spec.rb | 12 +- .../gitlab/ci/config/entry/artifacts_spec.rb | 8 +- .../ci/config/entry/attributable_spec.rb | 12 +- .../gitlab/ci/config/entry/boolean_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/cache_spec.rb | 12 +- .../gitlab/ci/config/entry/commands_spec.rb | 4 +- .../ci/config/entry/configurable_spec.rb | 4 +- .../ci/config/entry/environment_spec.rb | 16 +- .../gitlab/ci/config/entry/factory_spec.rb | 52 +++--- .../lib/gitlab/ci/config/entry/global_spec.rb | 44 ++--- spec/lib/gitlab/ci/config/entry/image_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/job_spec.rb | 8 +- spec/lib/gitlab/ci/config/entry/jobs_spec.rb | 16 +- spec/lib/gitlab/ci/config/entry/key_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/paths_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/script_spec.rb | 4 +- .../gitlab/ci/config/entry/services_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/stage_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/stages_spec.rb | 4 +- .../gitlab/ci/config/entry/trigger_spec.rb | 4 +- .../ci/config/entry/validatable_spec.rb | 4 +- .../gitlab/ci/config/entry/validator_spec.rb | 4 +- .../gitlab/ci/config/entry/variables_spec.rb | 4 +- .../lib/gitlab/ci/status/build/common_spec.rb | 6 +- .../gitlab/ci/status/build/factory_spec.rb | 32 ++-- spec/lib/gitlab/ci/status/extended_spec.rb | 4 +- .../gitlab/ci/status/external/common_spec.rb | 6 +- spec/lib/gitlab/ci/status/factory_spec.rb | 16 +- .../gitlab/ci/status/pipeline/common_spec.rb | 10 +- .../gitlab/ci/status/pipeline/factory_spec.rb | 8 +- .../lib/gitlab/ci/status/stage/common_spec.rb | 12 +- .../gitlab/ci/status/stage/factory_spec.rb | 4 +- .../gitlab/closing_issue_extractor_spec.rb | 32 ++-- spec/lib/gitlab/conflict/file_spec.rb | 24 +-- spec/lib/gitlab/conflict/parser_spec.rb | 60 +++--- spec/lib/gitlab/data_builder/note_spec.rb | 36 ++-- spec/lib/gitlab/data_builder/push_spec.rb | 4 +- .../gitlab/database/migration_helpers_spec.rb | 64 +++---- spec/lib/gitlab/database_spec.rb | 12 +- spec/lib/gitlab/downtime_check_spec.rb | 32 ++-- spec/lib/gitlab/email/reply_parser_spec.rb | 36 ++-- spec/lib/gitlab/file_detector_spec.rb | 8 +- spec/lib/gitlab/git/attributes_spec.rb | 44 ++--- spec/lib/gitlab/git/blob_spec.rb | 6 +- spec/lib/gitlab/git/diff_collection_spec.rb | 16 +- spec/lib/gitlab/git/diff_spec.rb | 8 +- spec/lib/gitlab/git/repository_spec.rb | 4 +- .../lib/gitlab/gitlab_import/importer_spec.rb | 4 +- spec/lib/gitlab/identifier_spec.rb | 12 +- .../import_export/avatar_restorer_spec.rb | 4 +- spec/lib/gitlab/incoming_email_spec.rb | 4 +- spec/lib/gitlab/job_waiter_spec.rb | 10 +- spec/lib/gitlab/ldap/adapter_spec.rb | 4 +- spec/lib/gitlab/ldap/authentication_spec.rb | 12 +- spec/lib/gitlab/ldap/user_spec.rb | 4 +- .../gitlab/metrics/instrumentation_spec.rb | 32 ++-- .../gitlab/metrics/rack_middleware_spec.rb | 12 +- spec/lib/gitlab/metrics/sampler_spec.rb | 54 +++--- .../gitlab/metrics/sidekiq_middleware_spec.rb | 36 ++-- .../metrics/subscribers/action_view_spec.rb | 8 +- .../metrics/subscribers/active_record_spec.rb | 18 +- .../metrics/subscribers/rails_cache_spec.rb | 80 ++++---- spec/lib/gitlab/metrics/transaction_spec.rb | 28 +-- spec/lib/gitlab/metrics_spec.rb | 48 ++--- spec/lib/gitlab/o_auth/user_spec.rb | 4 +- spec/lib/gitlab/route_map_spec.rb | 24 +-- spec/lib/gitlab/serializer/pagination_spec.rb | 8 +- spec/lib/gitlab/sherlock/file_sample_spec.rb | 4 +- .../lib/gitlab/sherlock/line_profiler_spec.rb | 6 +- spec/lib/gitlab/sherlock/middleware_spec.rb | 4 +- spec/lib/gitlab/sherlock/query_spec.rb | 4 +- spec/lib/gitlab/sherlock/transaction_spec.rb | 28 +-- .../sidekiq_status/client_middleware_spec.rb | 4 +- .../sidekiq_status/server_middleware_spec.rb | 4 +- spec/lib/gitlab/url_builder_spec.rb | 4 +- .../gitlab/view/presenter/delegated_spec.rb | 4 +- spec/lib/light_url_builder_spec.rb | 4 +- spec/lib/mattermost/command_spec.rb | 16 +- spec/lib/mattermost/session_spec.rb | 14 +- spec/lib/mattermost/team_spec.rb | 12 +- spec/mailers/abuse_report_mailer_spec.rb | 4 +- ...migrate_process_commit_worker_jobs_spec.rb | 54 +++--- spec/models/ability_spec.rb | 56 +++--- spec/models/abuse_report_spec.rb | 4 +- spec/models/application_setting_spec.rb | 6 +- spec/models/ci/build_spec.rb | 20 +- spec/models/ci/pipeline_spec.rb | 12 +- spec/models/ci/variable_spec.rb | 4 +- spec/models/commit_range_spec.rb | 6 +- spec/models/commit_status_spec.rb | 4 +- spec/models/concerns/case_sensitivity_spec.rb | 148 +++++++-------- spec/models/concerns/has_status_spec.rb | 4 +- spec/models/concerns/issuable_spec.rb | 36 ++-- spec/models/discussion_spec.rb | 12 +- spec/models/email_spec.rb | 4 +- spec/models/environment_spec.rb | 6 +- spec/models/event_spec.rb | 4 +- spec/models/group_label_spec.rb | 4 +- spec/models/group_spec.rb | 4 +- spec/models/issue_collection_spec.rb | 4 +- spec/models/issue_spec.rb | 8 +- spec/models/key_spec.rb | 8 +- spec/models/lfs_objects_project_spec.rb | 8 +- spec/models/member_spec.rb | 8 +- spec/models/members/group_member_spec.rb | 8 +- spec/models/merge_request_diff_spec.rb | 8 +- spec/models/merge_request_spec.rb | 72 ++++---- spec/models/milestone_spec.rb | 8 +- spec/models/namespace_spec.rb | 4 +- spec/models/note_spec.rb | 16 +- spec/models/project_authorization_spec.rb | 4 +- spec/models/project_label_spec.rb | 12 +- .../mattermost_slash_commands_service_spec.rb | 24 +-- spec/models/project_spec.rb | 56 +++--- spec/models/project_wiki_spec.rb | 24 +-- spec/models/repository_spec.rb | 174 +++++++++--------- spec/models/user_spec.rb | 16 +- spec/models/wiki_page_spec.rb | 4 +- spec/policies/project_policy_spec.rb | 4 +- spec/presenters/ci/build_presenter_spec.rb | 4 +- spec/requests/api/broadcast_messages_spec.rb | 12 +- spec/requests/api/commit_statuses_spec.rb | 4 +- spec/requests/api/files_spec.rb | 4 +- spec/requests/api/groups_spec.rb | 12 +- spec/requests/api/internal_spec.rb | 4 +- spec/requests/api/merge_requests_spec.rb | 4 +- spec/requests/api/notes_spec.rb | 4 +- spec/requests/api/project_snippets_spec.rb | 32 ++-- spec/requests/api/projects_spec.rb | 24 +-- spec/requests/api/runners_spec.rb | 8 +- spec/requests/api/snippets_spec.rb | 32 ++-- spec/requests/api/users_spec.rb | 32 ++-- spec/requests/api/v3/files_spec.rb | 4 +- spec/requests/api/v3/merge_requests_spec.rb | 4 +- spec/requests/api/v3/project_snippets_spec.rb | 32 ++-- spec/requests/api/v3/projects_spec.rb | 24 +-- spec/requests/ci/api/builds_spec.rb | 16 +- spec/requests/git_http_spec.rb | 8 +- .../analytics_build_serializer_spec.rb | 4 +- .../analytics_issue_serializer_spec.rb | 6 +- ...analytics_merge_request_serializer_spec.rb | 6 +- .../analytics_summary_serializer_spec.rb | 8 +- .../serializers/build_artifact_entity_spec.rb | 4 +- spec/serializers/commit_entity_spec.rb | 4 +- .../environment_serializer_spec.rb | 32 ++-- spec/serializers/pipeline_entity_spec.rb | 12 +- spec/serializers/pipeline_serializer_spec.rb | 10 +- spec/serializers/request_aware_entity_spec.rb | 4 +- spec/serializers/stage_entity_spec.rb | 8 +- .../ci/process_pipeline_service_spec.rb | 8 +- spec/services/ci/retry_build_service_spec.rb | 12 +- .../ci/retry_pipeline_service_spec.rb | 8 +- .../ci/stop_environments_service_spec.rb | 16 +- .../ci/update_build_queue_service_spec.rb | 16 +- spec/services/files/update_service_spec.rb | 4 +- spec/services/git_push_service_spec.rb | 42 ++--- .../issuable/bulk_update_service_spec.rb | 20 +- spec/services/issues/close_service_spec.rb | 16 +- spec/services/issues/move_service_spec.rb | 20 +- spec/services/labels/promote_service_spec.rb | 6 +- spec/services/members/destroy_service_spec.rb | 4 +- .../add_todo_when_build_fails_service_spec.rb | 16 +- .../merge_requests/close_service_spec.rb | 4 +- .../merge_requests/merge_service_spec.rb | 6 +- ...rge_when_pipeline_succeeds_service_spec.rb | 20 +- .../merge_requests/refresh_service_spec.rb | 12 +- .../merge_requests/reopen_service_spec.rb | 4 +- .../merge_requests/resolve_service_spec.rb | 24 +-- .../merge_requests/update_service_spec.rb | 8 +- .../projects/housekeeping_service_spec.rb | 12 +- spec/services/projects/import_service_spec.rb | 18 +- .../projects/transfer_service_spec.rb | 14 +- .../projects/unlink_fork_service_spec.rb | 6 +- spec/services/system_note_service_spec.rb | 76 ++++---- spec/services/tags/create_service_spec.rb | 12 +- spec/services/todo_service_spec.rb | 8 +- ...ser_project_access_changed_service_spec.rb | 4 +- ...efresh_authorized_projects_service_spec.rb | 20 +- ...ubish_import_controller_shared_examples.rb | 64 +++---- spec/support/ldap_helpers.rb | 8 +- spec/support/mentionable_shared_examples.rb | 12 +- spec/support/reactive_caching_helpers.rb | 6 +- spec/support/services_shared_context.rb | 6 +- ...attermost_notifications_shared_examples.rb | 42 ++--- spec/support/stub_configuration.rb | 4 +- spec/support/stub_gitlab_calls.rb | 38 ++-- spec/support/test_env.rb | 8 +- spec/tasks/gitlab/backup_rake_spec.rb | 20 +- spec/tasks/gitlab/check_rake_spec.rb | 4 +- spec/tasks/gitlab/shell_rake_spec.rb | 4 +- spec/tasks/gitlab/task_helpers_spec.rb | 32 ++-- spec/tasks/gitlab/workhorse_rake_spec.rb | 8 +- .../shared/_signin_box.html.haml_spec.rb | 4 +- spec/views/layouts/_head.html.haml_spec.rb | 4 +- .../merge_requests/edit.html.haml_spec.rb | 4 +- spec/workers/build_coverage_worker_spec.rb | 8 +- spec/workers/build_finished_worker_spec.rb | 20 +- spec/workers/build_hooks_worker_spec.rb | 8 +- spec/workers/build_success_worker_spec.rb | 12 +- spec/workers/delete_user_worker_spec.rb | 8 +- spec/workers/every_sidekiq_worker_spec.rb | 10 +- .../git_garbage_collect_worker_spec.rb | 4 +- spec/workers/new_note_worker_spec.rb | 4 +- spec/workers/pipeline_hooks_worker_spec.rb | 8 +- .../pipeline_notification_worker_spec.rb | 20 +- spec/workers/pipeline_proccess_worker_spec.rb | 4 +- spec/workers/pipeline_success_worker_spec.rb | 4 +- spec/workers/pipeline_update_worker_spec.rb | 4 +- spec/workers/post_receive_spec.rb | 6 +- spec/workers/process_commit_worker_spec.rb | 20 +- spec/workers/project_cache_worker_spec.rb | 34 ++-- spec/workers/repository_fork_worker_spec.rb | 8 +- spec/workers/repository_import_worker_spec.rb | 8 +- spec/workers/use_key_worker_spec.rb | 4 +- 466 files changed, 3214 insertions(+), 3214 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 70e11be29cf..2ce32ca5002 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -138,7 +138,7 @@ Style/Documentation: Style/DotPosition: Enabled: true - EnforcedStyle: trailing + EnforcedStyle: leading # Align elses and elsifs correctly. Style/ElseAlignment: diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index f801fac1839..b0f5d4a9933 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -5,9 +5,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end def update - successful = ApplicationSettings::UpdateService. - new(@application_setting, current_user, application_setting_params). - execute + successful = ApplicationSettings::UpdateService + .new(@application_setting, current_user, application_setting_params) + .execute if successful redirect_to admin_application_settings_path, diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 2fe03020d2d..41c660be378 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -83,8 +83,8 @@ module CreatesCommit def merge_request_exists? return @merge_request if defined?(@merge_request) - @merge_request = MergeRequestsFinder.new(current_user, project_id: @mr_target_project.id).execute.opened. - find_by(source_branch: @mr_source_branch, target_branch: @mr_target_branch, source_project_id: @mr_source_project) + @merge_request = MergeRequestsFinder.new(current_user, project_id: @mr_target_project.id).execute.opened + .find_by(source_branch: @mr_source_branch, target_branch: @mr_target_branch, source_project_id: @mr_source_project) end def different_project? diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index 8b985b6d003..b17c138d5c7 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -5,9 +5,9 @@ module IssuesAction def issues @label = issues_finder.labels.first - @issues = issues_collection. - non_archived. - page(params[:page]) + @issues = issues_collection + .non_archived + .page(params[:page]) @collection_type = "Issue" @issuable_meta_data = issuable_meta_data(@issues, @collection_type) diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index c13333641d3..43ca4b6ac02 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -15,8 +15,8 @@ module MembershipActions end def leave - member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id). - execute(:all) + member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id) + .execute(:all) source_type = membershipable.class.to_s.humanize(capitalize: false) notice = diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index 28e34cffc24..d3c8e4888bc 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -5,8 +5,8 @@ module MergeRequestsAction def merge_requests @label = merge_requests_finder.labels.first - @merge_requests = merge_requests_collection. - page(params[:page]) + @merge_requests = merge_requests_collection + .page(params[:page]) @collection_type = "MergeRequest" @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index cd5cef2c20f..8e42cdf415f 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -29,9 +29,9 @@ class Import::BitbucketController < Import::BaseController end def jobs - render json: current_user.created_projects. - where(import_type: 'bitbucket'). - to_json(only: [:id, :import_status]) + render json: current_user.created_projects + .where(import_type: 'bitbucket') + .to_json(only: [:id, :import_status]) end def create diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index cc3df3bd127..3eac6285394 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -11,8 +11,8 @@ class JwtController < ApplicationController service = SERVICES[params[:service]] return head :not_found unless service - result = service.new(@authentication_result.project, @authentication_result.actor, auth_params). - execute(authentication_abilities: @authentication_result.authentication_abilities) + result = service.new(@authentication_result.project, @authentication_result.actor, auth_params) + .execute(authentication_abilities: @authentication_result.authentication_abilities) render json: result, status: result[:http_status] end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 58d50ad647b..0faa446aff9 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -144,7 +144,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end def log_audit_event(user, options = {}) - AuditEventService.new(user, user, options). - for_authentication.security_event + AuditEventService.new(user, user, options) + .for_authentication.security_event end end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index f0c71725ea8..cc500af81db 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -41,9 +41,9 @@ class ProfilesController < Profiles::ApplicationController end def audit_log - @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id). - order("created_at DESC"). - page(params[:page]) + @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id) + .order("created_at DESC") + .page(params[:page]) end def update_username diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index c1727d9fa28..6c25cd83a24 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -4,15 +4,15 @@ class Projects::BadgesController < Projects::ApplicationController before_action :no_cache_headers, except: [:index] def build - build_status = Gitlab::Badge::Build::Status. - new(project, params[:ref]) + build_status = Gitlab::Badge::Build::Status + .new(project, params[:ref]) render_badge build_status end def coverage - coverage_report = Gitlab::Badge::Coverage::Report. - new(project, params[:ref], params[:job]) + coverage_report = Gitlab::Badge::Coverage::Report + .new(project, params[:ref], params[:job]) render_badge coverage_report end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 39ba815cfca..647faca40a0 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -164,7 +164,7 @@ class Projects::BlobController < Projects::ApplicationController end def set_last_commit_sha - @last_commit_sha = Gitlab::Git::Commit. - last_for_path(@repository, @ref, @path).sha + @last_commit_sha = Gitlab::Git::Commit + .last_for_path(@repository, @ref, @path).sha end end diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb index 8bcf18642cf..61fef4dc133 100644 --- a/app/controllers/projects/boards/issues_controller.rb +++ b/app/controllers/projects/boards/issues_controller.rb @@ -40,10 +40,10 @@ module Projects def issue @issue ||= - IssuesFinder.new(current_user, project_id: project.id). - execute. - where(iid: params[:id]). - first! + IssuesFinder.new(current_user, project_id: project.id) + .execute + .where(iid: params[:id]) + .first! end def authorize_read_issue! diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index 89d84809e3a..c37a0653ff9 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -32,8 +32,8 @@ class Projects::BranchesController < Projects::ApplicationController branch_name = sanitize(strip_tags(params[:branch_name])) branch_name = Addressable::URI.unescape(branch_name) - result = CreateBranchService.new(project, current_user). - execute(branch_name, ref) + result = CreateBranchService.new(project, current_user) + .execute(branch_name, ref) if params[:issue_iid] issue = IssuesFinder.new(current_user, project_id: @project.id).find_by(iid: params[:issue_iid]) diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index 886934a3f67..0db18d444f7 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -48,8 +48,8 @@ class Projects::BuildsController < Projects::ApplicationController respond_to do |format| format.json do state = params[:state].presence - render json: @build.trace_with_state(state: state). - merge!(id: @build.id, status: @build.status) + render json: @build.trace_with_state(state: state) + .merge!(id: @build.id, status: @build.status) end end end diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 23466dda981..e10d7992db7 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -35,9 +35,9 @@ class Projects::CommitController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: PipelineSerializer. - new(project: @project, user: @current_user). - represent(@pipelines) + render json: PipelineSerializer + .new(project: @project, user: @current_user) + .represent(@pipelines) end end end diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index ad92f05a42d..855147c8984 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -18,11 +18,11 @@ class Projects::CommitsController < Projects::ApplicationController @repository.commits(@ref, path: @path, limit: @limit, offset: @offset) end - @note_counts = project.notes.where(commit_id: @commits.map(&:id)). - group(:commit_id).count + @note_counts = project.notes.where(commit_id: @commits.map(&:id)) + .group(:commit_id).count - @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened. - find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref) + @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened + .find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref) respond_to do |format| format.html diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 99204c82784..7ef2f90ef01 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -46,8 +46,8 @@ class Projects::CompareController < Projects::ApplicationController end def define_diff_vars - @compare = CompareService.new(@project, @head_ref). - execute(@project, @start_ref) + @compare = CompareService.new(@project, @head_ref) + .execute(@project, @start_ref) if @compare @commits = @compare.commits @@ -66,7 +66,7 @@ class Projects::CompareController < Projects::ApplicationController end def merge_request - @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened. - find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref) + @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened + .find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref) end end diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 2bbd8c6d046..fed75396d6e 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -9,18 +9,18 @@ class Projects::EnvironmentsController < Projects::ApplicationController before_action :verify_api_request!, only: :terminal_websocket_authorize def index - @environments = project.environments. - with_state(params[:scope] || :available) + @environments = project.environments + .with_state(params[:scope] || :available) respond_to do |format| format.html format.json do render json: { - environments: EnvironmentSerializer. - new(project: @project, user: @current_user). - with_pagination(request, response). - within_folders. - represent(@environments), + environments: EnvironmentSerializer + .new(project: @project, user: @current_user) + .with_pagination(request, response) + .within_folders + .represent(@environments), available_count: project.environments.available.count, stopped_count: project.environments.stopped.count } @@ -36,10 +36,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController format.html format.json do render json: { - environments: EnvironmentSerializer. - new(project: @project, user: @current_user). - with_pagination(request, response). - represent(@environments), + environments: EnvironmentSerializer + .new(project: @project, user: @current_user) + .with_pagination(request, response) + .represent(@environments), available_count: folder_environments.available.count, stopped_count: folder_environments.stopped.count } diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index ca5e81100da..4c009dd238c 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -77,8 +77,8 @@ class Projects::IssuesController < Projects::ApplicationController def show raw_notes = @issue.notes.inc_relations_for_view.fresh - @notes = Banzai::NoteRenderer. - render(raw_notes, @project, current_user, @path, @project_wiki, @ref) + @notes = Banzai::NoteRenderer + .render(raw_notes, @project, current_user, @path, @project_wiki, @ref) @note = @project.notes.new(noteable: @issue) @noteable = @issue @@ -189,9 +189,9 @@ class Projects::IssuesController < Projects::ApplicationController def merge_request_for_resolving_discussions return unless merge_request_iid = params[:merge_request_for_resolving_discussions] - @merge_request_for_resolving_discussions ||= MergeRequestsFinder.new(current_user, project_id: project.id). - execute. - find_by(iid: merge_request_iid) + @merge_request_for_resolving_discussions ||= MergeRequestsFinder.new(current_user, project_id: project.id) + .execute + .find_by(iid: merge_request_iid) end def authorize_read_issue! diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 5ee7972e29e..1f228d28f80 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -162,8 +162,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController # Get commits from repository # or from cache if already merged @commits = @merge_request.commits - @note_counts = Note.where(commit_id: @commits.map(&:id)). - group(:commit_id).count + @note_counts = Note.where(commit_id: @commits.map(&:id)) + .group(:commit_id).count render json: { html: view_to_html_string('projects/merge_requests/show/_commits') } end @@ -232,9 +232,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end format.json do - render json: PipelineSerializer. - new(project: @project, user: @current_user). - represent(@pipelines) + render json: PipelineSerializer + .new(project: @project, user: @current_user) + .represent(@pipelines) end end end @@ -245,9 +245,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController format.json do define_pipelines_vars - render json: PipelineSerializer. - new(project: @project, user: @current_user). - represent(@pipelines) + render json: PipelineSerializer + .new(project: @project, user: @current_user) + .represent(@pipelines) end end end @@ -332,9 +332,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController return access_denied! end - MergeRequests::MergeWhenPipelineSucceedsService. - new(@project, current_user). - cancel(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService + .new(@project, current_user) + .cancel(@merge_request) end def merge @@ -361,9 +361,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end if @merge_request.head_pipeline.active? - MergeRequests::MergeWhenPipelineSucceedsService. - new(@project, current_user, merge_params). - execute(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService + .new(@project, current_user, merge_params) + .execute(@merge_request) @status = :merge_when_build_succeeds elsif @merge_request.head_pipeline.success? @@ -624,8 +624,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController @commit = @merge_request.diff_head_commit @base_commit = @merge_request.diff_base_commit - @note_counts = Note.where(commit_id: @commits.map(&:id)). - group(:commit_id).count + @note_counts = Note.where(commit_id: @commits.map(&:id)) + .group(:commit_id).count @labels = LabelsFinder.new(current_user, project_id: @project.id).execute @@ -640,8 +640,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_request_params - params.require(:merge_request). - permit(merge_request_params_ce) + params.require(:merge_request) + .permit(merge_request_params_ce) end def merge_request_params_ce diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 0f2b7b2a4c8..e436c6666c3 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -7,11 +7,11 @@ class Projects::PipelinesController < Projects::ApplicationController def index @scope = params[:scope] - @pipelines = PipelinesFinder. - new(project). - execute(scope: @scope). - page(params[:page]). - per(30) + @pipelines = PipelinesFinder + .new(project) + .execute(scope: @scope) + .page(params[:page]) + .per(30) @running_count = PipelinesFinder. .new(project).execute(scope: 'running').count @@ -29,10 +29,10 @@ class Projects::PipelinesController < Projects::ApplicationController format.html format.json do render json: { - pipelines: PipelineSerializer. - new(project: @project, user: @current_user). - with_pagination(request, response). - represent(@pipelines), + pipelines: PipelineSerializer + .new(project: @project, user: @current_user) + .with_pagination(request, response) + .represent(@pipelines), count: { all: @pipelines_count, running: @running_count, @@ -49,9 +49,9 @@ class Projects::PipelinesController < Projects::ApplicationController end def create - @pipeline = Ci::CreatePipelineService. - new(project, current_user, create_params). - execute(ignore_skip_ci: true, save_on_errors: false) + @pipeline = Ci::CreatePipelineService + .new(project, current_user, create_params) + .execute(ignore_skip_ci: true, save_on_errors: false) unless @pipeline.persisted? render 'new' return diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 6e158e685e9..3c582d15a4c 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -31,8 +31,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController end def destroy - Members::DestroyService.new(@project, current_user, params). - execute(:all) + Members::DestroyService.new(@project, current_user, params) + .execute(:all) respond_to do |format| format.html do diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 6f009d61950..24fe78bc1bd 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -14,8 +14,8 @@ module Projects def define_runners_variables @project_runners = @project.runners.ordered - @assignable_runners = current_user.ci_authorized_runners. - assignable_for(project).ordered.page(params[:page]).per(20) + @assignable_runners = current_user.ci_authorized_runners + .assignable_for(project).ordered.page(params[:page]).per(20) @shared_runners = Ci::Runner.shared.active @shared_runners_count = @shared_runners.count(:all) end diff --git a/app/controllers/projects/settings/members_controller.rb b/app/controllers/projects/settings/members_controller.rb index 5735e281f66..f4c79b796fd 100644 --- a/app/controllers/projects/settings/members_controller.rb +++ b/app/controllers/projects/settings/members_controller.rb @@ -41,10 +41,10 @@ module Projects wheres = ["members.id IN (#{@project_members.select(:id).to_sql})"] wheres << "members.id IN (#{group_members.select(:id).to_sql})" if group_members - @project_members = Member. - where(wheres.join(' OR ')). - sort(@sort). - page(params[:page]) + @project_members = Member + .where(wheres.join(' OR ')) + .sort(@sort) + .page(params[:page]) @requesters = AccessRequestsFinder.new(@project).execute(current_user) diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index 33379659d73..5aaec97a082 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -27,8 +27,8 @@ class Projects::TagsController < Projects::ApplicationController end def create - result = Tags::CreateService.new(@project, current_user). - execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) + result = Tags::CreateService.new(@project, current_user) + .execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) if result[:status] == :success @tag = result[:tag] diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb index 61686499bd3..1e7d72f5faa 100644 --- a/app/controllers/projects/uploads_controller.rb +++ b/app/controllers/projects/uploads_controller.rb @@ -5,8 +5,8 @@ class Projects::UploadsController < Projects::ApplicationController before_action :authorize_upload_file!, only: [:create] def create - link_to_file = ::Projects::UploadService.new(project, params[:file]). - execute + link_to_file = ::Projects::UploadService.new(project, params[:file]) + .execute respond_to do |format| if link_to_file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 9ffb8152e32..acca821782c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -293,8 +293,8 @@ class ProjectsController < Projects::ApplicationController end def project_params - params.require(:project). - permit(project_params_ce) + params.require(:project) + .permit(project_params_ce) end def project_params_ce diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 7d81c96262f..b632bbaaf78 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -119,8 +119,8 @@ class SessionsController < Devise::SessionsController end def log_audit_event(user, options = {}) - AuditEventService.new(user, user, options). - for_authentication.security_event + AuditEventService.new(user, user, options) + .for_authentication.security_event end def load_recaptcha diff --git a/app/controllers/sherlock/application_controller.rb b/app/controllers/sherlock/application_controller.rb index 682ca5e3821..6bdd3568a78 100644 --- a/app/controllers/sherlock/application_controller.rb +++ b/app/controllers/sherlock/application_controller.rb @@ -4,8 +4,8 @@ module Sherlock def find_transaction if params[:transaction_id] - @transaction = Gitlab::Sherlock.collection. - find_transaction(params[:transaction_id]) + @transaction = Gitlab::Sherlock.collection + .find_transaction(params[:transaction_id]) end end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 2d26718873f..d22a0ffd88a 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -28,8 +28,8 @@ class SnippetsController < ApplicationController @snippets = SnippetsFinder.new.execute(current_user, { filter: :by_user, user: @user, - scope: params[:scope] }). - page(params[:page]) + scope: params[:scope] }) + .page(params[:page]) render 'index' else @@ -82,8 +82,8 @@ class SnippetsController < ApplicationController @snippet ||= if current_user PersonalSnippet.where("author_id = ? OR visibility_level IN (?)", current_user.id, - [Snippet::PUBLIC, Snippet::INTERNAL]). - find(params[:id]) + [Snippet::PUBLIC, Snippet::INTERNAL]) + .find(params[:id]) else PersonalSnippet.find(params[:id]) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c92594d4097..73056df5bef 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -109,17 +109,17 @@ class UsersController < ApplicationController def load_events # Get user activity feed for projects common for both users - @events = user.recent_events. - merge(projects_for_current_user). - references(:project). - with_associations. - limit_recent(20, params[:offset]) + @events = user.recent_events + .merge(projects_for_current_user) + .references(:project) + .with_associations + .limit_recent(20, params[:offset]) end def load_projects @projects = - PersonalProjectsFinder.new(user).execute(current_user). - page(params[:page]) + PersonalProjectsFinder.new(user).execute(current_user) + .page(params[:page]) end def load_contributed_projects diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb index 52c73abc31d..a59f8c1efa3 100644 --- a/app/finders/environments_finder.rb +++ b/app/finders/environments_finder.rb @@ -17,12 +17,12 @@ class EnvironmentsFinder deployments.none end - environment_ids = deployments. - group(:environment_id). - select(:environment_id) + environment_ids = deployments + .group(:environment_id) + .select(:environment_id) - environments = project.environments.available. - where(id: environment_ids).order_by_last_deployed_at.to_a + environments = project.environments.available + .where(id: environment_ids).order_by_last_deployed_at.to_a environments.select! do |environment| Ability.allowed?(current_user, :read_environment, environment) diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb index 9f2206346ce..873a253e2b5 100644 --- a/app/finders/group_members_finder.rb +++ b/app/finders/group_members_finder.rb @@ -8,9 +8,9 @@ class GroupMembersFinder < Projects::ApplicationController return group_members unless @group.parent - parents_members = GroupMember.non_request. - where(source_id: @group.ancestors.select(:id)). - where.not(user_id: @group.users.select(:id)) + parents_members = GroupMember.non_request + .where(source_id: @group.ancestors.select(:id)) + .where.not(user_id: @group.users.select(:id)) wheres = ["members.id IN (#{group_members.select(:id).to_sql})"] wheres << "members.id IN (#{parents_members.select(:id).to_sql})" diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb index 1182939f656..913db3a3e26 100644 --- a/app/helpers/form_helper.rb +++ b/app/helpers/form_helper.rb @@ -8,10 +8,10 @@ module FormHelper content_tag(:div, class: 'alert alert-danger', id: 'error_explanation') do content_tag(:h4, headline) << content_tag(:ul) do - model.errors.full_messages. - map { |msg| content_tag(:li, msg) }. - join. - html_safe + model.errors.full_messages + .map { |msg| content_tag(:li, msg) } + .join + .html_safe end end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 8ff8db16514..7a164cfd26d 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -97,8 +97,8 @@ module SearchHelper # Autocomplete results for the current user's projects def projects_autocomplete(term, limit = 5) - current_user.authorized_projects.search_by_title(term). - sorted_by_stars.non_archived.limit(limit).map do |p| + current_user.authorized_projects.search_by_title(term) + .sorted_by_stars.non_archived.limit(limit).map do |p| { category: "Projects", id: p.id, diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 3e3f6246fc5..99212a3438f 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -6,8 +6,8 @@ module WikiHelper # Returns a String composed of the capitalized name of each directory and the # capitalized name of the page itself. def breadcrumb(page_slug) - page_slug.split('/'). - map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize }. - join(' / ') + page_slug.split('/') + .map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize } + .join(' / ') end end diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb index 6937ad3bdd9..2eedbf3ffde 100644 --- a/app/models/award_emoji.rb +++ b/app/models/award_emoji.rb @@ -18,9 +18,9 @@ class AwardEmoji < ActiveRecord::Base class << self def votes_for_collection(ids, type) - select('name', 'awardable_id', 'COUNT(*) as count'). - where('name IN (?) AND awardable_type = ? AND awardable_id IN (?)', [DOWNVOTE_NAME, UPVOTE_NAME], type, ids). - group('name', 'awardable_id') + select('name', 'awardable_id', 'COUNT(*) as count') + .where('name IN (?) AND awardable_type = ? AND awardable_id IN (?)', [DOWNVOTE_NAME, UPVOTE_NAME], type, ids) + .group('name', 'awardable_id') end end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index f9592873ea0..de9fe352059 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -63,9 +63,9 @@ module Ci end def retry(build, current_user) - Ci::RetryBuildService. - new(build.project, current_user). - execute(build) + Ci::RetryBuildService + .new(build.project, current_user) + .execute(build) end end @@ -96,9 +96,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Build::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Build::Factory + .new(self, current_user) + .fabricate! end def manual? @@ -220,9 +220,9 @@ module Ci end def merge_request - merge_requests = MergeRequest.includes(:merge_request_diff). - where(source_branch: ref, source_project_id: pipeline.gl_project_id). - reorder(iid: :asc) + merge_requests = MergeRequest.includes(:merge_request_diff) + .where(source_branch: ref, source_project_id: pipeline.gl_project_id) + .reorder(iid: :asc) merge_requests.find do |merge_request| merge_request.commits_sha.include?(pipeline.sha) @@ -278,8 +278,8 @@ module Ci def raw_trace(last_lines: nil) if File.exist?(trace_file_path) - Gitlab::Ci::TraceReader.new(trace_file_path). - read(last_lines: last_lines) + Gitlab::Ci::TraceReader.new(trace_file_path) + .read(last_lines: last_lines) else # backward compatibility read_attribute :trace diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 673647f284a..999720d2ea3 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -89,9 +89,9 @@ module Ci # ref can't be HEAD or SHA, can only be branch/tag name scope :latest, ->(ref = nil) do - max_id = unscope(:select). - select("max(#{quoted_table_name}.id)"). - group(:ref, :sha) + max_id = unscope(:select) + .select("max(#{quoted_table_name}.id)") + .group(:ref, :sha) if ref where(ref: ref, id: max_id.where(ref: ref)) @@ -126,23 +126,23 @@ module Ci end def stages_name - statuses.order(:stage_idx).distinct. - pluck(:stage, :stage_idx).map(&:first) + statuses.order(:stage_idx).distinct + .pluck(:stage, :stage_idx).map(&:first) end def stages # TODO, this needs refactoring, see gitlab-ce#26481. - stages_query = statuses. - group('stage').select(:stage).order('max(stage_idx)') + stages_query = statuses + .group('stage').select(:stage).order('max(stage_idx)') status_sql = statuses.latest.where('stage=sg.stage').status_sql - warnings_sql = statuses.latest.select('COUNT(*) > 0'). - where('stage=sg.stage').failed_but_allowed.to_sql + warnings_sql = statuses.latest.select('COUNT(*) > 0') + .where('stage=sg.stage').failed_but_allowed.to_sql - stages_with_statuses = CommitStatus.from(stages_query, :sg). - pluck('sg.stage', status_sql, "(#{warnings_sql})") + stages_with_statuses = CommitStatus.from(stages_query, :sg) + .pluck('sg.stage', status_sql, "(#{warnings_sql})") stages_with_statuses.map do |stage| Ci::Stage.new(self, Hash[%i[name status warnings].zip(stage)]) @@ -222,8 +222,8 @@ module Ci end def retry_failed(current_user) - Ci::RetryPipelineService.new(project, current_user). - execute(self) + Ci::RetryPipelineService.new(project, current_user) + .execute(self) end def mark_as_processable_after_stage(stage_idx) @@ -255,9 +255,9 @@ module Ci def config_builds_attributes return [] unless config_processor - config_processor. - builds_for_ref(ref, tag?, trigger_requests.first). - sort_by { |build| build[:stage_idx] } + config_processor + .builds_for_ref(ref, tag?, trigger_requests.first) + .sort_by { |build| build[:stage_idx] } end def has_warnings? @@ -355,15 +355,15 @@ module Ci # Merge requests for which the current pipeline is running against # the merge request's latest commit. def merge_requests - @merge_requests ||= project.merge_requests. - where(source_branch: self.ref). - select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } + @merge_requests ||= project.merge_requests + .where(source_branch: self.ref) + .select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } end def detailed_status(current_user) - Gitlab::Ci::Status::Pipeline::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Pipeline::Factory + .new(self, current_user) + .fabricate! end private diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index a120112e882..9cf6164e8dd 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -23,15 +23,15 @@ module Ci scope :ordered, ->() { order(id: :desc) } scope :owned_or_shared, ->(project_id) do - joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id'). - where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) + joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id') + .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end scope :assignable_for, ->(project) do # FIXME: That `to_sql` is needed to workaround a weird Rails bug. # Without that, placeholders would miss one and couldn't match. - where(locked: false). - where.not("id IN (#{project.runners.select(:id).to_sql})").specific + where(locked: false) + .where.not("id IN (#{project.runners.select(:id).to_sql})").specific end validate :tag_constraints diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index 0751ab1b7d8..ca74c91b062 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -28,9 +28,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Stage::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Stage::Factory + .new(self, current_user) + .fabricate! end def statuses diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index ef5e6202519..df835b99189 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -96,8 +96,8 @@ class CommitStatus < ActiveRecord::Base after_transition any => :failed do |commit_status| commit_status.run_after_commit do - MergeRequests::AddTodoWhenBuildFailsService. - new(pipeline.project, nil).execute(self) + MergeRequests::AddTodoWhenBuildFailsService + .new(pipeline.project, nil).execute(self) end end end @@ -133,9 +133,9 @@ class CommitStatus < ActiveRecord::Base end def detailed_status(current_user) - Gitlab::Ci::Status::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Factory + .new(self, current_user) + .fabricate! end def sortable_name diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 768baa80c01..303d4910ee1 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -162,9 +162,9 @@ module Issuable highest_priority = highest_label_priority(params).to_sql - select("#{table_name}.*, (#{highest_priority}) AS highest_priority"). - group(arel_table[:id]). - reorder(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')) + select("#{table_name}.*, (#{highest_priority}) AS highest_priority") + .group(arel_table[:id]) + .reorder(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')) end def with_label(title, sort = nil) diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 7e56e371b27..a8ce36e51fc 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -48,8 +48,8 @@ module Mentionable if extractor @extractor = extractor else - @extractor ||= Gitlab::ReferenceExtractor. - new(project, current_user) + @extractor ||= Gitlab::ReferenceExtractor + .new(project, current_user) @extractor.reset_memoized_values end diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index 870a6fbaa90..f449229864d 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -39,8 +39,8 @@ module Milestoneish def issues_visible_to_user(user) memoize_per_user(user, :issues_visible_to_user) do - IssuesFinder.new(user, issues_finder_params). - execute.where(milestone_id: milestoneish_ids) + IssuesFinder.new(user, issues_finder_params) + .execute.where(milestone_id: milestoneish_ids) end end diff --git a/app/models/concerns/presentable.rb b/app/models/concerns/presentable.rb index d0f84831d71..7b33b837004 100644 --- a/app/models/concerns/presentable.rb +++ b/app/models/concerns/presentable.rb @@ -1,7 +1,7 @@ module Presentable def present(**attributes) - Gitlab::View::Presenter::Factory. - new(self, attributes). - fabricate! + Gitlab::View::Presenter::Factory + .new(self, attributes) + .fabricate! end end diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 9f6d215ceb3..c2373de32c5 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -75,11 +75,11 @@ module Routable # # Returns an ActiveRecord::Relation. def member_descendants(user_id) - joins(:route). - joins("INNER JOIN routes r2 ON routes.path LIKE CONCAT(r2.path, '/%') + joins(:route) + .joins("INNER JOIN routes r2 ON routes.path LIKE CONCAT(r2.path, '/%') INNER JOIN members ON members.source_id = r2.source_id - AND members.source_type = r2.source_type"). - where('members.user_id = ?', user_id) + AND members.source_type = r2.source_type") + .where('members.user_id = ?', user_id) end end diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index b9a2d812edd..a155a064032 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -39,12 +39,12 @@ module Sortable private def highest_label_priority(target_type_column: nil, target_type: nil, target_column:, project_column:, excluded_labels: []) - query = Label.select(LabelPriority.arel_table[:priority].minimum). - left_join_priorities. - joins(:label_links). - where("label_priorities.project_id = #{project_column}"). - where("label_links.target_id = #{target_column}"). - reorder(nil) + query = Label.select(LabelPriority.arel_table[:priority].minimum) + .left_join_priorities + .joins(:label_links) + .where("label_priorities.project_id = #{project_column}") + .where("label_links.target_id = #{target_column}") + .reorder(nil) query = if target_type_column diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index e4f5818d0e3..f60a0f8f438 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -27,30 +27,30 @@ module Subscribable end def subscribers(project) - subscriptions_available(project). - where(subscribed: true). - map(&:user) + subscriptions_available(project) + .where(subscribed: true) + .map(&:user) end def toggle_subscription(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project). - update(subscribed: !subscribed?(user, project)) + find_or_initialize_subscription(user, project) + .update(subscribed: !subscribed?(user, project)) end def subscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project). - update(subscribed: true) + find_or_initialize_subscription(user, project) + .update(subscribed: true) end def unsubscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project). - update(subscribed: false) + find_or_initialize_subscription(user, project) + .update(subscribed: false) end private @@ -69,14 +69,14 @@ module Subscribable end def find_or_initialize_subscription(user, project) - subscriptions. - find_or_initialize_by(user_id: user.id, project_id: project.try(:id)) + subscriptions + .find_or_initialize_by(user_id: user.id, project_id: project.try(:id)) end def subscriptions_available(project) t = Subscription.arel_table - subscriptions. - where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id)))) + subscriptions + .where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id)))) end end diff --git a/app/models/deployment.rb b/app/models/deployment.rb index afad001d50f..43f7460bd5d 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -53,10 +53,10 @@ class Deployment < ActiveRecord::Base def update_merge_request_metrics! return unless environment.update_merge_request_metrics? - merge_requests = project.merge_requests. - joins(:metrics). - where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil }). - where("merge_request_metrics.merged_at <= ?", self.created_at) + merge_requests = project.merge_requests + .joins(:metrics) + .where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil }) + .where("merge_request_metrics.merged_at <= ?", self.created_at) if previous_deployment merge_requests = merge_requests.where("merge_request_metrics.merged_at >= ?", previous_deployment.created_at) @@ -71,17 +71,17 @@ class Deployment < ActiveRecord::Base merge_requests.map(&:id) end - MergeRequest::Metrics. - where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil). - update_all(first_deployed_to_production_at: self.created_at) + MergeRequest::Metrics + .where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil) + .update_all(first_deployed_to_production_at: self.created_at) end def previous_deployment @previous_deployment ||= - project.deployments.joins(:environment). - where(environments: { name: self.environment.name }, ref: self.ref). - where.not(id: self.id). - take + project.deployments.joins(:environment) + .where(environments: { name: self.environment.name }, ref: self.ref) + .where.not(id: self.id) + .take end def stop_action diff --git a/app/models/environment.rb b/app/models/environment.rb index 1a21b5e52b5..f917f52f832 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -40,9 +40,9 @@ class Environment < ActiveRecord::Base scope :stopped, -> { with_state(:stopped) } scope :order_by_last_deployed_at, -> do max_deployment_id_sql = - Deployment.select(Deployment.arel_table[:id].maximum). - where(Deployment.arel_table[:environment_id].eq(arel_table[:id])). - to_sql + Deployment.select(Deployment.arel_table[:id].maximum) + .where(Deployment.arel_table[:environment_id].eq(arel_table[:id])) + .to_sql order(Gitlab::Database.nulls_first_order("(#{max_deployment_id_sql})", 'ASC')) end diff --git a/app/models/event.rb b/app/models/event.rb index e5027df3f8a..42c4a233ce3 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -343,9 +343,9 @@ class Event < ActiveRecord::Base # At this point it's possible for multiple threads/processes to try to # update the project. Only one query should actually perform the update, # hence we add the extra WHERE clause for last_activity_at. - Project.unscoped.where(id: project_id). - where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago). - update_all(last_activity_at: created_at) + Project.unscoped.where(id: project_id) + .where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago) + .update_all(last_activity_at: created_at) end def authored_by?(user) diff --git a/app/models/generic_commit_status.rb b/app/models/generic_commit_status.rb index 36b8568871b..8867ba0d2ff 100644 --- a/app/models/generic_commit_status.rb +++ b/app/models/generic_commit_status.rb @@ -18,8 +18,8 @@ class GenericCommitStatus < CommitStatus end def detailed_status(current_user) - Gitlab::Ci::Status::External::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::External::Factory + .new(self, current_user) + .fabricate! end end diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb index 84deb67ba9b..b991d78e27f 100644 --- a/app/models/global_milestone.rb +++ b/app/models/global_milestone.rb @@ -76,8 +76,8 @@ class GlobalMilestone end def labels - @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten). - sort_by!(&:title) + @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten) + .sort_by!(&:title) end def due_date diff --git a/app/models/group.rb b/app/models/group.rb index 1835ce118a1..5ef3f9513fc 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -71,9 +71,9 @@ class Group < Namespace def select_for_project_authorization if current_scope.joins_values.include?(:shared_projects) - joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id'). - where('project_namespace.share_with_group_lock = ?', false). - select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") + joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id') + .where('project_namespace.share_with_group_lock = ?', false) + .select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") else super end @@ -197,8 +197,8 @@ class Group < Namespace end def refresh_members_authorized_projects - UserProjectAccessChangedService.new(user_ids_for_project_authorizations). - execute + UserProjectAccessChangedService.new(user_ids_for_project_authorizations) + .execute end def user_ids_for_project_authorizations diff --git a/app/models/issue_collection.rb b/app/models/issue_collection.rb index f0b7d9914c8..49f011c113f 100644 --- a/app/models/issue_collection.rb +++ b/app/models/issue_collection.rb @@ -17,9 +17,9 @@ class IssueCollection # Given all the issue projects we get a list of projects that the current # user has at least reporter access to. - projects_with_reporter_access = user. - projects_with_reporter_access_limited_to(project_ids). - pluck(:id) + projects_with_reporter_access = user + .projects_with_reporter_access_limited_to(project_ids) + .pluck(:id) collection.select do |issue| if projects_with_reporter_access.include?(issue.project_id) diff --git a/app/models/label.rb b/app/models/label.rb index 27429e60e4a..e97e53301cc 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -34,18 +34,18 @@ class Label < ActiveRecord::Base scope :with_title, ->(title) { where(title: title) } def self.prioritized(project) - joins(:priorities). - where(label_priorities: { project_id: project }). - reorder('label_priorities.priority ASC, labels.title ASC') + joins(:priorities) + .where(label_priorities: { project_id: project }) + .reorder('label_priorities.priority ASC, labels.title ASC') end def self.unprioritized(project) labels = Label.arel_table priorities = LabelPriority.arel_table - label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin). - on(labels[:id].eq(priorities[:label_id]).and(priorities[:project_id].eq(project.id))). - join_sources + label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin) + .on(labels[:id].eq(priorities[:label_id]).and(priorities[:project_id].eq(project.id))) + .join_sources joins(label_priorities).where(priorities[:priority].eq(nil)) end @@ -54,9 +54,9 @@ class Label < ActiveRecord::Base labels = Label.arel_table priorities = LabelPriority.arel_table - label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin). - on(labels[:id].eq(priorities[:label_id])). - join_sources + label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin) + .on(labels[:id].eq(priorities[:label_id])) + .join_sources joins(label_priorities) end diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index ee9ac282e39..7712d5783e0 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -19,8 +19,8 @@ class LfsObject < ActiveRecord::Base end def self.destroy_unreferenced - joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id"). - where(lfs_objects_projects: { id: nil }). - destroy_all + joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id") + .where(lfs_objects_projects: { id: nil }) + .destroy_all end end diff --git a/app/models/member.rb b/app/models/member.rb index 0f6b75b0b93..2ea4abacea4 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -39,9 +39,9 @@ class Member < ActiveRecord::Base is_external_invite = arel_table[:user_id].eq(nil).and(arel_table[:invite_token].not_eq(nil)) user_is_active = User.arel_table[:state].eq(:active) - includes(:user).references(:users). - where(is_external_invite.or(user_is_active)). - where(requested_at: nil) + includes(:user).references(:users) + .where(is_external_invite.or(user_is_active)) + .where(requested_at: nil) end scope :invite, -> { where.not(invite_token: nil) } @@ -99,9 +99,9 @@ class Member < ActiveRecord::Base users = User.arel_table members = Member.arel_table - member_users = members.join(users, Arel::Nodes::OuterJoin). - on(members[:user_id].eq(users[:id])). - join_sources + member_users = members.join(users, Arel::Nodes::OuterJoin) + .on(members[:user_id].eq(users[:id])) + .join_sources joins(member_users) end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index ea784f77015..c4520c16a43 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -475,10 +475,10 @@ class MergeRequest < ActiveRecord::Base end def discussions - @discussions ||= self.related_notes. - inc_relations_for_view. - fresh. - discussions + @discussions ||= self.related_notes + .inc_relations_for_view + .fresh + .discussions end def diff_discussions @@ -564,8 +564,8 @@ class MergeRequest < ActiveRecord::Base messages = [title, description] messages.concat(commits.map(&:safe_message)) if merge_request_diff - Gitlab::ClosingIssueExtractor.new(project, current_user). - closed_by_message(messages.join("\n")) + Gitlab::ClosingIssueExtractor.new(project, current_user) + .closed_by_message(messages.join("\n")) else [] end @@ -813,9 +813,9 @@ class MergeRequest < ActiveRecord::Base def all_pipelines return Ci::Pipeline.none unless source_project - @all_pipelines ||= source_project.pipelines. - where(sha: all_commits_sha, ref: source_branch). - order(id: :desc) + @all_pipelines ||= source_project.pipelines + .where(sha: all_commits_sha, ref: source_branch) + .order(id: :desc) end # Note that this could also return SHA from now dangling commits diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 53d08488788..baee00b8fcd 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -169,8 +169,8 @@ class MergeRequestDiff < ActiveRecord::Base # When compare merge request versions we want diff A..B instead of A...B # so we handle cases when user does squash and rebase of the commits between versions. # For this reason we set straight to true by default. - CompareService.new(project, head_commit_sha). - execute(project, sha, straight: straight) + CompareService.new(project, head_commit_sha) + .execute(project, sha, straight: straight) end def commits_count diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index daafb137be4..7f7c114803d 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -7,9 +7,9 @@ class MergeRequestsClosingIssues < ActiveRecord::Base class << self def count_for_collection(ids) - group(:issue_id). - where(issue_id: ids). - pluck('issue_id', 'COUNT(*) as count') + group(:issue_id) + .where(issue_id: ids) + .pluck('issue_id', 'COUNT(*) as count') end end end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 7331000a9f2..30e5dfd096e 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -98,11 +98,11 @@ class Milestone < ActiveRecord::Base if Gitlab::Database.postgresql? rel.order(:project_id, :due_date).select('DISTINCT ON (project_id) id') else - rel. - group(:project_id). - having('due_date = MIN(due_date)'). - pluck(:id, :project_id, :due_date). - map(&:first) + rel + .group(:project_id) + .having('due_date = MIN(due_date)') + .pluck(:id, :project_id, :due_date) + .map(&:first) end end @@ -177,8 +177,8 @@ class Milestone < ActiveRecord::Base conditions = 'WHEN id = ? THEN ? ' * ids.length - issues.where(id: ids). - update_all(["position = CASE #{conditions} ELSE position END", *pairs]) + issues.where(id: ids) + .update_all(["position = CASE #{conditions} ELSE position END", *pairs]) end private diff --git a/app/models/namespace.rb b/app/models/namespace.rb index e207ac3db4e..9334b7d9e61 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -48,9 +48,9 @@ class Namespace < ActiveRecord::Base scope :root, -> { where('type IS NULL') } scope :with_statistics, -> do - joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id'). - group('namespaces.id'). - select( + joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id') + .group('namespaces.id') + .select( 'namespaces.*', 'COALESCE(SUM(ps.storage_size), 0) AS storage_size', 'COALESCE(SUM(ps.repository_size), 0) AS repository_size', @@ -251,10 +251,10 @@ class Namespace < ActiveRecord::Base end def refresh_access_of_projects_invited_groups - Group. - joins(project_group_links: :project). - where(projects: { namespace_id: id }). - find_each(&:refresh_members_authorized_projects) + Group + .joins(project_group_links: :project) + .where(projects: { namespace_id: id }) + .find_each(&:refresh_members_authorized_projects) end def remove_exports! diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb index a48e872ad84..8417f200e36 100644 --- a/app/models/network/commit.rb +++ b/app/models/network/commit.rb @@ -28,8 +28,8 @@ module Network if map.include?(p.id) map[p.id] end - end. - compact + end + .compact end end end diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index 2a7fa7d0607..0bbc9451ffd 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -23,12 +23,12 @@ module Network def collect_notes h = Hash.new(0) - @project. - notes. - where('noteable_type = ?', 'Commit'). - group('notes.commit_id'). - select('notes.commit_id, count(notes.id) as note_count'). - each do |item| + @project + .notes + .where('noteable_type = ?', 'Commit') + .group('notes.commit_id') + .select('notes.commit_id, count(notes.id) as note_count') + .each do |item| h[item.commit_id] = item.note_count.to_i end diff --git a/app/models/note.rb b/app/models/note.rb index 029fe667a45..4f87b9a4dc2 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -105,14 +105,14 @@ class Note < ActiveRecord::Base def grouped_diff_discussions active_notes = diff_notes.fresh.select(&:active?) - Discussion.for_diff_notes(active_notes). - map { |d| [d.line_code, d] }.to_h + Discussion.for_diff_notes(active_notes) + .map { |d| [d.line_code, d] }.to_h end def count_for_collection(ids, type) - user.select('noteable_id', 'COUNT(*) as count'). - group(:noteable_id). - where(noteable_type: type, noteable_id: ids) + user.select('noteable_id', 'COUNT(*) as count') + .group(:noteable_id) + .where(noteable_type: type, noteable_id: ids) end end diff --git a/app/models/project.rb b/app/models/project.rb index e75ba3abb98..f2be9e6a80c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -233,8 +233,8 @@ class Project < ActiveRecord::Base scope :inside_path, ->(path) do # We need routes alias rs for JOIN so it does not conflict with # includes(:route) which we use in ProjectsFinder. - joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'"). - where('rs.path LIKE ?', "#{path}/%") + joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'") + .where('rs.path LIKE ?', "#{path}/%") end # "enabled" here means "not disabled". It includes private features! @@ -311,9 +311,9 @@ class Project < ActiveRecord::Base pattern = "%#{query}%" projects = select(:id).where( - ptable[:path].matches(pattern). - or(ptable[:name].matches(pattern)). - or(ptable[:description].matches(pattern)) + ptable[:path].matches(pattern) + .or(ptable[:name].matches(pattern)) + .or(ptable[:description].matches(pattern)) ) # We explicitly remove any eager loading clauses as they're: @@ -322,10 +322,10 @@ class Project < ActiveRecord::Base # 2. Combined with .joins(:namespace) lead to all columns from the # projects & namespaces tables being selected, leading to a SQL error # due to the columns of all UNION'd queries no longer being the same. - namespaces = select(:id). - except(:includes). - joins(:namespace). - where(ntable[:name].matches(pattern)) + namespaces = select(:id) + .except(:includes) + .joins(:namespace) + .where(ntable[:name].matches(pattern)) union = Gitlab::SQL::Union.new([projects, namespaces]) @@ -367,8 +367,8 @@ class Project < ActiveRecord::Base end def trending - joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id'). - reorder('trending_projects.id ASC') + joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id') + .reorder('trending_projects.id ASC') end def cached_count diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index eb5019c08b5..caf71676837 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -109,9 +109,9 @@ class KubernetesService < DeploymentService def terminals(environment) with_reactive_cache do |data| pods = data.fetch(:pods, nil) - filter_pods(pods, app: environment.slug). - flat_map { |pod| terminals_for_pod(api_url, namespace, pod) }. - each { |terminal| add_terminal_auth(terminal, terminal_auth) } + filter_pods(pods, app: environment.slug) + .flat_map { |pod| terminals_for_pod(api_url, namespace, pod) } + .each { |terminal| add_terminal_auth(terminal, terminal_auth) } end end diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb index 56f42d63b2d..26376fd87ff 100644 --- a/app/models/project_services/mattermost_slash_commands_service.rb +++ b/app/models/project_services/mattermost_slash_commands_service.rb @@ -20,8 +20,8 @@ class MattermostSlashCommandsService < ChatSlashCommandsService end def configure(user, params) - token = Mattermost::Command.new(user). - create(command(params)) + token = Mattermost::Command.new(user) + .create(command(params)) update(active: true, token: token) if token rescue Mattermost::Error => e diff --git a/app/models/project_team.rb b/app/models/project_team.rb index 8a53e974b6f..67cc06642f1 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -169,10 +169,10 @@ class ProjectTeam # Lookup only the IDs we need user_ids = user_ids - access.keys - users_access = project.project_authorizations. - where(user: user_ids). - group(:user_id). - maximum(:access_level) + users_access = project.project_authorizations + .where(user: user_ids) + .group(:user_id) + .maximum(:access_level) access.merge!(users_access) access diff --git a/app/models/repository.rb b/app/models/repository.rb index 32252957a84..7113879417e 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -249,11 +249,11 @@ class Repository cache.fetch(:"diverging_commit_counts_#{branch.name}") do # Rugged seems to throw a `ReferenceError` when given branch_names rather # than SHA-1 hashes - number_commits_behind = raw_repository. - count_commits_between(branch.dereferenced_target.sha, root_ref_hash) + number_commits_behind = raw_repository + .count_commits_between(branch.dereferenced_target.sha, root_ref_hash) - number_commits_ahead = raw_repository. - count_commits_between(root_ref_hash, branch.dereferenced_target.sha) + number_commits_ahead = raw_repository + .count_commits_between(root_ref_hash, branch.dereferenced_target.sha) { behind: number_commits_behind, ahead: number_commits_ahead } end @@ -759,8 +759,8 @@ class Repository check_tree_entry_for_dir(branch_name, path) if start_branch_name - start_project.repository. - check_tree_entry_for_dir(start_branch_name, path) + start_project.repository + .check_tree_entry_for_dir(start_branch_name, path) end commit_file( diff --git a/app/models/todo.rb b/app/models/todo.rb index 47789a21133..32bb9bf2045 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -64,9 +64,9 @@ class Todo < ActiveRecord::Base highest_priority = highest_label_priority(params).to_sql - select("#{table_name}.*, (#{highest_priority}) AS highest_priority"). - order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')). - order('todos.created_at') + select("#{table_name}.*, (#{highest_priority}) AS highest_priority") + .order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')) + .order('todos.created_at') end end diff --git a/app/models/user.rb b/app/models/user.rb index f37735c5eba..296bcc699a9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -197,13 +197,13 @@ class User < ActiveRecord::Base scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('last_sign_in_at', 'ASC')) } def self.with_two_factor - joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id"). - where("u2f.id IS NOT NULL OR otp_required_for_login = ?", true).distinct(arel_table[:id]) + joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id") + .where("u2f.id IS NOT NULL OR otp_required_for_login = ?", true).distinct(arel_table[:id]) end def self.without_two_factor - joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id"). - where("u2f.id IS NULL AND otp_required_for_login = ?", false) + joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id") + .where("u2f.id IS NULL AND otp_required_for_login = ?", false) end # @@ -274,9 +274,9 @@ class User < ActiveRecord::Base pattern = "%#{query}%" where( - table[:name].matches(pattern). - or(table[:email].matches(pattern)). - or(table[:username].matches(pattern)) + table[:name].matches(pattern) + .or(table[:email].matches(pattern)) + .or(table[:username].matches(pattern)) ) end @@ -291,10 +291,10 @@ class User < ActiveRecord::Base matched_by_emails_user_ids = email_table.project(email_table[:user_id]).where(email_table[:email].matches(pattern)) where( - table[:name].matches(pattern). - or(table[:email].matches(pattern)). - or(table[:username].matches(pattern)). - or(table[:id].in(matched_by_emails_user_ids)) + table[:name].matches(pattern) + .or(table[:email].matches(pattern)) + .or(table[:username].matches(pattern)) + .or(table[:id].in(matched_by_emails_user_ids)) ) end @@ -447,8 +447,8 @@ class User < ActiveRecord::Base # Returns the groups a user has access to def authorized_groups - union = Gitlab::SQL::Union. - new([groups.select(:id), authorized_projects.select(:namespace_id)]) + union = Gitlab::SQL::Union + .new([groups.select(:id), authorized_projects.select(:namespace_id)]) Group.where("namespaces.id IN (#{union.to_sql})") end @@ -458,8 +458,8 @@ class User < ActiveRecord::Base end def nested_projects - Project.joins(:namespace).where('namespaces.parent_id IS NOT NULL'). - member_descendants(id) + Project.joins(:namespace).where('namespaces.parent_id IS NOT NULL') + .member_descendants(id) end def refresh_authorized_projects @@ -579,8 +579,8 @@ class User < ActiveRecord::Base next unless project if project.repository.branch_exists?(event.branch_name) - merge_requests = MergeRequest.where("created_at >= ?", event.created_at). - where(source_project_id: project.id, + merge_requests = MergeRequest.where("created_at >= ?", event.created_at) + .where(source_project_id: project.id, source_branch: event.branch_name) merge_requests.empty? end @@ -793,8 +793,8 @@ class User < ActiveRecord::Base def toggle_star(project) UsersStarProject.transaction do - user_star_project = users_star_projects. - where(project: project, user: self).lock(true).first + user_star_project = users_star_projects + .where(project: project, user: self).lock(true).first if user_star_project user_star_project.destroy @@ -830,11 +830,11 @@ class User < ActiveRecord::Base # ms on a database with a similar size to GitLab.com's database. On the other # hand, using a subquery means we can get the exact same data in about 40 ms. def contributed_projects - events = Event.select(:project_id). - contributions.where(author_id: self). - where("created_at > ?", Time.now - 1.year). - uniq. - reorder(nil) + events = Event.select(:project_id) + .contributions.where(author_id: self) + .where("created_at > ?", Time.now - 1.year) + .uniq + .reorder(nil) Project.where(id: events) end @@ -845,9 +845,9 @@ class User < ActiveRecord::Base def ci_authorized_runners @ci_authorized_runners ||= begin - runner_ids = Ci::RunnerProject. - where("ci_runner_projects.gl_project_id IN (#{ci_projects_union.to_sql})"). - select(:runner_id) + runner_ids = Ci::RunnerProject + .where("ci_runner_projects.gl_project_id IN (#{ci_projects_union.to_sql})") + .select(:runner_id) Ci::Runner.specific.where(id: runner_ids) end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 2caebb496db..0fa9d77a771 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -22,16 +22,16 @@ class WikiPage def self.group_by_directory(pages) return [] if pages.blank? - pages.sort_by { |page| [page.directory, page.slug] }. - group_by(&:directory). - map do |dir, pages| + pages.sort_by { |page| [page.directory, page.slug] } + .group_by(&:directory) + .map do |dir, pages| if dir.present? WikiDirectory.new(dir, pages) else pages end - end. - flatten + end + .flatten end def self.unhyphenize(name) diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb index 032c44274ef..311ee9c96be 100644 --- a/app/serializers/base_serializer.rb +++ b/app/serializers/base_serializer.rb @@ -4,9 +4,9 @@ class BaseSerializer end def represent(resource, opts = {}) - self.class.entity_class. - represent(resource, opts.merge(request: @request)). - as_json + self.class.entity_class + .represent(resource, opts.merge(request: @request)) + .as_json end def self.entity(entity_class) diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index ffc4fd34c75..d0a60f134da 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -36,9 +36,9 @@ class EnvironmentSerializer < BaseSerializer private def itemize(resource) - items = resource.order('folder_name ASC'). - group('COALESCE(environment_type, name)'). - select('COALESCE(environment_type, name) AS folder_name', + items = resource.order('folder_name ASC') + .group('COALESCE(environment_type, name)') + .select('COALESCE(environment_type, name) AS folder_name', 'COUNT(*) AS size', 'MAX(id) AS last_id') # It makes a difference when you call `paginate` method, because diff --git a/app/services/after_branch_delete_service.rb b/app/services/after_branch_delete_service.rb index 95492f709bb..227e9ea9c6d 100644 --- a/app/services/after_branch_delete_service.rb +++ b/app/services/after_branch_delete_service.rb @@ -14,8 +14,8 @@ class AfterBranchDeleteService < BaseService private def stop_environments - Ci::StopEnvironmentsService. - new(project, current_user). - execute(branch_name) + Ci::StopEnvironmentsService + .new(project, current_user) + .execute(branch_name) end end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 2d664f3f0c8..8a94c54b6ab 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -57,15 +57,15 @@ module Boards return issues unless board_label_ids.any? issues.where.not( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). - where(label_id: board_label_ids).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") + .where(label_id: board_label_ids).limit(1).arel.exists ) end def with_list_label(issues) issues.where( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). - where("label_links.label_id = ?", list.label_id).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") + .where("label_links.label_id = ?", list.label_id).limit(1).arel.exists ) end end diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index 6c80dd61873..f986e05944c 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -17,8 +17,8 @@ module Boards attr_reader :board def decrement_higher_lists(list) - board.lists.movable.where('position > ?', list.position). - update_all('position = position - 1') + board.lists.movable.where('position > ?', list.position) + .update_all('position = position - 1') end def remove_list(list) diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index 2f109934ea9..f2a68865f7b 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -33,15 +33,15 @@ module Boards end def decrement_intermediate_lists - board.lists.movable.where('position > ?', old_position). - where('position <= ?', new_position). - update_all('position = position - 1') + board.lists.movable.where('position > ?', old_position) + .where('position <= ?', new_position) + .update_all('position = position - 1') end def increment_intermediate_lists - board.lists.movable.where('position >= ?', new_position). - where('position < ?', old_position). - update_all('position = position + 1') + board.lists.movable.where('position >= ?', new_position) + .where('position < ?', old_position) + .update_all('position = position + 1') end def update_list_position(list) diff --git a/app/services/ci/create_pipeline_builds_service.rb b/app/services/ci/create_pipeline_builds_service.rb index b7da3f8e7eb..c5da757c840 100644 --- a/app/services/ci/create_pipeline_builds_service.rb +++ b/app/services/ci/create_pipeline_builds_service.rb @@ -36,8 +36,8 @@ module Ci end def new_builds - @new_builds ||= pipeline.config_builds_attributes. - reject { |build| existing_build_names.include?(build[:name]) } + @new_builds ||= pipeline.config_builds_attributes + .reject { |build| existing_build_names.include?(build[:name]) } end def existing_build_names diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index b53a467655f..38a85e9fc42 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -48,9 +48,9 @@ module Ci Ci::Pipeline.transaction do pipeline.save - Ci::CreatePipelineBuildsService. - new(project, current_user). - execute(pipeline) + Ci::CreatePipelineBuildsService + .new(project, current_user) + .execute(pipeline) end pipeline.tap(&:process!) diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index 6af3c1ca5b1..062e7be5be8 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -3,8 +3,8 @@ module Ci def execute(project, trigger, ref, variables = nil) trigger_request = trigger.trigger_requests.create(variables: variables) - pipeline = Ci::CreatePipelineService.new(project, nil, ref: ref). - execute(ignore_skip_ci: true, trigger_request: trigger_request) + pipeline = Ci::CreatePipelineService.new(project, nil, ref: ref) + .execute(ignore_skip_ci: true, trigger_request: trigger_request) if pipeline.persisted? trigger_request end diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 442230abe29..79eb97b7b55 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -78,9 +78,9 @@ module Ci def ensure_created_builds! return if created_builds.any? - Ci::CreatePipelineBuildsService. - new(project, current_user). - execute(pipeline) + Ci::CreatePipelineBuildsService + .new(project, current_user) + .execute(pipeline) end end end diff --git a/app/services/ci/register_build_service.rb b/app/services/ci/register_build_service.rb index 6f03bf2be13..9c7abf97b4c 100644 --- a/app/services/ci/register_build_service.rb +++ b/app/services/ci/register_build_service.rb @@ -42,15 +42,15 @@ module Ci def builds_for_shared_runner new_builds. # don't run projects which have not enabled shared runners and builds - joins(:project).where(projects: { shared_runners_enabled: true }). - joins('LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id'). - where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'). + joins(:project).where(projects: { shared_runners_enabled: true }) + .joins('LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id') + .where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'). # Implement fair scheduling # this returns builds that are ordered by number of running builds # we prefer projects that don't use shared runners at all - joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id"). - order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC') + joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id") + .order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC') end def builds_for_specific_runner @@ -58,8 +58,8 @@ module Ci end def running_builds_for_shared_runners - Ci::Build.running.where(runner: Ci::Runner.shared). - group(:gl_project_id).select(:gl_project_id, 'count(*) AS running_builds') + Ci::Build.running.where(runner: Ci::Runner.shared) + .group(:gl_project_id).select(:gl_project_id, 'count(*) AS running_builds') end def new_builds diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index c1fa9278f0f..38ef323f6e5 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -2,8 +2,8 @@ module Ci class RetryBuildService < ::BaseService CLONE_ATTRIBUTES = %i[pipeline project ref tag options commands name allow_failure stage stage_idx trigger_request - yaml_variables when environment coverage_regex]. - freeze + yaml_variables when environment coverage_regex] + .freeze REJECT_ATTRIBUTES = %i[id status user token coverage trace runner artifacts_expire_at artifacts_file @@ -20,9 +20,9 @@ module Ci new_build.enqueue! - MergeRequests::AddTodoWhenBuildFailsService. - new(project, current_user). - close(new_build) + MergeRequests::AddTodoWhenBuildFailsService + .new(project, current_user) + .close(new_build) end end diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 6e9781ca8cf..2c5e130e5aa 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -8,13 +8,13 @@ module Ci pipeline.builds.failed_or_canceled.find_each do |build| next unless build.retryable? - Ci::RetryBuildService.new(project, current_user). - reprocess(build) + Ci::RetryBuildService.new(project, current_user) + .reprocess(build) end - MergeRequests::AddTodoWhenBuildFailsService. - new(project, current_user). - close_all(pipeline) + MergeRequests::AddTodoWhenBuildFailsService + .new(project, current_user) + .close_all(pipeline) pipeline.process! end diff --git a/app/services/commits/change_service.rb b/app/services/commits/change_service.rb index 75281837b09..25e22f14e60 100644 --- a/app/services/commits/change_service.rb +++ b/app/services/commits/change_service.rb @@ -70,8 +70,8 @@ module Commits # Temporary branch exists and contains the change commit return if repository.find_branch(new_branch) - result = ValidateNewBranchService.new(@project, current_user). - execute(new_branch) + result = ValidateNewBranchService.new(@project, current_user) + .execute(new_branch) if result[:status] == :error raise ChangeError, "There was an error creating the source branch: #{result[:message]}" diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 1b5e504573a..77459d8779d 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -1,7 +1,7 @@ class CreateBranchService < BaseService def execute(branch_name, ref) - result = ValidateNewBranchService.new(project, current_user). - execute(branch_name) + result = ValidateNewBranchService.new(project, current_user) + .execute(branch_name) return result if result[:status] == :error diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb index 0a25f56d24c..dcec604b455 100644 --- a/app/services/files/base_service.rb +++ b/app/services/files/base_service.rb @@ -72,8 +72,8 @@ module Files end def validate_target_branch - result = ValidateNewBranchService.new(project, current_user). - execute(@target_branch) + result = ValidateNewBranchService.new(project, current_user) + .execute(@target_branch) if result[:status] == :error raise_error("Something went wrong when we tried to create #{@target_branch} for you: #{result[:message]}") diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb index a71fe61a4b6..b1e8d11fdcf 100644 --- a/app/services/files/update_service.rb +++ b/app/services/files/update_service.rb @@ -24,8 +24,8 @@ module Files end def last_commit - @last_commit ||= Gitlab::Git::Commit. - last_for_path(@start_project.repository, @start_branch, @file_path) + @last_commit ||= Gitlab::Git::Commit + .last_for_path(@start_project.repository, @start_branch, @file_path) end end end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index f681f831cbd..ee6e695c134 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -85,8 +85,8 @@ class GitPushService < BaseService default = is_default_branch? push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit| - ProcessCommitWorker. - perform_async(project.id, current_user.id, commit.to_hash, default) + ProcessCommitWorker + .perform_async(project.id, current_user.id, commit.to_hash, default) end end @@ -96,8 +96,8 @@ class GitPushService < BaseService # Update merge requests that may be affected by this push. A new branch # could cause the last commit of a merge request to change. # - UpdateMergeRequestsWorker. - perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) + UpdateMergeRequestsWorker + .perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) EventCreateService.new.push(@project, current_user, build_push_data) @project.execute_hooks(build_push_data.dup, :push_hooks) @@ -105,9 +105,9 @@ class GitPushService < BaseService Ci::CreatePipelineService.new(@project, current_user, build_push_data).execute if push_remove_branch? - AfterBranchDeleteService. - new(project, current_user). - execute(branch_name) + AfterBranchDeleteService + .new(project, current_user) + .execute(branch_name) end end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 9500faf2862..457dcf76995 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -144,8 +144,8 @@ class IssuableBaseService < BaseService def merge_slash_commands_into_params!(issuable) description, command_params = - SlashCommands::InterpretService.new(project, current_user). - execute(params[:description], issuable) + SlashCommands::InterpretService.new(project, current_user) + .execute(params[:description], issuable) # Avoid a description already set on an issuable to be overwritten by a nil params[:description] = description if params.has_key?(:description) diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb index 366b3572738..9e0c90b56f6 100644 --- a/app/services/issues/create_service.rb +++ b/app/services/issues/create_service.rb @@ -29,8 +29,8 @@ module Issues def resolve_discussions_in_merge_request(issue) Discussions::ResolveService.new(project, current_user, merge_request: merge_request_for_resolving_discussions, - follow_up_issue: issue). - execute(merge_request_for_resolving_discussions.resolvable_discussions) + follow_up_issue: issue) + .execute(merge_request_for_resolving_discussions.resolvable_discussions) end private diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb index 17b65947468..a2a5f57d069 100644 --- a/app/services/issues/move_service.rb +++ b/app/services/issues/move_service.rb @@ -61,8 +61,8 @@ module Issues end def cloneable_milestone_id - @new_project.milestones. - find_by(title: @old_issue.milestone.try(:title)).try(:id) + @new_project.milestones + .find_by(title: @old_issue.milestone.try(:title)).try(:id) end def rewrite_notes diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb index 76d0ba67b07..43b539ded53 100644 --- a/app/services/labels/promote_service.rb +++ b/app/services/labels/promote_service.rb @@ -26,29 +26,29 @@ module Labels private def label_ids_for_merge(new_label) - LabelsFinder. - new(current_user, title: new_label.title, group_id: project.group.id). - execute(skip_authorization: true). - where.not(id: new_label). - select(:id) # Can't use pluck() to avoid object-creation because of the batching + LabelsFinder + .new(current_user, title: new_label.title, group_id: project.group.id) + .execute(skip_authorization: true) + .where.not(id: new_label) + .select(:id) # Can't use pluck() to avoid object-creation because of the batching end def update_issuables(new_label, label_ids) - LabelLink. - where(label: label_ids). - update_all(label_id: new_label) + LabelLink + .where(label: label_ids) + .update_all(label_id: new_label) end def update_issue_board_lists(new_label, label_ids) - List. - where(label: label_ids). - update_all(label_id: new_label) + List + .where(label: label_ids) + .update_all(label_id: new_label) end def update_priorities(new_label, label_ids) - LabelPriority. - where(label: label_ids). - update_all(label_id: new_label) + LabelPriority + .where(label: label_ids) + .update_all(label_id: new_label) end def update_project_labels(label_ids) diff --git a/app/services/labels/transfer_service.rb b/app/services/labels/transfer_service.rb index 514679ed29d..d2ece354efc 100644 --- a/app/services/labels/transfer_service.rb +++ b/app/services/labels/transfer_service.rb @@ -41,16 +41,16 @@ module Labels end def group_labels_applied_to_issues - Label.joins(:issues). - where( + Label.joins(:issues) + .where( issues: { project_id: project.id }, labels: { type: 'GroupLabel', group_id: old_group.id } ) end def group_labels_applied_to_merge_requests - Label.joins(:merge_requests). - where( + Label.joins(:merge_requests) + .where( merge_requests: { target_project_id: project.id }, labels: { type: 'GroupLabel', group_id: old_group.id } ) @@ -64,15 +64,15 @@ module Labels end def update_label_links(labels, old_label_id:, new_label_id:) - LabelLink.joins(:label). - merge(labels). - where(label_id: old_label_id). - update_all(label_id: new_label_id) + LabelLink.joins(:label) + .merge(labels) + .where(label_id: old_label_id) + .update_all(label_id: new_label_id) end def update_label_priorities(old_label_id:, new_label_id:) - LabelPriority.where(project_id: project.id, label_id: old_label_id). - update_all(label_id: new_label_id) + LabelPriority.where(project_id: project.id, label_id: old_label_id) + .update_all(label_id: new_label_id) end end end diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index fd9d7de35f4..5a53b973059 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -40,11 +40,11 @@ module MergeRequests # Returns all origin and fork merge requests from `@project` satisfying passed arguments. def merge_requests_for(source_branch, mr_states: [:opened]) - MergeRequest. - with_state(mr_states). - where(source_branch: source_branch, source_project_id: @project.id). - preload(:source_project). # we don't need a #includes since we're just preloading for the #select - select(&:source_project) + MergeRequest + .with_state(mr_states) + .where(source_branch: source_branch, source_project_id: @project.id) + .preload(:source_project) # we don't need a #includes since we're just preloading for the #select + .select(&:source_project) end def pipeline_merge_requests(pipeline) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 3da1b657a41..1657f8624a7 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -63,8 +63,8 @@ module MergeRequests MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) if params[:should_remove_source_branch].present? || @merge_request.force_remove_source_branch? - DeleteBranchService.new(@merge_request.source_project, branch_deletion_user). - execute(merge_request.source_branch) + DeleteBranchService.new(@merge_request.source_project, branch_deletion_user) + .execute(merge_request.source_branch) end end diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index edee3032683..9277f67e5ae 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -43,9 +43,9 @@ module MergeRequests end filter_merge_requests(merge_requests).each do |merge_request| - MergeRequests::PostMergeService. - new(merge_request.target_project, @current_user). - execute(merge_request) + MergeRequests::PostMergeService + .new(merge_request.target_project, @current_user) + .execute(merge_request) end end @@ -56,13 +56,13 @@ module MergeRequests # Refresh merge request diff if we push to source or target branch of merge request # Note: we should update merge requests from forks too def reload_merge_requests - merge_requests = @project.merge_requests.opened. - by_source_or_target_branch(@branch_name).to_a + merge_requests = @project.merge_requests.opened + .by_source_or_target_branch(@branch_name).to_a # Fork merge requests - merge_requests += MergeRequest.opened. - where(source_branch: @branch_name, source_project: @project). - where.not(target_project: @project).to_a + merge_requests += MergeRequest.opened + .where(source_branch: @branch_name, source_project: @project) + .where.not(target_project: @project).to_a filter_merge_requests(merge_requests).each do |merge_request| if merge_request.source_branch == @branch_name || force_push? diff --git a/app/services/notes/slash_commands_service.rb b/app/services/notes/slash_commands_service.rb index ad1e6f6774a..addb6a7e65b 100644 --- a/app/services/notes/slash_commands_service.rb +++ b/app/services/notes/slash_commands_service.rb @@ -22,8 +22,8 @@ module Notes def extract_commands(note, options = {}) return [note.note, {}] unless supported?(note) - SlashCommands::InterpretService.new(project, current_user, options). - execute(note.note, note.noteable) + SlashCommands::InterpretService.new(project, current_user, options) + .execute(note.note, note.noteable) end def execute(command_params, note) diff --git a/app/services/tags/create_service.rb b/app/services/tags/create_service.rb index 1756da9e519..674792f6138 100644 --- a/app/services/tags/create_service.rb +++ b/app/services/tags/create_service.rb @@ -19,8 +19,8 @@ module Tags if new_tag if release_description - CreateReleaseService.new(@project, @current_user). - execute(tag_name, release_description) + CreateReleaseService.new(@project, @current_user) + .execute(tag_name, release_description) end success.merge(tag: new_tag) diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index fad741531ea..4411eda3b02 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -103,11 +103,11 @@ module Users end def fresh_authorizations - ProjectAuthorization. - unscoped. - select('project_id, MAX(access_level) AS access_level'). - from("(#{project_authorizations_union.to_sql}) #{ProjectAuthorization.table_name}"). - group(:project_id) + ProjectAuthorization + .unscoped + .select('project_id, MAX(access_level) AS access_level') + .from("(#{project_authorizations_union.to_sql}) #{ProjectAuthorization.table_name}") + .group(:project_id) end private diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index 31e2dc448da..def0ab1dde1 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -3,7 +3,7 @@ class BuildCoverageWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id). - try(:update_coverage) + Ci::Build.find_by(id: build_id) + .try(:update_coverage) end end diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index ff22313c491..9965af935d4 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -3,7 +3,7 @@ class BuildHooksWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id). - try(:execute_hooks) + Ci::Build.find_by(id: build_id) + .try(:execute_hooks) end end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index d4c3f14ec06..f5ccc84c160 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -33,15 +33,15 @@ class EmailsOnPushWorker reverse_compare = false if action == :push - compare = CompareService.new(project, after_sha). - execute(project, before_sha) + compare = CompareService.new(project, after_sha) + .execute(project, before_sha) diff_refs = compare.diff_refs return false if compare.same if compare.commits.empty? - compare = CompareService.new(project, before_sha). - execute(project, after_sha) + compare = CompareService.new(project, before_sha) + .execute(project, after_sha) diff_refs = compare.diff_refs reverse_compare = true diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index 2c29a9a58e1..eb403c134d1 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -3,10 +3,10 @@ class ExpireBuildInstanceArtifactsWorker include DedicatedSidekiqQueue def perform(build_id) - build = Ci::Build. - with_expired_artifacts. - reorder(nil). - find_by(id: build_id) + build = Ci::Build + .with_expired_artifacts + .reorder(nil) + .find_by(id: build_id) return unless build.try(:project) diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index 79efca4f2f9..48e2da338f6 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -7,7 +7,7 @@ class MergeWorker current_user = User.find(current_user_id) merge_request = MergeRequest.find(merge_request_id) - MergeRequests::MergeService.new(merge_request.target_project, current_user, params). - execute(merge_request) + MergeRequests::MergeService.new(merge_request.target_project, current_user, params) + .execute(merge_request) end end diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index 7480a055e6a..7e36eacebf8 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -3,7 +3,7 @@ class PipelineHooksWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id). - try(:execute_hooks) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:execute_hooks) end end diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 5dcb09f553e..357e4a9a1c3 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -3,7 +3,7 @@ class PipelineProcessWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id). - try(:process!) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:process!) end end diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb index ef710f374ca..cc0eb708cf9 100644 --- a/app/workers/pipeline_success_worker.rb +++ b/app/workers/pipeline_success_worker.rb @@ -4,9 +4,9 @@ class PipelineSuccessWorker def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| - MergeRequests::MergeWhenPipelineSucceedsService. - new(pipeline.project, nil). - trigger(pipeline) + MergeRequests::MergeWhenPipelineSucceedsService + .new(pipeline.project, nil) + .trigger(pipeline) end end end diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index e6d06d0577d..96c4152c674 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -3,7 +3,7 @@ class PipelineUpdateWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id). - try(:update_status) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:update_status) end end diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb index e9a5bd7f24e..5d7561732f1 100644 --- a/app/workers/process_commit_worker.rb +++ b/app/workers/process_commit_worker.rb @@ -45,16 +45,16 @@ class ProcessCommitWorker # therefor we use IssueCollection here and skip the authorization check in # Issues::CloseService#execute. IssueCollection.new(issues).updatable_by_user(user).each do |issue| - Issues::CloseService.new(project, author). - close_issue(issue, commit: commit) + Issues::CloseService.new(project, author) + .close_issue(issue, commit: commit) end end def update_issue_metrics(commit, author) mentioned_issues = commit.all_references(author).issues - Issue::Metrics.where(issue_id: mentioned_issues.map(&:id), first_mentioned_in_commit_at: nil). - update_all(first_mentioned_in_commit_at: commit.committed_date) + Issue::Metrics.where(issue_id: mentioned_issues.map(&:id), first_mentioned_in_commit_at: nil) + .update_all(first_mentioned_in_commit_at: commit.committed_date) end def build_commit(project, hash) diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb index 8ff9d07860f..505ff9e086e 100644 --- a/app/workers/project_cache_worker.rb +++ b/app/workers/project_cache_worker.rb @@ -32,8 +32,8 @@ class ProjectCacheWorker private def try_obtain_lease_for(project_id, section) - Gitlab::ExclusiveLease. - new("project_cache_worker:#{project_id}:#{section}", timeout: LEASE_TIMEOUT). - try_obtain + Gitlab::ExclusiveLease + .new("project_cache_worker:#{project_id}:#{section}", timeout: LEASE_TIMEOUT) + .try_obtain end end diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb index 392abb9c21b..2b43bb19ad1 100644 --- a/app/workers/prune_old_events_worker.rb +++ b/app/workers/prune_old_events_worker.rb @@ -10,9 +10,9 @@ class PruneOldEventsWorker '(id IN (SELECT id FROM (?) ids_to_remove))', Event.unscoped.where( 'created_at < ?', - (12.months + 1.day).ago). - select(:id). - limit(10_000)). - delete_all + (12.months + 1.day).ago) + .select(:id) + .limit(10_000)) + .delete_all end end diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb index c3e7491ec4e..b94d83bd709 100644 --- a/app/workers/repository_check/batch_worker.rb +++ b/app/workers/repository_check/batch_worker.rb @@ -32,10 +32,10 @@ module RepositoryCheck # has to sit and wait for this query to finish. def project_ids limit = 10_000 - never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago). - limit(limit).pluck(:id) - old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago). - reorder('last_repository_check_at ASC').limit(limit).pluck(:id) + never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago) + .limit(limit).pluck(:id) + old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago) + .reorder('last_repository_check_at ASC').limit(limit).pluck(:id) never_checked_projects + old_check_projects end diff --git a/config/initializers/metrics.rb b/config/initializers/metrics.rb index e0702e06cc9..2dcaaa09242 100644 --- a/config/initializers/metrics.rb +++ b/config/initializers/metrics.rb @@ -147,8 +147,8 @@ if Gitlab::Metrics.enabled? ActiveRecord::Querying.public_instance_methods(false).map(&:to_s) ) - Gitlab::Metrics::Instrumentation. - instrument_class_hierarchy(ActiveRecord::Base) do |klass, method| + Gitlab::Metrics::Instrumentation + .instrument_class_hierarchy(ActiveRecord::Base) do |klass, method| # Instrumenting the ApplicationSetting class can lead to an infinite # loop. Since the data is cached any way we don't really need to # instrument it. diff --git a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb index 35697aab207..3865f3e3a08 100644 --- a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb +++ b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb @@ -6,9 +6,9 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration class Project < ActiveRecord::Base def self.find_including_path(id) - select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace"). - joins('INNER JOIN namespaces ON namespaces.id = projects.namespace_id'). - find_by(id: id) + select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace") + .joins('INNER JOIN namespaces ON namespaces.id = projects.namespace_id') + .find_by(id: id) end def repository_storage_path diff --git a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb index 57f28e809de..b31f9699f3d 100644 --- a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb +++ b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb @@ -8,11 +8,11 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration environments = Arel::Table.new(:environments) # Get all [project_id, name] pairs that occur more than once - finder_sql = environments. - group(environments[:project_id], environments[:name]). - having(Arel.sql("COUNT(1)").gt(1)). - project(environments[:project_id], environments[:name]). - to_sql + finder_sql = environments + .group(environments[:project_id], environments[:name]) + .having(Arel.sql("COUNT(1)").gt(1)) + .project(environments[:project_id], environments[:name]) + .to_sql conflicting = connection.exec_query(finder_sql) @@ -28,12 +28,12 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration # Rename conflicting environments by appending "-#{id}" to all but the first def fix_duplicates(project_id, name) environments = Arel::Table.new(:environments) - finder_sql = environments. - where(environments[:project_id].eq(project_id)). - where(environments[:name].eq(name)). - order(environments[:id].asc). - project(environments[:id], environments[:name]). - to_sql + finder_sql = environments + .where(environments[:project_id].eq(project_id)) + .where(environments[:name].eq(name)) + .order(environments[:id].asc) + .project(environments[:id], environments[:name]) + .to_sql # Now we have the data for all the conflicting rows conflicts = connection.exec_query(finder_sql).rows @@ -41,11 +41,11 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration conflicts.each do |id, name| update_sql = - Arel::UpdateManager.new(ActiveRecord::Base). - table(environments). - set(environments[:name] => name + "-" + id.to_s). - where(environments[:id].eq(id)). - to_sql + Arel::UpdateManager.new(ActiveRecord::Base) + .table(environments) + .set(environments[:name] => name + "-" + id.to_s) + .where(environments[:id].eq(id)) + .to_sql connection.exec_update(update_sql, self.class.name, []) end diff --git a/db/migrate/20161207231626_add_environment_slug.rb b/db/migrate/20161207231626_add_environment_slug.rb index aec08dc79f2..1dec96a1299 100644 --- a/db/migrate/20161207231626_add_environment_slug.rb +++ b/db/migrate/20161207231626_add_environment_slug.rb @@ -19,10 +19,10 @@ class AddEnvironmentSlug < ActiveRecord::Migration finder = environments.project(:id, :name) connection.exec_query(finder.to_sql).rows.each do |id, name| - updater = Arel::UpdateManager.new(ActiveRecord::Base). - table(environments). - set(environments[:slug] => generate_slug(name)). - where(environments[:id].eq(id)) + updater = Arel::UpdateManager.new(ActiveRecord::Base) + .table(environments) + .set(environments[:slug] => generate_slug(name)) + .where(environments[:id].eq(id)) connection.exec_update(updater.to_sql, self.class.name, []) end diff --git a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb index df38591a333..823274b08c0 100644 --- a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb +++ b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb @@ -13,13 +13,13 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration namespaces = Arel::Table.new(:namespaces) finder_sql = - projects. - join(namespaces, Arel::Nodes::InnerJoin). - on(projects[:namespace_id].eq(namespaces[:id])). - where(projects[:visibility_level].gt(namespaces[:visibility_level])). - project(projects[:id], namespaces[:visibility_level]). - take(BATCH_SIZE). - to_sql + projects + .join(namespaces, Arel::Nodes::InnerJoin) + .on(projects[:namespace_id].eq(namespaces[:id])) + .where(projects[:visibility_level].gt(namespaces[:visibility_level])) + .project(projects[:id], namespaces[:visibility_level]) + .take(BATCH_SIZE) + .to_sql # Update matching rows in batches. Each batch can cause up to 3 UPDATE # statements, in addition to the SELECT: one per visibility_level @@ -33,10 +33,10 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration end updates.each do |visibility_level, project_ids| - updater = Arel::UpdateManager.new(ActiveRecord::Base). - table(projects). - set(projects[:visibility_level] => visibility_level). - where(projects[:id].in(project_ids)) + updater = Arel::UpdateManager.new(ActiveRecord::Base) + .table(projects) + .set(projects[:visibility_level] => visibility_level) + .where(projects[:id].in(project_ids)) ActiveRecord::Base.connection.exec_update(updater.to_sql, self.class.name, []) end diff --git a/db/post_migrate/20161221153951_rename_reserved_project_names.rb b/db/post_migrate/20161221153951_rename_reserved_project_names.rb index 49a6bc884a8..d322844e2fd 100644 --- a/db/post_migrate/20161221153951_rename_reserved_project_names.rb +++ b/db/post_migrate/20161221153951_rename_reserved_project_names.rb @@ -79,17 +79,17 @@ class RenameReservedProjectNames < ActiveRecord::Migration private def reserved_projects - Project.unscoped. - includes(:namespace). - where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)'). - where('projects.path' => KNOWN_PATHS) + Project.unscoped + .includes(:namespace) + .where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)') + .where('projects.path' => KNOWN_PATHS) end def route_exists?(full_path) quoted_path = ActiveRecord::Base.connection.quote_string(full_path) - ActiveRecord::Base.connection. - select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present? + ActiveRecord::Base.connection + .select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present? end # Adds number to the end of the path that is not taken by other route diff --git a/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb b/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb index f399950bd5e..d7be004d47f 100644 --- a/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb +++ b/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb @@ -39,11 +39,11 @@ class RequeuePendingDeleteProjects < ActiveRecord::Migration def find_batch projects = Arel::Table.new(:projects) - projects.project(projects[:id]). - where(projects[:pending_delete].eq(true)). - where(projects[:namespace_id].not_eq(nil)). - skip(@offset * BATCH_SIZE). - take(BATCH_SIZE). - to_sql + projects.project(projects[:id]) + .where(projects[:pending_delete].eq(true)) + .where(projects[:namespace_id].not_eq(nil)) + .skip(@offset * BATCH_SIZE) + .take(BATCH_SIZE) + .to_sql end end diff --git a/db/post_migrate/20170106142508_fill_authorized_projects.rb b/db/post_migrate/20170106142508_fill_authorized_projects.rb index 314c8440c8b..0ca20587981 100644 --- a/db/post_migrate/20170106142508_fill_authorized_projects.rb +++ b/db/post_migrate/20170106142508_fill_authorized_projects.rb @@ -15,8 +15,8 @@ class FillAuthorizedProjects < ActiveRecord::Migration disable_ddl_transaction! def up - relation = User.select(:id). - where('authorized_projects_populated IS NOT TRUE') + relation = User.select(:id) + .where('authorized_projects_populated IS NOT TRUE') relation.find_in_batches(batch_size: 1_000) do |rows| args = rows.map { |row| [row.id] } diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index 789f45489eb..4d4e442cb49 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -68,8 +68,8 @@ module API delete ":id/access_requests/:user_id" do source = find_source(source_type, params[:id]) - ::Members::DestroyService.new(source, current_user, params). - execute(:requesters) + ::Members::DestroyService.new(source, current_user, params) + .execute(:requesters) end end end diff --git a/lib/api/branches.rb b/lib/api/branches.rb index c65de90cca2..804fca9b0fb 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -102,8 +102,8 @@ module API end post ":id/repository/branches" do authorize_push_project - result = CreateBranchService.new(user_project, current_user). - execute(params[:branch], params[:ref]) + result = CreateBranchService.new(user_project, current_user) + .execute(params[:branch], params[:ref]) if result[:status] == :success present result[:branch], @@ -121,8 +121,8 @@ module API delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do authorize_push_project - result = DeleteBranchService.new(user_project, current_user). - execute(params[:branch]) + result = DeleteBranchService.new(user_project, current_user) + .execute(params[:branch]) if result[:status] == :success { diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 85aa6932f81..a9429262981 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -451,9 +451,9 @@ module API expose :tag_push_events, :note_events, :build_events, :pipeline_events # Expose serialized properties expose :properties do |service, options| - field_names = service.fields. - select { |field| options[:include_passwords] || field[:type] != 'password' }. - map { |field| field[:name] } + field_names = service.fields + .select { |field| options[:include_passwords] || field[:type] != 'password' } + .map { |field| field[:name] } service.properties.slice(*field_names) end end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 6d30c5d81b1..0515533b850 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -128,9 +128,9 @@ module API issue_params = declared_params(include_missing: false) if merge_request_iid = params[:merge_request_for_resolving_discussions] - issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id). - execute. - find_by(iid: merge_request_iid) + issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id) + .execute + .find_by(iid: merge_request_iid) end issue = ::Issues::CreateService.new(user_project, diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 6a2476424a7..bdd764abfeb 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -193,13 +193,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) else - ::MergeRequests::MergeService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) end present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project @@ -213,9 +213,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user). - cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user) + .cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/api/notes.rb b/lib/api/notes.rb index f559a7f74a0..dc47aeafb82 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -33,8 +33,8 @@ module API # paginate() only works with a relation. This could lead to a # mismatch between the pagination headers info and the actual notes # array returned, but this is really a edge-case. - paginate(noteable.notes). - reject { |n| n.cross_reference_not_visible_for?(current_user) } + paginate(noteable.notes) + .reject { |n| n.cross_reference_not_visible_for?(current_user) } present notes, with: Entities::Note else not_found!("Notes") diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index ffa73696029..f59f7959173 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -36,8 +36,8 @@ module API new_pipeline = Ci::CreatePipelineService.new(user_project, current_user, - declared_params(include_missing: false)). - execute(ignore_skip_ci: true, save_on_errors: false) + declared_params(include_missing: false)) + .execute(ignore_skip_ci: true, save_on_errors: false) if new_pipeline.persisted? present new_pipeline, with: Entities::Pipeline else diff --git a/lib/api/tags.rb b/lib/api/tags.rb index 86759ab882f..40d37e44db1 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -44,8 +44,8 @@ module API post ':id/repository/tags' do authorize_push_project - result = ::Tags::CreateService.new(user_project, current_user). - execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) + result = ::Tags::CreateService.new(user_project, current_user) + .execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) if result[:status] == :success present result[:tag], @@ -63,8 +63,8 @@ module API delete ":id/repository/tags/:tag_name", requirements: { tag_name: /.+/ } do authorize_push_project - result = ::Tags::DestroyService.new(user_project, current_user). - execute(params[:tag_name]) + result = ::Tags::DestroyService.new(user_project, current_user) + .execute(params[:tag_name]) if result[:status] == :success { @@ -85,8 +85,8 @@ module API post ':id/repository/tags/:tag_name/release', requirements: { tag_name: /.+/ } do authorize_push_project - result = CreateReleaseService.new(user_project, current_user). - execute(params[:tag_name], params[:description]) + result = CreateReleaseService.new(user_project, current_user) + .execute(params[:tag_name], params[:description]) if result[:status] == :success present result[:release], with: Entities::Release @@ -105,8 +105,8 @@ module API put ':id/repository/tags/:tag_name/release', requirements: { tag_name: /.+/ } do authorize_push_project - result = UpdateReleaseService.new(user_project, current_user). - execute(params[:tag_name], params[:description]) + result = UpdateReleaseService.new(user_project, current_user) + .execute(params[:tag_name], params[:description]) if result[:status] == :success present result[:release], with: Entities::Release diff --git a/lib/api/users.rb b/lib/api/users.rb index 94b2b6653d2..9824f8c2ce6 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -117,13 +117,13 @@ module API if user.save present user, with: Entities::UserPublic else - conflict!('Email has already been taken') if User. - where(email: user.email). - count > 0 + conflict!('Email has already been taken') if User + .where(email: user.email) + .count > 0 - conflict!('Username has already been taken') if User. - where(username: user.username). - count > 0 + conflict!('Username has already been taken') if User + .where(username: user.username) + .count > 0 render_validation_error!(user) end @@ -151,12 +151,12 @@ module API not_found!('User') unless user conflict!('Email has already been taken') if params[:email] && - User.where(email: params[:email]). - where.not(id: user.id).count > 0 + User.where(email: params[:email]) + .where.not(id: user.id).count > 0 conflict!('Username has already been taken') if params[:username] && - User.where(username: params[:username]). - where.not(id: user.id).count > 0 + User.where(username: params[:username]) + .where.not(id: user.id).count > 0 user_params = declared_params(include_missing: false) identity_attrs = user_params.slice(:provider, :extern_uid) @@ -354,11 +354,11 @@ module API user = User.find_by(id: params[:id]) not_found!('User') unless user - events = user.events. - merge(ProjectsFinder.new.execute(current_user)). - references(:project). - with_associations. - recent + events = user.events + .merge(ProjectsFinder.new.execute(current_user)) + .references(:project) + .with_associations + .recent present paginate(events), with: Entities::Event end diff --git a/lib/api/v3/issues.rb b/lib/api/v3/issues.rb index d0af09f0e1e..264ad8d0da5 100644 --- a/lib/api/v3/issues.rb +++ b/lib/api/v3/issues.rb @@ -141,9 +141,9 @@ module API issue_params = declared_params(include_missing: false) if merge_request_iid = params[:merge_request_for_resolving_discussions] - issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id). - execute. - find_by(iid: merge_request_iid) + issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id) + .execute + .find_by(iid: merge_request_iid) end issue = ::Issues::CreateService.new(user_project, diff --git a/lib/api/v3/merge_requests.rb b/lib/api/v3/merge_requests.rb index 5a8dacc9c44..129f9d850e9 100644 --- a/lib/api/v3/merge_requests.rb +++ b/lib/api/v3/merge_requests.rb @@ -200,13 +200,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) else - ::MergeRequests::MergeService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) end present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project @@ -220,9 +220,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user). - cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user) + .cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/banzai/pipeline/wiki_pipeline.rb b/lib/banzai/pipeline/wiki_pipeline.rb index 17b460608d7..c37b8e71cb0 100644 --- a/lib/banzai/pipeline/wiki_pipeline.rb +++ b/lib/banzai/pipeline/wiki_pipeline.rb @@ -3,8 +3,8 @@ module Banzai class WikiPipeline < FullPipeline def self.filters @filters ||= begin - super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter). - insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) + super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter) + .insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) end end end diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index c6426210a92..7e6357f8a00 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -10,8 +10,8 @@ module Banzai end def references(type, project, current_user = nil) - processor = Banzai::ReferenceParser[type]. - new(project, current_user) + processor = Banzai::ReferenceParser[type] + .new(project, current_user) processor.process(html_documents) end @@ -28,8 +28,8 @@ module Banzai # text blobs to parse. return [] if @texts_and_contexts.empty? - @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts). - map { |html| Nokogiri::HTML.fragment(html) } + @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts) + .map { |html| Nokogiri::HTML.fragment(html) } end end end diff --git a/lib/banzai/reference_parser/issue_parser.rb b/lib/banzai/reference_parser/issue_parser.rb index 6c20dec5734..0ffaf79d9d8 100644 --- a/lib/banzai/reference_parser/issue_parser.rb +++ b/lib/banzai/reference_parser/issue_parser.rb @@ -9,8 +9,8 @@ module Banzai issues = issues_for_nodes(nodes) - readable_issues = Ability. - issues_readable_by_user(issues.values, user).to_set + readable_issues = Ability + .issues_readable_by_user(issues.values, user).to_set nodes.select do |node| readable_issues.include?(issue_for_node(issues, node)) diff --git a/lib/banzai/reference_parser/user_parser.rb b/lib/banzai/reference_parser/user_parser.rb index 7adaffa19c1..e0125fabcec 100644 --- a/lib/banzai/reference_parser/user_parser.rb +++ b/lib/banzai/reference_parser/user_parser.rb @@ -99,8 +99,8 @@ module Banzai def find_users_for_projects(ids) return [] if ids.empty? - collection_objects_for_ids(Project, ids). - flat_map { |p| p.team.members.to_a } + collection_objects_for_ids(Project, ids) + .flat_map { |p| p.team.members.to_a } end def can_read_reference?(user, ref_project) diff --git a/lib/ci/charts.rb b/lib/ci/charts.rb index 3decc3b1a26..6063d6f45e8 100644 --- a/lib/ci/charts.rb +++ b/lib/ci/charts.rb @@ -2,10 +2,10 @@ module Ci module Charts module DailyInterval def grouped_count(query) - query. - group("DATE(#{Ci::Build.table_name}.created_at)"). - count(:created_at). - transform_keys { |date| date.strftime(@format) } + query + .group("DATE(#{Ci::Build.table_name}.created_at)") + .count(:created_at) + .transform_keys { |date| date.strftime(@format) } end def interval_step @@ -16,14 +16,14 @@ module Ci module MonthlyInterval def grouped_count(query) if Gitlab::Database.postgresql? - query. - group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')"). - count(:created_at). - transform_keys(&:squish) + query + .group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')") + .count(:created_at) + .transform_keys(&:squish) else - query. - group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')"). - count(:created_at) + query + .group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')") + .count(:created_at) end end @@ -46,8 +46,8 @@ module Ci end def collect - query = project.builds. - where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from) + query = project.builds + .where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from) totals_count = grouped_count(query) success_count = grouped_count(query.success) diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 04d9756657a..649ee4d018b 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -115,8 +115,8 @@ module Ci end def yaml_variables(name) - variables = (@variables || {}). - merge(job_variables(name)) + variables = (@variables || {}) + .merge(job_variables(name)) variables.map do |key, value| { key: key.to_s, value: value, public: true } diff --git a/lib/gitlab/badge/build/status.rb b/lib/gitlab/badge/build/status.rb index 3c65fd02e4c..b762d85b6e5 100644 --- a/lib/gitlab/badge/build/status.rb +++ b/lib/gitlab/badge/build/status.rb @@ -19,9 +19,9 @@ module Gitlab end def status - @project.pipelines. - where(sha: @sha). - latest_status(@ref) || 'unknown' + @project.pipelines + .where(sha: @sha) + .latest_status(@ref) || 'unknown' end def metadata diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb index 8a6564755ab..9a0482306b7 100644 --- a/lib/gitlab/badge/coverage/report.rb +++ b/lib/gitlab/badge/coverage/report.rb @@ -42,9 +42,9 @@ module Gitlab if @job.blank? @pipeline.coverage else - @pipeline.builds. - find_by(name: @job). - try(:coverage) + @pipeline.builds + .find_by(name: @job) + .try(:coverage) end end end diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb index 03a7981b1db..44323b47dca 100644 --- a/lib/gitlab/bitbucket_import/importer.rb +++ b/lib/gitlab/bitbucket_import/importer.rb @@ -48,10 +48,10 @@ module Gitlab return users[username] if users.key?(username) - users[username] = User.select(:id). - joins(:identities). - find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username). - try(:id) + users[username] = User.select(:id) + .joins(:identities) + .find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username) + .try(:id) end def repo diff --git a/lib/gitlab/checks/matching_merge_request.rb b/lib/gitlab/checks/matching_merge_request.rb index bd295c25194..849848515da 100644 --- a/lib/gitlab/checks/matching_merge_request.rb +++ b/lib/gitlab/checks/matching_merge_request.rb @@ -8,10 +8,10 @@ module Gitlab end def match? - @project.merge_requests. - with_state(:locked). - where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name). - exists? + @project.merge_requests + .with_state(:locked) + .where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name) + .exists? end end end diff --git a/lib/gitlab/ci/config/entry/configurable.rb b/lib/gitlab/ci/config/entry/configurable.rb index deaaf06bbd7..e05aca9881b 100644 --- a/lib/gitlab/ci/config/entry/configurable.rb +++ b/lib/gitlab/ci/config/entry/configurable.rb @@ -27,9 +27,9 @@ module Gitlab return unless valid? self.class.nodes.each do |key, factory| - factory. - value(@config[key]). - with(key: key, parent: self) + factory + .value(@config[key]) + .with(key: key, parent: self) @entries[key] = factory.create! end @@ -49,8 +49,8 @@ module Gitlab private # rubocop:disable Lint/UselessAccessModifier def entry(key, entry, metadata) - factory = Entry::Factory.new(entry). - with(description: metadata[:description]) + factory = Entry::Factory.new(entry) + .with(description: metadata[:description]) (@nodes ||= {}).merge!(key.to_sym => factory) end diff --git a/lib/gitlab/ci/config/entry/global.rb b/lib/gitlab/ci/config/entry/global.rb index 0a404331225..ac771662b2f 100644 --- a/lib/gitlab/ci/config/entry/global.rb +++ b/lib/gitlab/ci/config/entry/global.rb @@ -46,9 +46,9 @@ module Gitlab private def compose_jobs! - factory = Entry::Factory.new(Entry::Jobs). - value(@config.except(*self.class.nodes.keys)). - with(key: :jobs, parent: self, + factory = Entry::Factory.new(Entry::Jobs) + .value(@config.except(*self.class.nodes.keys)) + .with(key: :jobs, parent: self, description: 'Jobs definition for this pipeline') @entries[:jobs] = factory.create! diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb index 7b83f0f1b69..a487a3a06d6 100644 --- a/lib/gitlab/ci/config/entry/jobs.rb +++ b/lib/gitlab/ci/config/entry/jobs.rb @@ -31,10 +31,10 @@ module Gitlab @config.each do |name, config| node = hidden?(name) ? Entry::Hidden : Entry::Job - factory = Entry::Factory.new(node). - value(config || {}). - metadata(name: name). - with(key: name, parent: self, + factory = Entry::Factory.new(node) + .value(config || {}) + .metadata(name: name) + .with(key: name, parent: self, description: "#{name} job definition.") @entries[name] = factory.create! diff --git a/lib/gitlab/ci/pipeline_duration.rb b/lib/gitlab/ci/pipeline_duration.rb index a210e76acaa..3208cc2bef6 100644 --- a/lib/gitlab/ci/pipeline_duration.rb +++ b/lib/gitlab/ci/pipeline_duration.rb @@ -87,8 +87,8 @@ module Gitlab def from_pipeline(pipeline) status = %w[success failed running canceled] - builds = pipeline.builds.latest. - where(status: status).where.not(started_at: nil).order(:started_at) + builds = pipeline.builds.latest + .where(status: status).where.not(started_at: nil).order(:started_at) from_builds(builds) end diff --git a/lib/gitlab/ci/status/factory.rb b/lib/gitlab/ci/status/factory.rb index efe756cc585..15836c699c7 100644 --- a/lib/gitlab/ci/status/factory.rb +++ b/lib/gitlab/ci/status/factory.rb @@ -17,10 +17,10 @@ module Gitlab end def core_status - Gitlab::Ci::Status. - const_get(@status.capitalize). - new(@subject, @user). - extend(self.class.common_helpers) + Gitlab::Ci::Status + .const_get(@status.capitalize) + .new(@subject, @user) + .extend(self.class.common_helpers) end def compound_extended_status diff --git a/lib/gitlab/ci/trace_reader.rb b/lib/gitlab/ci/trace_reader.rb index dd6a84d7d1c..1d7ddeb3e0f 100644 --- a/lib/gitlab/ci/trace_reader.rb +++ b/lib/gitlab/ci/trace_reader.rb @@ -41,8 +41,8 @@ module Gitlab chunks.unshift(buf) end - chunks.join.lines.last(max_lines).join. - force_encoding(Encoding.default_external) + chunks.join.lines.last(max_lines).join + .force_encoding(Encoding.default_external) end end end diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb index 15992b77680..5d271829f37 100644 --- a/lib/gitlab/contributions_calendar.rb +++ b/lib/gitlab/contributions_calendar.rb @@ -16,14 +16,14 @@ module Gitlab # Can't use Event.contributions here because we need to check 3 different # project_features for the (currently) 3 different contribution types date_from = 1.year.ago - repo_events = event_counts(date_from, :repository). - having(action: Event::PUSHED) - issue_events = event_counts(date_from, :issues). - having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue") - mr_events = event_counts(date_from, :merge_requests). - having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest") - note_events = event_counts(date_from, :merge_requests). - having(action: [Event::COMMENTED], target_type: "Note") + repo_events = event_counts(date_from, :repository) + .having(action: Event::PUSHED) + issue_events = event_counts(date_from, :issues) + .having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue") + mr_events = event_counts(date_from, :merge_requests) + .having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest") + note_events = event_counts(date_from, :merge_requests) + .having(action: [Event::COMMENTED], target_type: "Note") union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events, note_events]) events = Event.find_by_sql(union.to_sql).map(&:attributes) @@ -34,9 +34,9 @@ module Gitlab end def events_by_date(date) - events = Event.contributions.where(author_id: contributor.id). - where(created_at: date.beginning_of_day..date.end_of_day). - where(project_id: projects) + events = Event.contributions.where(author_id: contributor.id) + .where(created_at: date.beginning_of_day..date.end_of_day) + .where(project_id: projects) # Use visible_to_user? instead of the complicated logic in activity_dates # because we're only viewing the events for a single day. @@ -60,20 +60,20 @@ module Gitlab # use IN(project_ids...) instead. It's the intersection of two users so # the list will be (relatively) short @contributed_project_ids ||= projects.uniq.pluck(:id) - authed_projects = Project.where(id: @contributed_project_ids). - with_feature_available_for_user(feature, current_user). - reorder(nil). - select(:id) + authed_projects = Project.where(id: @contributed_project_ids) + .with_feature_available_for_user(feature, current_user) + .reorder(nil) + .select(:id) - conditions = t[:created_at].gteq(date_from.beginning_of_day). - and(t[:created_at].lteq(Date.today.end_of_day)). - and(t[:author_id].eq(contributor.id)) + conditions = t[:created_at].gteq(date_from.beginning_of_day) + .and(t[:created_at].lteq(Date.today.end_of_day)) + .and(t[:author_id].eq(contributor.id)) - Event.reorder(nil). - select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount'). - group(t[:project_id], t[:target_type], t[:action], 'date(created_at)'). - where(conditions). - having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql))) + Event.reorder(nil) + .select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount') + .group(t[:project_id], t[:target_type], t[:action], 'date(created_at)') + .where(conditions) + .having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql))) end end end diff --git a/lib/gitlab/cycle_analytics/base_query.rb b/lib/gitlab/cycle_analytics/base_query.rb index d560dca45c8..58729d3ced8 100644 --- a/lib/gitlab/cycle_analytics/base_query.rb +++ b/lib/gitlab/cycle_analytics/base_query.rb @@ -12,17 +12,17 @@ module Gitlab end def stage_query - query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])). - join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id])). - where(issue_table[:project_id].eq(@project.id)). - where(issue_table[:deleted_at].eq(nil)). - where(issue_table[:created_at].gteq(@options[:from])) + query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])) + .join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id])) + .where(issue_table[:project_id].eq(@project.id)) + .where(issue_table[:deleted_at].eq(nil)) + .where(issue_table[:created_at].gteq(@options[:from])) # Load merge_requests - query = query.join(mr_table, Arel::Nodes::OuterJoin). - on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id])). - join(mr_metrics_table). - on(mr_table[:id].eq(mr_metrics_table[:merge_request_id])) + query = query.join(mr_table, Arel::Nodes::OuterJoin) + .on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id])) + .join(mr_metrics_table) + .on(mr_table[:id].eq(mr_metrics_table[:merge_request_id])) query end diff --git a/lib/gitlab/database/median.rb b/lib/gitlab/database/median.rb index e46c551098d..4e4ddf32754 100644 --- a/lib/gitlab/database/median.rb +++ b/lib/gitlab/database/median.rb @@ -29,10 +29,10 @@ module Gitlab end def mysql_median_datetime_sql(arel_table, query_so_far, column_sym) - query = arel_table. - from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name)). - project(average([arel_table[column_sym]], 'median')). - where( + query = arel_table + .from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name)) + .project(average([arel_table[column_sym]], 'median')) + .where( Arel::Nodes::Between.new( Arel.sql("(select @row_id := @row_id + 1)"), Arel::Nodes::And.new( @@ -67,8 +67,8 @@ module Gitlab cte_table = Arel::Table.new("ordered_records") cte = Arel::Nodes::As.new( cte_table, - arel_table. - project( + arel_table + .project( arel_table[column_sym].as(column_sym.to_s), Arel::Nodes::Over.new(Arel::Nodes::NamedFunction.new("row_number", []), Arel::Nodes::Window.new.order(arel_table[column_sym])).as('row_id'), @@ -79,8 +79,8 @@ module Gitlab # From the CTE, select either the middle row or the middle two rows (this is accomplished # by 'where cte.row_id between cte.ct / 2.0 AND cte.ct / 2.0 + 1'). Find the average of the # selected rows, and this is the median value. - cte_table.project(average([extract_epoch(cte_table[column_sym])], "median")). - where( + cte_table.project(average([extract_epoch(cte_table[column_sym])], "median")) + .where( Arel::Nodes::Between.new( cte_table[:row_id], Arel::Nodes::And.new( @@ -88,9 +88,9 @@ module Gitlab (cte_table[:ct] / Arel.sql('2.0') + 1)] ) ) - ). - with(query_so_far, cte). - to_sql + ) + .with(query_so_far, cte) + .to_sql end private diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index fc445ab9483..0c7c77f52e3 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -140,19 +140,19 @@ module Gitlab start_id = exec_query(start_arel.to_sql).to_hash.first['id'].to_i loop do - stop_arel = table.project(table[:id]). - where(table[:id].gteq(start_id)). - order(table[:id].asc). - take(1). - skip(batch_size) + stop_arel = table.project(table[:id]) + .where(table[:id].gteq(start_id)) + .order(table[:id].asc) + .take(1) + .skip(batch_size) stop_arel = yield table, stop_arel if block_given? stop_row = exec_query(stop_arel.to_sql).to_hash.first - update_arel = Arel::UpdateManager.new(ActiveRecord::Base). - table(table). - set([[table[column], value]]). - where(table[:id].gteq(start_id)) + update_arel = Arel::UpdateManager.new(ActiveRecord::Base) + .table(table) + .set([[table[column], value]]) + .where(table[:id].gteq(start_id)) if stop_row stop_id = stop_row['id'].to_i diff --git a/lib/gitlab/downtime_check.rb b/lib/gitlab/downtime_check.rb index ab9537ed7d7..941244694e2 100644 --- a/lib/gitlab/downtime_check.rb +++ b/lib/gitlab/downtime_check.rb @@ -50,8 +50,8 @@ module Gitlab # Returns the class for the given migration file path. def class_for_migration_file(path) - File.basename(path, File.extname(path)).split('_', 2).last.camelize. - constantize + File.basename(path, File.extname(path)).split('_', 2).last.camelize + .constantize end # Returns true if the given migration can be performed without downtime. diff --git a/lib/gitlab/git/encoding_helper.rb b/lib/gitlab/git/encoding_helper.rb index 874fd8fe6e2..e57d228e688 100644 --- a/lib/gitlab/git/encoding_helper.rb +++ b/lib/gitlab/git/encoding_helper.rb @@ -49,9 +49,9 @@ module Gitlab private def clean(message) - message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: ""). - encode("UTF-8"). - gsub("\0".encode("UTF-8"), "") + message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: "") + .encode("UTF-8") + .gsub("\0".encode("UTF-8"), "") end end end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index a160869541a..dc73cad93a5 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -178,9 +178,9 @@ module Gitlab def apply_labels(issuable, raw) return unless raw.labels.count > 0 - label_ids = raw.labels. - map { |attrs| @labels[attrs.name] }. - compact + label_ids = raw.labels + .map { |attrs| @labels[attrs.name] } + .compact issuable.update_attribute(:label_ids, label_ids) end diff --git a/lib/gitlab/github_import/user_formatter.rb b/lib/gitlab/github_import/user_formatter.rb index 7f3bf0052a7..04c2964da20 100644 --- a/lib/gitlab/github_import/user_formatter.rb +++ b/lib/gitlab/github_import/user_formatter.rb @@ -25,8 +25,8 @@ module Gitlab def find_by_email return nil unless email - User.find_by_any_email(email). - try(:id) + User.find_by_any_email(email) + .try(:id) end def find_by_external_uid @@ -34,11 +34,11 @@ module Gitlab identities = ::Identity.arel_table - User.select(:id). - joins(:identities).where(identities[:provider].eq(:github). - and(identities[:extern_uid].eq(id))). - first. - try(:id) + User.select(:id) + .joins(:identities).where(identities[:provider].eq(:github) + .and(identities[:extern_uid].eq(id))) + .first + .try(:id) end end end diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb index 9360afedfcb..bfc57544485 100644 --- a/lib/gitlab/highlight.rb +++ b/lib/gitlab/highlight.rb @@ -1,8 +1,8 @@ module Gitlab class Highlight def self.highlight(blob_name, blob_content, repository: nil, plain: false) - new(blob_name, blob_content, repository: repository). - highlight(blob_content, continue: false, plain: plain) + new(blob_name, blob_content, repository: repository) + .highlight(blob_content, continue: false, plain: plain) end def self.highlight_lines(repository, ref, file_name) diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index b84c81f1a6c..8bf32f9e43f 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -12,9 +12,9 @@ module Gitlab class << self def find_by_uid_and_provider(uid, provider) # LDAP distinguished name is case-insensitive - identity = ::Identity. - where(provider: provider). - iwhere(extern_uid: uid).last + identity = ::Identity + .where(provider: provider) + .iwhere(extern_uid: uid).last identity && identity.user end end diff --git a/lib/gitlab/metrics.rb b/lib/gitlab/metrics.rb index 857e0abf710..c5b746a83a6 100644 --- a/lib/gitlab/metrics.rb +++ b/lib/gitlab/metrics.rb @@ -145,8 +145,8 @@ module Gitlab host = settings[:host] port = settings[:port] - InfluxDB::Client. - new(udp: { host: host, port: port }) + InfluxDB::Client + .new(udp: { host: host, port: port }) end end diff --git a/lib/gitlab/metrics/system.rb b/lib/gitlab/metrics/system.rb index 3aaebb3e9c3..aba3e0df382 100644 --- a/lib/gitlab/metrics/system.rb +++ b/lib/gitlab/metrics/system.rb @@ -34,13 +34,13 @@ module Gitlab # THREAD_CPUTIME is not supported on OS X if Process.const_defined?(:CLOCK_THREAD_CPUTIME_ID) def self.cpu_time - Process. - clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond) + Process + .clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond) end else def self.cpu_time - Process. - clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond) + Process + .clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond) end end diff --git a/lib/gitlab/other_markup.rb b/lib/gitlab/other_markup.rb index e67acf28c94..7b0e9e4a7b4 100644 --- a/lib/gitlab/other_markup.rb +++ b/lib/gitlab/other_markup.rb @@ -12,8 +12,8 @@ module Gitlab # :ref # def self.render(file_name, input, context) - html = GitHub::Markup.render(file_name, input). - force_encoding(input.encoding) + html = GitHub::Markup.render(file_name, input) + .force_encoding(input.encoding) html = Banzai.post_process(html, context) diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 7374d2bc8b8..71e798424a5 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -30,8 +30,8 @@ module Gitlab end def version_required - @version_required ||= File.read(Rails.root. - join('GITLAB_SHELL_VERSION')).strip + @version_required ||= File.read(Rails.root + .join('GITLAB_SHELL_VERSION')).strip end def strip_key(key) diff --git a/lib/gitlab/sherlock/line_profiler.rb b/lib/gitlab/sherlock/line_profiler.rb index aa1468bff6b..b5f9d040047 100644 --- a/lib/gitlab/sherlock/line_profiler.rb +++ b/lib/gitlab/sherlock/line_profiler.rb @@ -77,8 +77,8 @@ module Gitlab line_samples << LineSample.new(duration, events) end - samples << FileSample. - new(file, line_samples, total_duration, total_events) + samples << FileSample + .new(file, line_samples, total_duration, total_events) end samples diff --git a/lib/gitlab/sherlock/query.rb b/lib/gitlab/sherlock/query.rb index 99e56e923eb..948bf5e6528 100644 --- a/lib/gitlab/sherlock/query.rb +++ b/lib/gitlab/sherlock/query.rb @@ -105,10 +105,10 @@ module Gitlab end def format_sql(query) - query.each_line. - map { |line| line.strip }. - join("\n"). - gsub(PREFIX_NEWLINE) { "\n#{$1} " } + query.each_line + .map { |line| line.strip } + .join("\n") + .gsub(PREFIX_NEWLINE) { "\n#{$1} " } end end end diff --git a/rubocop/cop/gem_fetcher.rb b/rubocop/cop/gem_fetcher.rb index 6a951f5f91a..e157d8e0791 100644 --- a/rubocop/cop/gem_fetcher.rb +++ b/rubocop/cop/gem_fetcher.rb @@ -25,12 +25,12 @@ module RuboCop private def gemfile?(node) - node. - location. - expression. - source_buffer. - name. - end_with?("Gemfile") + node + .location + .expression + .source_buffer + .name + .end_with?("Gemfile") end end end diff --git a/rubocop/migration_helpers.rb b/rubocop/migration_helpers.rb index 3160a784a04..35f1868fcc0 100644 --- a/rubocop/migration_helpers.rb +++ b/rubocop/migration_helpers.rb @@ -3,8 +3,8 @@ module RuboCop module MigrationHelpers # Returns true if the given node originated from the db/migrate directory. def in_migration?(node) - File.dirname(node.location.expression.source_buffer.name). - end_with?('db/migrate') + File.dirname(node.location.expression.source_buffer.name) + .end_with?('db/migrate') end end end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 2ab2ca1b667..03f46f82874 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -105,8 +105,8 @@ describe Admin::UsersController do it 'displays an alert' do go - expect(flash[:notice]). - to eq 'Two-factor Authentication has been disabled for this user' + expect(flash[:notice]) + .to eq 'Two-factor Authentication has been disabled for this user' end def go diff --git a/spec/controllers/blob_controller_spec.rb b/spec/controllers/blob_controller_spec.rb index 2fcb4a6a528..45fbe09c9f7 100644 --- a/spec/controllers/blob_controller_spec.rb +++ b/spec/controllers/blob_controller_spec.rb @@ -59,8 +59,8 @@ describe Projects::BlobController do context 'redirect to tree' do let(:id) { 'markdown/doc' } it 'redirects' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc") + expect(subject) + .to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc") end end end diff --git a/spec/controllers/ci/projects_controller_spec.rb b/spec/controllers/ci/projects_controller_spec.rb index 3cd955dc9d4..86f01f437a2 100644 --- a/spec/controllers/ci/projects_controller_spec.rb +++ b/spec/controllers/ci/projects_controller_spec.rb @@ -33,8 +33,8 @@ describe Ci::ProjectsController do shared_examples 'badge provider' do it 'shows badge' do expect(response.status).to eq 200 - expect(response.headers). - to include('Content-Type' => 'image/svg+xml') + expect(response.headers) + .to include('Content-Type' => 'image/svg+xml') end end diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index fa4cc0ebbe0..66b45cf33c1 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -31,8 +31,8 @@ describe Import::BitbucketController do expires_at: expires_at, expires_in: expires_in, refresh_token: refresh_token) - allow_any_instance_of(OAuth2::Client). - to receive(:get_token).and_return(access_token) + allow_any_instance_of(OAuth2::Client) + .to receive(:get_token).and_return(access_token) stub_omniauth_provider('bitbucket') get :callback @@ -93,9 +93,9 @@ describe Import::BitbucketController do context "when the repository owner is the Bitbucket user" do context "when the Bitbucket user and GitLab user's usernames match" do it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -105,9 +105,9 @@ describe Import::BitbucketController do let(:bitbucket_username) { "someone_else" } it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -126,9 +126,9 @@ describe Import::BitbucketController do context "when the namespace is owned by the GitLab user" do it "takes the existing namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -141,8 +141,8 @@ describe Import::BitbucketController do end it "doesn't create a project" do - expect(Gitlab::BitbucketImport::ProjectCreator). - not_to receive(:new) + expect(Gitlab::BitbucketImport::ProjectCreator) + .not_to receive(:new) post :create, format: :js end @@ -152,16 +152,16 @@ describe Import::BitbucketController do context "when a namespace with the Bitbucket user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.to change(Namespace, :count).by(1) end it "takes the new namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params). - and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -173,16 +173,16 @@ describe Import::BitbucketController do end it "doesn't create the namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.not_to change(Namespace, :count) end it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator) + .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index 95696e14b6c..45c3fa075ef 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -21,10 +21,10 @@ describe Import::GithubController do describe "GET callback" do it "updates access token" do token = "asdasd12345" - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:get_token).and_return(token) - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:github_options).and_return({}) + allow_any_instance_of(Gitlab::GithubImport::Client) + .to receive(:get_token).and_return(token) + allow_any_instance_of(Gitlab::GithubImport::Client) + .to receive(:github_options).and_return({}) stub_omniauth_provider('github') get :callback diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 3f73ea000ae..3ef1bbaa9b7 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -18,8 +18,8 @@ describe Import::GitlabController do describe "GET callback" do it "updates access token" do - allow_any_instance_of(Gitlab::GitlabImport::Client). - to receive(:get_token).and_return(token) + allow_any_instance_of(Gitlab::GitlabImport::Client) + .to receive(:get_token).and_return(token) stub_omniauth_provider('gitlab') get :callback @@ -78,9 +78,9 @@ describe Import::GitlabController do context "when the repository owner is the GitLab.com user" do context "when the GitLab.com user and GitLab server user's usernames match" do it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, user.namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).with(gitlab_repo, user.namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -90,9 +90,9 @@ describe Import::GitlabController do let(:gitlab_username) { "someone_else" } it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, user.namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).with(gitlab_repo, user.namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -112,9 +112,9 @@ describe Import::GitlabController do context "when the namespace is owned by the GitLab server user" do it "takes the existing namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, existing_namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).with(gitlab_repo, existing_namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -127,8 +127,8 @@ describe Import::GitlabController do end it "doesn't create a project" do - expect(Gitlab::GitlabImport::ProjectCreator). - not_to receive(:new) + expect(Gitlab::GitlabImport::ProjectCreator) + .not_to receive(:new) post :create, format: :js end @@ -138,16 +138,16 @@ describe Import::GitlabController do context "when a namespace with the GitLab.com user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.to change(Namespace, :count).by(1) end it "takes the new namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params). - and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params) + .and_return(double(execute: true)) post :create, format: :js end @@ -159,16 +159,16 @@ describe Import::GitlabController do end it "doesn't create the namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.not_to change(Namespace, :count) end it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, user.namespace, user, access_params). - and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator) + .to receive(:new).with(gitlab_repo, user.namespace, user, access_params) + .and_return(double(execute: true)) post :create, format: :js end diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 9de03876755..6df654087dc 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -32,8 +32,8 @@ describe Projects::BranchesController do let(:branch) { "merge_branch" } let(:ref) { "master" } it 'redirects' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/merge_branch") + expect(subject) + .to redirect_to("/#{project.path_with_namespace}/tree/merge_branch") end end @@ -41,8 +41,8 @@ describe Projects::BranchesController do let(:branch) { "" } let(:ref) { "master" } it 'redirects' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") + expect(subject) + .to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") end end @@ -81,8 +81,8 @@ describe Projects::BranchesController do branch_name: branch, issue_iid: issue.iid - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch") + expect(subject) + .to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch") end it 'posts a system note' do diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb index ebd2d0e092b..1b5f6c4b43a 100644 --- a/spec/controllers/projects/commit_controller_spec.rb +++ b/spec/controllers/projects/commit_controller_spec.rb @@ -66,8 +66,8 @@ describe Projects::CommitController do end it "does not escape Html" do - allow_any_instance_of(Commit).to receive(:"to_#{format}"). - and_return('HTML entities &<>" ') + allow_any_instance_of(Commit).to receive(:"to_#{format}") + .and_return('HTML entities &<>" ') go(id: commit.id, format: format) diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 84d119f1867..72a13d77a85 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -150,14 +150,14 @@ describe Projects::EnvironmentsController do context 'and valid id' do it 'returns the first terminal for the environment' do - expect_any_instance_of(Environment). - to receive(:terminals). - and_return([:fake_terminal]) + expect_any_instance_of(Environment) + .to receive(:terminals) + .and_return([:fake_terminal]) - expect(Gitlab::Workhorse). - to receive(:terminal_websocket). - with(:fake_terminal). - and_return(workhorse: :response) + expect(Gitlab::Workhorse) + .to receive(:terminal_websocket) + .with(:fake_terminal) + .and_return(workhorse: :response) get :terminal_websocket_authorize, environment_params diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 7871b6a9e10..85ad883534a 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -226,8 +226,8 @@ describe Projects::IssuesController do it 'redirect to issue page' do update_verified_issue - expect(response). - to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + expect(response) + .to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) end it 'accepts an issue after recaptcha is verified' do @@ -241,8 +241,8 @@ describe Projects::IssuesController do it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do spam_log = create(:spam_log) - expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) }. - not_to change { SpamLog.last.recaptcha_verified } + expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) } + .not_to change { SpamLog.last.recaptcha_verified } end end end @@ -558,8 +558,8 @@ describe Projects::IssuesController do it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do spam_log = create(:spam_log) - expect { post_new_issue({}, { spam_log_id: spam_log.id, recaptcha_verification: true } ) }. - not_to change { SpamLog.last.recaptcha_verified } + expect { post_new_issue({}, { spam_log_id: spam_log.id, recaptcha_verification: true } ) } + .not_to change { SpamLog.last.recaptcha_verified } end end end diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb index cae733f0cfb..a8c365a209f 100644 --- a/spec/controllers/projects/mattermosts_controller_spec.rb +++ b/spec/controllers/projects/mattermosts_controller_spec.rb @@ -11,8 +11,8 @@ describe Projects::MattermostsController do describe 'GET #new' do before do - allow_any_instance_of(MattermostSlashCommandsService). - to receive(:list_teams).and_return([]) + allow_any_instance_of(MattermostSlashCommandsService) + .to receive(:list_teams).and_return([]) end it 'accepts the request' do diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 1c5dbda0de2..b990f4dae86 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -105,8 +105,8 @@ describe Projects::MergeRequestsController do end it "does not escape Html" do - allow_any_instance_of(MergeRequest).to receive(:"to_#{format}"). - and_return('HTML entities &<>" ') + allow_any_instance_of(MergeRequest).to receive(:"to_#{format}") + .and_return('HTML entities &<>" ') get(:show, namespace_id: project.namespace.to_param, @@ -334,9 +334,9 @@ describe Projects::MergeRequestsController do it 'sets the MR to merge when the build succeeds' do service = double(:merge_when_build_succeeds_service) - expect(MergeRequests::MergeWhenPipelineSucceedsService). - to receive(:new).with(project, anything, anything). - and_return(service) + expect(MergeRequests::MergeWhenPipelineSucceedsService) + .to receive(:new).with(project, anything, anything) + .and_return(service) expect(service).to receive(:execute).with(merge_request) merge_when_build_succeeds @@ -720,8 +720,8 @@ describe Projects::MergeRequestsController do describe 'GET conflicts' do context 'when the conflicts cannot be resolved in the UI' do before do - allow_any_instance_of(Gitlab::Conflict::Parser). - to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) + allow_any_instance_of(Gitlab::Conflict::Parser) + .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) get :conflicts, namespace_id: merge_request_with_conflicts.project.namespace.to_param, @@ -826,8 +826,8 @@ describe Projects::MergeRequestsController do context 'when the conflicts cannot be resolved in the UI' do before do - allow_any_instance_of(Gitlab::Conflict::Parser). - to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) + allow_any_instance_of(Gitlab::Conflict::Parser) + .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) conflict_for_path('files/ruby/regex.rb') end @@ -1043,9 +1043,9 @@ describe Projects::MergeRequestsController do end it 'calls MergeRequests::AssignIssuesService' do - expect(MergeRequests::AssignIssuesService).to receive(:new). - with(project, user, merge_request: merge_request). - and_return(double(execute: { count: 1 })) + expect(MergeRequests::AssignIssuesService).to receive(:new) + .with(project, user, merge_request: merge_request) + .and_return(double(execute: { count: 1 })) post_assign_issues end diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb index b23d6e257ba..68fe29ce2d5 100644 --- a/spec/controllers/projects/raw_controller_spec.rb +++ b/spec/controllers/projects/raw_controller_spec.rb @@ -15,8 +15,8 @@ describe Projects::RawController do expect(response).to have_http_status(200) expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.header['Content-Disposition']). - to eq("inline") + expect(response.header['Content-Disposition']) + .to eq("inline") expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-blob:") end end diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 8bab094a79e..65e554aee49 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -89,21 +89,21 @@ describe Projects::SnippetsController do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) } + .to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } + .not_to change { Snippet.count } expect(response).to render_template(:new) end it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end it 'renders :new with recaptcha disabled' do @@ -169,8 +169,8 @@ describe Projects::SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'updates the snippet' do - expect { update_snippet(title: 'Foo') }. - to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') } + .to change { snippet.reload.title }.to('Foo') end end @@ -178,13 +178,13 @@ describe Projects::SnippetsController do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo') }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') } + .to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do @@ -223,13 +223,13 @@ describe Projects::SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb index b81645a3d2d..71193feaaaa 100644 --- a/spec/controllers/projects/tree_controller_spec.rb +++ b/spec/controllers/projects/tree_controller_spec.rb @@ -82,8 +82,8 @@ describe Projects::TreeController do let(:id) { 'master/README.md' } it 'redirects' do redirect_url = "/#{project.path_with_namespace}/blob/master/README.md" - expect(subject). - to redirect_to(redirect_url) + expect(subject) + .to redirect_to(redirect_url) end end end @@ -106,8 +106,8 @@ describe Projects::TreeController do let(:target_branch) { 'master-test'} it 'redirects to the new directory' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/#{target_branch}/#{path}") + expect(subject) + .to redirect_to("/#{project.path_with_namespace}/tree/#{target_branch}/#{path}") expect(flash[:notice]).to eq('The directory has been successfully created.') end end @@ -117,8 +117,8 @@ describe Projects::TreeController do let(:target_branch) { 'master'} it 'does not allow overwriting of existing files' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/master") + expect(subject) + .to redirect_to("/#{project.path_with_namespace}/tree/master") expect(flash[:alert]).to eq('Directory already exists as a file') end end diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb index 954fc2eaf21..6a437350248 100644 --- a/spec/controllers/sent_notifications_controller_spec.rb +++ b/spec/controllers/sent_notifications_controller_spec.rb @@ -77,8 +77,8 @@ describe SentNotificationsController, type: :controller do end it 'redirects to the issue page' do - expect(response). - to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + expect(response) + .to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) end end @@ -100,8 +100,8 @@ describe SentNotificationsController, type: :controller do end it 'redirects to the merge request page' do - expect(response). - to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request)) + expect(response) + .to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request)) end end end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index d951325f765..42fd37f81d4 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -11,8 +11,8 @@ describe SessionsController do it 'does not authenticate user' do post(:create, user: { login: 'invalid', password: 'invalid' }) - expect(response). - to set_flash.now[:alert].to /Invalid Login or password/ + expect(response) + .to set_flash.now[:alert].to /Invalid Login or password/ end end @@ -42,8 +42,8 @@ describe SessionsController do context 'remember_me field' do it 'sets a remember_user_token cookie when enabled' do allow(controller).to receive(:find_user).and_return(user) - expect(controller). - to receive(:remember_me).with(user).and_call_original + expect(controller) + .to receive(:remember_me).with(user).and_call_original authenticate_2fa(remember_me: '1', otp_attempt: user.current_otp) @@ -102,8 +102,8 @@ describe SessionsController do end it 'warns about invalid OTP code' do - expect(response).to set_flash.now[:alert]. - to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert] + .to /Invalid two-factor code/ end end end @@ -129,8 +129,8 @@ describe SessionsController do end it 'warns about invalid login' do - expect(response).to set_flash.now[:alert]. - to /Invalid Login or password/ + expect(response).to set_flash.now[:alert] + .to /Invalid Login or password/ end it 'locks the user' do @@ -140,8 +140,8 @@ describe SessionsController do it 'keeps the user locked on future login attempts' do post(:create, user: { login: user.username, password: user.password }) - expect(response). - to set_flash.now[:alert].to /Invalid Login or password/ + expect(response) + .to set_flash.now[:alert].to /Invalid Login or password/ end end end @@ -153,8 +153,8 @@ describe SessionsController do authenticate_2fa(login: another_user.username, otp_attempt: 'invalid') - expect(response).to set_flash.now[:alert]. - to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert] + .to /Invalid two-factor code/ end end end @@ -177,8 +177,8 @@ describe SessionsController do it 'sets a remember_user_token cookie when enabled' do allow(U2fRegistration).to receive(:authenticate).and_return(true) allow(controller).to receive(:find_user).and_return(user) - expect(controller). - to receive(:remember_me).with(user).and_call_original + expect(controller) + .to receive(:remember_me).with(user).and_call_original authenticate_2fa_u2f(remember_me: '1', login: user.username, device_response: "{}") diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 5de3b9890ef..6b52839fe2c 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -156,20 +156,20 @@ describe SnippetsController do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PRIVATE) } + .to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } + expect { create_snippet(visibility_level: Snippet::PUBLIC) } + .not_to change { Snippet.count } end it 'creates a spam log' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end it 'renders :new with recaptcha disabled' do @@ -230,8 +230,8 @@ describe SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'updates the snippet' do - expect { update_snippet(title: 'Foo') }. - to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') } + .to change { snippet.reload.title }.to('Foo') end end @@ -239,13 +239,13 @@ describe SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do @@ -284,13 +284,13 @@ describe SnippetsController do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo') }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') } + .to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index c80b09e9b9d..8df86435501 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -90,8 +90,8 @@ FactoryGirl.define do builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min - project.project_feature. - update_attributes!( + project.project_feature + .update_attributes!( wiki_access_level: evaluator.wiki_access_level, builds_access_level: builds_access_level, snippets_access_level: evaluator.snippets_access_level, diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index 87a8f62687a..7b82c3ae3d1 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -57,8 +57,8 @@ describe "Admin::Projects", feature: true do before do create(:group, name: 'Web') - allow_any_instance_of(Projects::TransferService). - to receive(:move_uploads_to_new_namespace).and_return(true) + allow_any_instance_of(Projects::TransferService) + .to receive(:move_uploads_to_new_namespace).and_return(true) end it 'transfers project to group web', js: true do diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index c0807b8c507..332abb121fc 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -77,10 +77,10 @@ describe "Admin::Users", feature: true do it "applies defaults to user" do click_button "Create user" user = User.find_by(username: 'bang') - expect(user.projects_limit). - to eq(Gitlab.config.gitlab.default_projects_limit) - expect(user.can_create_group). - to eq(Gitlab.config.gitlab.default_can_create_group) + expect(user.projects_limit) + .to eq(Gitlab.config.gitlab.default_projects_limit) + expect(user.can_create_group) + .to eq(Gitlab.config.gitlab.default_can_create_group) end it "creates user with valid data" do diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index 746df36bb25..4ed06bb3a32 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -28,8 +28,8 @@ describe "Dashboard Feed", feature: true do end it "has issue comment event" do - expect(body). - to have_content("#{user.name} commented on issue ##{issue.iid}") + expect(body) + .to have_content("#{user.name} commented on issue ##{issue.iid}") end end end diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index a01a050a013..6caaa703ae0 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -17,8 +17,8 @@ describe 'Issues Feed', feature: true do login_with user visit namespace_project_issues_path(project.namespace, project, :atom) - expect(response_headers['Content-Type']). - to have_content('application/atom+xml') + expect(response_headers['Content-Type']) + .to have_content('application/atom+xml') expect(body).to have_selector('title', text: "#{project.name} issues") expect(body).to have_selector('author email', text: issue.author_email) expect(body).to have_selector('entry summary', text: issue.title) @@ -30,8 +30,8 @@ describe 'Issues Feed', feature: true do visit namespace_project_issues_path(project.namespace, project, :atom, private_token: user.private_token) - expect(response_headers['Content-Type']). - to have_content('application/atom+xml') + expect(response_headers['Content-Type']) + .to have_content('application/atom+xml') expect(body).to have_selector('title', text: "#{project.name} issues") expect(body).to have_selector('author email', text: issue.author_email) expect(body).to have_selector('entry summary', text: issue.title) diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index f8c3ccb416b..9b569e83257 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -48,8 +48,8 @@ describe "User Feed", feature: true do end it 'has issue comment event' do - expect(body). - to have_content("#{safe_name} commented on issue ##{issue.iid}") + expect(body) + .to have_content("#{safe_name} commented on issue ##{issue.iid}") end it 'has XHTML summaries in issue descriptions' do diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index 513de297fdf..78be7d36f47 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -111,8 +111,8 @@ feature 'Environments page', :feature, :js do find('.js-dropdown-play-icon-container').click expect(page).to have_content(manual.name.humanize) - expect { click_link(manual.name.humanize) }. - not_to change { Ci::Pipeline.count } + expect { click_link(manual.name.humanize) } + .not_to change { Ci::Pipeline.count } expect(manual.reload).to be_pending end diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb index 84d73d693bc..45d21817824 100644 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ b/spec/features/gitlab_flavored_markdown_spec.rb @@ -11,8 +11,8 @@ describe "GitLab Flavored Markdown", feature: true do end before do - allow_any_instance_of(Commit).to receive(:title). - and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details") + allow_any_instance_of(Commit).to receive(:title) + .and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details") end let(:commit) { project.commit } diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb index ae609160e18..d545d38424c 100644 --- a/spec/features/login_spec.rb +++ b/spec/features/login_spec.rb @@ -110,8 +110,8 @@ feature 'Login', feature: true do end it 'invalidates the used code' do - expect { enter_code(codes.sample) }. - to change { user.reload.otp_backup_codes.size }.by(-1) + expect { enter_code(codes.sample) } + .to change { user.reload.otp_backup_codes.size }.by(-1) end end diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 32159559c37..75ade80012c 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -58,8 +58,8 @@ describe 'GitLab Markdown', feature: true do end it 'allows Markdown in tables' do - expect(doc.at_css('td:contains("Baz")').children.to_html). - to eq 'Baz' + expect(doc.at_css('td:contains("Baz")').children.to_html) + .to eq 'Baz' end it 'parses fenced code blocks' do @@ -150,14 +150,14 @@ describe 'GitLab Markdown', feature: true do describe 'Edge Cases' do it 'allows markup inside link elements' do aggregate_failures do - expect(doc.at_css('a[href="#link-emphasis"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-emphasis"]').to_html) + .to eq %{text} - expect(doc.at_css('a[href="#link-strong"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-strong"]').to_html) + .to eq %{text} - expect(doc.at_css('a[href="#link-code"]').to_html). - to eq %{text} + expect(doc.at_css('a[href="#link-code"]').to_html) + .to eq %{text} end end end diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index 9fc5339308c..73c5ef31edc 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -61,8 +61,8 @@ feature 'Merge request created from fork' do expect(page).to have_content pipeline.id end - expect(page.find('a.btn-remove')[:href]). - to include fork_project.path_with_namespace + expect(page.find('a.btn-remove')[:href]) + .to include fork_project.path_with_namespace end end diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb index fab2d532e06..bfb28e1de15 100644 --- a/spec/features/notes_on_merge_requests_spec.rb +++ b/spec/features/notes_on_merge_requests_spec.rb @@ -25,8 +25,8 @@ describe 'Comments', feature: true do describe 'the note form' do it 'is valid' do is_expected.to have_css('.js-main-target-form', visible: true, count: 1) - expect(find('.js-main-target-form input[type=submit]').value). - to eq('Comment') + expect(find('.js-main-target-form input[type=submit]').value) + .to eq('Comment') page.within('.js-main-target-form') do expect(page).not_to have_link('Cancel') end @@ -121,8 +121,8 @@ describe 'Comments', feature: true do page.within("#note_#{note.id}") do is_expected.to have_css('.note_edited_ago') - expect(find('.note_edited_ago').text). - to match(/less than a minute ago/) + expect(find('.note_edited_ago').text) + .to match(/less than a minute ago/) end end end @@ -201,8 +201,8 @@ describe 'Comments', feature: true do it "does not add a second form for same row" do click_diff_line - is_expected. - to have_css("form[data-line-code='#{line_code}']", + is_expected + .to have_css("form[data-line-code='#{line_code}']", count: 1) end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 845490badd4..0e12618b629 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -366,8 +366,8 @@ describe 'Pipelines', :feature, :js do before { stub_ci_pipeline_to_return_yaml_file } it 'creates a new pipeline' do - expect { click_on 'Create pipeline' }. - to change { Ci::Pipeline.count }.by(1) + expect { click_on 'Create pipeline' } + .to change { Ci::Pipeline.count }.by(1) end end diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb index ed60a95deba..0c063f6d5ee 100644 --- a/spec/finders/environments_finder_spec.rb +++ b/spec/finders/environments_finder_spec.rb @@ -16,18 +16,18 @@ describe EnvironmentsFinder do end it 'returns environment when with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute) + .to contain_exactly(environment) end it 'does not return environment when no with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). - to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) + .to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). - to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) + .to be_empty end end @@ -37,23 +37,23 @@ describe EnvironmentsFinder do end it 'returns environment when ref is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) + .to contain_exactly(environment) end it 'does not environment when ref is different' do - expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute). - to be_empty + expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute) + .to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). - to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) + .to be_empty end it 'returns environment when commit constraint is not set' do - expect(described_class.new(project, user, ref: 'master').execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master').execute) + .to contain_exactly(environment) end end @@ -63,8 +63,8 @@ describe EnvironmentsFinder do end it 'returns environment' do - expect(described_class.new(project, user, commit: project.commit).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, commit: project.commit).execute) + .to contain_exactly(environment) end end @@ -75,8 +75,8 @@ describe EnvironmentsFinder do end it 'finds recently updated environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) + .to contain_exactly(environment) end end @@ -87,8 +87,8 @@ describe EnvironmentsFinder do end it 'does not find environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). - to be_empty + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) + .to be_empty end end @@ -101,8 +101,8 @@ describe EnvironmentsFinder do end it 'finds both environments' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). - to contain_exactly(environment, second_environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) + .to contain_exactly(environment, second_environment) end end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index fd40fe99941..e96576b5d45 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -58,8 +58,8 @@ describe ApplicationHelper do project = create(:empty_project, avatar: File.open(uploaded_image_temp_path)) avatar_url = "http://#{Gitlab.config.gitlab.host}/uploads/project/avatar/#{project.id}/banana_sample.gif" - expect(helper.project_icon("#{project.namespace.to_param}/#{project.to_param}").to_s). - to eq "\"Banana" + expect(helper.project_icon("#{project.namespace.to_param}/#{project.to_param}").to_s) + .to eq "\"Banana" end it 'gives uploaded icon when present' do @@ -77,8 +77,8 @@ describe ApplicationHelper do it 'returns an url for the avatar' do user = create(:user, avatar: File.open(uploaded_image_temp_path)) - expect(helper.avatar_icon(user.email).to_s). - to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") + expect(helper.avatar_icon(user.email).to_s) + .to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") end it 'returns an url for the avatar with relative url' do @@ -88,8 +88,8 @@ describe ApplicationHelper do user = create(:user, avatar: File.open(uploaded_image_temp_path)) - expect(helper.avatar_icon(user.email).to_s). - to match("/gitlab/uploads/user/avatar/#{user.id}/banana_sample.gif") + expect(helper.avatar_icon(user.email).to_s) + .to match("/gitlab/uploads/user/avatar/#{user.id}/banana_sample.gif") end it 'calls gravatar_icon when no User exists with the given email' do @@ -102,8 +102,8 @@ describe ApplicationHelper do it 'returns an URL for the avatar' do user = create(:user, avatar: File.open(uploaded_image_temp_path)) - expect(helper.avatar_icon(user).to_s). - to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") + expect(helper.avatar_icon(user).to_s) + .to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") end end end @@ -133,22 +133,22 @@ describe ApplicationHelper do it 'returns a valid Gravatar URL' do stub_config_setting(https: false) - expect(helper.gravatar_icon(user_email)). - to match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118') + expect(helper.gravatar_icon(user_email)) + .to match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118') end it 'uses HTTPs when configured' do stub_config_setting(https: true) - expect(helper.gravatar_icon(user_email)). - to match('https://secure.gravatar.com') + expect(helper.gravatar_icon(user_email)) + .to match('https://secure.gravatar.com') end it 'returns custom gravatar path when gravatar_url is set' do stub_gravatar_setting(plain_url: 'http://example.local/?s=%{size}&hash=%{hash}') - expect(gravatar_icon(user_email, 20)). - to eq('http://example.local/?s=40&hash=b58c6f14d292556214bd64909bcdb118') + expect(gravatar_icon(user_email, 20)) + .to eq('http://example.local/?s=40&hash=b58c6f14d292556214bd64909bcdb118') end it 'accepts a custom size argument' do @@ -220,8 +220,8 @@ describe ApplicationHelper do end it 'accepts a custom html_class' do - expect(element(html_class: 'custom_class').attr('class')). - to eq 'js-timeago custom_class' + expect(element(html_class: 'custom_class').attr('class')) + .to eq 'js-timeago custom_class' end it 'accepts a custom tooltip placement' do diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb index c6e3c5c2368..9bec0f9f432 100644 --- a/spec/helpers/broadcast_messages_helper_spec.rb +++ b/spec/helpers/broadcast_messages_helper_spec.rb @@ -33,8 +33,8 @@ describe BroadcastMessagesHelper do it 'allows custom style' do broadcast_message = double(color: '#f2dede', font: '#b94a48') - expect(helper.broadcast_message_style(broadcast_message)). - to match('background-color: #f2dede; color: #b94a48') + expect(helper.broadcast_message_style(broadcast_message)) + .to match('background-color: #f2dede; color: #b94a48') end end diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb index a2c008790f9..c245bb439db 100644 --- a/spec/helpers/commits_helper_spec.rb +++ b/spec/helpers/commits_helper_spec.rb @@ -9,8 +9,8 @@ describe CommitsHelper do author_email: 'my@email.com" onmouseover="alert(1)' ) - expect(helper.commit_author_link(commit)). - not_to include('onmouseover="alert(1)"') + expect(helper.commit_author_link(commit)) + .not_to include('onmouseover="alert(1)"') end end @@ -22,8 +22,8 @@ describe CommitsHelper do committer_email: 'my@email.com" onmouseover="alert(1)' ) - expect(helper.commit_committer_link(commit)). - not_to include('onmouseover="alert(1)"') + expect(helper.commit_committer_link(commit)) + .not_to include('onmouseover="alert(1)"') end end diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb index b20373a96fb..18cf0031d5f 100644 --- a/spec/helpers/form_helper_spec.rb +++ b/spec/helpers/form_helper_spec.rb @@ -11,18 +11,18 @@ describe FormHelper do it 'renders an alert div' do model = double(errors: errors_stub('Error 1')) - expect(helper.form_errors(model)). - to include('
    ') + expect(helper.form_errors(model)) + .to include('
    ') end it 'contains a summary message' do single_error = double(errors: errors_stub('A')) multi_errors = double(errors: errors_stub('A', 'B', 'C')) - expect(helper.form_errors(single_error)). - to include('

    The form contains the following error:') - expect(helper.form_errors(multi_errors)). - to include('

    The form contains the following errors:') + expect(helper.form_errors(single_error)) + .to include('

    The form contains the following error:') + expect(helper.form_errors(multi_errors)) + .to include('

    The form contains the following errors:') end it 'renders each message' do diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 520b6afddc3..908e1a65c55 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -70,8 +70,8 @@ describe GitlabMarkdownHelper do expect(doc.css('a')[0].text).to eq 'This should finally fix ' # First issue link - expect(doc.css('a')[1].attr('href')). - to eq namespace_project_issue_path(project.namespace, project, issues[0]) + expect(doc.css('a')[1].attr('href')) + .to eq namespace_project_issue_path(project.namespace, project, issues[0]) expect(doc.css('a')[1].text).to eq issues[0].to_reference # Internal commit link @@ -79,8 +79,8 @@ describe GitlabMarkdownHelper do expect(doc.css('a')[2].text).to eq ' and ' # Second issue link - expect(doc.css('a')[3].attr('href')). - to eq namespace_project_issue_path(project.namespace, project, issues[1]) + expect(doc.css('a')[3].attr('href')) + .to eq namespace_project_issue_path(project.namespace, project, issues[1]) expect(doc.css('a')[3].text).to eq issues[1].to_reference # Trailing commit link @@ -100,8 +100,8 @@ describe GitlabMarkdownHelper do it "escapes HTML passed in as the body" do actual = "This is a

    test

    - see #{issues[0].to_reference}" - expect(helper.link_to_gfm(actual, link)). - to match('<h1>test</h1>') + expect(helper.link_to_gfm(actual, link)) + .to match('<h1>test</h1>') end it 'ignores reference links when they are the entire body' do @@ -112,8 +112,8 @@ describe GitlabMarkdownHelper do it 'replaces commit message with emoji to link' do actual = link_to_gfm(':book:Book', '/foo') - expect(actual). - to eq %(:book:Book) + expect(actual) + .to eq %(:book:Book) end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index c8b0d86425f..531a54a9b8d 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -8,8 +8,8 @@ describe GroupsHelper do group = create(:group) group.avatar = fixture_file_upload(avatar_file_path) group.save! - expect(group_icon(group.path).to_s). - to match("/uploads/group/avatar/#{group.id}/banana_sample.gif") + expect(group_icon(group.path).to_s) + .to match("/uploads/group/avatar/#{group.id}/banana_sample.gif") end it 'gives default avatar_icon when no avatar is present' do diff --git a/spec/helpers/import_helper_spec.rb b/spec/helpers/import_helper_spec.rb index 10f293cddf5..9afff47f4e9 100644 --- a/spec/helpers/import_helper_spec.rb +++ b/spec/helpers/import_helper_spec.rb @@ -29,21 +29,21 @@ describe ImportHelper do context 'when provider is "github"' do context 'when provider does not specify a custom URL' do it 'uses default GitHub URL' do - allow(Gitlab.config.omniauth).to receive(:providers). - and_return([Settingslogic.new('name' => 'github')]) + allow(Gitlab.config.omniauth).to receive(:providers) + .and_return([Settingslogic.new('name' => 'github')]) - expect(helper.provider_project_link('github', 'octocat/Hello-World')). - to include('href="https://github.com/octocat/Hello-World"') + expect(helper.provider_project_link('github', 'octocat/Hello-World')) + .to include('href="https://github.com/octocat/Hello-World"') end end context 'when provider specify a custom URL' do it 'uses custom URL' do - allow(Gitlab.config.omniauth).to receive(:providers). - and_return([Settingslogic.new('name' => 'github', 'url' => 'https://github.company.com')]) + allow(Gitlab.config.omniauth).to receive(:providers) + .and_return([Settingslogic.new('name' => 'github', 'url' => 'https://github.company.com')]) - expect(helper.provider_project_link('github', 'octocat/Hello-World')). - to include('href="https://github.company.com/octocat/Hello-World"') + expect(helper.provider_project_link('github', 'octocat/Hello-World')) + .to include('href="https://github.company.com/octocat/Hello-World"') end end end @@ -54,8 +54,8 @@ describe ImportHelper do end it 'uses given host' do - expect(helper.provider_project_link('gitea', 'octocat/Hello-World')). - to include('href="https://try.gitea.io/octocat/Hello-World"') + expect(helper.provider_project_link('gitea', 'octocat/Hello-World')) + .to include('href="https://try.gitea.io/octocat/Hello-World"') end end end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index df71680e44c..69e30913d1c 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -23,23 +23,23 @@ describe IssuablesHelper do end it 'returns "Open" when state is :opened' do - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') end it 'returns "Closed" when state is :closed' do - expect(helper.issuables_state_counter_text(:issues, :closed)). - to eq('Closed 42') + expect(helper.issuables_state_counter_text(:issues, :closed)) + .to eq('Closed 42') end it 'returns "Merged" when state is :merged' do - expect(helper.issuables_state_counter_text(:merge_requests, :merged)). - to eq('Merged 42') + expect(helper.issuables_state_counter_text(:merge_requests, :merged)) + .to eq('Merged 42') end it 'returns "All" when state is :all' do - expect(helper.issuables_state_counter_text(:merge_requests, :all)). - to eq('All 42') + expect(helper.issuables_state_counter_text(:merge_requests, :all)) + .to eq('All 42') end end @@ -64,13 +64,13 @@ describe IssuablesHelper do expect(helper).to receive(:params).twice.and_return(params) expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42) - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') expect(helper).not_to receive(:issuables_count_for_state) - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') end it 'does not take some keys into account in the cache key' do @@ -83,8 +83,8 @@ describe IssuablesHelper do }.with_indifferent_access) expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42) - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') expect(helper).to receive(:params).and_return({ author_id: '11', @@ -95,22 +95,22 @@ describe IssuablesHelper do }.with_indifferent_access) expect(helper).not_to receive(:issuables_count_for_state) - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') end it 'does not take params order into account in the cache key' do expect(helper).to receive(:params).and_return('author_id' => '11', 'state' => 'opened') expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42) - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') expect(helper).to receive(:params).and_return('state' => 'opened', 'author_id' => '11') expect(helper).not_to receive(:issuables_count_for_state) - expect(helper.issuables_state_counter_text(:issues, :opened)). - to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)) + .to eq('Open 42') end end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 4a9cbba69f9..5a466e3f743 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -67,8 +67,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Joe') awards = Array.new(3, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)). - to eq('Joe, Joe, and Joe') + expect(award_user_list(awards, nil, limit: 3)) + .to eq('Joe, Joe, and Joe') end it "displays the current user's name as 'You'" do @@ -83,8 +83,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Jane') awards = Array.new(5, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)). - to eq('Jane, Jane, Jane, and 2 more.') + expect(award_user_list(awards, nil, limit: 3)) + .to eq('Jane, Jane, Jane, and 2 more.') end it "displays the current user in front of other users" do @@ -93,8 +93,8 @@ describe IssuesHelper do award = build_stubbed(:award_emoji, user: build_stubbed(:user, name: 'Jane')) awards = Array.new(5, award).push(my_award) - expect(award_user_list(awards, current_user, limit: 2)). - to eq("You, Jane, and 4 more.") + expect(award_user_list(awards, current_user, limit: 2)) + .to eq("You, Jane, and 4 more.") end end diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb index 7cf535fadae..a8d6044fda7 100644 --- a/spec/helpers/labels_helper_spec.rb +++ b/spec/helpers/labels_helper_spec.rb @@ -55,8 +55,8 @@ describe LabelsHelper do context 'without block' do it 'uses render_colored_label as the link content' do - expect(self).to receive(:render_colored_label). - with(label, tooltip: true).and_return('Foo') + expect(self).to receive(:render_colored_label) + .with(label, tooltip: true).and_return('Foo') expect(link_to_label(label)).to match('Foo') end end diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index 25f23826648..67e839878c9 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -15,8 +15,8 @@ describe MergeRequestsHelper do end it 'does not include api credentials in a link' do - allow(ci_service). - to receive(:build_page).and_return("http://secretuser:secretpass@jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c") + allow(ci_service) + .to receive(:build_page).and_return("http://secretuser:secretpass@jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c") expect(helper.ci_build_details_path(merge_request)).not_to match("secret") end end diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index 9d7a39d3721..9e18a1f88bf 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -86,8 +86,8 @@ describe PageLayoutHelper do it 'raises ArgumentError when given more than two attributes' do map = { foo: 'foo', bar: 'bar', baz: 'baz' } - expect { helper.page_card_attributes(map) }. - to raise_error(ArgumentError, /more than two attributes/) + expect { helper.page_card_attributes(map) } + .to raise_error(ArgumentError, /more than two attributes/) end it 'rejects blank values' do @@ -111,8 +111,8 @@ describe PageLayoutHelper do end it 'escapes content' do - allow(helper).to receive(:page_card_attributes). - and_return(foo: %q{foo" http-equiv="refresh}.html_safe) + allow(helper).to receive(:page_card_attributes) + .and_return(foo: %q{foo" http-equiv="refresh}.html_safe) tags = helper.page_card_meta_tags diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb index f3e79cc7290..2575e8d8568 100644 --- a/spec/helpers/preferences_helper_spec.rb +++ b/spec/helpers/preferences_helper_spec.rb @@ -29,15 +29,15 @@ describe PreferencesHelper do describe 'user_color_scheme' do context 'with a user' do it "returns user's scheme's css_class" do - allow(helper).to receive(:current_user). - and_return(double(color_scheme_id: 3)) + allow(helper).to receive(:current_user) + .and_return(double(color_scheme_id: 3)) expect(helper.user_color_scheme).to eq 'solarized-light' end it 'returns the default when id is invalid' do - allow(helper).to receive(:current_user). - and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5)) + allow(helper).to receive(:current_user) + .and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5)) end end @@ -45,8 +45,8 @@ describe PreferencesHelper do it 'returns the default theme' do stub_user - expect(helper.user_color_scheme). - to eq Gitlab::ColorSchemes.default.css_class + expect(helper.user_color_scheme) + .to eq Gitlab::ColorSchemes.default.css_class end end end @@ -55,8 +55,8 @@ describe PreferencesHelper do if messages.empty? allow(helper).to receive(:current_user).and_return(nil) else - allow(helper).to receive(:current_user). - and_return(double('user', messages)) + allow(helper).to receive(:current_user) + .and_return(double('user', messages)) end end diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index 387279b2031..8942b00b128 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -9,52 +9,52 @@ describe VisibilityLevelHelper do describe 'visibility_level_description' do context 'used with a Project' do it 'delegates projects to #project_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)). - to match /project/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)) + .to match /project/i end end context 'used with a Group' do it 'delegates groups to #group_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)). - to match /group/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)) + .to match /group/i end end context 'called with a Snippet' do it 'delegates snippets to #snippet_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)). - to match /snippet/i + expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)) + .to match /snippet/i end end end describe "#project_visibility_level_description" do it "describes private projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). - to eq "Project access must be granted explicitly to each user." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) + .to eq "Project access must be granted explicitly to each user." end it "describes public projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)). - to eq "The project can be cloned without any authentication." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)) + .to eq "The project can be cloned without any authentication." end end describe "#snippet_visibility_level_description" do it 'describes visibility only for me' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)). - to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)) + .to eq "The snippet is visible only to me." end it 'describes visibility for project members' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)). - to eq "The snippet is visible only to project members." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)) + .to eq "The snippet is visible only to project members." end it 'defaults to personal snippet' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). - to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) + .to eq "The snippet is visible only to me." end end diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb index 152c36a3ae6..267318faed4 100644 --- a/spec/lib/api/helpers/pagination_spec.rb +++ b/spec/lib/api/helpers/pagination_spec.rb @@ -37,8 +37,8 @@ describe API::Helpers::Pagination do describe 'first page' do before do - allow(subject).to receive(:params). - and_return({ page: 1, per_page: 2 }) + allow(subject).to receive(:params) + .and_return({ page: 1, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -60,8 +60,8 @@ describe API::Helpers::Pagination do describe 'second page' do before do - allow(subject).to receive(:params). - and_return({ page: 2, per_page: 2 }) + allow(subject).to receive(:params) + .and_return({ page: 2, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -87,8 +87,8 @@ describe API::Helpers::Pagination do end def expect_message(method) - expect(subject).to receive(method). - at_least(:once).and_return(value) + expect(subject).to receive(method) + .at_least(:once).and_return(value) end end end diff --git a/spec/lib/banzai/cross_project_reference_spec.rb b/spec/lib/banzai/cross_project_reference_spec.rb index deaabceef1c..787212581e2 100644 --- a/spec/lib/banzai/cross_project_reference_spec.rb +++ b/spec/lib/banzai/cross_project_reference_spec.rb @@ -24,8 +24,8 @@ describe Banzai::CrossProjectReference, lib: true do it 'returns the referenced project' do project2 = double('referenced project') - expect(Project).to receive(:find_by_full_path). - with('cross/reference').and_return(project2) + expect(Project).to receive(:find_by_full_path) + .with('cross/reference').and_return(project2) expect(project_from_ref('cross/reference')).to eq project2 end diff --git a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb index 27684882435..fb614762a0d 100644 --- a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb @@ -23,11 +23,11 @@ describe Banzai::Filter::AbstractReferenceFilter do doc = Nokogiri::HTML.fragment('') filter = described_class.new(doc, project: project) - expect(filter).to receive(:references_per_project). - and_return({ project.path_with_namespace => Set.new(%w[1]) }) + expect(filter).to receive(:references_per_project) + .and_return({ project.path_with_namespace => Set.new(%w[1]) }) - expect(filter.projects_per_reference). - to eq({ project.path_with_namespace => project }) + expect(filter.projects_per_reference) + .to eq({ project.path_with_namespace => project }) end end @@ -37,13 +37,13 @@ describe Banzai::Filter::AbstractReferenceFilter do context 'with RequestStore disabled' do it 'returns a list of Projects for a list of paths' do - expect(filter.find_projects_for_paths([project.path_with_namespace])). - to eq([project]) + expect(filter.find_projects_for_paths([project.path_with_namespace])) + .to eq([project]) end it "return an empty array for paths that don't exist" do - expect(filter.find_projects_for_paths(['nonexistent/project'])). - to eq([]) + expect(filter.find_projects_for_paths(['nonexistent/project'])) + .to eq([]) end end @@ -58,14 +58,14 @@ describe Banzai::Filter::AbstractReferenceFilter do end it 'returns a list of Projects for a list of paths' do - expect(filter.find_projects_for_paths([project.path_with_namespace])). - to eq([project]) + expect(filter.find_projects_for_paths([project.path_with_namespace])) + .to eq([project]) end context "when no project with that path exists" do it "returns no value" do - expect(filter.find_projects_for_paths(['nonexistent/project'])). - to eq([]) + expect(filter.find_projects_for_paths(['nonexistent/project'])) + .to eq([]) end it "adds the ref to the project refs cache" do @@ -84,8 +84,8 @@ describe Banzai::Filter::AbstractReferenceFilter do end it "return an empty array for paths that don't exist" do - expect(filter.find_projects_for_paths(['nonexistent/project'])). - to eq([]) + expect(filter.find_projects_for_paths(['nonexistent/project'])) + .to eq([]) end end end diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb index deadc36524c..fc67c7ec3c4 100644 --- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb @@ -28,15 +28,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid two-dot reference' do doc = reference_filter("See #{reference2}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param) end it 'links to a valid three-dot reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param) end it 'links to a valid short ID' do @@ -105,15 +105,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) end it 'link has valid text' do doc = reference_filter("Fixed (#{reference}.)") - expect(doc.css('a').first.text). - to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}") + expect(doc.css('a').first.text) + .to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}") end it 'has valid text' do @@ -140,15 +140,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) end it 'link has valid text' do doc = reference_filter("Fixed (#{reference}.)") - expect(doc.css('a').first.text). - to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") + expect(doc.css('a').first.text) + .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") end it 'has valid text' do @@ -175,15 +175,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) end it 'link has valid text' do doc = reference_filter("Fixed (#{reference}.)") - expect(doc.css('a').first.text). - to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") + expect(doc.css('a').first.text) + .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") end it 'has valid text' do @@ -214,8 +214,8 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq reference + expect(doc.css('a').first.attr('href')) + .to eq reference end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb index a19aac61229..c4d8d3b6682 100644 --- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb @@ -26,8 +26,8 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do doc = reference_filter("See #{reference[0...size]}") expect(doc.css('a').first.text).to eq commit.short_id - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_commit_url(project.namespace, project, reference) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_commit_url(project.namespace, project, reference) end end @@ -180,8 +180,8 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id) end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb index efd145e9452..5d625fe05bb 100644 --- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb @@ -33,8 +33,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do doc = filter("Issue #{reference}") issue_id = doc.css('a').first.attr("data-external-issue") - expect(doc.css('a').first.attr('href')). - to eq helper.url_for_issue(issue_id, project) + expect(doc.css('a').first.attr('href')) + .to eq helper.url_for_issue(issue_id, project) end it 'links to the external tracker' do @@ -58,8 +58,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do end it 'escapes the title attribute' do - allow(project.external_issue_tracker).to receive(:title). - and_return(%{">whateverwhatever project }) + expect(filter).to receive(:projects_per_reference) + .and_return({ project.path_with_namespace => project }) - expect(filter).to receive(:references_per_project). - and_return({ project.path_with_namespace => Set.new([issue.iid]) }) + expect(filter).to receive(:references_per_project) + .and_return({ project.path_with_namespace => Set.new([issue.iid]) }) - expect(filter.issues_per_project). - to eq({ project => { issue.iid => issue } }) + expect(filter.issues_per_project) + .to eq({ project => { issue.iid => issue } }) end end @@ -335,14 +335,14 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do expect(project).to receive(:default_issues_tracker?).and_return(false) - expect(filter).to receive(:projects_per_reference). - and_return({ project.path_with_namespace => project }) + expect(filter).to receive(:projects_per_reference) + .and_return({ project.path_with_namespace => project }) - expect(filter).to receive(:references_per_project). - and_return({ project.path_with_namespace => Set.new([1]) }) + expect(filter).to receive(:references_per_project) + .and_return({ project.path_with_namespace => Set.new([1]) }) - expect(filter.issues_per_project[project][1]). - to be_an_instance_of(ExternalIssue) + expect(filter.issues_per_project[project][1]) + .to be_an_instance_of(ExternalIssue) end end end diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index e72d9935bd4..80fa940f330 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -72,8 +72,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) end it 'links with adjacent text' do @@ -95,8 +95,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See gfm' end @@ -119,8 +119,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See 2fa' end @@ -143,8 +143,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See ?g.fm&' end @@ -168,8 +168,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See gfm references' end @@ -192,8 +192,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See 2 factor authentication' end @@ -216,8 +216,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See g.fm & references?' end @@ -287,8 +287,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: label.name) end it 'links with adjacent text' do @@ -324,8 +324,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}", project: project) - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: group_label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: group_label.name) expect(doc.text).to eq 'See gfm references' end @@ -347,8 +347,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}", project: project) - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_issues_url(project.namespace, project, label_name: group_label.name) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_issues_url(project.namespace, project, label_name: group_label.name) expect(doc.text).to eq "See gfm references" end @@ -372,8 +372,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -406,8 +406,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -440,15 +440,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')). - to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ end it 'has valid link text' do @@ -476,25 +476,25 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(another_project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(another_project.namespace, another_project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')). - to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ end it 'has valid link text' do - expect(result.css('a').first.text). - to eq "#{group_label.name} in #{another_project.name_with_namespace}" + expect(result.css('a').first.text) + .to eq "#{group_label.name} in #{another_project.name_with_namespace}" end it 'has valid text' do - expect(result.text). - to eq "See #{group_label.name} in #{another_project.name_with_namespace}" + expect(result.text) + .to eq "See #{group_label.name} in #{another_project.name_with_namespace}" end it 'ignores invalid IDs on the referenced label' do @@ -513,25 +513,25 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(another_project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(another_project.namespace, another_project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')). - to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ end it 'has valid link text' do - expect(result.css('a').first.text). - to eq "#{group_label.name} in #{another_project.name}" + expect(result.css('a').first.text) + .to eq "#{group_label.name} in #{another_project.name}" end it 'has valid text' do - expect(result.text). - to eq "See #{group_label.name} in #{another_project.name}" + expect(result.text) + .to eq "See #{group_label.name} in #{another_project.name}" end it 'ignores invalid IDs on the referenced label' do @@ -549,15 +549,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')). - to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ end it 'has valid link text' do @@ -583,15 +583,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')). - to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ end it 'has valid link text' do diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb index 3d3d36061f4..0fc017788bd 100644 --- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb @@ -23,8 +23,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_merge_request_url(project.namespace, project, merge) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_merge_request_url(project.namespace, project, merge) end it 'links with adjacent text' do @@ -94,8 +94,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_merge_request_url(project2.namespace, + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_merge_request_url(project2.namespace, project2, merge) end @@ -128,8 +128,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_merge_request_url(project2.namespace, + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_merge_request_url(project2.namespace, project2, merge) end @@ -162,8 +162,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_merge_request_url(project2.namespace, + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_merge_request_url(project2.namespace, project2, merge) end @@ -195,8 +195,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq reference + expect(doc.css('a').first.attr('href')) + .to eq reference end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index cd94729b442..0f4619a6dfb 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -44,16 +44,16 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls. - namespace_project_milestone_path(project.namespace, project, milestone) + expect(link).to eq urls + .namespace_project_milestone_path(project.namespace, project, milestone) end context 'Integer-based references' do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(project.namespace, project, milestone) end it 'links with adjacent text' do @@ -75,8 +75,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(project.namespace, project, milestone) expect(doc.text).to eq 'See gfm' end @@ -99,8 +99,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(project.namespace, project, milestone) expect(doc.text).to eq 'See gfm references' end @@ -122,8 +122,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(project.namespace, project, milestone) end it 'links with adjacent text' do @@ -156,8 +156,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'points to referenced project milestone page' do - expect(result.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(another_project.namespace, + expect(result.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(another_project.namespace, another_project, milestone) end @@ -165,15 +165,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'link has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.css('a').first.text). - to eq("#{milestone.name} in #{another_project.path_with_namespace}") + expect(doc.css('a').first.text) + .to eq("#{milestone.name} in #{another_project.path_with_namespace}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.text). - to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)") + expect(doc.text) + .to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)") end it 'escapes the name attribute' do @@ -181,8 +181,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text). - to eq "#{milestone.name} in #{another_project.path_with_namespace}" + expect(doc.css('a').first.text) + .to eq "#{milestone.name} in #{another_project.path_with_namespace}" end end @@ -195,8 +195,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'points to referenced project milestone page' do - expect(result.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(another_project.namespace, + expect(result.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(another_project.namespace, another_project, milestone) end @@ -204,15 +204,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'link has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.css('a').first.text). - to eq("#{milestone.name} in #{another_project.path}") + expect(doc.css('a').first.text) + .to eq("#{milestone.name} in #{another_project.path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.text). - to eq("See (#{milestone.name} in #{another_project.path}.)") + expect(doc.text) + .to eq("See (#{milestone.name} in #{another_project.path}.)") end it 'escapes the name attribute' do @@ -220,8 +220,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text). - to eq "#{milestone.name} in #{another_project.path}" + expect(doc.css('a').first.text) + .to eq "#{milestone.name} in #{another_project.path}" end end @@ -234,8 +234,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'points to referenced project milestone page' do - expect(result.css('a').first.attr('href')).to eq urls. - namespace_project_milestone_url(another_project.namespace, + expect(result.css('a').first.attr('href')).to eq urls + .namespace_project_milestone_url(another_project.namespace, another_project, milestone) end @@ -243,15 +243,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'link has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.css('a').first.text). - to eq("#{milestone.name} in #{another_project.path}") + expect(doc.css('a').first.text) + .to eq("#{milestone.name} in #{another_project.path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.text). - to eq("See (#{milestone.name} in #{another_project.path}.)") + expect(doc.text) + .to eq("See (#{milestone.name} in #{another_project.path}.)") end it 'escapes the name attribute' do @@ -259,8 +259,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text). - to eq "#{milestone.name} in #{another_project.path}" + expect(doc.css('a').first.text) + .to eq "#{milestone.name} in #{another_project.path}" end end end diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb index 0140a91c7ba..84bddda723a 100644 --- a/spec/lib/banzai/filter/redactor_filter_spec.rb +++ b/spec/lib/banzai/filter/redactor_filter_spec.rb @@ -23,9 +23,9 @@ describe Banzai::Filter::RedactorFilter, lib: true do end before do - allow(Banzai::ReferenceParser).to receive(:[]). - with('test'). - and_return(parser_class) + allow(Banzai::ReferenceParser).to receive(:[]) + .with('test') + .and_return(parser_class) end context 'valid projects' do diff --git a/spec/lib/banzai/filter/reference_filter_spec.rb b/spec/lib/banzai/filter/reference_filter_spec.rb index 55e681f6faf..ba0fa4a609a 100644 --- a/spec/lib/banzai/filter/reference_filter_spec.rb +++ b/spec/lib/banzai/filter/reference_filter_spec.rb @@ -8,8 +8,8 @@ describe Banzai::Filter::ReferenceFilter, lib: true do document = Nokogiri::HTML.fragment('foo') filter = described_class.new(document, project: project) - expect { |b| filter.each_node(&b) }. - to yield_with_args(an_instance_of(Nokogiri::XML::Element)) + expect { |b| filter.each_node(&b) } + .to yield_with_args(an_instance_of(Nokogiri::XML::Element)) end it 'returns an Enumerator when no block is given' do diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb index 1957ba739e2..1ce7bd7706e 100644 --- a/spec/lib/banzai/filter/relative_link_filter_spec.rb +++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb @@ -72,15 +72,15 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do it 'ignores ref if commit is passed' do doc = filter(link('non/existent.file'), commit: project.commit('empty-branch') ) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree end shared_examples :valid_repository do it 'rebuilds absolute URL for a file in the repo' do doc = filter(link('/doc/api/README.md')) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'ignores absolute URLs with two leading slashes' do @@ -90,71 +90,71 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do it 'rebuilds relative URL for a file in the repo' do doc = filter(link('doc/api/README.md')) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repo with leading ./' do doc = filter(link('./doc/api/README.md')) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repo up one directory' do relative_link = link('../api/README.md') doc = filter(relative_link, requested_path: 'doc/update/7.14-to-8.0.md') - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repo up multiple directories' do relative_link = link('../../../api/README.md') doc = filter(relative_link, requested_path: 'doc/foo/bar/baz/README.md') - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repository root' do relative_link = link('../README.md') doc = filter(relative_link, requested_path: 'doc/some-file.md') - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/README.md" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/README.md" end it 'rebuilds relative URL for a file in the repo with an anchor' do doc = filter(link('README.md#section')) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/blob/#{ref}/README.md#section" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/blob/#{ref}/README.md#section" end it 'rebuilds relative URL for a directory in the repo' do doc = filter(link('doc/api/')) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/tree/#{ref}/doc/api" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/tree/#{ref}/doc/api" end it 'rebuilds relative URL for an image in the repo' do doc = filter(image('files/images/logo-black.png')) - expect(doc.at_css('img')['src']). - to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" + expect(doc.at_css('img')['src']) + .to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" end it 'rebuilds relative URL for link to an image in the repo' do doc = filter(link('files/images/logo-black.png')) - expect(doc.at_css('a')['href']). - to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" + expect(doc.at_css('a')['href']) + .to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" end it 'rebuilds relative URL for a video in the repo' do doc = filter(video('files/videos/intro.mp4'), commit: project.commit('video'), ref: 'video') - expect(doc.at_css('video')['src']). - to eq "/#{project_path}/raw/video/files/videos/intro.mp4" + expect(doc.at_css('video')['src']) + .to eq "/#{project_path}/raw/video/files/videos/intro.mp4" end it 'does not modify relative URL with an anchor only' do diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb index b38e3b17e64..f2cff6861bc 100644 --- a/spec/lib/banzai/filter/sanitization_filter_spec.rb +++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb @@ -194,8 +194,8 @@ describe Banzai::Filter::SanitizationFilter, lib: true do end it 'disallows invalid URIs' do - expect(Addressable::URI).to receive(:parse).with('foo://example.com'). - and_raise(Addressable::URI::InvalidURIError) + expect(Addressable::URI).to receive(:parse).with('foo://example.com') + .and_raise(Addressable::URI::InvalidURIError) input = 'Foo' output = filter(input) diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb index e036514d283..e851120bc3a 100644 --- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb @@ -22,8 +22,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls. - namespace_project_snippet_url(project.namespace, project, snippet) + expect(doc.css('a').first.attr('href')).to eq urls + .namespace_project_snippet_url(project.namespace, project, snippet) end it 'links with adjacent text' do @@ -88,8 +88,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'link has valid text' do @@ -121,8 +121,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'link has valid text' do @@ -154,8 +154,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'link has valid text' do @@ -186,8 +186,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/upload_link_filter_spec.rb b/spec/lib/banzai/filter/upload_link_filter_spec.rb index 639cac6406a..6327ca8bbfd 100644 --- a/spec/lib/banzai/filter/upload_link_filter_spec.rb +++ b/spec/lib/banzai/filter/upload_link_filter_spec.rb @@ -51,22 +51,22 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do context 'with a valid repository' do it 'rebuilds relative URL for a link' do doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('a')['href']). - to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('a')['href']) + .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" doc = filter(nested_link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('a')['href']). - to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('a')['href']) + .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" end it 'rebuilds relative URL for an image' do doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('img')['src']). - to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('img')['src']) + .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" doc = filter(nested_image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('img')['src']). - to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('img')['src']) + .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" end it 'does not modify absolute URL' do @@ -79,10 +79,10 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do escaped = Addressable::URI.escape(path) # Stub these methods so the file doesn't actually need to be in the repo - allow_any_instance_of(described_class). - to receive(:file_exists?).and_return(true) - allow_any_instance_of(described_class). - to receive(:image?).with(path).and_return(true) + allow_any_instance_of(described_class) + .to receive(:file_exists?).and_return(true) + allow_any_instance_of(described_class) + .to receive(:image?).with(path).and_return(true) doc = filter(image(escaped)) expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png" diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index 6afeee4d76d..6d6a00a3b1f 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -37,8 +37,8 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do doc = reference_filter("Hey #{reference}", author: user) expect(doc.css('a').length).to eq 1 - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_url(project.namespace, project) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_url(project.namespace, project) end it 'includes a data-author attribute when there is an author' do diff --git a/spec/lib/banzai/note_renderer_spec.rb b/spec/lib/banzai/note_renderer_spec.rb index 49556074278..32764bee5eb 100644 --- a/spec/lib/banzai/note_renderer_spec.rb +++ b/spec/lib/banzai/note_renderer_spec.rb @@ -8,15 +8,15 @@ describe Banzai::NoteRenderer do wiki = double(:wiki) user = double(:user) - expect(Banzai::ObjectRenderer).to receive(:new). - with(project, user, + expect(Banzai::ObjectRenderer).to receive(:new) + .with(project, user, requested_path: 'foo', project_wiki: wiki, - ref: 'bar'). - and_call_original + ref: 'bar') + .and_call_original - expect_any_instance_of(Banzai::ObjectRenderer). - to receive(:render).with([note], :note) + expect_any_instance_of(Banzai::ObjectRenderer) + .to receive(:render).with([note], :note) described_class.render([note], project, user, 'foo', wiki, 'bar') end diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb index 6bcda87c999..2ce72a4c92e 100644 --- a/spec/lib/banzai/object_renderer_spec.rb +++ b/spec/lib/banzai/object_renderer_spec.rb @@ -17,12 +17,12 @@ describe Banzai::ObjectRenderer do renderer = described_class.new(project, user) object = fake_object(note: 'hello', note_html: nil) - expect(renderer).to receive(:render_objects).with([object], :note). - and_call_original + expect(renderer).to receive(:render_objects).with([object], :note) + .and_call_original - expect(renderer).to receive(:redact_documents). - with(an_instance_of(Array)). - and_call_original + expect(renderer).to receive(:redact_documents) + .with(an_instance_of(Array)) + .and_call_original expect(object).to receive(:redacted_note_html=).with('

    hello

    ') expect(object).to receive(:user_visible_reference_count=).with(0) @@ -37,8 +37,8 @@ describe Banzai::ObjectRenderer do renderer = described_class.new(project, user) - expect(renderer).to receive(:render_attributes).with([object], :note). - and_call_original + expect(renderer).to receive(:render_attributes).with([object], :note) + .and_call_original rendered = renderer.render_objects([object], :note) @@ -52,9 +52,9 @@ describe Banzai::ObjectRenderer do doc = Nokogiri::HTML.fragment('

    hello

    ') renderer = described_class.new(project, user) - expect_any_instance_of(Banzai::Redactor).to receive(:redact). - with([doc]). - and_call_original + expect_any_instance_of(Banzai::Redactor).to receive(:redact) + .with([doc]) + .and_call_original redacted = renderer.redact_documents([doc]) diff --git a/spec/lib/banzai/redactor_spec.rb b/spec/lib/banzai/redactor_spec.rb index 6d2c141e18b..a14a1405ca6 100644 --- a/spec/lib/banzai/redactor_spec.rb +++ b/spec/lib/banzai/redactor_spec.rb @@ -12,11 +12,11 @@ describe Banzai::Redactor do end it 'redacts an array of documents' do - doc1 = Nokogiri::HTML. - fragment('foo') + doc1 = Nokogiri::HTML + .fragment('foo') - doc2 = Nokogiri::HTML. - fragment('bar') + doc2 = Nokogiri::HTML + .fragment('bar') redacted_data = redactor.redact([doc1, doc2]) @@ -68,9 +68,9 @@ describe Banzai::Redactor do doc = Nokogiri::HTML.fragment('foo') node = doc.children[0] - expect(redactor).to receive(:nodes_visible_to_user). - with([node]). - and_return(Set.new) + expect(redactor).to receive(:nodes_visible_to_user) + .with([node]) + .and_return(Set.new) redactor.redact_document_nodes([{ document: doc, nodes: [node] }]) @@ -83,10 +83,10 @@ describe Banzai::Redactor do doc = Nokogiri::HTML.fragment('') node = doc.children[0] - expect_any_instance_of(Banzai::ReferenceParser::IssueParser). - to receive(:nodes_visible_to_user). - with(user, [node]). - and_return([node]) + expect_any_instance_of(Banzai::ReferenceParser::IssueParser) + .to receive(:nodes_visible_to_user) + .with(user, [node]) + .and_return([node]) expect(redactor.nodes_visible_to_user([node])).to eq(Set.new([node])) end diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb index aa127f0179d..9126afb0693 100644 --- a/spec/lib/banzai/reference_parser/base_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb @@ -54,8 +54,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do describe '#referenced_by' do context 'when references_relation is implemented' do it 'returns a collection of objects' do - links = Nokogiri::HTML.fragment(""). - children + links = Nokogiri::HTML.fragment("") + .children expect(subject).to receive(:references_relation).and_return(User) expect(subject.referenced_by(links)).to eq([user]) @@ -66,8 +66,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'raises NotImplementedError' do links = Nokogiri::HTML.fragment('').children - expect { subject.referenced_by(links) }. - to raise_error(NotImplementedError) + expect { subject.referenced_by(links) } + .to raise_error(NotImplementedError) end end end @@ -80,8 +80,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do describe '#gather_attributes_per_project' do it 'returns a Hash containing attribute values per project' do - link = Nokogiri::HTML.fragment(''). - children[0] + link = Nokogiri::HTML.fragment('') + .children[0] hash = subject.gather_attributes_per_project([link], 'data-foo') @@ -95,9 +95,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'returns a Hash grouping objects per ID' do nodes = [double(:node)] - expect(subject).to receive(:unique_attribute_values). - with(nodes, 'data-user'). - and_return([user.id]) + expect(subject).to receive(:unique_attribute_values) + .with(nodes, 'data-user') + .and_return([user.id]) hash = subject.grouped_objects_for_nodes(nodes, User, 'data-user') @@ -113,15 +113,15 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'returns an Array of unique values' do link = double(:link) - expect(link).to receive(:has_attribute?). - with('data-foo'). - twice. - and_return(true) + expect(link).to receive(:has_attribute?) + .with('data-foo') + .twice + .and_return(true) - expect(link).to receive(:attr). - with('data-foo'). - twice. - and_return('1') + expect(link).to receive(:attr) + .with('data-foo') + .twice + .and_return('1') nodes = [link, link] @@ -138,9 +138,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do instance = dummy.new(project, user) document = Nokogiri::HTML.fragment('') - expect(instance).to receive(:gather_references). - with([document.children[1]]). - and_return([user]) + expect(instance).to receive(:gather_references) + .with([document.children[1]]) + .and_return([user]) expect(instance.process([document])).to eq([user]) end @@ -150,9 +150,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do let(:link) { double(:link) } it 'does not process links a user can not reference' do - expect(subject).to receive(:nodes_user_can_reference). - with(user, [link]). - and_return([]) + expect(subject).to receive(:nodes_user_can_reference) + .with(user, [link]) + .and_return([]) expect(subject).to receive(:referenced_by).with([]) @@ -160,13 +160,13 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do end it 'does not process links a user can not see' do - expect(subject).to receive(:nodes_user_can_reference). - with(user, [link]). - and_return([link]) + expect(subject).to receive(:nodes_user_can_reference) + .with(user, [link]) + .and_return([link]) - expect(subject).to receive(:nodes_visible_to_user). - with(user, [link]). - and_return([]) + expect(subject).to receive(:nodes_visible_to_user) + .with(user, [link]) + .and_return([]) expect(subject).to receive(:referenced_by).with([]) @@ -174,13 +174,13 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do end it 'returns the references if a user can reference and see a link' do - expect(subject).to receive(:nodes_user_can_reference). - with(user, [link]). - and_return([link]) + expect(subject).to receive(:nodes_user_can_reference) + .with(user, [link]) + .and_return([link]) - expect(subject).to receive(:nodes_visible_to_user). - with(user, [link]). - and_return([link]) + expect(subject).to receive(:nodes_visible_to_user) + .with(user, [link]) + .and_return([link]) expect(subject).to receive(:referenced_by).with([link]) @@ -192,8 +192,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'delegates the permissions check to the Ability class' do user = double(:user) - expect(Ability).to receive(:allowed?). - with(user, :read_project, project) + expect(Ability).to receive(:allowed?) + .with(user, :read_project, project) subject.can?(user, :read_project, project) end @@ -201,8 +201,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do describe '#find_projects_for_hash_keys' do it 'returns a list of Projects' do - expect(subject.find_projects_for_hash_keys(project.id => project)). - to eq([project]) + expect(subject.find_projects_for_hash_keys(project.id => project)) + .to eq([project]) end end @@ -214,8 +214,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do expect(collection).to receive(:where).twice.and_call_original 2.times do - expect(subject.collection_objects_for_ids(collection, [user.id])). - to eq([user]) + expect(subject.collection_objects_for_ids(collection, [user.id])) + .to eq([user]) end end end @@ -229,8 +229,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do end it 'queries the collection on the first call' do - expect(subject.collection_objects_for_ids(User, [user.id])). - to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id])) + .to eq([user]) end it 'does not query previously queried objects' do @@ -239,34 +239,34 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do expect(collection).to receive(:where).once.and_call_original 2.times do - expect(subject.collection_objects_for_ids(collection, [user.id])). - to eq([user]) + expect(subject.collection_objects_for_ids(collection, [user.id])) + .to eq([user]) end end it 'casts String based IDs to Fixnums before querying objects' do 2.times do - expect(subject.collection_objects_for_ids(User, [user.id.to_s])). - to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id.to_s])) + .to eq([user]) end end it 'queries any additional objects after the first call' do other_user = create(:user) - expect(subject.collection_objects_for_ids(User, [user.id])). - to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id])) + .to eq([user]) - expect(subject.collection_objects_for_ids(User, [user.id, other_user.id])). - to eq([user, other_user]) + expect(subject.collection_objects_for_ids(User, [user.id, other_user.id])) + .to eq([user, other_user]) end it 'caches objects on a per collection class basis' do - expect(subject.collection_objects_for_ids(User, [user.id])). - to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id])) + .to eq([user]) - expect(subject.collection_objects_for_ids(Project, [project.id])). - to eq([project]) + expect(subject.collection_objects_for_ids(Project, [project.id])) + .to eq([project]) end end end diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb index 412ffa77c36..9c2b2c0a1a9 100644 --- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb @@ -30,30 +30,30 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do it 'returns an Array of commits' do commit = double(:commit) - allow_any_instance_of(Project).to receive(:valid_repo?). - and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?) + .and_return(true) - expect(subject).to receive(:find_commits). - with(project, ['123']). - and_return([commit]) + expect(subject).to receive(:find_commits) + .with(project, ['123']) + .and_return([commit]) expect(subject.referenced_by([link])).to eq([commit]) end it 'returns an empty Array when the commit could not be found' do - allow_any_instance_of(Project).to receive(:valid_repo?). - and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?) + .and_return(true) - expect(subject).to receive(:find_commits). - with(project, ['123']). - and_return([]) + expect(subject).to receive(:find_commits) + .with(project, ['123']) + .and_return([]) expect(subject.referenced_by([link])).to eq([]) end it 'skips projects without valid repositories' do - allow_any_instance_of(Project).to receive(:valid_repo?). - and_return(false) + allow_any_instance_of(Project).to receive(:valid_repo?) + .and_return(false) expect(subject.referenced_by([link])).to eq([]) end @@ -61,8 +61,8 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do context 'when the link does not have a data-commit attribute' do it 'returns an empty Array' do - allow_any_instance_of(Project).to receive(:valid_repo?). - and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?) + .and_return(true) expect(subject.referenced_by([link])).to eq([]) end @@ -71,8 +71,8 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do context 'when the link does not have a data-project attribute' do it 'returns an empty Array' do - allow_any_instance_of(Project).to receive(:valid_repo?). - and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?) + .and_return(true) expect(subject.referenced_by([link])).to eq([]) end diff --git a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb index 96e55b0997a..5aec04e8d5b 100644 --- a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb @@ -30,17 +30,17 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do it 'returns an Array of commit ranges' do range = double(:range) - expect(subject).to receive(:find_object). - with(project, '123..456'). - and_return(range) + expect(subject).to receive(:find_object) + .with(project, '123..456') + .and_return(range) expect(subject.referenced_by([link])).to eq([range]) end it 'returns an empty Array when the commit range could not be found' do - expect(subject).to receive(:find_object). - with(project, '123..456'). - and_return(nil) + expect(subject).to receive(:find_object) + .with(project, '123..456') + .and_return(nil) expect(subject.referenced_by([link])).to eq([]) end @@ -86,17 +86,17 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do it 'returns an Array of range objects' do range = double(:commit) - expect(subject).to receive(:find_object). - with(project, '123..456'). - and_return(range) + expect(subject).to receive(:find_object) + .with(project, '123..456') + .and_return(range) expect(subject.find_ranges(project, ['123..456'])).to eq([range]) end it 'skips ranges that could not be found' do - expect(subject).to receive(:find_object). - with(project, '123..456'). - and_return(nil) + expect(subject).to receive(:find_object) + .with(project, '123..456') + .and_return(nil) expect(subject.find_ranges(project, ['123..456'])).to eq([]) end diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb index 6873b7b85f9..bc81d2808b5 100644 --- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb @@ -18,17 +18,17 @@ describe Banzai::ReferenceParser::IssueParser, lib: true do it_behaves_like "referenced feature visibility", "issues" it 'returns the nodes when the user can read the issue' do - expect(Ability).to receive(:issues_readable_by_user). - with([issue], user). - and_return([issue]) + expect(Ability).to receive(:issues_readable_by_user) + .with([issue], user) + .and_return([issue]) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end it 'returns an empty Array when the user can not read the issue' do - expect(Ability).to receive(:issues_readable_by_user). - with([issue], user). - and_return([]) + expect(Ability).to receive(:issues_readable_by_user) + .with([issue], user) + .and_return([]) expect(subject.nodes_visible_to_user(user, [link])).to eq([]) end diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb index 31ca9d27b0b..f2f11cd5088 100644 --- a/spec/lib/banzai/reference_parser/user_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb @@ -82,17 +82,17 @@ describe Banzai::ReferenceParser::UserParser, lib: true do end it 'returns the nodes if the user can read the group' do - expect(Ability).to receive(:allowed?). - with(user, :read_group, group). - and_return(true) + expect(Ability).to receive(:allowed?) + .with(user, :read_group, group) + .and_return(true) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end it 'returns an empty Array if the user can not read the group' do - expect(Ability).to receive(:allowed?). - with(user, :read_group, group). - and_return(false) + expect(Ability).to receive(:allowed?) + .with(user, :read_group, group) + .and_return(false) expect(subject.nodes_visible_to_user(user, [link])).to eq([]) end @@ -115,9 +115,9 @@ describe Banzai::ReferenceParser::UserParser, lib: true do link['data-project'] = other_project.id.to_s - expect(Ability).to receive(:allowed?). - with(user, :read_project, other_project). - and_return(true) + expect(Ability).to receive(:allowed?) + .with(user, :read_project, other_project) + .and_return(true) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end @@ -127,9 +127,9 @@ describe Banzai::ReferenceParser::UserParser, lib: true do link['data-project'] = other_project.id.to_s - expect(Ability).to receive(:allowed?). - with(user, :read_project, other_project). - and_return(false) + expect(Ability).to receive(:allowed?) + .with(user, :read_project, other_project) + .and_return(false) expect(subject.nodes_visible_to_user(user, [link])).to eq([]) end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 86eec3d6392..a1bde4a0518 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -25,8 +25,8 @@ module Ci end it 'includes coverage regexp in build attributes' do - expect(subject). - to include(coverage_regex: 'Code coverage: \d+\.\d+') + expect(subject) + .to include(coverage_regex: 'Code coverage: \d+\.\d+') end end end @@ -584,8 +584,8 @@ module Ci end it 'raises error' do - expect { subject }. - to raise_error(GitlabCiYamlProcessor::ValidationError, + expect { subject } + .to raise_error(GitlabCiYamlProcessor::ValidationError, /jobs:rspec:variables config should be a hash of key value pairs/) end end @@ -1365,8 +1365,8 @@ EOT it "returns an error about invalid configutaion" do content = YAML.dump("invalid: yaml: test") - expect(GitlabCiYamlProcessor.validation_message(content)). - to eq "Invalid configuration format" + expect(GitlabCiYamlProcessor.validation_message(content)) + .to eq "Invalid configuration format" end end @@ -1374,15 +1374,15 @@ EOT it "returns an error about invalid tags" do content = YAML.dump({ rspec: { script: "test", tags: "mysql" } }) - expect(GitlabCiYamlProcessor.validation_message(content)). - to eq "jobs:rspec tags should be an array of strings" + expect(GitlabCiYamlProcessor.validation_message(content)) + .to eq "jobs:rspec tags should be an array of strings" end end context "when YAML content is empty" do it "returns an error about missing content" do - expect(GitlabCiYamlProcessor.validation_message('')). - to eq "Please provide content of .gitlab-ci.yml" + expect(GitlabCiYamlProcessor.validation_message('')) + .to eq "Please provide content of .gitlab-ci.yml" end end diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb index bbacdc67ebd..7fd2321d18a 100644 --- a/spec/lib/container_registry/blob_spec.rb +++ b/spec/lib/container_registry/blob_spec.rb @@ -51,8 +51,8 @@ describe ContainerRegistry::Blob do context '#delete' do before do - stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). - to_return(status: 200) + stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345') + .to_return(status: 200) end subject { blob.delete } @@ -67,8 +67,8 @@ describe ContainerRegistry::Blob do context 'when locally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345') + .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: data) @@ -79,9 +79,9 @@ describe ContainerRegistry::Blob do context 'when externally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). - with(headers: { 'Authorization' => "bearer #{token}" }). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345') + .with(headers: { 'Authorization' => "bearer #{token}" }) + .to_return( status: 307, headers: { 'Location' => location }) end @@ -90,9 +90,9 @@ describe ContainerRegistry::Blob do let(:location) { 'http://external.com/blob/file' } before do - stub_request(:get, location). - with(headers: { 'Authorization' => nil }). - to_return( + stub_request(:get, location) + .with(headers: { 'Authorization' => nil }) + .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: data) diff --git a/spec/lib/container_registry/repository_spec.rb b/spec/lib/container_registry/repository_spec.rb index c364e759108..eeb924ebe48 100644 --- a/spec/lib/container_registry/repository_spec.rb +++ b/spec/lib/container_registry/repository_spec.rb @@ -16,9 +16,9 @@ describe ContainerRegistry::Repository do context 'manifest processing' do before do - stub_request(:get, 'http://example.com/v2/group/test/tags/list'). - with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/tags/list') + .with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }) + .to_return( status: 200, body: JSON.dump(tags: ['test']), headers: { 'Content-Type' => 'application/json' }) diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb index c5e31ae82b6..2d7e355a737 100644 --- a/spec/lib/container_registry/tag_spec.rb +++ b/spec/lib/container_registry/tag_spec.rb @@ -19,9 +19,9 @@ describe ContainerRegistry::Tag do context 'manifest processing' do context 'schema v1' do before do - stub_request(:get, 'http://example.com/v2/group/test/manifests/tag'). - with(headers: headers). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/manifests/tag') + .with(headers: headers) + .to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest_1.json'), headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v1+prettyjws' }) @@ -56,9 +56,9 @@ describe ContainerRegistry::Tag do context 'schema v2' do before do - stub_request(:get, 'http://example.com/v2/group/test/manifests/tag'). - with(headers: headers). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/manifests/tag') + .with(headers: headers) + .to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest.json'), headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json' }) @@ -93,9 +93,9 @@ describe ContainerRegistry::Tag do context 'when locally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac'). - with(headers: { 'Accept' => 'application/octet-stream' }). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac') + .with(headers: { 'Accept' => 'application/octet-stream' }) + .to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json')) end @@ -105,14 +105,14 @@ describe ContainerRegistry::Tag do context 'when externally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac'). - with(headers: { 'Accept' => 'application/octet-stream' }). - to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac') + .with(headers: { 'Accept' => 'application/octet-stream' }) + .to_return( status: 307, headers: { 'Location' => 'http://external.com/blob/file' }) - stub_request(:get, 'http://external.com/blob/file'). - to_return( + stub_request(:get, 'http://external.com/blob/file') + .to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json')) end @@ -125,9 +125,9 @@ describe ContainerRegistry::Tag do context 'manifest digest' do before do - stub_request(:head, 'http://example.com/v2/group/test/manifests/tag'). - with(headers: headers). - to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' }) + stub_request(:head, 'http://example.com/v2/group/test/manifests/tag') + .with(headers: headers) + .to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' }) end context '#digest' do @@ -138,9 +138,9 @@ describe ContainerRegistry::Tag do context '#delete' do before do - stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest'). - with(headers: headers). - to_return(status: 200) + stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest') + .with(headers: headers) + .to_return(status: 200) end subject { tag.delete } diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb index 29c07655ae8..78ac4da8dfe 100644 --- a/spec/lib/extracts_path_spec.rb +++ b/spec/lib/extracts_path_spec.rb @@ -14,8 +14,8 @@ describe ExtractsPath, lib: true do repo = double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0', 'release/app', 'release/app/v1.0.0']) allow(project).to receive(:repository).and_return(repo) - allow(project).to receive(:path_with_namespace). - and_return('gitlab/gitlab-ci') + allow(project).to receive(:path_with_namespace) + .and_return('gitlab/gitlab-ci') allow(request).to receive(:format=) end diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index e193a3b79a6..bca57105d1d 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -19,8 +19,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS } - expect(Asciidoctor).to receive(:convert). - with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert) + .with(input, expected_asciidoc_opts).and_return(html) expect( render(input, context) ).to eql html end @@ -35,8 +35,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS + ['foo'] } - expect(Asciidoctor).to receive(:convert). - with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert) + .with(input, expected_asciidoc_opts).and_return(html) render(input, context, asciidoc_opts) end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 57c416fb35a..b234de4c772 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -140,8 +140,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). - to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) + .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end it 'falls through oauth authentication when the username is oauth2' do @@ -151,8 +151,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). - to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) + .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end end diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index e9c69183d00..f84782ab440 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -141,8 +141,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts). - with(a_string_matching('No backups found')) + expect(progress).to have_received(:puts) + .with(a_string_matching('No backups found')) end end @@ -158,8 +158,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts). - with(a_string_matching('Found more than one backup')) + expect(progress).to have_received(:puts) + .with(a_string_matching('Found more than one backup')) end end @@ -178,8 +178,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts). - with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress).to have_received(:puts) + .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) end end @@ -200,8 +200,8 @@ describe Backup::Manager, lib: true do it 'unpacks the file' do subject.unpack - expect(Kernel).to have_received(:system). - with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") + expect(Kernel).to have_received(:system) + .with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") expect(progress).to have_received(:puts).with(a_string_matching('done')) end end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb index 8a4bf4dc89b..3c5414701a7 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -20,8 +20,8 @@ describe Gitlab::Badge::Build::Status do describe '#metadata' do it 'returns badge metadata' do - expect(badge.metadata.image_url). - to include 'badges/master/build.svg' + expect(badge.metadata.image_url) + .to include 'badges/master/build.svg' end end diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb index 0a2fe5af2c3..9e557d06ef0 100644 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -86,9 +86,9 @@ describe Gitlab::BitbucketImport::Importer, lib: true do headers: { "Content-Type" => "application/json" }, body: issues_statuses_sample_data.to_json) - stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on"). - with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }). - to_return(status: 200, + stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on") + .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }) + .to_return(status: 200, body: "", headers: {}) diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb index eea01f91879..6a52ae01b2f 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb @@ -33,8 +33,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/').find_entries! } it 'matches correct paths' do - expect(subject.keys). - to contain_exactly 'other_artifacts_0.1.2/', + expect(subject.keys) + .to contain_exactly 'other_artifacts_0.1.2/', 'other_artifacts_0.1.2/doc_sample.txt', 'other_artifacts_0.1.2/another-subdirectory/' end @@ -44,8 +44,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/another-subdirectory/').find_entries! } it 'matches correct paths' do - expect(subject.keys). - to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/', + expect(subject.keys) + .to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/', 'other_artifacts_0.1.2/another-subdirectory/empty_directory/', 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif' end @@ -55,8 +55,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/', recursive: true).find_entries! } it 'matches correct paths' do - expect(subject.keys). - to contain_exactly 'other_artifacts_0.1.2/', + expect(subject.keys) + .to contain_exactly 'other_artifacts_0.1.2/', 'other_artifacts_0.1.2/doc_sample.txt', 'other_artifacts_0.1.2/another-subdirectory/', 'other_artifacts_0.1.2/another-subdirectory/empty_directory/', diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb index 987a0b1f67f..5c31423fdee 100644 --- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb @@ -26,8 +26,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { name: 10 } } it 'reports error' do - expect(entry.errors). - to include 'artifacts name should be a string' + expect(entry.errors) + .to include 'artifacts name should be a string' end end @@ -35,8 +35,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { test: 100 } } it 'reports error' do - expect(entry.errors). - to include 'artifacts config contains unknown keys: test' + expect(entry.errors) + .to include 'artifacts config contains unknown keys: test' end end end diff --git a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb index efb8c5adab1..fde03c51e2c 100644 --- a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb @@ -14,9 +14,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is a hash' do before do - allow(instance). - to receive(:config). - and_return({ name: 'some name', test: 'some test' }) + allow(instance) + .to receive(:config) + .and_return({ name: 'some name', test: 'some test' }) end it 'returns the value of config' do @@ -31,9 +31,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is not a hash' do before do - allow(instance). - to receive(:config). - and_return('some test') + allow(instance) + .to receive(:config) + .and_return('some test') end it 'returns nil' do diff --git a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb index 8987c0549c5..5f067cad93c 100644 --- a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Boolean do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'boolean config should be a boolean value' + expect(entry.errors) + .to include 'boolean config should be a boolean value' end end end diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index e91f049ee72..70a327c5183 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -32,8 +32,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { 'ls' } it 'reports errors with config value' do - expect(entry.errors). - to include 'cache config should be a hash' + expect(entry.errors) + .to include 'cache config should be a hash' end end @@ -41,8 +41,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { key: 1 } } it 'reports error with descendants' do - expect(entry.errors). - to include 'key config should be a string or symbol' + expect(entry.errors) + .to include 'key config should be a string or symbol' end end @@ -50,8 +50,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { invalid: true } } it 'reports error with descendants' do - expect(entry.errors). - to include 'cache config contains unknown keys: invalid' + expect(entry.errors) + .to include 'cache config contains unknown keys: invalid' end end end diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb index fa3dbd9bf32..b8b0825a1c7 100644 --- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb @@ -40,8 +40,8 @@ describe Gitlab::Ci::Config::Entry::Commands do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'commands config should be a ' \ + expect(entry.errors) + .to include 'commands config should be a ' \ 'string or an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb index 490ba9b7df1..ae7e628b5b5 100644 --- a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb @@ -52,8 +52,8 @@ describe Gitlab::Ci::Config::Entry::Configurable do end it 'creates a node factory' do - expect(entry.nodes[:object]). - to be_an_instance_of Gitlab::Ci::Config::Entry::Factory + expect(entry.nodes[:object]) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Factory end it 'returns a duplicated factory object' do diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb index fab2825fbb0..2adbed2154f 100644 --- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb @@ -112,8 +112,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors). - to include 'environment action should be start or stop' + expect(entry.errors) + .to include 'environment action should be start or stop' end end end @@ -143,8 +143,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors). - to include 'environment on stop should be a string' + expect(entry.errors) + .to include 'environment on stop should be a string' end end end @@ -174,8 +174,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid type' do - expect(entry.errors). - to include 'environment config should be a hash or a string' + expect(entry.errors) + .to include 'environment config should be a hash or a string' end end end @@ -191,8 +191,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors?' do it 'contains error about missing environment name' do - expect(entry.errors). - to include "environment name can't be blank" + expect(entry.errors) + .to include "environment name can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/factory_spec.rb b/spec/lib/gitlab/ci/config/entry/factory_spec.rb index 281a110071a..00dad5d9591 100644 --- a/spec/lib/gitlab/ci/config/entry/factory_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/factory_spec.rb @@ -7,19 +7,19 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting a concrete value' do it 'creates entry with valid value' do - entry = factory. - value(['ls', 'pwd']). - create! + entry = factory + .value(['ls', 'pwd']) + .create! expect(entry.value).to eq ['ls', 'pwd'] end context 'when setting description' do it 'creates entry with description' do - entry = factory. - value(['ls', 'pwd']). - with(description: 'test description'). - create! + entry = factory + .value(['ls', 'pwd']) + .with(description: 'test description') + .create! expect(entry.value).to eq ['ls', 'pwd'] expect(entry.description).to eq 'test description' @@ -28,10 +28,10 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting key' do it 'creates entry with custom key' do - entry = factory. - value(['ls', 'pwd']). - with(key: 'test key'). - create! + entry = factory + .value(['ls', 'pwd']) + .with(key: 'test key') + .create! expect(entry.key).to eq 'test key' end @@ -41,10 +41,10 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:object) { Object.new } it 'creates entry with valid parent' do - entry = factory. - value('ls'). - with(parent: object). - create! + entry = factory + .value('ls') + .with(parent: object) + .create! expect(entry.parent).to eq object end @@ -61,12 +61,12 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when creating entry with nil value' do it 'creates an undefined entry' do - entry = factory. - value(nil). - create! + entry = factory + .value(nil) + .create! - expect(entry). - to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(entry) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -74,13 +74,13 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:entry) { spy('entry') } it 'passes metadata as a parameter' do - factory. - value('some value'). - metadata(some: 'hash'). - create! + factory + .value('some value') + .metadata(some: 'hash') + .create! - expect(entry).to have_received(:new). - with('some value', { some: 'hash' }) + expect(entry).to have_received(:new) + .with('some value', { some: 'hash' }) end end end diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 3b2d043301e..8a74743eda8 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when filtering all the entry/node names' do it 'contains the expected node names' do - expect(described_class.nodes.keys). - to match_array(%i[before_script image services + expect(described_class.nodes.keys) + .to match_array(%i[before_script image services after_script variables stages types cache]) end @@ -44,17 +44,17 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'creates node object using valid class' do - expect(global.descendants.first). - to be_an_instance_of Gitlab::Ci::Config::Entry::Script - expect(global.descendants.second). - to be_an_instance_of Gitlab::Ci::Config::Entry::Image + expect(global.descendants.first) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Script + expect(global.descendants.second) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Image end it 'sets correct description for nodes' do - expect(global.descendants.first.description). - to eq 'Script that will be executed before each job.' - expect(global.descendants.second.description). - to eq 'Docker image that will be used to execute jobs.' + expect(global.descendants.first.description) + .to eq 'Script that will be executed before each job.' + expect(global.descendants.second.description) + .to eq 'Docker image that will be used to execute jobs.' end describe '#leaf?' do @@ -138,8 +138,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#cache_value' do it 'returns cache configuration' do - expect(global.cache_value). - to eq(key: 'k', untracked: true, paths: ['public/']) + expect(global.cache_value) + .to eq(key: 'k', untracked: true, paths: ['public/']) end end @@ -185,8 +185,8 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'contains unspecified nodes' do - expect(global.descendants.first). - to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(global.descendants.first) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -246,8 +246,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors from child nodes' do - expect(global.errors). - to include 'before_script config should be an array of strings' + expect(global.errors) + .to include 'before_script config should be an array of strings' end end @@ -265,8 +265,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors about missing script' do - expect(global.errors). - to include "jobs:rspec script can't be blank" + expect(global.errors) + .to include "jobs:rspec script can't be blank" end end end @@ -303,16 +303,16 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when entry exists' do it 'returns correct entry' do - expect(global[:cache]). - to be_an_instance_of Gitlab::Ci::Config::Entry::Cache + expect(global[:cache]) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Cache expect(global[:jobs][:rspec][:script].value).to eq ['ls'] end end context 'when entry does not exist' do it 'always return unspecified node' do - expect(global[:some][:unknown][:node]). - not_to be_specified + expect(global[:some][:unknown][:node]) + .not_to be_specified end end end diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb index 062817e07fd..3c99cb0a1ee 100644 --- a/spec/lib/gitlab/ci/config/entry/image_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Image do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'image config should be a string' + expect(entry.errors) + .to include 'image config should be a string' end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 82feff0af1c..7a733e6a4a7 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -44,8 +44,8 @@ describe Gitlab::Ci::Config::Entry::Job do describe '#errors' do it 'reports error about a config type' do - expect(entry.errors). - to include 'job config should be a hash' + expect(entry.errors) + .to include 'job config should be a hash' end end end @@ -138,8 +138,8 @@ describe Gitlab::Ci::Config::Entry::Job do end it 'returns correct value' do - expect(entry.value). - to eq(name: :rspec, + expect(entry.value) + .to eq(name: :rspec, before_script: %w[ls pwd], script: %w[rspec], commands: "ls\npwd\nrspec", diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index c332b70dc71..aaebf783962 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -22,8 +22,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { ['incorrect'] } it 'returns error about incorrect type' do - expect(entry.errors). - to include 'jobs config should be a hash' + expect(entry.errors) + .to include 'jobs config should be a hash' end end @@ -39,8 +39,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { { '.hidden'.to_sym => { script: [] } } } it 'returns error about no visible jobs defined' do - expect(entry.errors). - to include 'jobs config should contain at least one visible job' + expect(entry.errors) + .to include 'jobs config should contain at least one visible job' end end end @@ -73,10 +73,10 @@ describe Gitlab::Ci::Config::Entry::Jobs do describe '#descendants' do it 'creates valid descendant nodes' do expect(entry.descendants.count).to eq 3 - expect(entry.descendants.first(2)). - to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) - expect(entry.descendants.last). - to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) + expect(entry.descendants.first(2)) + .to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) + expect(entry.descendants.last) + .to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) end end diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb index cd7b03ffb11..0dd36fe1f44 100644 --- a/spec/lib/gitlab/ci/config/entry/key_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Key do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'key config should be a string or symbol' + expect(entry.errors) + .to include 'key config should be a string or symbol' end end end diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb index b0ac90f1d94..1d9c5ddee9b 100644 --- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Paths do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'paths config should be an array of strings' + expect(entry.errors) + .to include 'paths config should be an array of strings' end end end diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb index 8c1305f376d..aa99cee2690 100644 --- a/spec/lib/gitlab/ci/config/entry/script_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Script do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'script config should be an array of strings' + expect(entry.errors) + .to include 'script config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb index c31a7c0ec3e..66fad3b6b16 100644 --- a/spec/lib/gitlab/ci/config/entry/services_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Services do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'services config should be an array of strings' + expect(entry.errors) + .to include 'services config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/stage_spec.rb b/spec/lib/gitlab/ci/config/entry/stage_spec.rb index cefef7a805a..70c8a0a355a 100644 --- a/spec/lib/gitlab/ci/config/entry/stage_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stage_spec.rb @@ -24,8 +24,8 @@ describe Gitlab::Ci::Config::Entry::Stage do let(:config) { { test: true } } it 'reports errors about wrong type' do - expect(stage.errors). - to include 'stage config should be a string' + expect(stage.errors) + .to include 'stage config should be a string' end end end diff --git a/spec/lib/gitlab/ci/config/entry/stages_spec.rb b/spec/lib/gitlab/ci/config/entry/stages_spec.rb index bdcd6c98a85..182c8d867c7 100644 --- a/spec/lib/gitlab/ci/config/entry/stages_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stages_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Stages do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'stages config should be an array of strings' + expect(entry.errors) + .to include 'stages config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb index 13b00a98b6a..e4ee44f1274 100644 --- a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Trigger do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'trigger config should be an array of strings or regexps' + expect(entry.errors) + .to include 'trigger config should be an array of strings or regexps' end end end diff --git a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb index e31e85538b9..d1856801827 100644 --- a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb @@ -19,8 +19,8 @@ describe Gitlab::Ci::Config::Entry::Validatable do end it 'returns validator' do - expect(entry.validator.superclass). - to be Gitlab::Ci::Config::Entry::Validator + expect(entry.validator.superclass) + .to be Gitlab::Ci::Config::Entry::Validator end it 'returns only one validator to mitigate leaks' do diff --git a/spec/lib/gitlab/ci/config/entry/validator_spec.rb b/spec/lib/gitlab/ci/config/entry/validator_spec.rb index c6e21cd67b0..ad7e6f07d3c 100644 --- a/spec/lib/gitlab/ci/config/entry/validator_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validator_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Validator do it 'returns errors' do validator_instance.validate - expect(validator_instance.messages). - to include "node test attribute can't be blank" + expect(validator_instance.messages) + .to include "node test attribute can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index c117f35c906..f15f02f403e 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -33,8 +33,8 @@ describe Gitlab::Ci::Config::Entry::Variables do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include /should be a hash of key value pairs/ + expect(entry.errors) + .to include /should be a hash of key value pairs/ end end diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index cd893a09748..40b96b1807b 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Build::Common do let(:project) { build.project } subject do - Gitlab::Ci::Status::Core. - new(build, user). - extend(described_class) + Gitlab::Ci::Status::Core + .new(build, user) + .extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index aa026a66460..16f0a7b5388 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -16,8 +16,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -42,8 +42,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -67,8 +67,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable, + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable, Gitlab::Ci::Status::Build::FailedAllowed] end @@ -96,8 +96,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -121,8 +121,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a canceable build status' do @@ -146,8 +146,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a cancelable build status' do @@ -196,8 +196,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Play] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Play] end it 'fabricates a core skipped status' do @@ -222,8 +222,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Stop] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Stop] end it 'fabricates a core skipped status' do diff --git a/spec/lib/gitlab/ci/status/extended_spec.rb b/spec/lib/gitlab/ci/status/extended_spec.rb index 459044eb968..c2d74ca5cde 100644 --- a/spec/lib/gitlab/ci/status/extended_spec.rb +++ b/spec/lib/gitlab/ci/status/extended_spec.rb @@ -6,7 +6,7 @@ describe Gitlab::Ci::Status::Extended do end it 'requires subclass to implement matcher' do - expect { subject.matches?(double, double) }. - to raise_error(NotImplementedError) + expect { subject.matches?(double, double) } + .to raise_error(NotImplementedError) end end diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index 6a564eeb8b7..5a97d98b55f 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -10,9 +10,9 @@ describe Gitlab::Ci::Status::External::Common do end subject do - Gitlab::Ci::Status::Core. - new(external_status, user). - extend(described_class) + Gitlab::Ci::Status::Core + .new(external_status, user) + .extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/factory_spec.rb b/spec/lib/gitlab/ci/status/factory_spec.rb index 45fd49b91ea..bbf9c7c83a3 100644 --- a/spec/lib/gitlab/ci/status/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/factory_spec.rb @@ -84,15 +84,15 @@ describe Gitlab::Ci::Status::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [first_extended_status, second_extended_status] + expect(factory.extended_statuses) + .to eq [first_extended_status, second_extended_status] end end context 'when exclusive statuses are matches' do before do - allow(described_class).to receive(:extended_statuses). - and_return([[first_extended_status, second_extended_status]]) + allow(described_class).to receive(:extended_statuses) + .and_return([[first_extended_status, second_extended_status]]) end it 'does not fabricate compound decorator' do @@ -116,8 +116,8 @@ describe Gitlab::Ci::Status::Factory do context 'when exclusive statuses are not matched' do before do - allow(described_class).to receive(:extended_statuses). - and_return([[first_extended_status], [second_extended_status]]) + allow(described_class).to receive(:extended_statuses) + .and_return([[first_extended_status], [second_extended_status]]) end it_behaves_like 'compound decorator factory' @@ -125,8 +125,8 @@ describe Gitlab::Ci::Status::Factory do context 'when using simplified status grouping' do before do - allow(described_class).to receive(:extended_statuses). - and_return([first_extended_status, second_extended_status]) + allow(described_class).to receive(:extended_statuses) + .and_return([first_extended_status, second_extended_status]) end it_behaves_like 'compound decorator factory' diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index 35dad60febf..d665674bf70 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Pipeline::Common do let(:pipeline) { create(:ci_pipeline, project: project) } subject do - Gitlab::Ci::Status::Core. - new(pipeline, user). - extend(described_class) + Gitlab::Ci::Status::Core + .new(pipeline, user) + .extend(described_class) end describe '#has_action?' do @@ -29,8 +29,8 @@ describe Gitlab::Ci::Status::Pipeline::Common do describe '#details_path' do it 'links to the pipeline details page' do - expect(subject.details_path). - to include "pipelines/#{pipeline.id}" + expect(subject.details_path) + .to include "pipelines/#{pipeline.id}" end end end diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index 7cee4435931..b10a447c27a 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do it 'extends core status with common pipeline methods' do expect(status).to have_details expect(status).not_to have_action - expect(status.details_path). - to include "pipelines/#{pipeline.id}" + expect(status.details_path) + .to include "pipelines/#{pipeline.id}" end end end @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::SuccessWarning] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::SuccessWarning] end it 'fabricates extended "success with warnings" status' do diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb index 3b25893d8c7..8814a7614a0 100644 --- a/spec/lib/gitlab/ci/status/stage/common_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Status::Stage::Common do end subject do - Class.new(Gitlab::Ci::Status::Core). - new(stage, user).extend(described_class) + Class.new(Gitlab::Ci::Status::Core) + .new(stage, user).extend(described_class) end it 'does not have action' do @@ -19,10 +19,10 @@ describe Gitlab::Ci::Status::Stage::Common do end it 'links to the pipeline details page' do - expect(subject.details_path). - to include "pipelines/#{pipeline.id}" - expect(subject.details_path). - to include "##{stage.name}" + expect(subject.details_path) + .to include "pipelines/#{pipeline.id}" + expect(subject.details_path) + .to include "##{stage.name}" end context 'when user has permission to read pipeline' do diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index c8503392b34..bbb40e2c1ab 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Stage::Factory do end it 'fabricates extended "success with warnings" status' do - expect(status). - to be_a Gitlab::Ci::Status::SuccessWarning + expect(status) + .to be_a Gitlab::Ci::Status::SuccessWarning end it 'extends core status with common stage method' do diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb index 97af1c2523d..ca68010cb89 100644 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb @@ -306,58 +306,58 @@ describe Gitlab::ClosingIssueExtractor, lib: true do it 'fetches issues in single line message' do message = "Closes #{reference} and fix #{reference2}" - expect(subject.closed_by_message(message)). - to match_array([issue, other_issue]) + expect(subject.closed_by_message(message)) + .to match_array([issue, other_issue]) end it 'fetches comma-separated issues references in single line message' do message = "Closes #{reference}, closes #{reference2}" - expect(subject.closed_by_message(message)). - to match_array([issue, other_issue]) + expect(subject.closed_by_message(message)) + .to match_array([issue, other_issue]) end it 'fetches comma-separated issues numbers in single line message' do message = "Closes #{reference}, #{reference2} and #{reference3}" - expect(subject.closed_by_message(message)). - to match_array([issue, other_issue, third_issue]) + expect(subject.closed_by_message(message)) + .to match_array([issue, other_issue, third_issue]) end it 'fetches issues in multi-line message' do message = "Awesome commit (closes #{reference})\nAlso fixes #{reference2}" - expect(subject.closed_by_message(message)). - to match_array([issue, other_issue]) + expect(subject.closed_by_message(message)) + .to match_array([issue, other_issue]) end it 'fetches issues in hybrid message' do message = "Awesome commit (closes #{reference})\n"\ "Also fixing issues #{reference2}, #{reference3} and #4" - expect(subject.closed_by_message(message)). - to match_array([issue, other_issue, third_issue]) + expect(subject.closed_by_message(message)) + .to match_array([issue, other_issue, third_issue]) end it "fetches cross-project references" do message = "Closes #{reference} and #{cross_reference}" - expect(subject.closed_by_message(message)). - to match_array([issue, issue2]) + expect(subject.closed_by_message(message)) + .to match_array([issue, issue2]) end it "fetches cross-project URL references" do message = "Closes #{urls.namespace_project_issue_url(issue2.project.namespace, issue2.project, issue2)} and #{reference}" - expect(subject.closed_by_message(message)). - to match_array([issue, issue2]) + expect(subject.closed_by_message(message)) + .to match_array([issue, issue2]) end it "ignores invalid cross-project URL references" do message = "Closes https://google.com#{urls.namespace_project_issue_path(issue2.project.namespace, issue2.project, issue2)} and #{reference}" - expect(subject.closed_by_message(message)). - to match_array([issue]) + expect(subject.closed_by_message(message)) + .to match_array([issue]) end end end diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb index fbf679c5215..3a24aff7fa9 100644 --- a/spec/lib/gitlab/conflict/file_spec.rb +++ b/spec/lib/gitlab/conflict/file_spec.rb @@ -43,8 +43,8 @@ describe Gitlab::Conflict::File, lib: true do end it 'returns a file containing only the chosen parts of the resolved sections' do - expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first)). - to eq(['both', 'new', 'both', 'old', 'both', 'new', 'both']) + expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first)) + .to eq(['both', 'new', 'both', 'old', 'both', 'new', 'both']) end end @@ -52,14 +52,14 @@ describe Gitlab::Conflict::File, lib: true do empty_hash = section_keys.map { |key| [key, nil] }.to_h invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h - expect { conflict_file.resolve_lines({}) }. - to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { conflict_file.resolve_lines({}) } + .to raise_error(Gitlab::Conflict::File::MissingResolution) - expect { conflict_file.resolve_lines(empty_hash) }. - to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { conflict_file.resolve_lines(empty_hash) } + .to raise_error(Gitlab::Conflict::File::MissingResolution) - expect { conflict_file.resolve_lines(invalid_hash) }. - to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { conflict_file.resolve_lines(invalid_hash) } + .to raise_error(Gitlab::Conflict::File::MissingResolution) end end @@ -250,8 +250,8 @@ FILE describe '#as_json' do it 'includes the blob path for the file' do - expect(conflict_file.as_json[:blob_path]). - to eq("/#{project.namespace.to_param}/#{merge_request.project.to_param}/blob/#{our_commit.oid}/files/ruby/regex.rb") + expect(conflict_file.as_json[:blob_path]) + .to eq("/#{project.namespace.to_param}/#{merge_request.project.to_param}/blob/#{our_commit.oid}/files/ruby/regex.rb") end it 'includes the blob icon for the file' do @@ -264,8 +264,8 @@ FILE end it 'includes the detected language of the conflict file' do - expect(conflict_file.as_json(full_content: true)[:blob_ace_mode]). - to eq('ruby') + expect(conflict_file.as_json(full_content: true)[:blob_ace_mode]) + .to eq('ruby') end end end diff --git a/spec/lib/gitlab/conflict/parser_spec.rb b/spec/lib/gitlab/conflict/parser_spec.rb index 16eb3766356..ca4bdcc3672 100644 --- a/spec/lib/gitlab/conflict/parser_spec.rb +++ b/spec/lib/gitlab/conflict/parser_spec.rb @@ -121,72 +121,72 @@ CONFLICT context 'when the file contents include conflict delimiters' do it 'raises UnexpectedDelimiter when there is a non-start delimiter first' do - expect { parse_text('=======') }. - to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text('=======') } + .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text('>>>>>>> README.md') }. - to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text('>>>>>>> README.md') } + .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text('>>>>>>> some-other-path.md') }. - not_to raise_error + expect { parse_text('>>>>>>> some-other-path.md') } + .not_to raise_error end it 'raises UnexpectedDelimiter when a start delimiter is followed by a non-middle delimiter' do start_text = "<<<<<<< README.md\n" end_text = "\n=======\n>>>>>>> README.md" - expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }. - to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + '>>>>>>> README.md' + end_text) } + .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + start_text + end_text) }. - to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + start_text + end_text) } + .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }. - not_to raise_error + expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) } + .not_to raise_error end it 'raises UnexpectedDelimiter when a middle delimiter is followed by a non-end delimiter' do start_text = "<<<<<<< README.md\n=======\n" end_text = "\n>>>>>>> README.md" - expect { parse_text(start_text + '=======' + end_text) }. - to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + '=======' + end_text) } + .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + start_text + end_text) }. - to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + start_text + end_text) } + .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }. - not_to raise_error + expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) } + .not_to raise_error end it 'raises MissingEndDelimiter when there is no end delimiter at the end' do start_text = "<<<<<<< README.md\n=======\n" - expect { parse_text(start_text) }. - to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) + expect { parse_text(start_text) } + .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) - expect { parse_text(start_text + '>>>>>>> some-other-path.md') }. - to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) + expect { parse_text(start_text + '>>>>>>> some-other-path.md') } + .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) end end context 'other file types' do it 'raises UnmergeableFile when lines is blank, indicating a binary file' do - expect { parse_text('') }. - to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) + expect { parse_text('') } + .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) - expect { parse_text(nil) }. - to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) + expect { parse_text(nil) } + .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) end it 'raises UnmergeableFile when the file is over 200 KB' do - expect { parse_text('a' * 204801) }. - to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) + expect { parse_text('a' * 204801) } + .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) end it 'raises UnsupportedEncoding when the file contains non-UTF-8 characters' do - expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }. - to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding) + expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) } + .to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding) end end end diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb index 7658153df0b..04ec34492e1 100644 --- a/spec/lib/gitlab/data_builder/note_spec.rb +++ b/spec/lib/gitlab/data_builder/note_spec.rb @@ -9,8 +9,8 @@ describe Gitlab::DataBuilder::Note, lib: true do before(:each) do expect(data).to have_key(:object_attributes) expect(data[:object_attributes]).to have_key(:url) - expect(data[:object_attributes][:url]). - to eq(Gitlab::UrlBuilder.build(note)) + expect(data[:object_attributes][:url]) + .to eq(Gitlab::UrlBuilder.build(note)) expect(data[:object_kind]).to eq('note') expect(data[:user]).to eq(user.hook_attrs) end @@ -49,10 +49,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and issue-specific data' do expect(data).to have_key(:issue) - expect(data[:issue].except('updated_at')). - to eq(issue.reload.hook_attrs.except('updated_at')) - expect(data[:issue]['updated_at']). - to be > issue.hook_attrs['updated_at'] + expect(data[:issue].except('updated_at')) + .to eq(issue.reload.hook_attrs.except('updated_at')) + expect(data[:issue]['updated_at']) + .to be > issue.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -73,10 +73,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')). - to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']). - to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')) + .to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']) + .to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -96,10 +96,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request diff data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')). - to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']). - to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')) + .to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']) + .to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -119,10 +119,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and project snippet data' do expect(data).to have_key(:snippet) - expect(data[:snippet].except('updated_at')). - to eq(snippet.reload.hook_attrs.except('updated_at')) - expect(data[:snippet]['updated_at']). - to be > snippet.hook_attrs['updated_at'] + expect(data[:snippet].except('updated_at')) + .to eq(snippet.reload.hook_attrs.except('updated_at')) + expect(data[:snippet]['updated_at']) + .to be > snippet.hook_attrs['updated_at'] end include_examples 'project hook data' diff --git a/spec/lib/gitlab/data_builder/push_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb index dbcfb9b7400..019d7d75814 100644 --- a/spec/lib/gitlab/data_builder/push_spec.rb +++ b/spec/lib/gitlab/data_builder/push_spec.rb @@ -46,8 +46,8 @@ describe Gitlab::DataBuilder::Push, lib: true do include_examples 'deprecated repository hook data' it 'does not raise an error when given nil commits' do - expect { described_class.build(spy, spy, spy, spy, spy, nil) }. - not_to raise_error + expect { described_class.build(spy, spy, spy, spy, spy, nil) } + .not_to raise_error end end end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index e007044868c..511b4a988aa 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -22,15 +22,15 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end it 'creates the index concurrently' do - expect(model).to receive(:add_index). - with(:users, :foo, algorithm: :concurrently) + expect(model).to receive(:add_index) + .with(:users, :foo, algorithm: :concurrently) model.add_concurrent_index(:users, :foo) end it 'creates unique index concurrently' do - expect(model).to receive(:add_index). - with(:users, :foo, { algorithm: :concurrently, unique: true }) + expect(model).to receive(:add_index) + .with(:users, :foo, { algorithm: :concurrently, unique: true }) model.add_concurrent_index(:users, :foo, unique: true) end @@ -40,8 +40,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do it 'creates a regular index' do expect(Gitlab::Database).to receive(:postgresql?).and_return(false) - expect(model).to receive(:add_index). - with(:users, :foo, {}) + expect(model).to receive(:add_index) + .with(:users, :foo, {}) model.add_concurrent_index(:users, :foo) end @@ -52,8 +52,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do it 'raises RuntimeError' do expect(model).to receive(:transaction_open?).and_return(true) - expect { model.add_concurrent_index(:users, :foo) }. - to raise_error(RuntimeError) + expect { model.add_concurrent_index(:users, :foo) } + .to raise_error(RuntimeError) end end end @@ -78,8 +78,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do it 'creates a regular foreign key' do allow(Gitlab::Database).to receive(:mysql?).and_return(true) - expect(model).to receive(:add_foreign_key). - with(:projects, :users, column: :user_id, on_delete: :cascade) + expect(model).to receive(:add_foreign_key) + .with(:projects, :users, column: :user_id, on_delete: :cascade) model.add_concurrent_foreign_key(:projects, :users, column: :user_id) end @@ -171,16 +171,16 @@ describe Gitlab::Database::MigrationHelpers, lib: true do expect(model).to receive(:transaction).and_yield - expect(model).to receive(:add_column). - with(:projects, :foo, :integer, default: nil) + expect(model).to receive(:add_column) + .with(:projects, :foo, :integer, default: nil) - expect(model).to receive(:change_column_default). - with(:projects, :foo, 10) + expect(model).to receive(:change_column_default) + .with(:projects, :foo, 10) end it 'adds the column while allowing NULL values' do - expect(model).to receive(:update_column_in_batches). - with(:projects, :foo, 10) + expect(model).to receive(:update_column_in_batches) + .with(:projects, :foo, 10) expect(model).not_to receive(:change_column_null) @@ -190,22 +190,22 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end it 'adds the column while not allowing NULL values' do - expect(model).to receive(:update_column_in_batches). - with(:projects, :foo, 10) + expect(model).to receive(:update_column_in_batches) + .with(:projects, :foo, 10) - expect(model).to receive(:change_column_null). - with(:projects, :foo, false) + expect(model).to receive(:change_column_null) + .with(:projects, :foo, false) model.add_column_with_default(:projects, :foo, :integer, default: 10) end it 'removes the added column whenever updating the rows fails' do - expect(model).to receive(:update_column_in_batches). - with(:projects, :foo, 10). - and_raise(RuntimeError) + expect(model).to receive(:update_column_in_batches) + .with(:projects, :foo, 10) + .and_raise(RuntimeError) - expect(model).to receive(:remove_column). - with(:projects, :foo) + expect(model).to receive(:remove_column) + .with(:projects, :foo) expect do model.add_column_with_default(:projects, :foo, :integer, default: 10) @@ -213,12 +213,12 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end it 'removes the added column whenever changing a column NULL constraint fails' do - expect(model).to receive(:change_column_null). - with(:projects, :foo, false). - and_raise(RuntimeError) + expect(model).to receive(:change_column_null) + .with(:projects, :foo, false) + .and_raise(RuntimeError) - expect(model).to receive(:remove_column). - with(:projects, :foo) + expect(model).to receive(:remove_column) + .with(:projects, :foo) expect do model.add_column_with_default(:projects, :foo, :integer, default: 10) @@ -234,8 +234,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do allow(model).to receive(:change_column_null).with(:projects, :foo, false) allow(model).to receive(:change_column_default).with(:projects, :foo, 10) - expect(model).to receive(:add_column). - with(:projects, :foo, :integer, default: nil, limit: 8) + expect(model).to receive(:add_column) + .with(:projects, :foo, :integer, default: nil, limit: 8) model.add_column_with_default(:projects, :foo, :integer, default: 10, limit: 8) end diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 5eff7e8425b..053ce1d9e68 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -28,8 +28,8 @@ describe Gitlab::Database, lib: true do describe '.version' do context "on mysql" do it "extracts the version number" do - allow(described_class).to receive(:database_version). - and_return("5.7.12-standard") + allow(described_class).to receive(:database_version) + .and_return("5.7.12-standard") expect(described_class.version).to eq '5.7.12-standard' end @@ -37,8 +37,8 @@ describe Gitlab::Database, lib: true do context "on postgresql" do it "extracts the version number" do - allow(described_class).to receive(:database_version). - and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0") + allow(described_class).to receive(:database_version) + .and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0") expect(described_class.version).to eq '9.4.4' end @@ -120,8 +120,8 @@ describe Gitlab::Database, lib: true do pool = described_class.create_connection_pool(5) begin - expect(pool). - to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) + expect(pool) + .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) expect(pool.spec.config[:pool]).to eq(5) ensure diff --git a/spec/lib/gitlab/downtime_check_spec.rb b/spec/lib/gitlab/downtime_check_spec.rb index 42d895e548e..1f1e4e0216c 100644 --- a/spec/lib/gitlab/downtime_check_spec.rb +++ b/spec/lib/gitlab/downtime_check_spec.rb @@ -11,12 +11,12 @@ describe Gitlab::DowntimeCheck do context 'when a migration does not specify if downtime is required' do it 'raises RuntimeError' do - expect(subject).to receive(:class_for_migration_file). - with(path). - and_return(Class.new) + expect(subject).to receive(:class_for_migration_file) + .with(path) + .and_return(Class.new) - expect { subject.check([path]) }. - to raise_error(RuntimeError, /it requires downtime/) + expect { subject.check([path]) } + .to raise_error(RuntimeError, /it requires downtime/) end end @@ -25,12 +25,12 @@ describe Gitlab::DowntimeCheck do it 'raises RuntimeError' do stub_const('TestMigration::DOWNTIME', true) - expect(subject).to receive(:class_for_migration_file). - with(path). - and_return(TestMigration) + expect(subject).to receive(:class_for_migration_file) + .with(path) + .and_return(TestMigration) - expect { subject.check([path]) }. - to raise_error(RuntimeError, /no reason was given/) + expect { subject.check([path]) } + .to raise_error(RuntimeError, /no reason was given/) end end @@ -39,9 +39,9 @@ describe Gitlab::DowntimeCheck do stub_const('TestMigration::DOWNTIME', true) stub_const('TestMigration::DOWNTIME_REASON', 'foo') - expect(subject).to receive(:class_for_migration_file). - with(path). - and_return(TestMigration) + expect(subject).to receive(:class_for_migration_file) + .with(path) + .and_return(TestMigration) messages = subject.check([path]) @@ -65,9 +65,9 @@ describe Gitlab::DowntimeCheck do expect(subject).to receive(:require).with(path) - expect(subject).to receive(:class_for_migration_file). - with(path). - and_return(TestMigration) + expect(subject).to receive(:class_for_migration_file) + .with(path) + .and_return(TestMigration) expect(subject).to receive(:puts).with(an_instance_of(String)) diff --git a/spec/lib/gitlab/email/reply_parser_spec.rb b/spec/lib/gitlab/email/reply_parser_spec.rb index 28698e89c33..02ff2a46c48 100644 --- a/spec/lib/gitlab/email/reply_parser_spec.rb +++ b/spec/lib/gitlab/email/reply_parser_spec.rb @@ -20,8 +20,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders plaintext-only email" do - expect(test_parse_body(fixture_file("emails/plaintext_only.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/plaintext_only.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp ### reply from default mail client in Windows 8.1 Metro @@ -46,8 +46,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles multiple paragraphs" do - expect(test_parse_body(fixture_file("emails/paragraphs.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/paragraphs.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp Is there any reason the *old* candy can't be be kept in silos while the new candy is imported into *new* silos? @@ -61,8 +61,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles multiple paragraphs when parsing html" do - expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp Awesome! @@ -74,8 +74,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles newlines" do - expect(test_parse_body(fixture_file("emails/newlines.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/newlines.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp This is my reply. It is my best reply. @@ -85,8 +85,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles inline reply" do - expect(test_parse_body(fixture_file("emails/inline_reply.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/inline_reply.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp > techAPJ > November 28 @@ -132,8 +132,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from gmail web client" do - expect(test_parse_body(fixture_file("emails/gmail_web.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/gmail_web.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp ### This is a reply from standard GMail in Google Chrome. @@ -151,8 +151,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from iOS default mail client" do - expect(test_parse_body(fixture_file("emails/ios_default.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/ios_default.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp ### this is a reply from iOS default mail @@ -166,8 +166,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from Android 5 gmail client" do - expect(test_parse_body(fixture_file("emails/android_gmail.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/android_gmail.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp ### this is a reply from Android 5 gmail @@ -184,8 +184,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from Windows 8.1 Metro default mail client" do - expect(test_parse_body(fixture_file("emails/windows_8_metro.eml"))). - to eq( + expect(test_parse_body(fixture_file("emails/windows_8_metro.eml"))) + .to eq( <<-BODY.strip_heredoc.chomp ### reply from default mail client in Windows 8.1 Metro diff --git a/spec/lib/gitlab/file_detector_spec.rb b/spec/lib/gitlab/file_detector_spec.rb index e5ba13bbaf8..695fd6f8573 100644 --- a/spec/lib/gitlab/file_detector_spec.rb +++ b/spec/lib/gitlab/file_detector_spec.rb @@ -3,13 +3,13 @@ require 'spec_helper' describe Gitlab::FileDetector do describe '.types_in_paths' do it 'returns the file types for the given paths' do - expect(described_class.types_in_paths(%w(README.md CHANGELOG VERSION VERSION))). - to eq(%i{readme changelog version}) + expect(described_class.types_in_paths(%w(README.md CHANGELOG VERSION VERSION))) + .to eq(%i{readme changelog version}) end it 'does not include unrecognized file paths' do - expect(described_class.types_in_paths(%w(README.md foo.txt))). - to eq(%i{readme}) + expect(described_class.types_in_paths(%w(README.md foo.txt))) + .to eq(%i{readme}) end end diff --git a/spec/lib/gitlab/git/attributes_spec.rb b/spec/lib/gitlab/git/attributes_spec.rb index 9c011e34c11..b29107eece4 100644 --- a/spec/lib/gitlab/git/attributes_spec.rb +++ b/spec/lib/gitlab/git/attributes_spec.rb @@ -14,13 +14,13 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'returns a Hash containing multiple attributes' do - expect(subject.attributes('test.sh')). - to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' }) + expect(subject.attributes('test.sh')) + .to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' }) end it 'returns a Hash containing attributes for a file with multiple extensions' do - expect(subject.attributes('test.haml.html')). - to eq({ 'gitlab-language' => 'haml' }) + expect(subject.attributes('test.haml.html')) + .to eq({ 'gitlab-language' => 'haml' }) end it 'returns a Hash containing attributes for a file in a directory' do @@ -28,8 +28,8 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'returns a Hash containing attributes with query string parameters' do - expect(subject.attributes('foo.cgi')). - to eq({ 'key' => 'value?p1=v1&p2=v2' }) + expect(subject.attributes('foo.cgi')) + .to eq({ 'key' => 'value?p1=v1&p2=v2' }) end it 'returns a Hash containing the attributes for an absolute path' do @@ -39,11 +39,11 @@ describe Gitlab::Git::Attributes, seed_helper: true do it 'returns a Hash containing the attributes when a pattern is defined using an absolute path' do # When a path is given without a leading slash it should still match # patterns defined with a leading slash. - expect(subject.attributes('foo.png')). - to eq({ 'gitlab-language' => 'png' }) + expect(subject.attributes('foo.png')) + .to eq({ 'gitlab-language' => 'png' }) - expect(subject.attributes('/foo.png')). - to eq({ 'gitlab-language' => 'png' }) + expect(subject.attributes('/foo.png')) + .to eq({ 'gitlab-language' => 'png' }) end it 'returns an empty Hash for a defined path without attributes' do @@ -74,8 +74,8 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'parses an entry that uses a tab to separate the pattern and attributes' do - expect(subject.patterns[File.join(path, '*.md')]). - to eq({ 'gitlab-language' => 'markdown' }) + expect(subject.patterns[File.join(path, '*.md')]) + .to eq({ 'gitlab-language' => 'markdown' }) end it 'stores patterns in reverse order' do @@ -91,9 +91,9 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'does not parse anything when the attributes file does not exist' do - expect(File).to receive(:exist?). - with(File.join(path, 'info/attributes')). - and_return(false) + expect(File).to receive(:exist?) + .with(File.join(path, 'info/attributes')) + .and_return(false) expect(subject.patterns).to eq({}) end @@ -115,13 +115,13 @@ describe Gitlab::Git::Attributes, seed_helper: true do it 'parses multiple attributes' do input = 'boolean key=value -negated' - expect(subject.parse_attributes(input)). - to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false }) + expect(subject.parse_attributes(input)) + .to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false }) end it 'parses attributes with query string parameters' do - expect(subject.parse_attributes('foo=bar?baz=1')). - to eq({ 'foo' => 'bar?baz=1' }) + expect(subject.parse_attributes('foo=bar?baz=1')) + .to eq({ 'foo' => 'bar?baz=1' }) end end @@ -133,9 +133,9 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'does not yield when the attributes file does not exist' do - expect(File).to receive(:exist?). - with(File.join(path, 'info/attributes')). - and_return(false) + expect(File).to receive(:exist?) + .with(File.join(path, 'info/attributes')) + .and_return(false) expect { |b| subject.each_line(&b) }.not_to yield_control end diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb index 0c321f0343c..327aba9cae7 100644 --- a/spec/lib/gitlab/git/blob_spec.rb +++ b/spec/lib/gitlab/git/blob_spec.rb @@ -92,9 +92,9 @@ describe Gitlab::Git::Blob, seed_helper: true do end it 'marks the blob as binary' do - expect(Gitlab::Git::Blob).to receive(:new). - with(hash_including(binary: true)). - and_call_original + expect(Gitlab::Git::Blob).to receive(:new) + .with(hash_including(binary: true)) + .and_call_original expect(blob).to be_binary end diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb index 47bdd7310d5..c6ff864268d 100644 --- a/spec/lib/gitlab/git/diff_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_collection_spec.rb @@ -309,8 +309,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do end it 'yields Diff instances even when they are too large' do - expect { |b| collection.each(&b) }. - to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| collection.each(&b) } + .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'prunes diffs that are too large' do @@ -331,8 +331,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do let(:no_collapse) { true } it 'yields Diff instances even when they are quite big' do - expect { |b| subject.each(&b) }. - to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| subject.each(&b) } + .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'does not prune diffs' do @@ -350,8 +350,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do let(:no_collapse) { false } it 'yields Diff instances even when they are quite big' do - expect { |b| subject.each(&b) }. - to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| subject.each(&b) } + .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'prunes diffs that are quite big' do @@ -437,8 +437,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do let(:all_diffs) { true } it 'yields Diff instances even when they are quite big' do - expect { |b| subject.each(&b) }. - to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| subject.each(&b) } + .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'does not prune diffs' do diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb index 4c55532d165..70d3b1a9f81 100644 --- a/spec/lib/gitlab/git/diff_spec.rb +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -70,8 +70,8 @@ EOT context 'using a diff that is too large' do it 'prunes the diff' do - expect_any_instance_of(String).to receive(:bytesize). - and_return(1024 * 1024 * 1024) + expect_any_instance_of(String).to receive(:bytesize) + .and_return(1024 * 1024 * 1024) diff = described_class.new(@rugged_diff) @@ -100,8 +100,8 @@ EOT context 'using a large binary diff' do it 'does not prune the diff' do - expect_any_instance_of(Rugged::Diff::Delta).to receive(:binary?). - and_return(true) + expect_any_instance_of(Rugged::Diff::Delta).to receive(:binary?) + .and_return(true) diff = described_class.new(@rugged_diff) diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 2a915bf426f..5e0c3a530e9 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -315,8 +315,8 @@ describe Gitlab::Git::Repository, seed_helper: true do end it "should move the tip of the master branch to the correct commit" do - new_tip = @normal_repo.rugged.references["refs/heads/master"]. - target.oid + new_tip = @normal_repo.rugged.references["refs/heads/master"] + .target.oid expect(new_tip).to eq(reset_commit) end diff --git a/spec/lib/gitlab/gitlab_import/importer_spec.rb b/spec/lib/gitlab/gitlab_import/importer_spec.rb index 9b499b593d3..4f588da0a83 100644 --- a/spec/lib/gitlab/gitlab_import/importer_spec.rb +++ b/spec/lib/gitlab/gitlab_import/importer_spec.rb @@ -45,8 +45,8 @@ describe Gitlab::GitlabImport::Importer, lib: true do def stub_request(path, body) url = "https://gitlab.com/api/v3/projects/asd%2Fvim/#{path}?page=1&per_page=100" - WebMock.stub_request(:get, url). - to_return( + WebMock.stub_request(:get, url) + .to_return( headers: { 'Content-Type' => 'application/json' }, body: body ) diff --git a/spec/lib/gitlab/identifier_spec.rb b/spec/lib/gitlab/identifier_spec.rb index bb758a8a202..29912da2e25 100644 --- a/spec/lib/gitlab/identifier_spec.rb +++ b/spec/lib/gitlab/identifier_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::Identifier do describe '#identify' do context 'without an identifier' do it 'identifies the user using a commit' do - expect(identifier).to receive(:identify_using_commit). - with(project, '123') + expect(identifier).to receive(:identify_using_commit) + .with(project, '123') identifier.identify('', project, '123') end @@ -21,8 +21,8 @@ describe Gitlab::Identifier do context 'with a user identifier' do it 'identifies the user using a user ID' do - expect(identifier).to receive(:identify_using_user). - with("user-#{user.id}") + expect(identifier).to receive(:identify_using_user) + .with("user-#{user.id}") identifier.identify("user-#{user.id}", project, '123') end @@ -30,8 +30,8 @@ describe Gitlab::Identifier do context 'with an SSH key identifier' do it 'identifies the user using an SSH key ID' do - expect(identifier).to receive(:identify_using_ssh_key). - with("key-#{key.id}") + expect(identifier).to receive(:identify_using_ssh_key) + .with("key-#{key.id}") identifier.identify("key-#{key.id}", project, '123') end diff --git a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb index c141762421f..08a42fd27a2 100644 --- a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb @@ -7,8 +7,8 @@ describe Gitlab::ImportExport::AvatarRestorer, lib: true do let(:project) { create(:empty_project) } before do - allow_any_instance_of(described_class).to receive(:avatar_export_file). - and_return(uploaded_image_temp_path) + allow_any_instance_of(described_class).to receive(:avatar_export_file) + .and_return(uploaded_image_temp_path) end after do diff --git a/spec/lib/gitlab/incoming_email_spec.rb b/spec/lib/gitlab/incoming_email_spec.rb index d54753ccf90..66fc3ad0c3b 100644 --- a/spec/lib/gitlab/incoming_email_spec.rb +++ b/spec/lib/gitlab/incoming_email_spec.rb @@ -99,8 +99,8 @@ describe Gitlab::IncomingEmail, lib: true do end it 'returns reply key' do - expect(described_class.scan_fallback_references(references)). - to eq(%w[issue_1@localhost + expect(described_class.scan_fallback_references(references)) + .to eq(%w[issue_1@localhost reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost exchange@microsoft.com]) end diff --git a/spec/lib/gitlab/job_waiter_spec.rb b/spec/lib/gitlab/job_waiter_spec.rb index 780f5b1f8d7..6186cec2689 100644 --- a/spec/lib/gitlab/job_waiter_spec.rb +++ b/spec/lib/gitlab/job_waiter_spec.rb @@ -4,8 +4,8 @@ describe Gitlab::JobWaiter do describe '#wait' do let(:waiter) { described_class.new(%w(a)) } it 'returns when all jobs have been completed' do - expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a)). - and_return(true) + expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a)) + .and_return(true) expect(waiter).not_to receive(:sleep) @@ -13,9 +13,9 @@ describe Gitlab::JobWaiter do end it 'sleeps between checking the job statuses' do - expect(Gitlab::SidekiqStatus).to receive(:all_completed?). - with(%w(a)). - and_return(false, true) + expect(Gitlab::SidekiqStatus).to receive(:all_completed?) + .with(%w(a)) + .and_return(false, true) expect(waiter).to receive(:sleep).with(described_class::INTERVAL) diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb index fe3709f30e1..563c074017a 100644 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/ldap/adapter_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::LDAP::Adapter, lib: true do end it 'searches with the proper options when searching with a limit' do - expect(adapter). - to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) + expect(adapter) + .to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) adapter.users('uid', 'johndoe', 100) end diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb index b8f3290e84c..f689b47fec4 100644 --- a/spec/lib/gitlab/ldap/authentication_spec.rb +++ b/spec/lib/gitlab/ldap/authentication_spec.rb @@ -16,8 +16,8 @@ describe Gitlab::LDAP::Authentication, lib: true do # try only to fake the LDAP call adapter = double('adapter', dn: dn).as_null_object - allow_any_instance_of(described_class). - to receive(:adapter).and_return(adapter) + allow_any_instance_of(described_class) + .to receive(:adapter).and_return(adapter) expect(described_class.login(login, password)).to be_truthy end @@ -25,8 +25,8 @@ describe Gitlab::LDAP::Authentication, lib: true do it "is false if the user does not exist" do # try only to fake the LDAP call adapter = double('adapter', dn: dn).as_null_object - allow_any_instance_of(described_class). - to receive(:adapter).and_return(adapter) + allow_any_instance_of(described_class) + .to receive(:adapter).and_return(adapter) expect(described_class.login(login, password)).to be_falsey end @@ -36,8 +36,8 @@ describe Gitlab::LDAP::Authentication, lib: true do # try only to fake the LDAP call adapter = double('adapter', bind_as: nil).as_null_object - allow_any_instance_of(described_class). - to receive(:adapter).and_return(adapter) + allow_any_instance_of(described_class) + .to receive(:adapter).and_return(adapter) expect(described_class.login(login, password)).to be_falsey end diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index 89790c9e1af..5c56c210123 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -138,8 +138,8 @@ describe Gitlab::LDAP::User, lib: true do describe 'blocking' do def configure_block(value) - allow_any_instance_of(Gitlab::LDAP::Config). - to receive(:block_auto_created_users).and_return(value) + allow_any_instance_of(Gitlab::LDAP::Config) + .to receive(:block_auto_created_users).and_return(value) end context 'signup' do diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb index d88bcae41fb..09131003388 100644 --- a/spec/lib/gitlab/metrics/instrumentation_spec.rb +++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb @@ -78,11 +78,11 @@ describe Gitlab::Metrics::Instrumentation do end it 'tracks the call duration upon calling the method' do - allow(Gitlab::Metrics).to receive(:method_call_threshold). - and_return(0) + allow(Gitlab::Metrics).to receive(:method_call_threshold) + .and_return(0) - allow(described_class).to receive(:transaction). - and_return(transaction) + allow(described_class).to receive(:transaction) + .and_return(transaction) expect_any_instance_of(Gitlab::Metrics::MethodCall).to receive(:measure) @@ -90,8 +90,8 @@ describe Gitlab::Metrics::Instrumentation do end it 'does not track method calls below a given duration threshold' do - allow(Gitlab::Metrics).to receive(:method_call_threshold). - and_return(100) + allow(Gitlab::Metrics).to receive(:method_call_threshold) + .and_return(100) expect(transaction).not_to receive(:add_metric) @@ -137,8 +137,8 @@ describe Gitlab::Metrics::Instrumentation do before do allow(Gitlab::Metrics).to receive(:enabled?).and_return(true) - described_class. - instrument_instance_method(@dummy, :bar) + described_class + .instrument_instance_method(@dummy, :bar) end it 'instruments instances of the Class' do @@ -156,11 +156,11 @@ describe Gitlab::Metrics::Instrumentation do end it 'tracks the call duration upon calling the method' do - allow(Gitlab::Metrics).to receive(:method_call_threshold). - and_return(0) + allow(Gitlab::Metrics).to receive(:method_call_threshold) + .and_return(0) - allow(described_class).to receive(:transaction). - and_return(transaction) + allow(described_class).to receive(:transaction) + .and_return(transaction) expect_any_instance_of(Gitlab::Metrics::MethodCall).to receive(:measure) @@ -168,8 +168,8 @@ describe Gitlab::Metrics::Instrumentation do end it 'does not track method calls below a given duration threshold' do - allow(Gitlab::Metrics).to receive(:method_call_threshold). - and_return(100) + allow(Gitlab::Metrics).to receive(:method_call_threshold) + .and_return(100) expect(transaction).not_to receive(:add_metric) @@ -183,8 +183,8 @@ describe Gitlab::Metrics::Instrumentation do end it 'does not instrument the method' do - described_class. - instrument_instance_method(@dummy, :bar) + described_class + .instrument_instance_method(@dummy, :bar) expect(described_class.instrumented?(@dummy)).to eq(false) end diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb index fb470ea7568..ec415f2bd85 100644 --- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb @@ -26,8 +26,8 @@ describe Gitlab::Metrics::RackMiddleware do allow(app).to receive(:call).with(env) - expect(middleware).to receive(:tag_controller). - with(an_instance_of(Gitlab::Metrics::Transaction), env) + expect(middleware).to receive(:tag_controller) + .with(an_instance_of(Gitlab::Metrics::Transaction), env) middleware.call(env) end @@ -40,8 +40,8 @@ describe Gitlab::Metrics::RackMiddleware do allow(app).to receive(:call).with(env) - expect(middleware).to receive(:tag_endpoint). - with(an_instance_of(Gitlab::Metrics::Transaction), env) + expect(middleware).to receive(:tag_endpoint) + .with(an_instance_of(Gitlab::Metrics::Transaction), env) middleware.call(env) end @@ -49,8 +49,8 @@ describe Gitlab::Metrics::RackMiddleware do it 'tracks any raised exceptions' do expect(app).to receive(:call).with(env).and_raise(RuntimeError) - expect_any_instance_of(Gitlab::Metrics::Transaction). - to receive(:add_event).with(:rails_exception) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .to receive(:add_event).with(:rails_exception) expect { middleware.call(env) }.to raise_error(RuntimeError) end diff --git a/spec/lib/gitlab/metrics/sampler_spec.rb b/spec/lib/gitlab/metrics/sampler_spec.rb index 1ab923b58cf..d07ce6f81af 100644 --- a/spec/lib/gitlab/metrics/sampler_spec.rb +++ b/spec/lib/gitlab/metrics/sampler_spec.rb @@ -38,8 +38,8 @@ describe Gitlab::Metrics::Sampler do describe '#flush' do it 'schedules the metrics using Sidekiq' do - expect(Gitlab::Metrics).to receive(:submit_metrics). - with([an_instance_of(Hash)]) + expect(Gitlab::Metrics).to receive(:submit_metrics) + .with([an_instance_of(Hash)]) sampler.sample_memory_usage sampler.flush @@ -48,12 +48,12 @@ describe Gitlab::Metrics::Sampler do describe '#sample_memory_usage' do it 'adds a metric containing the memory usage' do - expect(Gitlab::Metrics::System).to receive(:memory_usage). - and_return(9000) + expect(Gitlab::Metrics::System).to receive(:memory_usage) + .and_return(9000) - expect(sampler).to receive(:add_metric). - with(/memory_usage/, value: 9000). - and_call_original + expect(sampler).to receive(:add_metric) + .with(/memory_usage/, value: 9000) + .and_call_original sampler.sample_memory_usage end @@ -61,12 +61,12 @@ describe Gitlab::Metrics::Sampler do describe '#sample_file_descriptors' do it 'adds a metric containing the amount of open file descriptors' do - expect(Gitlab::Metrics::System).to receive(:file_descriptor_count). - and_return(4) + expect(Gitlab::Metrics::System).to receive(:file_descriptor_count) + .and_return(4) - expect(sampler).to receive(:add_metric). - with(/file_descriptors/, value: 4). - and_call_original + expect(sampler).to receive(:add_metric) + .with(/file_descriptors/, value: 4) + .and_call_original sampler.sample_file_descriptors end @@ -75,10 +75,10 @@ describe Gitlab::Metrics::Sampler do if Gitlab::Metrics.mri? describe '#sample_objects' do it 'adds a metric containing the amount of allocated objects' do - expect(sampler).to receive(:add_metric). - with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash)). - at_least(:once). - and_call_original + expect(sampler).to receive(:add_metric) + .with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash)) + .at_least(:once) + .and_call_original sampler.sample_objects end @@ -86,8 +86,8 @@ describe Gitlab::Metrics::Sampler do it 'ignores classes without a name' do expect(Allocations).to receive(:to_hash).and_return({ Class.new => 4 }) - expect(sampler).not_to receive(:add_metric). - with('object_counts', an_instance_of(Hash), type: nil) + expect(sampler).not_to receive(:add_metric) + .with('object_counts', an_instance_of(Hash), type: nil) sampler.sample_objects end @@ -98,9 +98,9 @@ describe Gitlab::Metrics::Sampler do it 'adds a metric containing garbage collection statistics' do expect(GC::Profiler).to receive(:total_time).and_return(0.24) - expect(sampler).to receive(:add_metric). - with(/gc_statistics/, an_instance_of(Hash)). - and_call_original + expect(sampler).to receive(:add_metric) + .with(/gc_statistics/, an_instance_of(Hash)) + .and_call_original sampler.sample_gc end @@ -110,9 +110,9 @@ describe Gitlab::Metrics::Sampler do it 'prefixes the series name for a Rails process' do expect(sampler).to receive(:sidekiq?).and_return(false) - expect(Gitlab::Metrics::Metric).to receive(:new). - with('rails_cats', { value: 10 }, {}). - and_call_original + expect(Gitlab::Metrics::Metric).to receive(:new) + .with('rails_cats', { value: 10 }, {}) + .and_call_original sampler.add_metric('cats', value: 10) end @@ -120,9 +120,9 @@ describe Gitlab::Metrics::Sampler do it 'prefixes the series name for a Sidekiq process' do expect(sampler).to receive(:sidekiq?).and_return(true) - expect(Gitlab::Metrics::Metric).to receive(:new). - with('sidekiq_cats', { value: 10 }, {}). - and_call_original + expect(Gitlab::Metrics::Metric).to receive(:new) + .with('sidekiq_cats', { value: 10 }, {}) + .and_call_original sampler.add_metric('cats', value: 10) end diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb index acaba785606..b576d7173f5 100644 --- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb @@ -8,12 +8,12 @@ describe Gitlab::Metrics::SidekiqMiddleware do it 'tracks the transaction' do worker = double(:worker, class: double(:class, name: 'TestWorker')) - expect(Gitlab::Metrics::Transaction).to receive(:new). - with('TestWorker#perform'). - and_call_original + expect(Gitlab::Metrics::Transaction).to receive(:new) + .with('TestWorker#perform') + .and_call_original - expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set). - with(:sidekiq_queue_duration, instance_of(Float)) + expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set) + .with(:sidekiq_queue_duration, instance_of(Float)) expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish) @@ -23,12 +23,12 @@ describe Gitlab::Metrics::SidekiqMiddleware do it 'tracks the transaction (for messages without `enqueued_at`)' do worker = double(:worker, class: double(:class, name: 'TestWorker')) - expect(Gitlab::Metrics::Transaction).to receive(:new). - with('TestWorker#perform'). - and_call_original + expect(Gitlab::Metrics::Transaction).to receive(:new) + .with('TestWorker#perform') + .and_call_original - expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set). - with(:sidekiq_queue_duration, instance_of(Float)) + expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set) + .with(:sidekiq_queue_duration, instance_of(Float)) expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish) @@ -38,17 +38,17 @@ describe Gitlab::Metrics::SidekiqMiddleware do it 'tracks any raised exceptions' do worker = double(:worker, class: double(:class, name: 'TestWorker')) - expect_any_instance_of(Gitlab::Metrics::Transaction). - to receive(:run).and_raise(RuntimeError) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .to receive(:run).and_raise(RuntimeError) - expect_any_instance_of(Gitlab::Metrics::Transaction). - to receive(:add_event).with(:sidekiq_exception) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .to receive(:add_event).with(:sidekiq_exception) - expect_any_instance_of(Gitlab::Metrics::Transaction). - to receive(:finish) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .to receive(:finish) - expect { middleware.call(worker, message, :test) }. - to raise_error(RuntimeError) + expect { middleware.call(worker, message, :test) } + .to raise_error(RuntimeError) end end end diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb index 0695c5ce096..e7b595405a8 100644 --- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb @@ -21,11 +21,11 @@ describe Gitlab::Metrics::Subscribers::ActionView do values = { duration: 2.1 } tags = { view: 'app/views/x.html.haml' } - expect(transaction).to receive(:increment). - with(:view_duration, 2.1) + expect(transaction).to receive(:increment) + .with(:view_duration, 2.1) - expect(transaction).to receive(:add_metric). - with(described_class::SERIES, values, tags) + expect(transaction).to receive(:add_metric) + .with(described_class::SERIES, values, tags) subscriber.render_template(event) end diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb index 49699ffe28f..ce6587e993f 100644 --- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do describe '#sql' do describe 'without a current transaction' do it 'simply returns' do - expect_any_instance_of(Gitlab::Metrics::Transaction). - not_to receive(:increment) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .not_to receive(:increment) subscriber.sql(event) end @@ -21,15 +21,15 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do describe 'with a current transaction' do it 'increments the :sql_duration value' do - expect(subscriber).to receive(:current_transaction). - at_least(:once). - and_return(transaction) + expect(subscriber).to receive(:current_transaction) + .at_least(:once) + .and_return(transaction) - expect(transaction).to receive(:increment). - with(:sql_duration, 0.2) + expect(transaction).to receive(:increment) + .with(:sql_duration, 0.2) - expect(transaction).to receive(:increment). - with(:sql_count, 1) + expect(transaction).to receive(:increment) + .with(:sql_count, 1) subscriber.sql(event) end diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb index d986c6fac43..f04dc8dcc02 100644 --- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb @@ -8,26 +8,26 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_read' do it 'increments the cache_read duration' do - expect(subscriber).to receive(:increment). - with(:cache_read, event.duration) + expect(subscriber).to receive(:increment) + .with(:cache_read, event.duration) subscriber.cache_read(event) end context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction). - and_return(transaction) + allow(subscriber).to receive(:current_transaction) + .and_return(transaction) end context 'with hit event' do let(:event) { double(:event, duration: 15.2, payload: { hit: true }) } it 'increments the cache_read_hit count' do - expect(transaction).to receive(:increment). - with(:cache_read_hit_count, 1) - expect(transaction).to receive(:increment). - with(any_args).at_least(1) # Other calls + expect(transaction).to receive(:increment) + .with(:cache_read_hit_count, 1) + expect(transaction).to receive(:increment) + .with(any_args).at_least(1) # Other calls subscriber.cache_read(event) end @@ -36,8 +36,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do let(:event) { double(:event, duration: 15.2, payload: { hit: true, super_operation: :fetch }) } it 'does not increment cache read miss' do - expect(transaction).not_to receive(:increment). - with(:cache_read_hit_count, 1) + expect(transaction).not_to receive(:increment) + .with(:cache_read_hit_count, 1) subscriber.cache_read(event) end @@ -48,10 +48,10 @@ describe Gitlab::Metrics::Subscribers::RailsCache do let(:event) { double(:event, duration: 15.2, payload: { hit: false }) } it 'increments the cache_read_miss count' do - expect(transaction).to receive(:increment). - with(:cache_read_miss_count, 1) - expect(transaction).to receive(:increment). - with(any_args).at_least(1) # Other calls + expect(transaction).to receive(:increment) + .with(:cache_read_miss_count, 1) + expect(transaction).to receive(:increment) + .with(any_args).at_least(1) # Other calls subscriber.cache_read(event) end @@ -60,8 +60,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do let(:event) { double(:event, duration: 15.2, payload: { hit: false, super_operation: :fetch }) } it 'does not increment cache read miss' do - expect(transaction).not_to receive(:increment). - with(:cache_read_miss_count, 1) + expect(transaction).not_to receive(:increment) + .with(:cache_read_miss_count, 1) subscriber.cache_read(event) end @@ -72,8 +72,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_write' do it 'increments the cache_write duration' do - expect(subscriber).to receive(:increment). - with(:cache_write, event.duration) + expect(subscriber).to receive(:increment) + .with(:cache_write, event.duration) subscriber.cache_write(event) end @@ -81,8 +81,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_delete' do it 'increments the cache_delete duration' do - expect(subscriber).to receive(:increment). - with(:cache_delete, event.duration) + expect(subscriber).to receive(:increment) + .with(:cache_delete, event.duration) subscriber.cache_delete(event) end @@ -90,8 +90,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_exist?' do it 'increments the cache_exists duration' do - expect(subscriber).to receive(:increment). - with(:cache_exists, event.duration) + expect(subscriber).to receive(:increment) + .with(:cache_exists, event.duration) subscriber.cache_exist?(event) end @@ -108,13 +108,13 @@ describe Gitlab::Metrics::Subscribers::RailsCache do context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction). - and_return(transaction) + allow(subscriber).to receive(:current_transaction) + .and_return(transaction) end it 'increments the cache_read_hit count' do - expect(transaction).to receive(:increment). - with(:cache_read_hit_count, 1) + expect(transaction).to receive(:increment) + .with(:cache_read_hit_count, 1) subscriber.cache_fetch_hit(event) end @@ -132,13 +132,13 @@ describe Gitlab::Metrics::Subscribers::RailsCache do context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction). - and_return(transaction) + allow(subscriber).to receive(:current_transaction) + .and_return(transaction) end it 'increments the cache_fetch_miss count' do - expect(transaction).to receive(:increment). - with(:cache_read_miss_count, 1) + expect(transaction).to receive(:increment) + .with(:cache_read_miss_count, 1) subscriber.cache_generate(event) end @@ -156,22 +156,22 @@ describe Gitlab::Metrics::Subscribers::RailsCache do context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction). - and_return(transaction) + allow(subscriber).to receive(:current_transaction) + .and_return(transaction) end it 'increments the total and specific cache duration' do - expect(transaction).to receive(:increment). - with(:cache_duration, event.duration) + expect(transaction).to receive(:increment) + .with(:cache_duration, event.duration) - expect(transaction).to receive(:increment). - with(:cache_count, 1) + expect(transaction).to receive(:increment) + .with(:cache_count, 1) - expect(transaction).to receive(:increment). - with(:cache_delete_duration, event.duration) + expect(transaction).to receive(:increment) + .with(:cache_delete_duration, event.duration) - expect(transaction).to receive(:increment). - with(:cache_delete_count, 1) + expect(transaction).to receive(:increment) + .with(:cache_delete_count, 1) subscriber.increment(:cache_delete, event.duration) end diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb index 0c5a6246d85..3779af81512 100644 --- a/spec/lib/gitlab/metrics/transaction_spec.rb +++ b/spec/lib/gitlab/metrics/transaction_spec.rb @@ -39,8 +39,8 @@ describe Gitlab::Metrics::Transaction do describe '#add_metric' do it 'adds a metric to the transaction' do - expect(Gitlab::Metrics::Metric).to receive(:new). - with('rails_foo', { number: 10 }, {}) + expect(Gitlab::Metrics::Metric).to receive(:new) + .with('rails_foo', { number: 10 }, {}) transaction.add_metric('foo', number: 10) end @@ -61,8 +61,8 @@ describe Gitlab::Metrics::Transaction do values = { duration: 0.0, time: 3, allocated_memory: a_kind_of(Numeric) } - expect(transaction).to receive(:add_metric). - with('transactions', values, {}) + expect(transaction).to receive(:add_metric) + .with('transactions', values, {}) transaction.track_self end @@ -78,8 +78,8 @@ describe Gitlab::Metrics::Transaction do allocated_memory: a_kind_of(Numeric) } - expect(transaction).to receive(:add_metric). - with('transactions', values, {}) + expect(transaction).to receive(:add_metric) + .with('transactions', values, {}) transaction.track_self end @@ -109,8 +109,8 @@ describe Gitlab::Metrics::Transaction do allocated_memory: a_kind_of(Numeric) } - expect(transaction).to receive(:add_metric). - with('transactions', values, {}) + expect(transaction).to receive(:add_metric) + .with('transactions', values, {}) transaction.track_self end @@ -120,8 +120,8 @@ describe Gitlab::Metrics::Transaction do it 'submits the metrics to Sidekiq' do transaction.track_self - expect(Gitlab::Metrics).to receive(:submit_metrics). - with([an_instance_of(Hash)]) + expect(Gitlab::Metrics).to receive(:submit_metrics) + .with([an_instance_of(Hash)]) transaction.submit end @@ -137,8 +137,8 @@ describe Gitlab::Metrics::Transaction do timestamp: a_kind_of(Integer) } - expect(Gitlab::Metrics).to receive(:submit_metrics). - with([hash]) + expect(Gitlab::Metrics).to receive(:submit_metrics) + .with([hash]) transaction.submit end @@ -154,8 +154,8 @@ describe Gitlab::Metrics::Transaction do timestamp: a_kind_of(Integer) } - expect(Gitlab::Metrics).to receive(:submit_metrics). - with([hash]) + expect(Gitlab::Metrics).to receive(:submit_metrics) + .with([hash]) transaction.submit end diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb index ab6e311b1e8..c8d292f4566 100644 --- a/spec/lib/gitlab/metrics_spec.rb +++ b/spec/lib/gitlab/metrics_spec.rb @@ -28,8 +28,8 @@ describe Gitlab::Metrics do describe '.prepare_metrics' do it 'returns a Hash with the keys as Symbols' do - metrics = described_class. - prepare_metrics([{ 'values' => {}, 'tags' => {} }]) + metrics = described_class + .prepare_metrics([{ 'values' => {}, 'tags' => {} }]) expect(metrics).to eq([{ values: {}, tags: {} }]) end @@ -74,19 +74,19 @@ describe Gitlab::Metrics do let(:transaction) { Gitlab::Metrics::Transaction.new } before do - allow(Gitlab::Metrics).to receive(:current_transaction). - and_return(transaction) + allow(Gitlab::Metrics).to receive(:current_transaction) + .and_return(transaction) end it 'adds a metric to the current transaction' do - expect(transaction).to receive(:increment). - with('foo_real_time', a_kind_of(Numeric)) + expect(transaction).to receive(:increment) + .with('foo_real_time', a_kind_of(Numeric)) - expect(transaction).to receive(:increment). - with('foo_cpu_time', a_kind_of(Numeric)) + expect(transaction).to receive(:increment) + .with('foo_cpu_time', a_kind_of(Numeric)) - expect(transaction).to receive(:increment). - with('foo_call_count', 1) + expect(transaction).to receive(:increment) + .with('foo_call_count', 1) Gitlab::Metrics.measure(:foo) { 10 } end @@ -102,8 +102,8 @@ describe Gitlab::Metrics do describe '.tag_transaction' do context 'without a transaction' do it 'does nothing' do - expect_any_instance_of(Gitlab::Metrics::Transaction). - not_to receive(:add_tag) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .not_to receive(:add_tag) Gitlab::Metrics.tag_transaction(:foo, 'bar') end @@ -113,11 +113,11 @@ describe Gitlab::Metrics do let(:transaction) { Gitlab::Metrics::Transaction.new } it 'adds the tag to the transaction' do - expect(Gitlab::Metrics).to receive(:current_transaction). - and_return(transaction) + expect(Gitlab::Metrics).to receive(:current_transaction) + .and_return(transaction) - expect(transaction).to receive(:add_tag). - with(:foo, 'bar') + expect(transaction).to receive(:add_tag) + .with(:foo, 'bar') Gitlab::Metrics.tag_transaction(:foo, 'bar') end @@ -127,8 +127,8 @@ describe Gitlab::Metrics do describe '.action=' do context 'without a transaction' do it 'does nothing' do - expect_any_instance_of(Gitlab::Metrics::Transaction). - not_to receive(:action=) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .not_to receive(:action=) Gitlab::Metrics.action = 'foo' end @@ -138,8 +138,8 @@ describe Gitlab::Metrics do it 'sets the action of a transaction' do trans = Gitlab::Metrics::Transaction.new - expect(Gitlab::Metrics).to receive(:current_transaction). - and_return(trans) + expect(Gitlab::Metrics).to receive(:current_transaction) + .and_return(trans) expect(trans).to receive(:action=).with('foo') @@ -157,8 +157,8 @@ describe Gitlab::Metrics do describe '.add_event' do context 'without a transaction' do it 'does nothing' do - expect_any_instance_of(Gitlab::Metrics::Transaction). - not_to receive(:add_event) + expect_any_instance_of(Gitlab::Metrics::Transaction) + .not_to receive(:add_event) Gitlab::Metrics.add_event(:meow) end @@ -170,8 +170,8 @@ describe Gitlab::Metrics do expect(transaction).to receive(:add_event).with(:meow) - expect(Gitlab::Metrics).to receive(:current_transaction). - and_return(transaction) + expect(Gitlab::Metrics).to receive(:current_transaction) + .and_return(transaction) Gitlab::Metrics.add_event(:meow) end diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 2c07c37b0ea..09c11462afd 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -184,8 +184,8 @@ describe Gitlab::OAuth::User, lib: true do oauth_user.save identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash). - to match_array( + expect(identities_as_hash) + .to match_array( [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'twitter', extern_uid: uid } diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb index 2370f56a613..21c00c6e5b8 100644 --- a/spec/lib/gitlab/route_map_spec.rb +++ b/spec/lib/gitlab/route_map_spec.rb @@ -4,43 +4,43 @@ describe Gitlab::RouteMap, lib: true do describe '#initialize' do context 'when the data is not YAML' do it 'raises an error' do - expect { described_class.new('"') }. - to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/) + expect { described_class.new('"') } + .to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/) end end context 'when the data is not a YAML array' do it 'raises an error' do - expect { described_class.new(YAML.dump('foo')) }. - to raise_error(Gitlab::RouteMap::FormatError, /an array/) + expect { described_class.new(YAML.dump('foo')) } + .to raise_error(Gitlab::RouteMap::FormatError, /an array/) end end context 'when an entry is not a hash' do it 'raises an error' do - expect { described_class.new(YAML.dump(['foo'])) }. - to raise_error(Gitlab::RouteMap::FormatError, /a hash/) + expect { described_class.new(YAML.dump(['foo'])) } + .to raise_error(Gitlab::RouteMap::FormatError, /a hash/) end end context 'when an entry does not have a source key' do it 'raises an error' do - expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) }. - to raise_error(Gitlab::RouteMap::FormatError, /source key/) + expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) } + .to raise_error(Gitlab::RouteMap::FormatError, /source key/) end end context 'when an entry does not have a public key' do it 'raises an error' do - expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) }. - to raise_error(Gitlab::RouteMap::FormatError, /public key/) + expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) } + .to raise_error(Gitlab::RouteMap::FormatError, /public key/) end end context 'when an entry source is not a valid regex' do it 'raises an error' do - expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) }. - to raise_error(Gitlab::RouteMap::FormatError, /regular expression/) + expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) } + .to raise_error(Gitlab::RouteMap::FormatError, /regular expression/) end end diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb index e05160da7a6..519eb1b274f 100644 --- a/spec/lib/gitlab/serializer/pagination_spec.rb +++ b/spec/lib/gitlab/serializer/pagination_spec.rb @@ -6,11 +6,11 @@ describe Gitlab::Serializer::Pagination do let(:headers) { spy('headers') } before do - allow(request).to receive(:query_parameters). - and_return(params) + allow(request).to receive(:query_parameters) + .and_return(params) - allow(response).to receive(:headers). - and_return(headers) + allow(response).to receive(:headers) + .and_return(headers) end let(:pagination) { described_class.new(request, response) } diff --git a/spec/lib/gitlab/sherlock/file_sample_spec.rb b/spec/lib/gitlab/sherlock/file_sample_spec.rb index cadf8bbce78..4989d14def3 100644 --- a/spec/lib/gitlab/sherlock/file_sample_spec.rb +++ b/spec/lib/gitlab/sherlock/file_sample_spec.rb @@ -35,8 +35,8 @@ describe Gitlab::Sherlock::FileSample, lib: true do describe '#relative_path' do it 'returns the relative path' do - expect(sample.relative_path). - to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb') + expect(sample.relative_path) + .to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb') end end diff --git a/spec/lib/gitlab/sherlock/line_profiler_spec.rb b/spec/lib/gitlab/sherlock/line_profiler_spec.rb index d57627bba2b..39c6b2a4844 100644 --- a/spec/lib/gitlab/sherlock/line_profiler_spec.rb +++ b/spec/lib/gitlab/sherlock/line_profiler_spec.rb @@ -20,9 +20,9 @@ describe Gitlab::Sherlock::LineProfiler, lib: true do describe '#profile_mri' do it 'returns an Array containing the return value and profiling samples' do - allow(profiler).to receive(:lineprof). - and_yield. - and_return({ __FILE__ => [[0, 0, 0, 0]] }) + allow(profiler).to receive(:lineprof) + .and_yield + .and_return({ __FILE__ => [[0, 0, 0, 0]] }) retval, samples = profiler.profile_mri { 42 } diff --git a/spec/lib/gitlab/sherlock/middleware_spec.rb b/spec/lib/gitlab/sherlock/middleware_spec.rb index 2bbeb25ce98..b98ab0b14a2 100644 --- a/spec/lib/gitlab/sherlock/middleware_spec.rb +++ b/spec/lib/gitlab/sherlock/middleware_spec.rb @@ -72,8 +72,8 @@ describe Gitlab::Sherlock::Middleware, lib: true do 'REQUEST_URI' => '/cats' } - expect(middleware.transaction_from_env(env)). - to be_an_instance_of(Gitlab::Sherlock::Transaction) + expect(middleware.transaction_from_env(env)) + .to be_an_instance_of(Gitlab::Sherlock::Transaction) end end end diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb index 0a620428138..d97b5eef573 100644 --- a/spec/lib/gitlab/sherlock/query_spec.rb +++ b/spec/lib/gitlab/sherlock/query_spec.rb @@ -13,8 +13,8 @@ describe Gitlab::Sherlock::Query, lib: true do sql = 'SELECT COUNT(*) FROM users WHERE id = $1' bindings = [[double(:column), 10]] - query = described_class. - new_with_bindings(sql, bindings, started_at, finished_at) + query = described_class + .new_with_bindings(sql, bindings, started_at, finished_at) expect(query.query).to eq('SELECT COUNT(*) FROM users WHERE id = 10;') end diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb index 9fe18f253f0..6ae1aa20ea7 100644 --- a/spec/lib/gitlab/sherlock/transaction_spec.rb +++ b/spec/lib/gitlab/sherlock/transaction_spec.rb @@ -109,8 +109,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do query1 = Gitlab::Sherlock::Query.new('SELECT 1', start_time, start_time) - query2 = Gitlab::Sherlock::Query. - new('SELECT 2', start_time, start_time + 5) + query2 = Gitlab::Sherlock::Query + .new('SELECT 2', start_time, start_time + 5) transaction.queries << query1 transaction.queries << query2 @@ -162,11 +162,11 @@ describe Gitlab::Sherlock::Transaction, lib: true do describe '#profile_lines' do describe 'when line profiling is enabled' do it 'yields the block using the line profiler' do - allow(Gitlab::Sherlock).to receive(:enable_line_profiler?). - and_return(true) + allow(Gitlab::Sherlock).to receive(:enable_line_profiler?) + .and_return(true) - allow_any_instance_of(Gitlab::Sherlock::LineProfiler). - to receive(:profile).and_return('cats are amazing', []) + allow_any_instance_of(Gitlab::Sherlock::LineProfiler) + .to receive(:profile).and_return('cats are amazing', []) retval = transaction.profile_lines { 'cats are amazing' } @@ -176,8 +176,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do describe 'when line profiling is disabled' do it 'yields the block' do - allow(Gitlab::Sherlock).to receive(:enable_line_profiler?). - and_return(false) + allow(Gitlab::Sherlock).to receive(:enable_line_profiler?) + .and_return(false) retval = transaction.profile_lines { 'cats are amazing' } @@ -196,8 +196,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do end it 'tracks executed queries' do - expect(transaction).to receive(:track_query). - with('SELECT 1', [], time, time) + expect(transaction).to receive(:track_query) + .with('SELECT 1', [], time, time) subscription.publish('test', time, time, nil, query_data) end @@ -205,8 +205,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do it 'only tracks queries triggered from the transaction thread' do expect(transaction).not_to receive(:track_query) - Thread.new { subscription.publish('test', time, time, nil, query_data) }. - join + Thread.new { subscription.publish('test', time, time, nil, query_data) } + .join end end @@ -228,8 +228,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do it 'only tracks views rendered from the transaction thread' do expect(transaction).not_to receive(:track_view) - Thread.new { subscription.publish('test', time, time, nil, view_data) }. - join + Thread.new { subscription.publish('test', time, time, nil, view_data) } + .join end end end diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb index 287bf62d9bd..5faa5597aa5 100644 --- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb +++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb @@ -5,8 +5,8 @@ describe Gitlab::SidekiqStatus::ClientMiddleware do it 'tracks the job in Redis' do expect(Gitlab::SidekiqStatus).to receive(:set).with('123') - described_class.new. - call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil } + described_class.new + .call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil } end end end diff --git a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb index 80728197b8c..04e09d3dec8 100644 --- a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb +++ b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb @@ -5,8 +5,8 @@ describe Gitlab::SidekiqStatus::ServerMiddleware do it 'stops tracking of a job upon completion' do expect(Gitlab::SidekiqStatus).to receive(:unset).with('123') - ret = described_class.new. - call(double(:worker), { 'jid' => '123' }, double(:queue)) { 10 } + ret = described_class.new + .call(double(:worker), { 'jid' => '123' }, double(:queue)) { 10 } expect(ret).to eq(10) end diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb index 3fe8cf43934..027d832308c 100644 --- a/spec/lib/gitlab/url_builder_spec.rb +++ b/spec/lib/gitlab/url_builder_spec.rb @@ -101,8 +101,8 @@ describe Gitlab::UrlBuilder, lib: true do it 'returns a proper URL' do project = build_stubbed(:empty_project) - expect { described_class.build(project) }. - to raise_error(NotImplementedError, 'No URL builder defined for Project') + expect { described_class.build(project) } + .to raise_error(NotImplementedError, 'No URL builder defined for Project') end end end diff --git a/spec/lib/gitlab/view/presenter/delegated_spec.rb b/spec/lib/gitlab/view/presenter/delegated_spec.rb index e9d4af54389..940a2ce6ebd 100644 --- a/spec/lib/gitlab/view/presenter/delegated_spec.rb +++ b/spec/lib/gitlab/view/presenter/delegated_spec.rb @@ -18,8 +18,8 @@ describe Gitlab::View::Presenter::Delegated do end it 'raise an error if the presentee already respond to method' do - expect { presenter_class.new(project, user: 'Jane Doe') }. - to raise_error Gitlab::View::Presenter::CannotOverrideMethodError + expect { presenter_class.new(project, user: 'Jane Doe') } + .to raise_error Gitlab::View::Presenter::CannotOverrideMethodError end end diff --git a/spec/lib/light_url_builder_spec.rb b/spec/lib/light_url_builder_spec.rb index 3fe8cf43934..027d832308c 100644 --- a/spec/lib/light_url_builder_spec.rb +++ b/spec/lib/light_url_builder_spec.rb @@ -101,8 +101,8 @@ describe Gitlab::UrlBuilder, lib: true do it 'returns a proper URL' do project = build_stubbed(:empty_project) - expect { described_class.build(project) }. - to raise_error(NotImplementedError, 'No URL builder defined for Project') + expect { described_class.build(project) } + .to raise_error(NotImplementedError, 'No URL builder defined for Project') end end end diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb index 5ccf1100898..c0393eafca9 100644 --- a/spec/lib/mattermost/command_spec.rb +++ b/spec/lib/mattermost/command_spec.rb @@ -6,8 +6,8 @@ describe Mattermost::Command do before do Mattermost::Session.base_uri('http://mattermost.example.com') - allow_any_instance_of(Mattermost::Client).to receive(:with_session). - and_yield(Mattermost::Session.new(nil)) + allow_any_instance_of(Mattermost::Client).to receive(:with_session) + .and_yield(Mattermost::Session.new(nil)) end describe '#create' do @@ -21,11 +21,11 @@ describe Mattermost::Command do context 'for valid trigger word' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). - with(body: { + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') + .with(body: { team_id: 'abc', - trigger: 'gitlab' }.to_json). - to_return( + trigger: 'gitlab' }.to_json) + .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: { token: 'token' }.to_json @@ -39,8 +39,8 @@ describe Mattermost::Command do context 'for error message' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). - to_return( + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') + .to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb index 74d12e37181..be3908e8f6a 100644 --- a/spec/lib/mattermost/session_spec.rb +++ b/spec/lib/mattermost/session_spec.rb @@ -21,8 +21,8 @@ describe Mattermost::Session, type: :request do describe '#with session' do let(:location) { 'http://location.tld' } let!(:stub) do - WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login"). - to_return(headers: { 'location' => location }, status: 307) + WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login") + .to_return(headers: { 'location' => location }, status: 307) end context 'without oauth uri' do @@ -60,9 +60,9 @@ describe Mattermost::Session, type: :request do end before do - WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete"). - with(query: hash_including({ 'state' => state })). - to_return do |request| + WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete") + .with(query: hash_including({ 'state' => state })) + .to_return do |request| post "/oauth/token", client_id: doorkeeper.uid, client_secret: doorkeeper.secret, @@ -75,8 +75,8 @@ describe Mattermost::Session, type: :request do end end - WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout"). - to_return(headers: { Authorization: 'token thisworksnow' }, status: 200) + WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout") + .to_return(headers: { Authorization: 'token thisworksnow' }, status: 200) end it 'can setup a session' do diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb index 2d14be6bcc2..4435e3c24b7 100644 --- a/spec/lib/mattermost/team_spec.rb +++ b/spec/lib/mattermost/team_spec.rb @@ -4,8 +4,8 @@ describe Mattermost::Team do before do Mattermost::Session.base_uri('http://mattermost.example.com') - allow_any_instance_of(Mattermost::Client).to receive(:with_session). - and_yield(Mattermost::Session.new(nil)) + allow_any_instance_of(Mattermost::Client).to receive(:with_session) + .and_yield(Mattermost::Session.new(nil)) end describe '#all' do @@ -29,8 +29,8 @@ describe Mattermost::Team do end before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). - to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') + .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: response.to_json @@ -44,8 +44,8 @@ describe Mattermost::Team do context 'for error message' do before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). - to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') + .to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { diff --git a/spec/mailers/abuse_report_mailer_spec.rb b/spec/mailers/abuse_report_mailer_spec.rb index eb433c38873..bda892083b3 100644 --- a/spec/mailers/abuse_report_mailer_spec.rb +++ b/spec/mailers/abuse_report_mailer_spec.rb @@ -30,8 +30,8 @@ describe AbuseReportMailer do it 'returns early' do stub_application_setting(admin_notification_email: nil) - expect { described_class.notify(spy).deliver_now }. - not_to change { ActionMailer::Base.deliveries.count } + expect { described_class.notify(spy).deliver_now } + .not_to change { ActionMailer::Base.deliveries.count } end end end diff --git a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb index b6d678bac18..1cbaa90151f 100644 --- a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb +++ b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb @@ -11,33 +11,33 @@ describe MigrateProcessCommitWorkerJobs do describe 'Project' do describe 'find_including_path' do it 'returns Project instances' do - expect(described_class::Project.find_including_path(project.id)). - to be_an_instance_of(described_class::Project) + expect(described_class::Project.find_including_path(project.id)) + .to be_an_instance_of(described_class::Project) end it 'selects the full path for every Project' do - migration_project = described_class::Project. - find_including_path(project.id) + migration_project = described_class::Project + .find_including_path(project.id) - expect(migration_project[:path_with_namespace]). - to eq(project.path_with_namespace) + expect(migration_project[:path_with_namespace]) + .to eq(project.path_with_namespace) end end describe '#repository_storage_path' do it 'returns the storage path for the repository' do - migration_project = described_class::Project. - find_including_path(project.id) + migration_project = described_class::Project + .find_including_path(project.id) - expect(File.directory?(migration_project.repository_storage_path)). - to eq(true) + expect(File.directory?(migration_project.repository_storage_path)) + .to eq(true) end end describe '#repository_path' do it 'returns the path to the repository' do - migration_project = described_class::Project. - find_including_path(project.id) + migration_project = described_class::Project + .find_including_path(project.id) expect(File.directory?(migration_project.repository_path)).to eq(true) end @@ -45,11 +45,11 @@ describe MigrateProcessCommitWorkerJobs do describe '#repository' do it 'returns a Rugged::Repository' do - migration_project = described_class::Project. - find_including_path(project.id) + migration_project = described_class::Project + .find_including_path(project.id) - expect(migration_project.repository). - to be_an_instance_of(Rugged::Repository) + expect(migration_project.repository) + .to be_an_instance_of(Rugged::Repository) end end end @@ -73,9 +73,9 @@ describe MigrateProcessCommitWorkerJobs do end it 'skips jobs using a project that no longer exists' do - allow(described_class::Project).to receive(:find_including_path). - with(project.id). - and_return(nil) + allow(described_class::Project).to receive(:find_including_path) + .with(project.id) + .and_return(nil) migration.up @@ -83,9 +83,9 @@ describe MigrateProcessCommitWorkerJobs do end it 'skips jobs using commits that no longer exist' do - allow_any_instance_of(Rugged::Repository).to receive(:lookup). - with(commit.oid). - and_raise(Rugged::OdbError) + allow_any_instance_of(Rugged::Repository).to receive(:lookup) + .with(commit.oid) + .and_raise(Rugged::OdbError) migration.up @@ -99,12 +99,12 @@ describe MigrateProcessCommitWorkerJobs do end it 'encodes data to UTF-8' do - allow_any_instance_of(Rugged::Repository).to receive(:lookup). - with(commit.oid). - and_return(commit) + allow_any_instance_of(Rugged::Repository).to receive(:lookup) + .with(commit.oid) + .and_return(commit) - allow(commit).to receive(:message). - and_return('김치'.force_encoding('BINARY')) + allow(commit).to receive(:message) + .and_return('김치'.force_encoding('BINARY')) migration.up diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 30f8fdf91b2..c34e58afaaf 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -63,8 +63,8 @@ describe Ability, lib: true do project = create(:empty_project, :public) user = build(:user) - expect(described_class.users_that_can_read_project([user], project)). - to eq([user]) + expect(described_class.users_that_can_read_project([user], project)) + .to eq([user]) end end @@ -74,8 +74,8 @@ describe Ability, lib: true do it 'returns users that are administrators' do user = build(:user, admin: true) - expect(described_class.users_that_can_read_project([user], project)). - to eq([user]) + expect(described_class.users_that_can_read_project([user], project)) + .to eq([user]) end it 'returns internal users while skipping external users' do @@ -83,8 +83,8 @@ describe Ability, lib: true do user2 = build(:user, external: true) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)). - to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([user1]) end it 'returns external users if they are the project owner' do @@ -94,8 +94,8 @@ describe Ability, lib: true do expect(project).to receive(:owner).twice.and_return(user1) - expect(described_class.users_that_can_read_project(users, project)). - to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([user1]) end it 'returns external users if they are project members' do @@ -105,8 +105,8 @@ describe Ability, lib: true do expect(project.team).to receive(:members).twice.and_return([user1]) - expect(described_class.users_that_can_read_project(users, project)). - to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([user1]) end it 'returns an empty Array if all users are external users without access' do @@ -114,8 +114,8 @@ describe Ability, lib: true do user2 = build(:user, external: true) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)). - to eq([]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([]) end end @@ -125,8 +125,8 @@ describe Ability, lib: true do it 'returns users that are administrators' do user = build(:user, admin: true) - expect(described_class.users_that_can_read_project([user], project)). - to eq([user]) + expect(described_class.users_that_can_read_project([user], project)) + .to eq([user]) end it 'returns external users if they are the project owner' do @@ -136,8 +136,8 @@ describe Ability, lib: true do expect(project).to receive(:owner).twice.and_return(user1) - expect(described_class.users_that_can_read_project(users, project)). - to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([user1]) end it 'returns external users if they are project members' do @@ -147,8 +147,8 @@ describe Ability, lib: true do expect(project.team).to receive(:members).twice.and_return([user1]) - expect(described_class.users_that_can_read_project(users, project)). - to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([user1]) end it 'returns an empty Array if all users are internal users without access' do @@ -156,8 +156,8 @@ describe Ability, lib: true do user2 = build(:user) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)). - to eq([]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([]) end it 'returns an empty Array if all users are external users without access' do @@ -165,8 +165,8 @@ describe Ability, lib: true do user2 = build(:user, external: true) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)). - to eq([]) + expect(described_class.users_that_can_read_project(users, project)) + .to eq([]) end end end @@ -204,8 +204,8 @@ describe Ability, lib: true do user = build(:user, admin: true) issue = build(:issue) - expect(described_class.issues_readable_by_user([issue], user)). - to eq([issue]) + expect(described_class.issues_readable_by_user([issue], user)) + .to eq([issue]) end end @@ -216,8 +216,8 @@ describe Ability, lib: true do expect(issue).to receive(:readable_by?).with(user).and_return(true) - expect(described_class.issues_readable_by_user([issue], user)). - to eq([issue]) + expect(described_class.issues_readable_by_user([issue], user)) + .to eq([issue]) end it 'returns an empty Array when no issues are readable' do @@ -238,8 +238,8 @@ describe Ability, lib: true do expect(hidden_issue).to receive(:publicly_visible?).and_return(false) expect(visible_issue).to receive(:publicly_visible?).and_return(true) - issues = described_class. - issues_readable_by_user([hidden_issue, visible_issue]) + issues = described_class + .issues_readable_by_user([hidden_issue, visible_issue]) expect(issues).to eq([visible_issue]) end diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb index c4486a32082..d26e491e548 100644 --- a/spec/models/abuse_report_spec.rb +++ b/spec/models/abuse_report_spec.rb @@ -37,8 +37,8 @@ RSpec.describe AbuseReport, type: :model do describe '#notify' do it 'delivers' do - expect(AbuseReportMailer).to receive(:notify).with(subject.id). - and_return(spy) + expect(AbuseReportMailer).to receive(:notify).with(subject.id) + .and_return(spy) subject.notify end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 53011008f44..b950fcdd81a 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -32,9 +32,9 @@ describe ApplicationSetting, models: true do it { is_expected.to validate_presence_of(:max_attachment_size) } it do - is_expected.to validate_numericality_of(:max_attachment_size). - only_integer. - is_greater_than(0) + is_expected.to validate_numericality_of(:max_attachment_size) + .only_integer + .is_greater_than(0) end it_behaves_like 'an object with email-formated attributes', :admin_notification_email do diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index eaff27efd5d..9a03485201b 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -212,15 +212,15 @@ describe Ci::Build, :models do retried_rspec = Ci::Build.retry(rspec_test, user) - expect(staging.depends_on_builds.map(&:id)). - to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) + expect(staging.depends_on_builds.map(&:id)) + .to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) end end describe '#detailed_status' do it 'returns a detailed status' do - expect(build.detailed_status(user)). - to be_a Gitlab::Ci::Status::Build::Cancelable + expect(build.detailed_status(user)) + .to be_a Gitlab::Ci::Status::Build::Cancelable end end @@ -784,8 +784,8 @@ describe Ci::Build, :models do pipeline2 = create(:ci_pipeline, project: project) @build2 = create(:ci_build, pipeline: pipeline2) - allow(@merge_request).to receive(:commits_sha). - and_return([pipeline.sha, pipeline2.sha]) + allow(@merge_request).to receive(:commits_sha) + .and_return([pipeline.sha, pipeline2.sha]) allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request]) end @@ -1151,8 +1151,8 @@ describe Ci::Build, :models do let!(:build) { create(:ci_build, artifacts_size: 23) } it 'updates project statistics when the artifact size changes' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(build.project_id, [], [:build_artifacts_size]) build.artifacts_size = 42 build.save! @@ -1166,8 +1166,8 @@ describe Ci::Build, :models do end it 'updates project statistics when the build is destroyed' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(build.project_id, [], [:build_artifacts_size]) build.destroy end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 10c2bfbb400..714a3123efd 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -455,8 +455,8 @@ describe Ci::Pipeline, models: true do it 'returns the latest pipeline for the same ref and different sha' do expect(pipelines.map(&:sha)).to contain_exactly('A', 'B', 'C') - expect(pipelines.map(&:status)). - to contain_exactly('success', 'failed', 'skipped') + expect(pipelines.map(&:status)) + .to contain_exactly('success', 'failed', 'skipped') end end @@ -465,8 +465,8 @@ describe Ci::Pipeline, models: true do it 'returns the latest pipeline for ref and different sha' do expect(pipelines.map(&:sha)).to contain_exactly('A', 'B') - expect(pipelines.map(&:status)). - to contain_exactly('success', 'failed') + expect(pipelines.map(&:status)) + .to contain_exactly('success', 'failed') end end end @@ -501,8 +501,8 @@ describe Ci::Pipeline, models: true do end it 'returns the latest successful pipeline' do - expect(described_class.latest_successful_for('ref')). - to eq(latest_successful_pipeline) + expect(described_class.latest_successful_for('ref')) + .to eq(latest_successful_pipeline) end end diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index bee9f714849..674c52eecb2 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -32,8 +32,8 @@ describe Ci::Variable, models: true do it 'fails to decrypt if iv is incorrect' do subject.encrypted_value_iv = SecureRandom.hex subject.instance_variable_set(:@value, nil) - expect { subject.value }. - to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt') + expect { subject.value } + .to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt') end end end diff --git a/spec/models/commit_range_spec.rb b/spec/models/commit_range_spec.rb index e4bddf67096..ba9c3f66d21 100644 --- a/spec/models/commit_range_spec.rb +++ b/spec/models/commit_range_spec.rb @@ -147,9 +147,9 @@ describe CommitRange, models: true do note: commit1.revert_description(user), project: issue.project) - expect_any_instance_of(Commit).to receive(:reverts_commit?). - with(commit1, user). - and_return(true) + expect_any_instance_of(Commit).to receive(:reverts_commit?) + .with(commit1, user) + .and_return(true) expect(commit1.has_been_reverted?(user, issue)).to eq(true) end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index f770e6a9e34..36533bdd11e 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -253,8 +253,8 @@ describe CommitStatus, :models do let(:user) { create(:user) } it 'returns a detailed status' do - expect(commit_status.detailed_status(user)). - to be_a Gitlab::Ci::Status::Success + expect(commit_status.detailed_status(user)) + .to be_a Gitlab::Ci::Status::Success end end diff --git a/spec/models/concerns/case_sensitivity_spec.rb b/spec/models/concerns/case_sensitivity_spec.rb index 92fdc5cd65d..a6fccb668e3 100644 --- a/spec/models/concerns/case_sensitivity_spec.rb +++ b/spec/models/concerns/case_sensitivity_spec.rb @@ -15,13 +15,13 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:foo). - and_return('"foo"') + expect(connection).to receive(:quote_table_name) + .with(:foo) + .and_return('"foo"') - expect(model).to receive(:where). - with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar'). - and_return(criteria) + expect(model).to receive(:where) + .with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar') + .and_return(criteria) expect(model.iwhere(foo: 'bar')).to eq(criteria) end @@ -29,13 +29,13 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column with a table, and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:'foo.bar'). - and_return('"foo"."bar"') + expect(connection).to receive(:quote_table_name) + .with(:'foo.bar') + .and_return('"foo"."bar"') - expect(model).to receive(:where). - with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar'). - and_return(criteria) + expect(model).to receive(:where) + .with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar') + .and_return(criteria) expect(model.iwhere('foo.bar'.to_sym => 'bar')).to eq(criteria) end @@ -46,21 +46,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:foo). - and_return('"foo"') + expect(connection).to receive(:quote_table_name) + .with(:foo) + .and_return('"foo"') - expect(connection).to receive(:quote_table_name). - with(:bar). - and_return('"bar"') + expect(connection).to receive(:quote_table_name) + .with(:bar) + .and_return('"bar"') - expect(model).to receive(:where). - with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar'). - and_return(initial) + expect(model).to receive(:where) + .with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar') + .and_return(initial) - expect(initial).to receive(:where). - with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz'). - and_return(final) + expect(initial).to receive(:where) + .with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz') + .and_return(final) got = model.iwhere(foo: 'bar', bar: 'baz') @@ -71,21 +71,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:'foo.bar'). - and_return('"foo"."bar"') + expect(connection).to receive(:quote_table_name) + .with(:'foo.bar') + .and_return('"foo"."bar"') - expect(connection).to receive(:quote_table_name). - with(:'foo.baz'). - and_return('"foo"."baz"') + expect(connection).to receive(:quote_table_name) + .with(:'foo.baz') + .and_return('"foo"."baz"') - expect(model).to receive(:where). - with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar'). - and_return(initial) + expect(model).to receive(:where) + .with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar') + .and_return(initial) - expect(initial).to receive(:where). - with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz'). - and_return(final) + expect(initial).to receive(:where) + .with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz') + .and_return(final) got = model.iwhere('foo.bar'.to_sym => 'bar', 'foo.baz'.to_sym => 'baz') @@ -105,13 +105,13 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:foo). - and_return('`foo`') + expect(connection).to receive(:quote_table_name) + .with(:foo) + .and_return('`foo`') - expect(model).to receive(:where). - with(%q{`foo` = :value}, value: 'bar'). - and_return(criteria) + expect(model).to receive(:where) + .with(%q{`foo` = :value}, value: 'bar') + .and_return(criteria) expect(model.iwhere(foo: 'bar')).to eq(criteria) end @@ -119,16 +119,16 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column with a table, and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:'foo.bar'). - and_return('`foo`.`bar`') + expect(connection).to receive(:quote_table_name) + .with(:'foo.bar') + .and_return('`foo`.`bar`') - expect(model).to receive(:where). - with(%q{`foo`.`bar` = :value}, value: 'bar'). - and_return(criteria) + expect(model).to receive(:where) + .with(%q{`foo`.`bar` = :value}, value: 'bar') + .and_return(criteria) - expect(model.iwhere('foo.bar'.to_sym => 'bar')). - to eq(criteria) + expect(model.iwhere('foo.bar'.to_sym => 'bar')) + .to eq(criteria) end end @@ -137,21 +137,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:foo). - and_return('`foo`') + expect(connection).to receive(:quote_table_name) + .with(:foo) + .and_return('`foo`') - expect(connection).to receive(:quote_table_name). - with(:bar). - and_return('`bar`') + expect(connection).to receive(:quote_table_name) + .with(:bar) + .and_return('`bar`') - expect(model).to receive(:where). - with(%q{`foo` = :value}, value: 'bar'). - and_return(initial) + expect(model).to receive(:where) + .with(%q{`foo` = :value}, value: 'bar') + .and_return(initial) - expect(initial).to receive(:where). - with(%q{`bar` = :value}, value: 'baz'). - and_return(final) + expect(initial).to receive(:where) + .with(%q{`bar` = :value}, value: 'baz') + .and_return(final) got = model.iwhere(foo: 'bar', bar: 'baz') @@ -162,21 +162,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name). - with(:'foo.bar'). - and_return('`foo`.`bar`') + expect(connection).to receive(:quote_table_name) + .with(:'foo.bar') + .and_return('`foo`.`bar`') - expect(connection).to receive(:quote_table_name). - with(:'foo.baz'). - and_return('`foo`.`baz`') + expect(connection).to receive(:quote_table_name) + .with(:'foo.baz') + .and_return('`foo`.`baz`') - expect(model).to receive(:where). - with(%q{`foo`.`bar` = :value}, value: 'bar'). - and_return(initial) + expect(model).to receive(:where) + .with(%q{`foo`.`bar` = :value}, value: 'bar') + .and_return(initial) - expect(initial).to receive(:where). - with(%q{`foo`.`baz` = :value}, value: 'baz'). - and_return(final) + expect(initial).to receive(:where) + .with(%q{`foo`.`baz` = :value}, value: 'baz') + .and_return(final) got = model.iwhere('foo.bar'.to_sym => 'bar', 'foo.baz'.to_sym => 'baz') diff --git a/spec/models/concerns/has_status_spec.rb b/spec/models/concerns/has_status_spec.rb index dbfe3cd2d36..e6107197368 100644 --- a/spec/models/concerns/has_status_spec.rb +++ b/spec/models/concerns/has_status_spec.rb @@ -132,8 +132,8 @@ describe HasStatus do describe ".#{status}" do it 'contains the job' do - expect(CommitStatus.public_send(status).all). - to contain_exactly(job) + expect(CommitStatus.public_send(status).all) + .to contain_exactly(job) end end diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index 545a11912e3..a372824b6e5 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -87,8 +87,8 @@ describe Issue, "Issuable" do let!(:searchable_issue) { create(:issue, title: "Searchable issue") } it 'returns notes with a matching title' do - expect(described_class.search(searchable_issue.title)). - to eq([searchable_issue]) + expect(described_class.search(searchable_issue.title)) + .to eq([searchable_issue]) end it 'returns notes with a partially matching title' do @@ -96,8 +96,8 @@ describe Issue, "Issuable" do end it 'returns notes with a matching title regardless of the casing' do - expect(described_class.search(searchable_issue.title.upcase)). - to eq([searchable_issue]) + expect(described_class.search(searchable_issue.title.upcase)) + .to eq([searchable_issue]) end end @@ -107,8 +107,8 @@ describe Issue, "Issuable" do end it 'returns notes with a matching title' do - expect(described_class.full_search(searchable_issue.title)). - to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.title)) + .to eq([searchable_issue]) end it 'returns notes with a partially matching title' do @@ -116,23 +116,23 @@ describe Issue, "Issuable" do end it 'returns notes with a matching title regardless of the casing' do - expect(described_class.full_search(searchable_issue.title.upcase)). - to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.title.upcase)) + .to eq([searchable_issue]) end it 'returns notes with a matching description' do - expect(described_class.full_search(searchable_issue.description)). - to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.description)) + .to eq([searchable_issue]) end it 'returns notes with a partially matching description' do - expect(described_class.full_search(searchable_issue.description)). - to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.description)) + .to eq([searchable_issue]) end it 'returns notes with a matching description regardless of the casing' do - expect(described_class.full_search(searchable_issue.description.upcase)). - to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.description.upcase)) + .to eq([searchable_issue]) end end @@ -287,16 +287,16 @@ describe Issue, "Issuable" do allow(issue).to receive(:author).and_return(double(name: 'Robert')) allow(issue).to receive(:assignee).and_return(nil) - expect(issue.card_attributes). - to eq({ 'Author' => 'Robert', 'Assignee' => nil }) + expect(issue.card_attributes) + .to eq({ 'Author' => 'Robert', 'Assignee' => nil }) end it 'includes the assignee name' do allow(issue).to receive(:author).and_return(double(name: 'Robert')) allow(issue).to receive(:assignee).and_return(double(name: 'Douwe')) - expect(issue.card_attributes). - to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' }) + expect(issue.card_attributes) + .to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' }) end end diff --git a/spec/models/discussion_spec.rb b/spec/models/discussion_spec.rb index bc32fadd391..47c22a03797 100644 --- a/spec/models/discussion_spec.rb +++ b/spec/models/discussion_spec.rb @@ -304,22 +304,22 @@ describe Discussion, model: true do it "doesn't change resolved_at on the resolved note" do expect(first_note.resolved_at).not_to be_nil - expect { subject.resolve!(current_user) }. - not_to change { first_note.reload.resolved_at } + expect { subject.resolve!(current_user) } + .not_to change { first_note.reload.resolved_at } end it "doesn't change resolved_by on the resolved note" do expect(first_note.resolved_by).to eq(user) - expect { subject.resolve!(current_user) }. - not_to change { first_note.reload && first_note.resolved_by } + expect { subject.resolve!(current_user) } + .not_to change { first_note.reload && first_note.resolved_by } end it "doesn't change the resolved state on the resolved note" do expect(first_note.resolved?).to be true - expect { subject.resolve!(current_user) }. - not_to change { first_note.reload && first_note.resolved? } + expect { subject.resolve!(current_user) } + .not_to change { first_note.reload && first_note.resolved? } end it "sets resolved_at on the unresolved note" do diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index 4652af1cb97..fe4de1b2afb 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -8,7 +8,7 @@ describe Email, models: true do end it 'normalize email value' do - expect(described_class.new(email: ' inFO@exAMPLe.com ').email). - to eq 'info@example.com' + expect(described_class.new(email: ' inFO@exAMPLe.com ').email) + .to eq 'info@example.com' end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 503e5b3eed8..1dd66c52437 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -283,9 +283,9 @@ describe Environment, models: true do before { allow(environment).to receive(:has_terminals?).and_return(true) } it 'returns the terminals from the deployment service' do - expect(project.deployment_service). - to receive(:terminals).with(environment). - and_return(:fake_terminals) + expect(project.deployment_service) + .to receive(:terminals).with(environment) + .and_return(:fake_terminals) is_expected.to eq(:fake_terminals) end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 8c90a538f57..c5acfceb853 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -240,8 +240,8 @@ describe Event, models: true do it 'does not update the project' do project.update(last_activity_at: Time.now) - expect(project).not_to receive(:update_column). - with(:last_activity_at, a_kind_of(Time)) + expect(project).not_to receive(:update_column) + .with(:last_activity_at, a_kind_of(Time)) create_event(project, project.owner) end diff --git a/spec/models/group_label_spec.rb b/spec/models/group_label_spec.rb index c8d88022ec7..555a876daeb 100644 --- a/spec/models/group_label_spec.rb +++ b/spec/models/group_label_spec.rb @@ -49,8 +49,8 @@ describe GroupLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) }. - to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) } + .to raise_error StandardError, /Unknown format/ end end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index a4e6eb4e3a6..57975d6c70b 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -309,8 +309,8 @@ describe Group, models: true do group.add_user(master, GroupMember::MASTER) group.add_user(developer, GroupMember::DEVELOPER) - expect(group.user_ids_for_project_authorizations). - to include(master.id, developer.id) + expect(group.user_ids_for_project_authorizations) + .to include(master.id, developer.id) end end end diff --git a/spec/models/issue_collection_spec.rb b/spec/models/issue_collection_spec.rb index d8aed25c041..79584f94a4c 100644 --- a/spec/models/issue_collection_spec.rb +++ b/spec/models/issue_collection_spec.rb @@ -50,8 +50,8 @@ describe IssueCollection do context 'using a user that is the owner of a project' do it 'returns the issues of the project' do - expect(collection.updatable_by_user(project.namespace.owner)). - to eq([issue1, issue2]) + expect(collection.updatable_by_user(project.namespace.owner)) + .to eq([issue1, issue2]) end end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index bba9058f394..143e84dac96 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -239,8 +239,8 @@ describe Issue, models: true do let(:user) { build(:admin) } before do - allow(subject.project.repository).to receive(:branch_names). - and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"]) + allow(subject.project.repository).to receive(:branch_names) + .and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"]) # Without this stub, the `create(:merge_request)` above fails because it can't find # the source branch. This seems like a reasonable compromise, in comparison with @@ -262,8 +262,8 @@ describe Issue, models: true do end it 'excludes stable branches from the related branches' do - allow(subject.project.repository).to receive(:branch_names). - and_return(["#{subject.iid}-0-stable"]) + allow(subject.project.repository).to receive(:branch_names) + .and_return(["#{subject.iid}-0-stable"]) expect(subject.related_branches(user)).to eq [] end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 7c40cfd8253..f5f7e82480e 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -34,8 +34,8 @@ describe Key, models: true do context 'when key was not updated during the last day' do before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). - and_return('000000') + allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) + .and_return('000000') end it 'enqueues a UseKeyWorker job' do @@ -46,8 +46,8 @@ describe Key, models: true do context 'when key was updated during the last day' do before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). - and_return(false) + allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) + .and_return(false) end it 'does not enqueue a UseKeyWorker job' do diff --git a/spec/models/lfs_objects_project_spec.rb b/spec/models/lfs_objects_project_spec.rb index a2031beeab2..7bc278e350f 100644 --- a/spec/models/lfs_objects_project_spec.rb +++ b/spec/models/lfs_objects_project_spec.rb @@ -18,8 +18,8 @@ describe LfsObjectsProject, models: true do describe '#update_project_statistics' do it 'updates project statistics when the object is added' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(project.id, [], [:lfs_objects_size]) subject.save! end @@ -27,8 +27,8 @@ describe LfsObjectsProject, models: true do it 'updates project statistics when the object is removed' do subject.save! - expect(ProjectCacheWorker).to receive(:perform_async). - with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(project.id, [], [:lfs_objects_size]) subject.destroy end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index c720cc9f2c2..ec17000d17a 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -83,8 +83,8 @@ describe Member, models: true do @accepted_invite_member = create(:project_member, :developer, project: project, invite_token: '1234', - invite_email: 'toto2@example.com'). - tap { |u| u.accept_invite!(accepted_invite_user) } + invite_email: 'toto2@example.com') + .tap { |u| u.accept_invite!(accepted_invite_user) } requested_user = create(:user).tap { |u| project.request_access(u) } @requested_member = project.requesters.find_by(user_id: requested_user.id) @@ -265,8 +265,8 @@ describe Member, models: true do expect(source.users).not_to include(user) expect(source.requesters.exists?(user_id: user)).to be_truthy - expect { described_class.add_user(source, user, :master) }. - to raise_error(Gitlab::Access::AccessDeniedError) + expect { described_class.add_user(source, user, :master) } + .to raise_error(Gitlab::Access::AccessDeniedError) expect(source.users.reload).not_to include(user) expect(source.requesters.reload.exists?(user_id: user)).to be_truthy diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index 370aeb9e0a9..4a8ea3b6893 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -33,8 +33,8 @@ describe GroupMember, models: true do it "sends email to user" do membership = build(:group_member) - allow(membership).to receive(:notification_service). - and_return(double('NotificationService').as_null_object) + allow(membership).to receive(:notification_service) + .and_return(double('NotificationService').as_null_object) expect(membership).to receive(:notification_service) membership.save @@ -44,8 +44,8 @@ describe GroupMember, models: true do describe "#after_update" do before do @group_member = create :group_member - allow(@group_member).to receive(:notification_service). - and_return(double('NotificationService').as_null_object) + allow(@group_member).to receive(:notification_service) + .and_return(double('NotificationService').as_null_object) end it "sends email to user" do diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index 1b7360257e8..6d599e148a2 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -84,8 +84,8 @@ describe MergeRequestDiff, models: true do end it 'saves overflow state' do - allow(Commit).to receive(:max_diff_options). - and_return(max_lines: 0, max_files: 0) + allow(Commit).to receive(:max_diff_options) + .and_return(max_lines: 0, max_files: 0) mr_diff = create(:merge_request).merge_request_diff @@ -93,8 +93,8 @@ describe MergeRequestDiff, models: true do end it 'saves empty state' do - allow_any_instance_of(MergeRequestDiff).to receive(:commits). - and_return([]) + allow_any_instance_of(MergeRequestDiff).to receive(:commits) + .and_return([]) mr_diff = create(:merge_request).merge_request_diff diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 810c08256dc..6a1f6cee03f 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -270,8 +270,8 @@ describe MergeRequest, models: true do end it 'accesses the set of issues that will be closed on acceptance' do - allow(subject.project).to receive(:default_branch). - and_return(subject.target_branch) + allow(subject.project).to receive(:default_branch) + .and_return(subject.target_branch) closed = subject.closes_issues @@ -297,8 +297,8 @@ describe MergeRequest, models: true do subject.description = "Is related to #{mentioned_issue.to_reference} and #{closing_issue.to_reference}" allow(subject).to receive(:commits).and_return([commit]) - allow(subject.project).to receive(:default_branch). - and_return(subject.target_branch) + allow(subject.project).to receive(:default_branch) + .and_return(subject.target_branch) expect(subject.issues_mentioned_but_not_closing(subject.author)).to match_array([mentioned_issue]) end @@ -412,15 +412,15 @@ describe MergeRequest, models: true do it 'includes merge information as the title' do request = build(:merge_request, source_branch: 'source', target_branch: 'target') - expect(request.merge_commit_message). - to match("Merge branch 'source' into 'target'\n\n") + expect(request.merge_commit_message) + .to match("Merge branch 'source' into 'target'\n\n") end it 'includes its title in the body' do request = build(:merge_request, title: 'Remove all technical debt') - expect(request.merge_commit_message). - to match("Remove all technical debt\n\n") + expect(request.merge_commit_message) + .to match("Remove all technical debt\n\n") end it 'includes its closed issues in the body' do @@ -429,18 +429,18 @@ describe MergeRequest, models: true do subject.project.team << [subject.author, :developer] subject.description = "This issue Closes #{issue.to_reference}" - allow(subject.project).to receive(:default_branch). - and_return(subject.target_branch) + allow(subject.project).to receive(:default_branch) + .and_return(subject.target_branch) - expect(subject.merge_commit_message). - to match("Closes #{issue.to_reference}") + expect(subject.merge_commit_message) + .to match("Closes #{issue.to_reference}") end it 'includes its reference in the body' do request = build_stubbed(:merge_request) - expect(request.merge_commit_message). - to match("See merge request #{request.to_reference}") + expect(request.merge_commit_message) + .to match("See merge request #{request.to_reference}") end it 'excludes multiple linebreak runs when description is blank' do @@ -452,15 +452,15 @@ describe MergeRequest, models: true do it 'includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message(include_description: true)). - to match("By removing all code\n\n") + expect(request.merge_commit_message(include_description: true)) + .to match("By removing all code\n\n") end it 'does not includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message). - not_to match("By removing all code\n\n") + expect(request.merge_commit_message) + .not_to match("By removing all code\n\n") end end @@ -551,18 +551,18 @@ describe MergeRequest, models: true do end it 'caches the output' do - expect(subject).to receive(:compute_diverged_commits_count). - once. - and_return(2) + expect(subject).to receive(:compute_diverged_commits_count) + .once + .and_return(2) subject.diverged_commits_count subject.diverged_commits_count end it 'invalidates the cache when the source sha changes' do - expect(subject).to receive(:compute_diverged_commits_count). - twice. - and_return(2) + expect(subject).to receive(:compute_diverged_commits_count) + .twice + .and_return(2) subject.diverged_commits_count allow(subject).to receive(:source_branch_sha).and_return('123abc') @@ -570,9 +570,9 @@ describe MergeRequest, models: true do end it 'invalidates the cache when the target sha changes' do - expect(subject).to receive(:compute_diverged_commits_count). - twice. - and_return(2) + expect(subject).to receive(:compute_diverged_commits_count) + .twice + .and_return(2) subject.diverged_commits_count allow(subject).to receive(:target_branch_sha).and_return('123abc') @@ -594,8 +594,8 @@ describe MergeRequest, models: true do describe '#commits_sha' do before do - allow(subject.merge_request_diff).to receive(:commits_sha). - and_return(['sha1']) + allow(subject.merge_request_diff).to receive(:commits_sha) + .and_return(['sha1']) end it 'delegates to merge request diff' do @@ -610,9 +610,9 @@ describe MergeRequest, models: true do allow(subject).to receive(:diff_head_sha).and_return('123abc') - expect(subject.source_project).to receive(:pipeline_for). - with('master', '123abc'). - and_return(pipeline) + expect(subject.source_project).to receive(:pipeline_for) + .with('master', '123abc') + .and_return(pipeline) expect(subject.head_pipeline).to eq(pipeline) end @@ -1632,8 +1632,8 @@ describe MergeRequest, models: true do describe '#has_commits?' do before do - allow(subject.merge_request_diff).to receive(:commits_count). - and_return(2) + allow(subject.merge_request_diff).to receive(:commits_count) + .and_return(2) end it 'returns true when merge request diff has commits' do @@ -1643,8 +1643,8 @@ describe MergeRequest, models: true do describe '#has_no_commits?' do before do - allow(subject.merge_request_diff).to receive(:commits_count). - and_return(0) + allow(subject.merge_request_diff).to receive(:commits_count) + .and_return(0) end it 'returns true when merge request diff has 0 commits' do diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 3cee2b7714f..0ffcbf7e3f6 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -205,13 +205,13 @@ describe Milestone, models: true do end it 'returns milestones with a partially matching description' do - expect(described_class.search(milestone.description[0..2])). - to eq([milestone]) + expect(described_class.search(milestone.description[0..2])) + .to eq([milestone]) end it 'returns milestones with a matching description regardless of the casing' do - expect(described_class.search(milestone.description.upcase)). - to eq([milestone]) + expect(described_class.search(milestone.description.upcase)) + .to eq([milestone]) end end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 35d932f1c64..74fbae07a6f 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -216,8 +216,8 @@ describe Namespace, models: true do describe '#user_ids_for_project_authorizations' do it 'returns the user IDs for which to refresh authorizations' do - expect(namespace.user_ids_for_project_authorizations). - to eq([namespace.owner_id]) + expect(namespace.user_ids_for_project_authorizations) + .to eq([namespace.owner_id]) end end end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index 1cde9e04951..973a0b9d592 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -148,8 +148,8 @@ describe Note, models: true do let!(:note2) { create(:note_on_issue) } it "reads the rendered note body from the cache" do - expect(Banzai::Renderer).to receive(:cache_collection_render). - with([{ + expect(Banzai::Renderer).to receive(:cache_collection_render) + .with([{ text: note1.note, context: { skip_project_check: false, @@ -160,8 +160,8 @@ describe Note, models: true do } }]).and_call_original - expect(Banzai::Renderer).to receive(:cache_collection_render). - with([{ + expect(Banzai::Renderer).to receive(:cache_collection_render) + .with([{ text: note2.note, context: { skip_project_check: false, @@ -361,8 +361,8 @@ describe Note, models: true do let(:note) { build(:note_on_project_snippet) } before do - expect(Banzai::Renderer).to receive(:cacheless_render_field). - with(note, :note, { skip_project_check: false }).and_return(html) + expect(Banzai::Renderer).to receive(:cacheless_render_field) + .with(note, :note, { skip_project_check: false }).and_return(html) note.save end @@ -376,8 +376,8 @@ describe Note, models: true do let(:note) { build(:note_on_personal_snippet) } before do - expect(Banzai::Renderer).to receive(:cacheless_render_field). - with(note, :note, { skip_project_check: true }).and_return(html) + expect(Banzai::Renderer).to receive(:cacheless_render_field) + .with(note, :note, { skip_project_check: true }).and_return(html) note.save end diff --git a/spec/models/project_authorization_spec.rb b/spec/models/project_authorization_spec.rb index 33ef67f97a7..4001851b9ec 100644 --- a/spec/models/project_authorization_spec.rb +++ b/spec/models/project_authorization_spec.rb @@ -7,8 +7,8 @@ describe ProjectAuthorization do describe '.insert_authorizations' do it 'inserts the authorizations' do - described_class. - insert_authorizations([[user.id, project1.id, Gitlab::Access::MASTER]]) + described_class + .insert_authorizations([[user.id, project1.id, Gitlab::Access::MASTER]]) expect(user.project_authorizations.count).to eq(1) end diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb index 5bfa9fffba9..f5596227c81 100644 --- a/spec/models/project_label_spec.rb +++ b/spec/models/project_label_spec.rb @@ -94,8 +94,8 @@ describe ProjectLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) }. - to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) } + .to raise_error StandardError, /Unknown format/ end end @@ -104,15 +104,15 @@ describe ProjectLabel, models: true do context 'using name' do it 'returns cross reference with label name' do - expect(label.to_reference(project, format: :name)). - to eq %(#{label.project.path_with_namespace}~"#{label.name}") + expect(label.to_reference(project, format: :name)) + .to eq %(#{label.project.path_with_namespace}~"#{label.name}") end end context 'using id' do it 'returns cross reference with label id' do - expect(label.to_reference(project, format: :id)). - to eq %(#{label.project.path_with_namespace}~#{label.id}) + expect(label.to_reference(project, format: :id)) + .to eq %(#{label.project.path_with_namespace}~#{label.id}) end end end diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb index 98f3d420c8a..0ee24ac1b5f 100644 --- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb +++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb @@ -11,8 +11,8 @@ describe MattermostSlashCommandsService, :models do before do Mattermost::Session.base_uri("http://mattermost.example.com") - allow_any_instance_of(Mattermost::Client).to receive(:with_session). - and_yield(Mattermost::Session.new(nil)) + allow_any_instance_of(Mattermost::Client).to receive(:with_session) + .and_yield(Mattermost::Session.new(nil)) end describe '#configure' do @@ -24,8 +24,8 @@ describe MattermostSlashCommandsService, :models do context 'the requests succeeds' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). - with(body: { + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') + .with(body: { team_id: 'abc', trigger: 'gitlab', url: 'http://trigger.url', @@ -36,8 +36,8 @@ describe MattermostSlashCommandsService, :models do description: "Perform common operations on: #{project.name_with_namespace}", display_name: "GitLab / #{project.name_with_namespace}", method: 'P', - username: 'GitLab' }.to_json). - to_return( + username: 'GitLab' }.to_json) + .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: { token: 'token' }.to_json @@ -57,8 +57,8 @@ describe MattermostSlashCommandsService, :models do context 'an error is received' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). - to_return( + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') + .to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { @@ -87,8 +87,8 @@ describe MattermostSlashCommandsService, :models do context 'the requests succeeds' do before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). - to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') + .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: ['list'].to_json @@ -102,8 +102,8 @@ describe MattermostSlashCommandsService, :models do context 'an error is received' do before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). - to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') + .to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index b0087a9e15d..66e0ea6d9a5 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1150,23 +1150,23 @@ describe Project, models: true do it 'renames a repository' do ns = project.namespace_dir - expect(gitlab_shell).to receive(:mv_repository). - ordered. - with(project.repository_storage_path, "#{ns}/foo", "#{ns}/#{project.path}"). - and_return(true) + expect(gitlab_shell).to receive(:mv_repository) + .ordered + .with(project.repository_storage_path, "#{ns}/foo", "#{ns}/#{project.path}") + .and_return(true) - expect(gitlab_shell).to receive(:mv_repository). - ordered. - with(project.repository_storage_path, "#{ns}/foo.wiki", "#{ns}/#{project.path}.wiki"). - and_return(true) + expect(gitlab_shell).to receive(:mv_repository) + .ordered + .with(project.repository_storage_path, "#{ns}/foo.wiki", "#{ns}/#{project.path}.wiki") + .and_return(true) - expect_any_instance_of(SystemHooksService). - to receive(:execute_hooks_for). - with(project, :rename) + expect_any_instance_of(SystemHooksService) + .to receive(:execute_hooks_for) + .with(project, :rename) - expect_any_instance_of(Gitlab::UploadsTransfer). - to receive(:rename_project). - with('foo', project.path, ns) + expect_any_instance_of(Gitlab::UploadsTransfer) + .to receive(:rename_project) + .with('foo', project.path, ns) expect(project).to receive(:expire_caches_before_rename) @@ -1191,13 +1191,13 @@ describe Project, models: true do let(:wiki) { double(:wiki, exists?: true) } it 'expires the caches of the repository and wiki' do - allow(Repository).to receive(:new). - with('foo', project). - and_return(repo) + allow(Repository).to receive(:new) + .with('foo', project) + .and_return(repo) - allow(Repository).to receive(:new). - with('foo.wiki', project). - and_return(wiki) + allow(Repository).to receive(:new) + .with('foo.wiki', project) + .and_return(wiki) expect(repo).to receive(:before_delete) expect(wiki).to receive(:before_delete) @@ -1248,9 +1248,9 @@ describe Project, models: true do context 'using a regular repository' do it 'creates the repository' do - expect(shell).to receive(:add_repository). - with(project.repository_storage_path, project.path_with_namespace). - and_return(true) + expect(shell).to receive(:add_repository) + .with(project.repository_storage_path, project.path_with_namespace) + .and_return(true) expect(project.repository).to receive(:after_create) @@ -1258,9 +1258,9 @@ describe Project, models: true do end it 'adds an error if the repository could not be created' do - expect(shell).to receive(:add_repository). - with(project.repository_storage_path, project.path_with_namespace). - and_return(false) + expect(shell).to receive(:add_repository) + .with(project.repository_storage_path, project.path_with_namespace) + .and_return(false) expect(project.repository).not_to receive(:after_create) @@ -1536,8 +1536,8 @@ describe Project, models: true do let(:project) { forked_project_link.forked_to_project } it 'schedules a RepositoryForkWorker job' do - expect(RepositoryForkWorker).to receive(:perform_async). - with(project.id, forked_from_project.repository_storage_path, + expect(RepositoryForkWorker).to receive(:perform_async) + .with(project.id, forked_from_project.repository_storage_path, forked_from_project.path_with_namespace, project.namespace.path) project.add_import_job diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index 58b57bd4fef..8c43937c398 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -143,15 +143,15 @@ describe ProjectWiki, models: true do describe '#find_file' do before do file = Gollum::File.new(subject.wiki) - allow_any_instance_of(Gollum::Wiki). - to receive(:file).with('image.jpg', 'master', true). - and_return(file) - allow_any_instance_of(Gollum::File). - to receive(:mime_type). - and_return('image/jpeg') - allow_any_instance_of(Gollum::Wiki). - to receive(:file).with('non-existant', 'master', true). - and_return(nil) + allow_any_instance_of(Gollum::Wiki) + .to receive(:file).with('image.jpg', 'master', true) + .and_return(file) + allow_any_instance_of(Gollum::File) + .to receive(:mime_type) + .and_return('image/jpeg') + allow_any_instance_of(Gollum::Wiki) + .to receive(:file).with('non-existant', 'master', true) + .and_return(nil) end after do @@ -253,9 +253,9 @@ describe ProjectWiki, models: true do describe '#create_repo!' do it 'creates a repository' do - expect(subject).to receive(:init_repo). - with(subject.path_with_namespace). - and_return(true) + expect(subject).to receive(:init_repo) + .with(subject.path_with_namespace) + .and_return(true) expect(subject.repository).to receive(:after_create) diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index a3fe412b229..dfa019d28b0 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -125,8 +125,8 @@ describe Repository, models: true do describe '#ref_name_for_sha' do context 'ref found' do it 'returns the ref' do - allow_any_instance_of(Gitlab::Popen).to receive(:popen). - and_return(["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0]) + allow_any_instance_of(Gitlab::Popen).to receive(:popen) + .and_return(["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0]) expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77' end @@ -134,8 +134,8 @@ describe Repository, models: true do context 'ref not found' do it 'returns nil' do - allow_any_instance_of(Gitlab::Popen).to receive(:popen). - and_return(["", 0]) + allow_any_instance_of(Gitlab::Popen).to receive(:popen) + .and_return(["", 0]) expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq nil end @@ -265,8 +265,8 @@ describe Repository, models: true do describe '#commit' do context 'when ref exists' do it 'returns commit object' do - expect(repository.commit('master')). - to be_an_instance_of Commit + expect(repository.commit('master')) + .to be_an_instance_of Commit end end @@ -596,8 +596,8 @@ describe Repository, models: true do user, 'LICENSE', 'Copyright!', message: 'Add LICENSE', branch_name: 'master', update: false) - allow(repository).to receive(:file_on_head). - and_raise(Rugged::ReferenceError) + allow(repository).to receive(:file_on_head) + .and_raise(Rugged::ReferenceError) expect(repository.license_blob).to be_nil end @@ -749,8 +749,8 @@ describe Repository, models: true do context 'when pre hooks were successful' do it 'runs without errors' do - expect_any_instance_of(GitHooksService).to receive(:execute). - with(user, project.repository.path_to_repo, old_rev, blank_sha, 'refs/heads/feature') + expect_any_instance_of(GitHooksService).to receive(:execute) + .with(user, project.repository.path_to_repo, old_rev, blank_sha, 'refs/heads/feature') expect { repository.rm_branch(user, 'feature') }.not_to raise_error end @@ -792,14 +792,14 @@ describe Repository, models: true do before do service = GitHooksService.new expect(GitHooksService).to receive(:new).and_return(service) - expect(service).to receive(:execute). - with( + expect(service).to receive(:execute) + .with( user, repository.path_to_repo, old_rev, new_rev, - 'refs/heads/feature'). - and_yield(service).and_return(true) + 'refs/heads/feature') + .and_yield(service).and_return(true) end it 'runs without errors' do @@ -893,8 +893,8 @@ describe Repository, models: true do expect(repository).not_to receive(:expire_emptiness_caches) expect(repository).to receive(:expire_branches_cache) - GitOperationService.new(user, repository). - with_branch('new-feature') do + GitOperationService.new(user, repository) + .with_branch('new-feature') do new_rev end end @@ -978,8 +978,8 @@ describe Repository, models: true do end it 'does nothing' do - expect(repository.raw_repository).not_to receive(:autocrlf=). - with(:input) + expect(repository.raw_repository).not_to receive(:autocrlf=) + .with(:input) GitOperationService.new(nil, repository).send(:update_autocrlf_option) end @@ -998,9 +998,9 @@ describe Repository, models: true do end it 'caches the output' do - expect(repository.raw_repository).to receive(:empty?). - once. - and_return(false) + expect(repository.raw_repository).to receive(:empty?) + .once + .and_return(false) repository.empty? repository.empty? @@ -1013,9 +1013,9 @@ describe Repository, models: true do end it 'caches the output' do - expect(repository.raw_repository).to receive(:root_ref). - once. - and_return('master') + expect(repository.raw_repository).to receive(:root_ref) + .once + .and_return('master') repository.root_ref repository.root_ref @@ -1026,9 +1026,9 @@ describe Repository, models: true do it 'expires the root reference cache' do repository.root_ref - expect(repository.raw_repository).to receive(:root_ref). - once. - and_return('foo') + expect(repository.raw_repository).to receive(:root_ref) + .once + .and_return('foo') repository.expire_root_ref_cache @@ -1042,17 +1042,17 @@ describe Repository, models: true do let(:cache) { repository.send(:cache) } it 'expires the cache for all branches' do - expect(cache).to receive(:expire). - at_least(repository.branches.length). - times + expect(cache).to receive(:expire) + .at_least(repository.branches.length) + .times repository.expire_branch_cache end it 'expires the cache for all branches when the root branch is given' do - expect(cache).to receive(:expire). - at_least(repository.branches.length). - times + expect(cache).to receive(:expire) + .at_least(repository.branches.length) + .times repository.expire_branch_cache(repository.root_ref) end @@ -1314,12 +1314,12 @@ describe Repository, models: true do describe '#after_push_commit' do it 'expires statistics caches' do - expect(repository).to receive(:expire_statistics_caches). - and_call_original + expect(repository).to receive(:expire_statistics_caches) + .and_call_original - expect(repository).to receive(:expire_branch_cache). - with('master'). - and_call_original + expect(repository).to receive(:expire_branch_cache) + .with('master') + .and_call_original repository.after_push_commit('master') end @@ -1394,9 +1394,9 @@ describe Repository, models: true do describe '#expire_branches_cache' do it 'expires the cache' do - expect(repository).to receive(:expire_method_caches). - with(%i(branch_names branch_count)). - and_call_original + expect(repository).to receive(:expire_method_caches) + .with(%i(branch_names branch_count)) + .and_call_original repository.expire_branches_cache end @@ -1404,9 +1404,9 @@ describe Repository, models: true do describe '#expire_tags_cache' do it 'expires the cache' do - expect(repository).to receive(:expire_method_caches). - with(%i(tag_names tag_count)). - and_call_original + expect(repository).to receive(:expire_method_caches) + .with(%i(tag_names tag_count)) + .and_call_original repository.expire_tags_cache end @@ -1417,11 +1417,11 @@ describe Repository, models: true do let(:user) { build_stubbed(:user) } it 'creates the tag using rugged' do - expect(repository.rugged.tags).to receive(:create). - with('8.5', repository.commit('master').id, + expect(repository.rugged.tags).to receive(:create) + .with('8.5', repository.commit('master').id, hash_including(message: 'foo', - tagger: hash_including(name: user.name, email: user.email))). - and_call_original + tagger: hash_including(name: user.name, email: user.email))) + .and_call_original repository.add_tag(user, '8.5', 'master', 'foo') end @@ -1438,8 +1438,8 @@ describe Repository, models: true do update_hook = Gitlab::Git::Hook.new('update', repository.path_to_repo) post_receive_hook = Gitlab::Git::Hook.new('post-receive', repository.path_to_repo) - allow(Gitlab::Git::Hook).to receive(:new). - and_return(pre_receive_hook, update_hook, post_receive_hook) + allow(Gitlab::Git::Hook).to receive(:new) + .and_return(pre_receive_hook, update_hook, post_receive_hook) allow(pre_receive_hook).to receive(:trigger).and_call_original allow(update_hook).to receive(:trigger).and_call_original @@ -1450,12 +1450,12 @@ describe Repository, models: true do commit_sha = repository.commit('master').id tag_sha = tag.target - expect(pre_receive_hook).to have_received(:trigger). - with(anything, anything, commit_sha, anything) - expect(update_hook).to have_received(:trigger). - with(anything, anything, commit_sha, anything) - expect(post_receive_hook).to have_received(:trigger). - with(anything, anything, tag_sha, anything) + expect(pre_receive_hook).to have_received(:trigger) + .with(anything, anything, commit_sha, anything) + expect(update_hook).to have_received(:trigger) + .with(anything, anything, commit_sha, anything) + expect(post_receive_hook).to have_received(:trigger) + .with(anything, anything, tag_sha, anything) end end @@ -1489,25 +1489,25 @@ describe Repository, models: true do describe '#avatar' do it 'returns nil if repo does not exist' do - expect(repository).to receive(:file_on_head). - and_raise(Rugged::ReferenceError) + expect(repository).to receive(:file_on_head) + .and_raise(Rugged::ReferenceError) expect(repository.avatar).to eq(nil) end it 'returns the first avatar file found in the repository' do - expect(repository).to receive(:file_on_head). - with(:avatar). - and_return(double(:tree, path: 'logo.png')) + expect(repository).to receive(:file_on_head) + .with(:avatar) + .and_return(double(:tree, path: 'logo.png')) expect(repository.avatar).to eq('logo.png') end it 'caches the output' do - expect(repository).to receive(:file_on_head). - with(:avatar). - once. - and_return(double(:tree, path: 'logo.png')) + expect(repository).to receive(:file_on_head) + .with(:avatar) + .once + .and_return(double(:tree, path: 'logo.png')) 2.times { expect(repository.avatar).to eq('logo.png') } end @@ -1567,24 +1567,24 @@ describe Repository, models: true do describe '#contribution_guide', caching: true do it 'returns and caches the output' do - expect(repository).to receive(:file_on_head). - with(:contributing). - and_return(Gitlab::Git::Tree.new(path: 'CONTRIBUTING.md')). - once + expect(repository).to receive(:file_on_head) + .with(:contributing) + .and_return(Gitlab::Git::Tree.new(path: 'CONTRIBUTING.md')) + .once 2.times do - expect(repository.contribution_guide). - to be_an_instance_of(Gitlab::Git::Tree) + expect(repository.contribution_guide) + .to be_an_instance_of(Gitlab::Git::Tree) end end end describe '#gitignore', caching: true do it 'returns and caches the output' do - expect(repository).to receive(:file_on_head). - with(:gitignore). - and_return(Gitlab::Git::Tree.new(path: '.gitignore')). - once + expect(repository).to receive(:file_on_head) + .with(:gitignore) + .and_return(Gitlab::Git::Tree.new(path: '.gitignore')) + .once 2.times do expect(repository.gitignore).to be_an_instance_of(Gitlab::Git::Tree) @@ -1594,10 +1594,10 @@ describe Repository, models: true do describe '#koding_yml', caching: true do it 'returns and caches the output' do - expect(repository).to receive(:file_on_head). - with(:koding). - and_return(Gitlab::Git::Tree.new(path: '.koding.yml')). - once + expect(repository).to receive(:file_on_head) + .with(:koding) + .and_return(Gitlab::Git::Tree.new(path: '.koding.yml')) + .once 2.times do expect(repository.koding_yml).to be_an_instance_of(Gitlab::Git::Tree) @@ -1623,8 +1623,8 @@ describe Repository, models: true do describe '#expire_statistics_caches' do it 'expires the caches' do - expect(repository).to receive(:expire_method_caches). - with(%i(size commit_count)) + expect(repository).to receive(:expire_method_caches) + .with(%i(size commit_count)) repository.expire_statistics_caches end @@ -1641,8 +1641,8 @@ describe Repository, models: true do describe '#expire_all_method_caches' do it 'expires the caches of all methods' do - expect(repository).to receive(:expire_method_caches). - with(Repository::CACHED_METHODS) + expect(repository).to receive(:expire_method_caches) + .with(Repository::CACHED_METHODS) repository.expire_all_method_caches end @@ -1667,8 +1667,8 @@ describe Repository, models: true do context 'with an existing repository' do it 'returns a Gitlab::Git::Tree' do - expect(repository.file_on_head(:readme)). - to be_an_instance_of(Gitlab::Git::Tree) + expect(repository.file_on_head(:readme)) + .to be_an_instance_of(Gitlab::Git::Tree) end end end @@ -1783,8 +1783,8 @@ describe Repository, models: true do describe '#refresh_method_caches' do it 'refreshes the caches of the given types' do - expect(repository).to receive(:expire_method_caches). - with(%i(readme license_blob license_key)) + expect(repository).to receive(:expire_method_caches) + .with(%i(readme license_blob license_key)) expect(repository).to receive(:readme) expect(repository).to receive(:license_blob) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 42029b15f4e..be9847f37b3 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -810,8 +810,8 @@ describe User, models: true do describe '.find_by_username!' do it 'raises RecordNotFound' do - expect { described_class.find_by_username!('JohnDoe') }. - to raise_error(ActiveRecord::RecordNotFound) + expect { described_class.find_by_username!('JohnDoe') } + .to raise_error(ActiveRecord::RecordNotFound) end it 'is case-insensitive' do @@ -1148,8 +1148,8 @@ describe User, models: true do user = create(:user) project = create(:empty_project, :private, namespace: user.namespace) - expect(user.authorized_projects(Gitlab::Access::REPORTER)). - to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)) + .to contain_exactly(project) end it 'includes projects for which the user is a master' do @@ -1158,8 +1158,8 @@ describe User, models: true do project.team << [user, Gitlab::Access::MASTER] - expect(user.authorized_projects(Gitlab::Access::REPORTER)). - to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)) + .to contain_exactly(project) end end @@ -1387,8 +1387,8 @@ describe User, models: true do end it 'returns the projects when using an ActiveRecord relation' do - projects = user. - projects_with_reporter_access_limited_to(Project.select(:id)) + projects = user + .projects_with_reporter_access_limited_to(Project.select(:id)) expect(projects).to eq([project1]) end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 753dc938c52..4a73552b8a6 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -61,8 +61,8 @@ describe WikiPage, models: true do actual_order = grouped_entries.map do |page_or_dir| get_slugs(page_or_dir) - end. - flatten + end + .flatten expect(actual_order).to eq(expected_order) end end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 0a5edf35f59..29315821ab7 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -80,8 +80,8 @@ describe ProjectPolicy, models: true do expect(project.team.member?(issue.author)).to eq(false) - expect(BasePolicy.class_for(project).abilities(user, project).can_set). - not_to include(:read_issue) + expect(BasePolicy.class_for(project).abilities(user, project).can_set) + .not_to include(:read_issue) expect(Ability.allowed?(user, :read_issue, project)).to be_falsy end diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index 7a35da38b2b..14290350c13 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -47,8 +47,8 @@ describe Ci::BuildPresenter do context 'when build is erased' do before do expect(presenter).to receive(:erased_by_user?).and_return(true) - expect(build).to receive(:erased_by). - and_return(double(:user, name: 'John Doe')) + expect(build).to receive(:erased_by) + .and_return(double(:user, name: 'John Doe')) end it 'returns the name of the eraser' do diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb index 576eb80605b..921d8714173 100644 --- a/spec/requests/api/broadcast_messages_spec.rb +++ b/spec/requests/api/broadcast_messages_spec.rb @@ -27,8 +27,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_kind_of(Array) - expect(json_response.first.keys). - to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.first.keys) + .to match_array(%w(id message starts_at ends_at color font active)) end end @@ -52,8 +52,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(json_response['id']).to eq message.id - expect(json_response.keys). - to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.keys) + .to match_array(%w(id message starts_at ends_at color font active)) end end @@ -174,8 +174,8 @@ describe API::BroadcastMessages, api: true do end it 'deletes the broadcast message for admins' do - expect { delete api("/broadcast_messages/#{message.id}", admin) }. - to change { BroadcastMessage.count }.by(-1) + expect { delete api("/broadcast_messages/#{message.id}", admin) } + .to change { BroadcastMessage.count }.by(-1) end end end diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index eface28976e..81a8856b8f1 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -207,8 +207,8 @@ describe API::CommitStatuses, api: true do it 'responds with bad request status and validation errors' do expect(response).to have_http_status(400) - expect(json_response['message']['target_url']). - to include 'must be a valid URL' + expect(json_response['message']['target_url']) + .to include 'must be a valid URL' end end end diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index a8ce0430401..b1380f660f9 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -127,8 +127,8 @@ describe API::Files, api: true do end it "returns a 400 if editor fails to create file" do - allow_any_instance_of(Repository).to receive(:commit_file). - and_return(false) + allow_any_instance_of(Repository).to receive(:commit_file) + .and_return(false) post api("/projects/#{project.id}/repository/files", user), valid_params diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index b82372b1b60..d13c67aa220 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -36,8 +36,8 @@ describe API::Groups, api: true do expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.length).to eq(1) - expect(json_response). - to satisfy_one { |group| group['name'] == group1.name } + expect(json_response) + .to satisfy_one { |group| group['name'] == group1.name } end it "does not include statistics" do @@ -84,8 +84,8 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response). - to satisfy_one { |group| group['statistics'] == attributes } + expect(json_response) + .to satisfy_one { |group| group['statistics'] == attributes } end end @@ -522,8 +522,8 @@ describe API::Groups, api: true do let(:project_path) { "#{project.namespace.path}%2F#{project.path}" } before(:each) do - allow_any_instance_of(Projects::TransferService). - to receive(:execute).and_return(true) + allow_any_instance_of(Projects::TransferService) + .to receive(:execute).and_return(true) end context "when authenticated as user" do diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index d1e765d1fdd..ffeacb15f17 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -74,8 +74,8 @@ describe API::Internal, api: true do context 'when two-factor is enabled' do it 'returns new recovery codes when the user exists' do allow_any_instance_of(User).to receive(:two_factor_enabled?).and_return(true) - allow_any_instance_of(User). - to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) + allow_any_instance_of(User) + .to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) post api('/internal/two_factor_recovery_codes'), secret_token: secret_token, diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index c125df8b90b..61b3906d134 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -426,8 +426,8 @@ describe API::MergeRequests, api: true do end it "returns 406 if branch can't be merged" do - allow_any_instance_of(MergeRequest). - to receive(:can_be_merged?).and_return(false) + allow_any_instance_of(MergeRequest) + .to receive(:can_be_merged?).and_return(false) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user) diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb index 3cca4468be7..5d5e57aa1ca 100644 --- a/spec/requests/api/notes_spec.rb +++ b/spec/requests/api/notes_spec.rb @@ -14,8 +14,8 @@ describe API::Notes, api: true do # For testing the cross-reference of a private issue in a public issue let(:private_user) { create(:user) } let(:private_project) do - create(:empty_project, namespace: private_user.namespace). - tap { |p| p.team << [private_user, :master] } + create(:empty_project, namespace: private_user.namespace) + .tap { |p| p.team << [private_user, :master] } end let(:private_issue) { create(:issue, project: private_project) } diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index da9df56401b..e79de9aacf2 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -80,23 +80,23 @@ describe API::ProjectSnippets, api: true do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) } + .to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } + .not_to change { Snippet.count } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end end end @@ -142,8 +142,8 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'creates the snippet' do - expect { update_snippet(title: 'Foo') }. - to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') } + .to change { snippet.reload.title }.to('Foo') end end @@ -151,13 +151,13 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo') }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') } + .to change { SpamLog.count }.by(1) end end @@ -165,16 +165,16 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .not_to change { snippet.reload.title } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 2f1181b2e8c..e78bc896ce8 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -263,15 +263,15 @@ describe API::Projects, api: true do context 'maximum number of projects reached' do it 'does not create new project and respond with 403' do allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0) - expect { post api('/projects', user2), name: 'foo' }. - to change {Project.count}.by(0) + expect { post api('/projects', user2), name: 'foo' } + .to change {Project.count}.by(0) expect(response).to have_http_status(403) end end it 'creates new project without path and return 201' do - expect { post api('/projects', user), name: 'foo' }. - to change { Project.count }.by(1) + expect { post api('/projects', user), name: 'foo' } + .to change { Project.count }.by(1) expect(response).to have_http_status(201) end @@ -406,8 +406,8 @@ describe API::Projects, api: true do end it 'responds with 400 on failure and not project' do - expect { post api("/projects/user/#{user.id}", admin) }. - not_to change { Project.count } + expect { post api("/projects/user/#{user.id}", admin) } + .not_to change { Project.count } expect(response).to have_http_status(400) expect(json_response['error']).to eq('name is missing') @@ -611,8 +611,8 @@ describe API::Projects, api: true do get api("/projects", user) expect(response).to have_http_status(200) - expect(json_response.first['permissions']['project_access']['access_level']). - to eq(Gitlab::Access::MASTER) + expect(json_response.first['permissions']['project_access']['access_level']) + .to eq(Gitlab::Access::MASTER) expect(json_response.first['permissions']['group_access']).to be_nil end end @@ -623,8 +623,8 @@ describe API::Projects, api: true do get api("/projects/#{project.id}", user) expect(response).to have_http_status(200) - expect(json_response['permissions']['project_access']['access_level']). - to eq(Gitlab::Access::MASTER) + expect(json_response['permissions']['project_access']['access_level']) + .to eq(Gitlab::Access::MASTER) expect(json_response['permissions']['group_access']).to be_nil end end @@ -639,8 +639,8 @@ describe API::Projects, api: true do expect(response).to have_http_status(200) expect(json_response['permissions']['project_access']).to be_nil - expect(json_response['permissions']['group_access']['access_level']). - to eq(Gitlab::Access::OWNER) + expect(json_response['permissions']['group_access']['access_level']) + .to eq(Gitlab::Access::OWNER) end end end diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 2e596f4197e..103d6755888 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -202,8 +202,8 @@ describe API::Runners, api: true do expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql') expect(shared_runner.run_untagged?).to be(false) expect(shared_runner.locked?).to be(true) - expect(shared_runner.ensure_runner_queue_value). - not_to eq(runner_queue_value) + expect(shared_runner.ensure_runner_queue_value) + .not_to eq(runner_queue_value) end end @@ -218,8 +218,8 @@ describe API::Runners, api: true do expect(response).to have_http_status(200) expect(specific_runner.description).to eq('test') expect(specific_runner.description).not_to eq(description) - expect(specific_runner.ensure_runner_queue_value). - not_to eq(runner_queue_value) + expect(specific_runner.ensure_runner_queue_value) + .not_to eq(runner_queue_value) end end diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index 41def7cd1d4..25cb75d8685 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -120,23 +120,23 @@ describe API::Snippets, api: true do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PRIVATE) } + .to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } + expect { create_snippet(visibility_level: Snippet::PUBLIC) } + .not_to change { Snippet.count } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end end end @@ -192,8 +192,8 @@ describe API::Snippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'updates the snippet' do - expect { update_snippet(title: 'Foo') }. - to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') } + .to change { snippet.reload.title }.to('Foo') end end @@ -201,16 +201,16 @@ describe API::Snippets, api: true do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo') }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') } + .not_to change { snippet.reload.title } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') } + .to change { SpamLog.count }.by(1) end end @@ -218,13 +218,13 @@ describe API::Snippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end end end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 603da9f49fc..b1bdf76d6b2 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -247,14 +247,14 @@ describe API::Users, api: true do bio: 'g' * 256, projects_limit: -1 expect(response).to have_http_status(400) - expect(json_response['message']['password']). - to eq(['is too short (minimum is 8 characters)']) - expect(json_response['message']['bio']). - to eq(['is too long (maximum is 255 characters)']) - expect(json_response['message']['projects_limit']). - to eq(['must be greater than or equal to 0']) - expect(json_response['message']['username']). - to eq([Gitlab::Regex.namespace_regex_message]) + expect(json_response['message']['password']) + .to eq(['is too short (minimum is 8 characters)']) + expect(json_response['message']['bio']) + .to eq(['is too long (maximum is 255 characters)']) + expect(json_response['message']['projects_limit']) + .to eq(['must be greater than or equal to 0']) + expect(json_response['message']['username']) + .to eq([Gitlab::Regex.namespace_regex_message]) end it "is not available for non admin users" do @@ -421,14 +421,14 @@ describe API::Users, api: true do bio: 'g' * 256, projects_limit: -1 expect(response).to have_http_status(400) - expect(json_response['message']['password']). - to eq(['is too short (minimum is 8 characters)']) - expect(json_response['message']['bio']). - to eq(['is too long (maximum is 255 characters)']) - expect(json_response['message']['projects_limit']). - to eq(['must be greater than or equal to 0']) - expect(json_response['message']['username']). - to eq([Gitlab::Regex.namespace_regex_message]) + expect(json_response['message']['password']) + .to eq(['is too short (minimum is 8 characters)']) + expect(json_response['message']['bio']) + .to eq(['is too long (maximum is 255 characters)']) + expect(json_response['message']['projects_limit']) + .to eq(['must be greater than or equal to 0']) + expect(json_response['message']['username']) + .to eq([Gitlab::Regex.namespace_regex_message]) end it 'returns 400 if provider is missing for identity update' do diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb index 4af05605ec6..2099e386c85 100644 --- a/spec/requests/api/v3/files_spec.rb +++ b/spec/requests/api/v3/files_spec.rb @@ -127,8 +127,8 @@ describe API::V3::Files, api: true do end it "returns a 400 if editor fails to create file" do - allow_any_instance_of(Repository).to receive(:commit_file). - and_return(false) + allow_any_instance_of(Repository).to receive(:commit_file) + .and_return(false) post v3_api("/projects/#{project.id}/repository/files", user), valid_params diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb index b94e1ef4ced..ce96ad0684f 100644 --- a/spec/requests/api/v3/merge_requests_spec.rb +++ b/spec/requests/api/v3/merge_requests_spec.rb @@ -413,8 +413,8 @@ describe API::MergeRequests, api: true do end it "returns 406 if branch can't be merged" do - allow_any_instance_of(MergeRequest). - to receive(:can_be_merged?).and_return(false) + allow_any_instance_of(MergeRequest) + .to receive(:can_be_merged?).and_return(false) put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user) diff --git a/spec/requests/api/v3/project_snippets_spec.rb b/spec/requests/api/v3/project_snippets_spec.rb index 957a3bf97ef..0b3b39ddaba 100644 --- a/spec/requests/api/v3/project_snippets_spec.rb +++ b/spec/requests/api/v3/project_snippets_spec.rb @@ -87,23 +87,23 @@ describe API::ProjectSnippets, api: true do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. - to change { Snippet.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) } + .to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - not_to change { Snippet.count } + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } + .not_to change { Snippet.count } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end end end @@ -149,8 +149,8 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'creates the snippet' do - expect { update_snippet(title: 'Foo') }. - to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') } + .to change { snippet.reload.title }.to('Foo') end end @@ -158,13 +158,13 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo') }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') } + .not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') } + .to change { SpamLog.count }.by(1) end end @@ -172,16 +172,16 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .not_to change { snippet.reload.title } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. - to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } + .to change { SpamLog.count }.by(1) end end end diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb index 36d99d80e79..fc7da939b34 100644 --- a/spec/requests/api/v3/projects_spec.rb +++ b/spec/requests/api/v3/projects_spec.rb @@ -303,15 +303,15 @@ describe API::V3::Projects, api: true do context 'maximum number of projects reached' do it 'does not create new project and respond with 403' do allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0) - expect { post v3_api('/projects', user2), name: 'foo' }. - to change {Project.count}.by(0) + expect { post v3_api('/projects', user2), name: 'foo' } + .to change {Project.count}.by(0) expect(response).to have_http_status(403) end end it 'creates new project without path and return 201' do - expect { post v3_api('/projects', user), name: 'foo' }. - to change { Project.count }.by(1) + expect { post v3_api('/projects', user), name: 'foo' } + .to change { Project.count }.by(1) expect(response).to have_http_status(201) end @@ -465,8 +465,8 @@ describe API::V3::Projects, api: true do end it 'responds with 400 on failure and not project' do - expect { post v3_api("/projects/user/#{user.id}", admin) }. - not_to change { Project.count } + expect { post v3_api("/projects/user/#{user.id}", admin) } + .not_to change { Project.count } expect(response).to have_http_status(400) expect(json_response['error']).to eq('name is missing') @@ -694,8 +694,8 @@ describe API::V3::Projects, api: true do get v3_api("/projects", user) expect(response).to have_http_status(200) - expect(json_response.first['permissions']['project_access']['access_level']). - to eq(Gitlab::Access::MASTER) + expect(json_response.first['permissions']['project_access']['access_level']) + .to eq(Gitlab::Access::MASTER) expect(json_response.first['permissions']['group_access']).to be_nil end end @@ -706,8 +706,8 @@ describe API::V3::Projects, api: true do get v3_api("/projects/#{project.id}", user) expect(response).to have_http_status(200) - expect(json_response['permissions']['project_access']['access_level']). - to eq(Gitlab::Access::MASTER) + expect(json_response['permissions']['project_access']['access_level']) + .to eq(Gitlab::Access::MASTER) expect(json_response['permissions']['group_access']).to be_nil end end @@ -722,8 +722,8 @@ describe API::V3::Projects, api: true do expect(response).to have_http_status(200) expect(json_response['permissions']['project_access']).to be_nil - expect(json_response['permissions']['group_access']['access_level']). - to eq(Gitlab::Access::OWNER) + expect(json_response['permissions']['group_access']['access_level']) + .to eq(Gitlab::Access::OWNER) end end end diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index 03b860ae54e..ecdcdb677f4 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -38,8 +38,8 @@ describe Ci::API::Builds do it 'gives 204 and set the same X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']). - to eq(last_update) + expect(response.header['X-GitLab-Last-Update']) + .to eq(last_update) end end @@ -49,8 +49,8 @@ describe Ci::API::Builds do it 'gives 204 and set a new X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']). - to eq(new_update) + expect(response.header['X-GitLab-Last-Update']) + .to eq(new_update) end end @@ -93,8 +93,8 @@ describe Ci::API::Builds do context 'when concurrently updating build' do before do - expect_any_instance_of(Ci::Build).to receive(:run!). - and_raise(ActiveRecord::StaleObjectError.new(nil, nil)) + expect_any_instance_of(Ci::Build).to receive(:run!) + .and_raise(ActiveRecord::StaleObjectError.new(nil, nil)) end it 'returns a conflict' do @@ -260,8 +260,8 @@ describe Ci::API::Builds do end it 'does not update runner info' do - expect { register_builds }. - not_to change { runner.reload.contacted_at } + expect { register_builds } + .not_to change { runner.reload.contacted_at } end end diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index 87786e85621..9adbcc3f814 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -389,8 +389,8 @@ describe 'Git HTTP requests', lib: true do shared_examples 'can download code only' do it 'downloads get status 200' do - allow_any_instance_of(Repository). - to receive(:exists?).and_return(true) + allow_any_instance_of(Repository) + .to receive(:exists?).and_return(true) clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token @@ -400,8 +400,8 @@ describe 'Git HTTP requests', lib: true do end it 'downloads from non-existing repository and gets 403' do - allow_any_instance_of(Repository). - to receive(:exists?).and_return(false) + allow_any_instance_of(Repository) + .to receive(:exists?).and_return(false) clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token diff --git a/spec/serializers/analytics_build_serializer_spec.rb b/spec/serializers/analytics_build_serializer_spec.rb index c8bad5ef105..e3b1dd93dc2 100644 --- a/spec/serializers/analytics_build_serializer_spec.rb +++ b/spec/serializers/analytics_build_serializer_spec.rb @@ -7,8 +7,8 @@ describe AnalyticsBuildSerializer do context 'when there is a single object provided' do it 'contains important elements of analyticsBuild' do - expect(subject). - to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) + expect(subject) + .to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) end end end diff --git a/spec/serializers/analytics_issue_serializer_spec.rb b/spec/serializers/analytics_issue_serializer_spec.rb index fe26b001740..2f08958a783 100644 --- a/spec/serializers/analytics_issue_serializer_spec.rb +++ b/spec/serializers/analytics_issue_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsIssueSerializer do subject do - described_class. - new(project: project, entity: :merge_request). - represent(resource) + described_class + .new(project: project, entity: :merge_request) + .represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_merge_request_serializer_spec.rb b/spec/serializers/analytics_merge_request_serializer_spec.rb index ee08762d237..62067cc0ef2 100644 --- a/spec/serializers/analytics_merge_request_serializer_spec.rb +++ b/spec/serializers/analytics_merge_request_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsMergeRequestSerializer do subject do - described_class. - new(project: project, entity: :merge_request). - represent(resource) + described_class + .new(project: project, entity: :merge_request) + .represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb index 3106af0ded7..5d7a94c2d02 100644 --- a/spec/serializers/analytics_summary_serializer_spec.rb +++ b/spec/serializers/analytics_summary_serializer_spec.rb @@ -9,13 +9,13 @@ describe AnalyticsSummarySerializer do let(:user) { create(:user) } let(:resource) do - Gitlab::CycleAnalytics::Summary::Issue. - new(project: double, from: 1.day.ago, current_user: user) + Gitlab::CycleAnalytics::Summary::Issue + .new(project: double, from: 1.day.ago, current_user: user) end before do - allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue). - to receive(:value).and_return(1.12) + allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue) + .to receive(:value).and_return(1.12) end it 'it generates payload for single object' do diff --git a/spec/serializers/build_artifact_entity_spec.rb b/spec/serializers/build_artifact_entity_spec.rb index 6ccea199376..2fc60aa9de6 100644 --- a/spec/serializers/build_artifact_entity_spec.rb +++ b/spec/serializers/build_artifact_entity_spec.rb @@ -15,8 +15,8 @@ describe BuildArtifactEntity do end it 'contains path to the artifacts' do - expect(subject[:path]). - to include "builds/#{build.id}/artifacts/download" + expect(subject[:path]) + .to include "builds/#{build.id}/artifacts/download" end end end diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index 895aeb30035..0333d73b5b5 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -42,8 +42,8 @@ describe CommitEntity do end it 'needs to receive project in the request' do - expect(request).to receive(:project). - and_return(project) + expect(request).to receive(:project) + .and_return(project) subject end diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb index 61b2fce8e8a..6a6df377b35 100644 --- a/spec/serializers/environment_serializer_spec.rb +++ b/spec/serializers/environment_serializer_spec.rb @@ -5,9 +5,9 @@ describe EnvironmentSerializer do let(:project) { create(:project) } let(:json) do - described_class. - new(user: user, project: project). - represent(resource) + described_class + .new(user: user, project: project) + .represent(resource) end context 'when there is a single object provided' do @@ -27,15 +27,15 @@ describe EnvironmentSerializer do let(:resource) { deployment.environment } it 'contains important elements of environment' do - expect(json). - to include(:name, :external_url, :environment_path, :last_deployment) + expect(json) + .to include(:name, :external_url, :environment_path, :last_deployment) end it 'contains relevant information about last deployment' do last_deployment = json.fetch(:last_deployment) - expect(last_deployment). - to include(:ref, :user, :commit, :deployable, :manual_actions) + expect(last_deployment) + .to include(:ref, :user, :commit, :deployable, :manual_actions) end end @@ -44,8 +44,8 @@ describe EnvironmentSerializer do let(:resource) { create_list(:environment, 2) } it 'contains important elements of environment' do - expect(json.first). - to include(:last_deployment, :name, :external_url) + expect(json.first) + .to include(:last_deployment, :name, :external_url) end it 'generates payload for collection' do @@ -122,13 +122,13 @@ describe EnvironmentSerializer do let(:pagination) { { page: 1, per_page: 2 } } let(:serializer) do - described_class.new(project: project). - with_pagination(request, response) + described_class.new(project: project) + .with_pagination(request, response) end before do - allow(request).to receive(:query_parameters). - and_return(pagination) + allow(request).to receive(:query_parameters) + .and_return(pagination) end subject { serializer.represent(resource) } @@ -164,9 +164,9 @@ describe EnvironmentSerializer do context 'when grouping environments within folders' do let(:serializer) do - described_class.new(project: project). - with_pagination(request, response). - within_folders + described_class.new(project: project) + .with_pagination(request, response) + .within_folders end before do diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb index 96ef1d3c071..ccb72973f9c 100644 --- a/spec/serializers/pipeline_entity_spec.rb +++ b/spec/serializers/pipeline_entity_spec.rb @@ -26,17 +26,17 @@ describe PipelineEntity do it 'contains details' do expect(subject).to include :details - expect(subject[:details]). - to include :duration, :finished_at - expect(subject[:details]). - to include :stages, :artifacts, :manual_actions + expect(subject[:details]) + .to include :duration, :finished_at + expect(subject[:details]) + .to include :stages, :artifacts, :manual_actions expect(subject[:details][:status]).to include :icon, :text, :label end it 'contains flags' do expect(subject).to include :flags - expect(subject[:flags]). - to include :latest, :triggered, :stuck, + expect(subject[:flags]) + .to include :latest, :triggered, :stuck, :yaml_errors, :retryable, :cancelable end end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 5f84a98f06d..2aaef03cb93 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -38,14 +38,14 @@ describe PipelineSerializer do let(:pagination) { {} } before do - allow(request). - to receive(:query_parameters). - and_return(pagination) + allow(request) + .to receive(:query_parameters) + .and_return(pagination) end let(:serializer) do - described_class.new(user: user). - with_pagination(request, response) + described_class.new(user: user) + .with_pagination(request, response) end it 'created a paginated serializer' do diff --git a/spec/serializers/request_aware_entity_spec.rb b/spec/serializers/request_aware_entity_spec.rb index 94dbf02aee8..aa666b961dc 100644 --- a/spec/serializers/request_aware_entity_spec.rb +++ b/spec/serializers/request_aware_entity_spec.rb @@ -14,8 +14,8 @@ describe RequestAwareEntity do end it 'fetches request from options' do - expect(subject).to receive(:options). - and_return({ request: 'some value' }) + expect(subject).to receive(:options) + .and_return({ request: 'some value' }) expect(subject.request).to eq 'some value' end diff --git a/spec/serializers/stage_entity_spec.rb b/spec/serializers/stage_entity_spec.rb index 42f19935453..4ab40d08432 100644 --- a/spec/serializers/stage_entity_spec.rb +++ b/spec/serializers/stage_entity_spec.rb @@ -35,13 +35,13 @@ describe StageEntity do end it 'contains path to the stage' do - expect(subject[:path]). - to include "pipelines/#{pipeline.id}##{stage.name}" + expect(subject[:path]) + .to include "pipelines/#{pipeline.id}##{stage.name}" end it 'contains path to the stage dropdown' do - expect(subject[:dropdown_path]). - to include "pipelines/#{pipeline.id}/stage.json?stage=test" + expect(subject[:dropdown_path]) + .to include "pipelines/#{pipeline.id}/stage.json?stage=test" end it 'contains stage title' do diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index ce691004178..ef2ddc4b1d7 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -284,14 +284,14 @@ describe Ci::ProcessPipelineService, :services do pipeline.builds.running_or_pending.each(&:success) - expect(builds.pluck(:name)). - to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)) + .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') pipeline.builds.find_by(name: 'test:1').success pipeline.builds.find_by(name: 'test:2').drop - expect(builds.pluck(:name)). - to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)) + .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') Ci::Build.retry(pipeline.builds.find_by(name: 'test:2'), user).success diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index 6499c7ad63e..d03f7505eac 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -61,8 +61,8 @@ describe Ci::RetryBuildService, :services do end it 'resolves todos for old build that failed' do - expect(MergeRequests::AddTodoWhenBuildFailsService). - to receive_message_chain(:new, :close) + expect(MergeRequests::AddTodoWhenBuildFailsService) + .to receive_message_chain(:new, :close) service.execute(build) end @@ -82,8 +82,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.execute(build) }. - to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(build) } + .to raise_error Gitlab::Access::AccessDeniedError end end end @@ -109,8 +109,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.reprocess(build) }. - to raise_error Gitlab::Access::AccessDeniedError + expect { service.reprocess(build) } + .to raise_error Gitlab::Access::AccessDeniedError end end end diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index 84915b5f1aa..c0af8b8450a 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -134,8 +134,8 @@ describe Ci::RetryPipelineService, '#execute', :services do end it 'closes all todos about failed jobs for pipeline' do - expect(MergeRequests::AddTodoWhenBuildFailsService). - to receive_message_chain(:new, :close_all) + expect(MergeRequests::AddTodoWhenBuildFailsService) + .to receive_message_chain(:new, :close_all) service.execute(pipeline) end @@ -149,8 +149,8 @@ describe Ci::RetryPipelineService, '#execute', :services do context 'when user is not allowed to retry pipeline' do it 'raises an error' do - expect { service.execute(pipeline) }. - to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(pipeline) } + .to raise_error Gitlab::Access::AccessDeniedError end end diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb index 23e0856fecd..560f83d94f7 100644 --- a/spec/services/ci/stop_environments_service_spec.rb +++ b/spec/services/ci/stop_environments_service_spec.rb @@ -44,8 +44,8 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment is not stopped' do before do - allow_any_instance_of(Environment). - to receive(:state).and_return(:stopped) + allow_any_instance_of(Environment) + .to receive(:state).and_return(:stopped) end it 'does not stop environment' do @@ -83,22 +83,22 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment does not exist' do it 'does not raise error' do - expect { service.execute('master') }. - not_to raise_error + expect { service.execute('master') } + .not_to raise_error end end end def expect_environment_stopped_on(branch) - expect_any_instance_of(Environment). - to receive(:stop!) + expect_any_instance_of(Environment) + .to receive(:stop!) service.execute(branch) end def expect_environment_not_stopped_on(branch) - expect_any_instance_of(Environment). - not_to receive(:stop!) + expect_any_instance_of(Environment) + .not_to receive(:stop!) service.execute(branch) end diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb index 14092d9dcca..f01a388b895 100644 --- a/spec/services/ci/update_build_queue_service_spec.rb +++ b/spec/services/ci/update_build_queue_service_spec.rb @@ -12,15 +12,15 @@ describe Ci::UpdateBuildQueueService, :services do before { build.project.runners << runner } it 'ticks runner queue value' do - expect { subject.execute(build) }. - to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .to change { runner.ensure_runner_queue_value } end end context 'when there are no runners that can pick build' do it 'does not tick runner queue value' do - expect { subject.execute(build) }. - not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .not_to change { runner.ensure_runner_queue_value } end end end @@ -30,8 +30,8 @@ describe Ci::UpdateBuildQueueService, :services do context 'when there are runner that can pick build' do it 'ticks runner queue value' do - expect { subject.execute(build) }. - to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .to change { runner.ensure_runner_queue_value } end end @@ -39,8 +39,8 @@ describe Ci::UpdateBuildQueueService, :services do before { build.tag_list = [:docker] } it 'does not tick runner queue value' do - expect { subject.execute(build) }. - not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .not_to change { runner.ensure_runner_queue_value } end end end diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb index 35e6e139238..3e0a0e95870 100644 --- a/spec/services/files/update_service_spec.rb +++ b/spec/services/files/update_service_spec.rb @@ -32,8 +32,8 @@ describe Files::UpdateService do let(:last_commit_sha) { "foo" } it "returns a hash with the correct error message and a :error status " do - expect { subject.execute }. - to raise_error(Files::UpdateService::FileChangedError, + expect { subject.execute } + .to raise_error(Files::UpdateService::FileChangedError, "You are attempting to update a file that has changed since you started editing it.") end end diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index 2a0f00ce937..d4fc4611bed 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -145,8 +145,8 @@ describe GitPushService, services: true do context "Updates merge requests" do it "when pushing a new branch for the first time" do - expect(UpdateMergeRequestsWorker).to receive(:perform_async). - with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master') + expect(UpdateMergeRequestsWorker).to receive(:perform_async) + .with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master') execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' ) end end @@ -263,8 +263,8 @@ describe GitPushService, services: true do author_email: commit_author.email ) - allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit). - and_return(commit) + allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) + .and_return(commit) allow(project.repository).to receive(:commits_between).and_return([commit]) end @@ -321,8 +321,8 @@ describe GitPushService, services: true do committed_date: commit_time ) - allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit). - and_return(commit) + allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) + .and_return(commit) allow(project.repository).to receive(:commits_between).and_return([commit]) end @@ -357,11 +357,11 @@ describe GitPushService, services: true do author_email: commit_author.email ) - allow(project.repository).to receive(:commits_between). - and_return([closing_commit]) + allow(project.repository).to receive(:commits_between) + .and_return([closing_commit]) - allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit). - and_return(closing_commit) + allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) + .and_return(closing_commit) project.team << [commit_author, :master] end @@ -383,8 +383,8 @@ describe GitPushService, services: true do end it "doesn't close issues when external issue tracker is in use" do - allow_any_instance_of(Project).to receive(:default_issues_tracker?). - and_return(false) + allow_any_instance_of(Project).to receive(:default_issues_tracker?) + .and_return(false) external_issue_tracker = double(title: 'My Tracker', issue_path: issue.iid, reference_pattern: project.issue_reference_pattern) allow_any_instance_of(Project).to receive(:external_issue_tracker).and_return(external_issue_tracker) @@ -577,13 +577,13 @@ describe GitPushService, services: true do commit = double(:commit) diff = double(:diff, new_path: 'README.md') - expect(commit).to receive(:raw_diffs).with(deltas_only: true). - and_return([diff]) + expect(commit).to receive(:raw_diffs).with(deltas_only: true) + .and_return([diff]) service.push_commits = [commit] - expect(ProjectCacheWorker).to receive(:perform_async). - with(project.id, %i(readme), %i(commit_count repository_size)) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(project.id, %i(readme), %i(commit_count repository_size)) service.update_caches end @@ -595,9 +595,9 @@ describe GitPushService, services: true do end it 'does not flush any conditional caches' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(project.id, [], %i(commit_count repository_size)). - and_call_original + expect(ProjectCacheWorker).to receive(:perform_async) + .with(project.id, [], %i(commit_count repository_size)) + .and_call_original service.update_caches end @@ -614,8 +614,8 @@ describe GitPushService, services: true do end it 'only schedules a limited number of commits' do - allow(service).to receive(:push_commits). - and_return(Array.new(1000, double(:commit, to_hash: {}))) + allow(service).to receive(:push_commits) + .and_return(Array.new(1000, double(:commit, to_hash: {}))) expect(ProcessCommitWorker).to receive(:perform_async).exactly(100).times diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb index 87da8581e68..0475f38fe5e 100644 --- a/spec/services/issuable/bulk_update_service_spec.rb +++ b/spec/services/issuable/bulk_update_service_spec.rb @@ -5,8 +5,8 @@ describe Issuable::BulkUpdateService, services: true do let(:project) { create(:empty_project, namespace: user.namespace) } def bulk_update(issues, extra_params = {}) - bulk_update_params = extra_params. - reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) + bulk_update_params = extra_params + .reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) Issuable::BulkUpdateService.new(project, user, bulk_update_params).execute('issue') end @@ -65,22 +65,22 @@ describe Issuable::BulkUpdateService, services: true do assignee = create(:user) project.team << [assignee, :developer] - expect { bulk_update(issue, assignee_id: assignee.id) }. - to change { issue.reload.assignee }.from(user).to(assignee) + expect { bulk_update(issue, assignee_id: assignee.id) } + .to change { issue.reload.assignee }.from(user).to(assignee) end end context "when the new assignee ID is #{IssuableFinder::NONE}" do it "unassigns the issues" do - expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) }. - to change { issue.reload.assignee }.to(nil) + expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) } + .to change { issue.reload.assignee }.to(nil) end end context 'when the new assignee ID is not present' do it 'does not unassign' do - expect { bulk_update(issue, assignee_id: nil) }. - not_to change { issue.reload.assignee } + expect { bulk_update(issue, assignee_id: nil) } + .not_to change { issue.reload.assignee } end end end @@ -97,8 +97,8 @@ describe Issuable::BulkUpdateService, services: true do end it 'updates the issue milestone' do - expect { bulk_update(issue, milestone_id: milestone.id) }. - to change { issue.reload.milestone }.from(nil).to(milestone) + expect { bulk_update(issue, milestone_id: milestone.id) } + .to change { issue.reload.milestone }.from(nil).to(milestone) end end diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index 7a54373963e..8f5bd4566ec 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -18,26 +18,26 @@ describe Issues::CloseService, services: true do let(:service) { described_class.new(project, user) } it 'checks if the user is authorized to update the issue' do - expect(service).to receive(:can?).with(user, :update_issue, issue). - and_call_original + expect(service).to receive(:can?).with(user, :update_issue, issue) + .and_call_original service.execute(issue) end it 'does not close the issue when the user is not authorized to do so' do - allow(service).to receive(:can?).with(user, :update_issue, issue). - and_return(false) + allow(service).to receive(:can?).with(user, :update_issue, issue) + .and_return(false) expect(service).not_to receive(:close_issue) expect(service.execute(issue)).to eq(issue) end it 'closes the issue when the user is authorized to do so' do - allow(service).to receive(:can?).with(user, :update_issue, issue). - and_return(true) + allow(service).to receive(:can?).with(user, :update_issue, issue) + .and_return(true) - expect(service).to receive(:close_issue). - with(issue, commit: nil, notifications: true, system_note: true) + expect(service).to receive(:close_issue) + .with(issue, commit: nil, notifications: true, system_note: true) service.execute(issue) end diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index 59c0fa50994..db196ed5751 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -188,8 +188,8 @@ describe Issues::MoveService, services: true do let(:new_note) { new_issue.notes.first } it 'rewrites references using a cross reference to old project' do - expect(new_note.note). - to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" + expect(new_note.note) + .to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" end end @@ -201,8 +201,8 @@ describe Issues::MoveService, services: true do it 'rewrites uploads in description' do expect(new_issue.description).not_to eq description - expect(new_issue.description). - to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) + expect(new_issue.description) + .to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) expect(new_issue.description).not_to include uploader.secret end end @@ -216,8 +216,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{another_issue.to_reference}" } it 'rewrites referenced issues creating cross project reference' do - expect(new_issue.description). - to eq "Some description #{another_issue.to_reference(new_project)}" + expect(new_issue.description) + .to eq "Some description #{another_issue.to_reference(new_project)}" end end @@ -226,8 +226,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{user.to_reference}" } it "doesn't throw any errors for issues containing user references" do - expect(new_issue.description). - to eq "Some description #{user.to_reference}" + expect(new_issue.description) + .to eq "Some description #{user.to_reference}" end end end @@ -236,8 +236,8 @@ describe Issues::MoveService, services: true do let(:new_project) { old_project } it 'raises error' do - expect { move_service.execute(old_issue, new_project) }. - to raise_error(StandardError, /Cannot move issue/) + expect { move_service.execute(old_issue, new_project) } + .to raise_error(StandardError, /Cannot move issue/) end end end diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb index 4b90ad19640..500afdfb916 100644 --- a/spec/services/labels/promote_service_spec.rb +++ b/spec/services/labels/promote_service_spec.rb @@ -66,9 +66,9 @@ describe Labels::PromoteService, services: true do end it 'recreates the label as a group label' do - expect { service.execute(project_label_1_1) }. - to change(project_1.labels, :count).by(-1). - and change(group_1.labels, :count).by(1) + expect { service.execute(project_label_1_1) } + .to change(project_1.labels, :count).by(-1) + .and change(group_1.labels, :count).by(1) expect(new_label).not_to be_nil end diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index 574df6e0f42..e6160e0ad42 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -104,8 +104,8 @@ describe Members::DestroyService, services: true do let(:params) { { id: project.members.find_by!(user_id: user.id).id } } it 'destroys the member' do - expect { described_class.new(project, user, params).execute }. - to change { project.members.count }.by(-1) + expect { described_class.new(project, user, params).execute } + .to change { project.members.count }.by(-1) end end end diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb index 881458c190f..d80fb8a1af1 100644 --- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb +++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb @@ -29,9 +29,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do end before do - allow_any_instance_of(MergeRequest). - to receive(:head_pipeline). - and_return(pipeline) + allow_any_instance_of(MergeRequest) + .to receive(:head_pipeline) + .and_return(pipeline) allow(service).to receive(:todo_service).and_return(todo_service) end @@ -113,9 +113,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'resolves todos about failed builds for pipeline' do service.close_all(pipeline) - expect(todo_service). - to have_received(:merge_request_build_retried). - with(merge_request) + expect(todo_service) + .to have_received(:merge_request_build_retried) + .with(merge_request) end end @@ -125,8 +125,8 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'does not resolve any todos about failed builds' do service.close_all(pipeline) - expect(todo_service). - not_to have_received(:merge_request_build_retried) + expect(todo_service) + .not_to have_received(:merge_request_build_retried) end end end diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb index d55a7657c0e..abc266b3aa7 100644 --- a/spec/services/merge_requests/close_service_spec.rb +++ b/spec/services/merge_requests/close_service_spec.rb @@ -30,8 +30,8 @@ describe MergeRequests::CloseService, services: true do it { expect(@merge_request).to be_closed } it 'executes hooks with close action' do - expect(service).to have_received(:execute_hooks). - with(@merge_request, 'close') + expect(service).to have_received(:execute_hooks) + .with(@merge_request, 'close') end it 'sends email to user2 about assign of new merge_request' do diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index d96f819e66a..1dcb4f6b3ee 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -139,9 +139,9 @@ describe MergeRequests::MergeService, services: true do end it 'removes the source branch' do - expect(DeleteBranchService).to receive(:new). - with(merge_request.source_project, merge_request.author). - and_call_original + expect(DeleteBranchService).to receive(:new) + .with(merge_request.source_project, merge_request.author) + .and_call_original service.execute(merge_request) end end diff --git a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb index 65c08ce15f7..f92978a33a3 100644 --- a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb @@ -27,9 +27,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do context 'first time enabling' do before do - allow(merge_request). - to receive(:head_pipeline). - and_return(pipeline) + allow(merge_request) + .to receive(:head_pipeline) + .and_return(pipeline) service.execute(merge_request) end @@ -52,11 +52,11 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) } before do - allow(mr_merge_if_green_enabled).to receive(:head_pipeline). - and_return(pipeline) + allow(mr_merge_if_green_enabled).to receive(:head_pipeline) + .and_return(pipeline) - allow(mr_merge_if_green_enabled).to receive(:mergeable?). - and_return(true) + allow(mr_merge_if_green_enabled).to receive(:mergeable?) + .and_return(true) allow(pipeline).to receive(:success?).and_return(true) end @@ -152,9 +152,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do before do # This behavior of MergeRequest: we instantiate a new object # - allow_any_instance_of(MergeRequest). - to receive(:head_pipeline). - and_wrap_original do + allow_any_instance_of(MergeRequest) + .to receive(:head_pipeline) + .and_wrap_original do Ci::Pipeline.find(pipeline.id) end end diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb index 983dac6efdb..af951588fc6 100644 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -56,8 +56,8 @@ describe MergeRequests::RefreshService, services: true do end it 'executes hooks with update action' do - expect(refresh_service).to have_received(:execute_hooks). - with(@merge_request, 'update', @oldrev) + expect(refresh_service).to have_received(:execute_hooks) + .with(@merge_request, 'update', @oldrev) end it { expect(@merge_request.notes).not_to be_empty } @@ -115,8 +115,8 @@ describe MergeRequests::RefreshService, services: true do end it 'executes hooks with update action' do - expect(refresh_service).to have_received(:execute_hooks). - with(@fork_merge_request, 'update', @oldrev) + expect(refresh_service).to have_received(:execute_hooks) + .with(@fork_merge_request, 'update', @oldrev) end it { expect(@merge_request.notes).to be_empty } @@ -191,8 +191,8 @@ describe MergeRequests::RefreshService, services: true do let(:refresh_service) { service.new(@fork_project, @user) } it 'refreshes the merge request' do - expect(refresh_service).to receive(:execute_hooks). - with(@fork_merge_request, 'update', Gitlab::Git::BLANK_SHA) + expect(refresh_service).to receive(:execute_hooks) + .with(@fork_merge_request, 'update', Gitlab::Git::BLANK_SHA) allow_any_instance_of(Repository).to receive(:merge_base).and_return(@oldrev) refresh_service.execute(Gitlab::Git::BLANK_SHA, @newrev, 'refs/heads/master') diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb index a99d4eac9bd..3fda94a8bc5 100644 --- a/spec/services/merge_requests/reopen_service_spec.rb +++ b/spec/services/merge_requests/reopen_service_spec.rb @@ -29,8 +29,8 @@ describe MergeRequests::ReopenService, services: true do it { expect(merge_request).to be_reopened } it 'executes hooks with reopen action' do - expect(service).to have_received(:execute_hooks). - with(merge_request, 'reopen') + expect(service).to have_received(:execute_hooks) + .with(merge_request, 'reopen') end it 'sends email to user2 about reopen of merge_request' do diff --git a/spec/services/merge_requests/resolve_service_spec.rb b/spec/services/merge_requests/resolve_service_spec.rb index a0e51681725..71e46969265 100644 --- a/spec/services/merge_requests/resolve_service_spec.rb +++ b/spec/services/merge_requests/resolve_service_spec.rb @@ -58,8 +58,8 @@ describe MergeRequests::ResolveService do end it 'creates a commit with the correct parents' do - expect(merge_request.source_branch_head.parents.map(&:id)). - to eq(['1450cd639e0bc6721eb02800169e464f212cde06', + expect(merge_request.source_branch_head.parents.map(&:id)) + .to eq(['1450cd639e0bc6721eb02800169e464f212cde06', '824be604a34828eb682305f0d963056cfac87b2d']) end end @@ -84,8 +84,8 @@ describe MergeRequests::ResolveService do end it 'creates a commit with the correct parents' do - expect(merge_request_from_fork.source_branch_head.parents.map(&:id)). - to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', + expect(merge_request_from_fork.source_branch_head.parents.map(&:id)) + .to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', target_head]) end end @@ -124,8 +124,8 @@ describe MergeRequests::ResolveService do end it 'creates a commit with the correct parents' do - expect(merge_request.source_branch_head.parents.map(&:id)). - to eq(['1450cd639e0bc6721eb02800169e464f212cde06', + expect(merge_request.source_branch_head.parents.map(&:id)) + .to eq(['1450cd639e0bc6721eb02800169e464f212cde06', '824be604a34828eb682305f0d963056cfac87b2d']) end @@ -158,8 +158,8 @@ describe MergeRequests::ResolveService do let(:service) { MergeRequests::ResolveService.new(project, user, invalid_params) } it 'raises a MissingResolution error' do - expect { service.execute(merge_request) }. - to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { service.execute(merge_request) } + .to raise_error(Gitlab::Conflict::File::MissingResolution) end end @@ -184,8 +184,8 @@ describe MergeRequests::ResolveService do let(:service) { MergeRequests::ResolveService.new(project, user, invalid_params) } it 'raises a MissingResolution error' do - expect { service.execute(merge_request) }. - to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { service.execute(merge_request) } + .to raise_error(Gitlab::Conflict::File::MissingResolution) end end @@ -206,8 +206,8 @@ describe MergeRequests::ResolveService do let(:service) { MergeRequests::ResolveService.new(project, user, invalid_params) } it 'raises a MissingFiles error' do - expect { service.execute(merge_request) }. - to raise_error(MergeRequests::ResolveService::MissingFiles) + expect { service.execute(merge_request) } + .to raise_error(MergeRequests::ResolveService::MissingFiles) end end end diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 7d73c0ea5d0..b67874ed4c3 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -68,8 +68,8 @@ describe MergeRequests::UpdateService, services: true do it { expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') } it 'executes hooks with update action' do - expect(service).to have_received(:execute_hooks). - with(@merge_request, 'update') + expect(service).to have_received(:execute_hooks) + .with(@merge_request, 'update') end it 'sends email to user2 about assign of new merge request and email to user3 about merge request unassignment' do @@ -171,8 +171,8 @@ describe MergeRequests::UpdateService, services: true do ref: merge_request.source_branch, sha: merge_request.diff_head_sha) - expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user). - and_return(service_mock) + expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user) + .and_return(service_mock) expect(service_mock).to receive(:execute).with(merge_request) end diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb index 57a5aa5cedc..471ba78714b 100644 --- a/spec/services/projects/housekeeping_service_spec.rb +++ b/spec/services/projects/housekeeping_service_spec.rb @@ -66,14 +66,14 @@ describe Projects::HousekeepingService do allow(subject).to receive(:lease_key).and_return(:the_lease_key) # At push 200 - expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid). - exactly(1).times + expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid) + .exactly(1).times # At push 50, 100, 150 - expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid). - exactly(3).times + expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid) + .exactly(3).times # At push 10, 20, ... (except those above) - expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid). - exactly(16).times + expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid) + .exactly(16).times 201.times do subject.increment! diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb index ab6e8f537ba..297837537a3 100644 --- a/spec/services/projects/import_service_spec.rb +++ b/spec/services/projects/import_service_spec.rb @@ -73,18 +73,18 @@ describe Projects::ImportService, services: true do end it 'flushes various caches' do - expect_any_instance_of(Gitlab::Shell).to receive(:import_repository). - with(project.repository_storage_path, project.path_with_namespace, project.import_url). - and_return(true) + expect_any_instance_of(Gitlab::Shell).to receive(:import_repository) + .with(project.repository_storage_path, project.path_with_namespace, project.import_url) + .and_return(true) - expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute). - and_return(true) + expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute) + .and_return(true) - expect_any_instance_of(Repository).to receive(:expire_emptiness_caches). - and_call_original + expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) + .and_call_original - expect_any_instance_of(Repository).to receive(:expire_exists_cache). - and_call_original + expect_any_instance_of(Repository).to receive(:expire_exists_cache) + .and_call_original subject.execute end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 5c6fbea8d0e..b6b7f94061e 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -7,10 +7,10 @@ describe Projects::TransferService, services: true do context 'namespace -> namespace' do before do - allow_any_instance_of(Gitlab::UploadsTransfer). - to receive(:move_project).and_return(true) - allow_any_instance_of(Gitlab::PagesTransfer). - to receive(:move_project).and_return(true) + allow_any_instance_of(Gitlab::UploadsTransfer) + .to receive(:move_project).and_return(true) + allow_any_instance_of(Gitlab::PagesTransfer) + .to receive(:move_project).and_return(true) group.add_owner(user) @result = transfer_project(project, user, group) end @@ -102,9 +102,9 @@ describe Projects::TransferService, services: true do end it 'only schedules a single job for every user' do - expect(UserProjectAccessChangedService).to receive(:new). - with([owner.id, group_member.id]). - and_call_original + expect(UserProjectAccessChangedService).to receive(:new) + .with([owner.id, group_member.id]) + .and_call_original transfer_project(project, owner, group) end diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb index 23f5555d3e0..d34652bd7ac 100644 --- a/spec/services/projects/unlink_fork_service_spec.rb +++ b/spec/services/projects/unlink_fork_service_spec.rb @@ -12,9 +12,9 @@ describe Projects::UnlinkForkService, services: true do let(:mr_close_service) { MergeRequests::CloseService.new(fork_project, user) } before do - allow(MergeRequests::CloseService).to receive(:new). - with(fork_project, user). - and_return(mr_close_service) + allow(MergeRequests::CloseService).to receive(:new) + .with(fork_project, user) + .and_return(mr_close_service) end it 'close all pending merge requests' do diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 7f027ae02a2..d7712804125 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -253,8 +253,8 @@ describe SystemNoteService, services: true do it_behaves_like 'a system note' it 'sets the note text' do - expect(subject.note). - to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**" + expect(subject.note) + .to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**" end end end @@ -388,8 +388,8 @@ describe SystemNoteService, services: true do context 'when mentioner is not a MergeRequest' do it 'is falsey' do mentioner = noteable.dup - expect(described_class.cross_reference_disallowed?(noteable, mentioner)). - to be_falsey + expect(described_class.cross_reference_disallowed?(noteable, mentioner)) + .to be_falsey end end @@ -399,14 +399,14 @@ describe SystemNoteService, services: true do it 'is truthy when noteable is in commits' do expect(mentioner).to receive(:commits).and_return([noteable]) - expect(described_class.cross_reference_disallowed?(noteable, mentioner)). - to be_truthy + expect(described_class.cross_reference_disallowed?(noteable, mentioner)) + .to be_truthy end it 'is falsey when noteable is not in commits' do expect(mentioner).to receive(:commits).and_return([]) - expect(described_class.cross_reference_disallowed?(noteable, mentioner)). - to be_falsey + expect(described_class.cross_reference_disallowed?(noteable, mentioner)) + .to be_falsey end end @@ -414,8 +414,8 @@ describe SystemNoteService, services: true do let(:noteable) { ExternalIssue.new('EXT-1234', project) } it 'is truthy' do mentioner = noteable.dup - expect(described_class.cross_reference_disallowed?(noteable, mentioner)). - to be_truthy + expect(described_class.cross_reference_disallowed?(noteable, mentioner)) + .to be_truthy end end @@ -425,13 +425,13 @@ describe SystemNoteService, services: true do it 'is truthy when issue is closed' do issue.close - expect(described_class.cross_reference_disallowed?(issue, project.commit)). - to be_truthy + expect(described_class.cross_reference_disallowed?(issue, project.commit)) + .to be_truthy end it 'is falsey when issue is open' do - expect(described_class.cross_reference_disallowed?(issue, project.commit)). - to be_falsy + expect(described_class.cross_reference_disallowed?(issue, project.commit)) + .to be_falsy end end @@ -441,20 +441,20 @@ describe SystemNoteService, services: true do it 'is truthy when merge request is closed' do allow(merge_request).to receive(:closed?).and_return(:true) - expect(described_class.cross_reference_disallowed?(merge_request, project.commit)). - to be_truthy + expect(described_class.cross_reference_disallowed?(merge_request, project.commit)) + .to be_truthy end it 'is truthy when merge request is merged' do allow(merge_request).to receive(:closed?).and_return(:true) - expect(described_class.cross_reference_disallowed?(merge_request, project.commit)). - to be_truthy + expect(described_class.cross_reference_disallowed?(merge_request, project.commit)) + .to be_truthy end it 'is falsey when merge request is open' do - expect(described_class.cross_reference_disallowed?(merge_request, project.commit)). - to be_falsy + expect(described_class.cross_reference_disallowed?(merge_request, project.commit)) + .to be_falsy end end end @@ -470,13 +470,13 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(noteable, commit0)). - to be_truthy + expect(described_class.cross_reference_exists?(noteable, commit0)) + .to be_truthy end it 'is falsey when not already mentioned' do - expect(described_class.cross_reference_exists?(noteable, commit1)). - to be_falsey + expect(described_class.cross_reference_exists?(noteable, commit1)) + .to be_falsey end context 'legacy capitalized cross reference' do @@ -487,8 +487,8 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(noteable, commit0)). - to be_truthy + expect(described_class.cross_reference_exists?(noteable, commit0)) + .to be_truthy end end end @@ -500,13 +500,13 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(commit0, commit1)). - to be_truthy + expect(described_class.cross_reference_exists?(commit0, commit1)) + .to be_truthy end it 'is falsey when not already mentioned' do - expect(described_class.cross_reference_exists?(commit1, commit0)). - to be_falsey + expect(described_class.cross_reference_exists?(commit1, commit0)) + .to be_falsey end context 'legacy capitalized cross reference' do @@ -517,8 +517,8 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(commit0, commit1)). - to be_truthy + expect(described_class.cross_reference_exists?(commit0, commit1)) + .to be_truthy end end end @@ -533,8 +533,8 @@ describe SystemNoteService, services: true do end it 'is true when a fork mentions an external issue' do - expect(described_class.cross_reference_exists?(noteable, commit2)). - to be true + expect(described_class.cross_reference_exists?(noteable, commit2)) + .to be true end context 'legacy capitalized cross reference' do @@ -544,8 +544,8 @@ describe SystemNoteService, services: true do end it 'is true when a fork mentions an external issue' do - expect(described_class.cross_reference_exists?(noteable, commit2)). - to be true + expect(described_class.cross_reference_exists?(noteable, commit2)) + .to be true end end end @@ -771,8 +771,8 @@ describe SystemNoteService, services: true do it 'creates a new note in the discussion' do # we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded. - expect { SystemNoteService.discussion_continued_in_issue(discussion, project, user, issue) }. - to change { reloaded_merge_request.discussions.first.notes.size }.by(1) + expect { SystemNoteService.discussion_continued_in_issue(discussion, project, user, issue) } + .to change { reloaded_merge_request.discussions.first.notes.size }.by(1) end it 'mentions the created issue in the system note' do diff --git a/spec/services/tags/create_service_spec.rb b/spec/services/tags/create_service_spec.rb index 5478b8c9ec0..4bb8a0ec290 100644 --- a/spec/services/tags/create_service_spec.rb +++ b/spec/services/tags/create_service_spec.rb @@ -26,9 +26,9 @@ describe Tags::CreateService, services: true do context 'when tag already exists' do it 'returns an error' do - expect(repository).to receive(:add_tag). - with(user, 'v1.1.0', 'master', 'Foo'). - and_raise(Rugged::TagError) + expect(repository).to receive(:add_tag) + .with(user, 'v1.1.0', 'master', 'Foo') + .and_raise(Rugged::TagError) response = service.execute('v1.1.0', 'master', 'Foo') @@ -39,9 +39,9 @@ describe Tags::CreateService, services: true do context 'when pre-receive hook fails' do it 'returns an error' do - expect(repository).to receive(:add_tag). - with(user, 'v1.1.0', 'master', 'Foo'). - and_raise(GitHooksService::PreReceiveError, 'something went wrong') + expect(repository).to receive(:add_tag) + .with(user, 'v1.1.0', 'master', 'Foo') + .and_raise(GitHooksService::PreReceiveError, 'something went wrong') response = service.execute('v1.1.0', 'master', 'Foo') diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 6dfcb702510..9f24cc0f3f2 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -768,15 +768,15 @@ describe TodoService, services: true do create(:todo, :mentioned, user: john_doe, target: issue, project: project) todos = TodosFinder.new(john_doe, {}).execute - expect { TodoService.new.mark_todos_as_done(todos, john_doe) }. - to change { john_doe.todos.done.count }.from(0).to(1) + expect { TodoService.new.mark_todos_as_done(todos, john_doe) } + .to change { john_doe.todos.done.count }.from(0).to(1) end it 'marks an array of todos as done' do todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project) - expect { TodoService.new.mark_todos_as_done([todo], john_doe) }. - to change { todo.reload.state }.from('pending').to('done') + expect { TodoService.new.mark_todos_as_done([todo], john_doe) } + .to change { todo.reload.state }.from('pending').to('done') end it 'returns the number of updated todos' do # Needed on API diff --git a/spec/services/user_project_access_changed_service_spec.rb b/spec/services/user_project_access_changed_service_spec.rb index b4efe7de431..14a5e40350a 100644 --- a/spec/services/user_project_access_changed_service_spec.rb +++ b/spec/services/user_project_access_changed_service_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe UserProjectAccessChangedService do describe '#execute' do it 'schedules the user IDs' do - expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait). - with([[1], [2]]) + expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait) + .with([[1], [2]]) described_class.new([1, 2]).execute end diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb index 690fe979492..0a527c7c5d1 100644 --- a/spec/services/users/refresh_authorized_projects_service_spec.rb +++ b/spec/services/users/refresh_authorized_projects_service_spec.rb @@ -6,17 +6,17 @@ describe Users::RefreshAuthorizedProjectsService do let(:service) { described_class.new(user) } def create_authorization(project, user, access_level = Gitlab::Access::MASTER) - ProjectAuthorization. - create!(project: project, user: user, access_level: access_level) + ProjectAuthorization + .create!(project: project, user: user, access_level: access_level) end describe '#execute', :redis do it 'refreshes the authorizations using a lease' do - expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). - and_return('foo') + expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) + .and_return('foo') - expect(Gitlab::ExclusiveLease).to receive(:cancel). - with(an_instance_of(String), 'foo') + expect(Gitlab::ExclusiveLease).to receive(:cancel) + .with(an_instance_of(String), 'foo') expect(service).to receive(:execute_without_lease) @@ -33,8 +33,8 @@ describe Users::RefreshAuthorizedProjectsService do project2 = create(:empty_project) to_remove = create_authorization(project2, user) - expect(service).to receive(:update_authorizations). - with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) + expect(service).to receive(:update_authorizations) + .with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) service.execute_without_lease end @@ -42,8 +42,8 @@ describe Users::RefreshAuthorizedProjectsService do it 'sets the access level of a project to the highest available level' do to_remove = create_authorization(project, user, Gitlab::Access::DEVELOPER) - expect(service).to receive(:update_authorizations). - with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) + expect(service).to receive(:update_authorizations) + .with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) service.execute_without_lease end diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index d0fd2d52004..c8f8d2d57b4 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -14,8 +14,8 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do it "updates access token" do token = 'asdfasdf9876' - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:user).and_return(true) + allow_any_instance_of(Gitlab::GithubImport::Client) + .to receive(:user).and_return(true) post :personal_access_token, personal_access_token: token @@ -79,8 +79,8 @@ shared_examples 'a GitHub-ish import controller: GET status' do end it "handles an invalid access token" do - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:repos).and_raise(Octokit::Unauthorized) + allow_any_instance_of(Gitlab::GithubImport::Client) + .to receive(:repos).and_raise(Octokit::Unauthorized) get :status @@ -110,9 +110,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do context "when the repository owner is the provider user" do context "when the provider user and GitLab user's usernames match" do it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, format: :js end @@ -122,9 +122,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do let(:provider_username) { "someone_else" } it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, format: :js end @@ -144,9 +144,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do context "when the namespace is owned by the GitLab user" do it "takes the existing namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, format: :js end @@ -159,9 +159,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do end it "creates a project using user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, format: :js end @@ -171,16 +171,16 @@ shared_examples 'a GitHub-ish import controller: POST create' do context "when a namespace with the provider user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).and_return(double(execute: true)) expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1) end it "takes the new namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider) + .and_return(double(execute: true)) post :create, target_namespace: provider_repo.name, format: :js end @@ -192,16 +192,16 @@ shared_examples 'a GitHub-ish import controller: POST create' do end it "doesn't create the namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.not_to change(Namespace, :count) end it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, format: :js end @@ -213,17 +213,17 @@ shared_examples 'a GitHub-ish import controller: POST create' do let(:test_name) { 'test_name' } it 'takes the selected namespace and name' do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js } end it 'takes the selected name and default namespace' do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider). - and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator) + .to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider) + .and_return(double(execute: true)) post :create, { new_name: test_name, format: :js } end diff --git a/spec/support/ldap_helpers.rb b/spec/support/ldap_helpers.rb index ab635711cf7..079f244475c 100644 --- a/spec/support/ldap_helpers.rb +++ b/spec/support/ldap_helpers.rb @@ -16,8 +16,8 @@ module LdapHelpers # ) def stub_ldap_config(messages) messages.each do |config, value| - allow_any_instance_of(::Gitlab::LDAP::Config). - to receive(config.to_sym).and_return(value) + allow_any_instance_of(::Gitlab::LDAP::Config) + .to receive(config.to_sym).and_return(value) end end @@ -32,8 +32,8 @@ module LdapHelpers def stub_ldap_person_find_by_uid(uid, entry, provider = 'ldapmain') return_value = ::Gitlab::LDAP::Person.new(entry, provider) if entry.present? - allow(::Gitlab::LDAP::Person). - to receive(:find_by_uid).with(uid, any_args).and_return(return_value) + allow(::Gitlab::LDAP::Person) + .to receive(:find_by_uid).with(uid, any_args).and_return(return_value) end # Create a simple LDAP user entry. diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb index 87936bb4859..3ac201f1fb1 100644 --- a/spec/support/mentionable_shared_examples.rb +++ b/spec/support/mentionable_shared_examples.rb @@ -81,8 +81,8 @@ shared_examples 'a mentionable' do ext_issue, ext_mr, ext_commit] mentioned_objects.each do |referenced| - expect(SystemNoteService).to receive(:cross_reference). - with(referenced, subject.local_reference, author) + expect(SystemNoteService).to receive(:cross_reference) + .with(referenced, subject.local_reference, author) end subject.create_cross_references! @@ -127,15 +127,15 @@ shared_examples 'an editable mentionable' do # These three objects were already referenced, and should not receive new # notes [mentioned_issue, mentioned_commit, ext_issue].each do |oldref| - expect(SystemNoteService).not_to receive(:cross_reference). - with(oldref, any_args) + expect(SystemNoteService).not_to receive(:cross_reference) + .with(oldref, any_args) end # These two issues are new and should receive reference notes # In the case of MergeRequests remember that cannot mention commits included in the MergeRequest new_issues.each do |newref| - expect(SystemNoteService).to receive(:cross_reference). - with(newref, subject.local_reference, author) + expect(SystemNoteService).to receive(:cross_reference) + .with(newref, subject.local_reference, author) end set_mentionable_text.call(new_text) diff --git a/spec/support/reactive_caching_helpers.rb b/spec/support/reactive_caching_helpers.rb index 98eb57f8b54..34124f02133 100644 --- a/spec/support/reactive_caching_helpers.rb +++ b/spec/support/reactive_caching_helpers.rb @@ -35,8 +35,8 @@ module ReactiveCachingHelpers end def expect_reactive_cache_update_queued(subject) - expect(ReactiveCachingWorker). - to receive(:perform_in). - with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) + expect(ReactiveCachingWorker) + .to receive(:perform_in) + .with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) end end diff --git a/spec/support/services_shared_context.rb b/spec/support/services_shared_context.rb index 66c93890e31..7457484a932 100644 --- a/spec/support/services_shared_context.rb +++ b/spec/support/services_shared_context.rb @@ -6,9 +6,9 @@ Service.available_services_names.each do |service| let(:service_fields) { service_klass.new.fields } let(:service_attrs_list) { service_fields.inject([]) {|arr, hash| arr << hash[:name].to_sym } } let(:service_attrs_list_without_passwords) do - service_fields. - select { |field| field[:type] != 'password' }. - map { |field| field[:name].to_sym} + service_fields + .select { |field| field[:type] != 'password' } + .map { |field| field[:name].to_sym} end let(:service_attrs) do service_attrs_list.inject({}) do |hash, k| diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb index 704922b6cf4..e18b79c89d1 100644 --- a/spec/support/slack_mattermost_notifications_shared_examples.rb +++ b/spec/support/slack_mattermost_notifications_shared_examples.rb @@ -104,9 +104,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it 'uses the username as an option for slack when configured' do allow(chat_service).to receive(:username).and_return(username) - expect(Slack::Notifier).to receive(:new). - with(webhook_url, username: username). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, username: username) + .and_return( double(:slack_service).as_null_object ) @@ -115,9 +115,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it 'uses the channel as an option when it is configured' do allow(chat_service).to receive(:channel).and_return(channel) - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: channel). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, channel: channel) + .and_return( double(:slack_service).as_null_object ) chat_service.execute(push_sample_data) @@ -127,9 +127,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for push event" do chat_service.update_attributes(push_channel: "random") - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, channel: "random") + .and_return( double(:slack_service).as_null_object ) @@ -139,9 +139,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for merge request event" do chat_service.update_attributes(merge_request_channel: "random") - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, channel: "random") + .and_return( double(:slack_service).as_null_object ) @@ -151,9 +151,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for issue event" do chat_service.update_attributes(issue_channel: "random") - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, channel: "random") + .and_return( double(:slack_service).as_null_object ) @@ -163,9 +163,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for wiki event" do chat_service.update_attributes(wiki_page_channel: "random") - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, channel: "random") + .and_return( double(:slack_service).as_null_object ) @@ -182,9 +182,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do note_data = Gitlab::DataBuilder::Note.build(issue_note, user) - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: "random"). - and_return( + expect(Slack::Notifier).to receive(:new) + .with(webhook_url, channel: "random") + .and_return( double(:slack_service).as_null_object ) diff --git a/spec/support/stub_configuration.rb b/spec/support/stub_configuration.rb index f40ee862df8..a04714622fc 100644 --- a/spec/support/stub_configuration.rb +++ b/spec/support/stub_configuration.rb @@ -5,8 +5,8 @@ module StubConfiguration # Stubbing both of these because we're not yet consistent with how we access # current application settings allow_any_instance_of(ApplicationSetting).to receive_messages(messages) - allow(Gitlab::CurrentSettings.current_application_settings). - to receive_messages(messages) + allow(Gitlab::CurrentSettings.current_application_settings) + .to receive_messages(messages) end def stub_config_setting(messages) diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index a01ef576234..641b11d51bf 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -51,22 +51,22 @@ module StubGitlabCalls def stub_session f = File.read(Rails.root.join('spec/support/gitlab_stubs/session.json')) - stub_request(:post, "#{gitlab_url}api/v3/session.json"). - with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}", - headers: { 'Content-Type' => 'application/json' }). - to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:post, "#{gitlab_url}api/v3/session.json") + .with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}", + headers: { 'Content-Type' => 'application/json' }) + .to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' }) end def stub_user f = File.read(Rails.root.join('spec/support/gitlab_stubs/user.json')) - stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz"). - with(headers: { 'Content-Type' => 'application/json' }). - to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz") + .with(headers: { 'Content-Type' => 'application/json' }) + .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) - stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token"). - with(headers: { 'Content-Type' => 'application/json' }). - to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token") + .with(headers: { 'Content-Type' => 'application/json' }) + .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) end def stub_project_8 @@ -82,21 +82,21 @@ module StubGitlabCalls def stub_projects f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json')) - stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz"). - with(headers: { 'Content-Type' => 'application/json' }). - to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz") + .with(headers: { 'Content-Type' => 'application/json' }) + .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) end def stub_projects_owned - stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz"). - with(headers: { 'Content-Type' => 'application/json' }). - to_return(status: 200, body: "", headers: {}) + stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz") + .with(headers: { 'Content-Type' => 'application/json' }) + .to_return(status: 200, body: "", headers: {}) end def stub_ci_enable - stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz"). - with(headers: { 'Content-Type' => 'application/json' }). - to_return(status: 200, body: "", headers: {}) + stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz") + .with(headers: { 'Content-Type' => 'application/json' }) + .to_return(status: 200, body: "", headers: {}) end def project_hash_array diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index 4e63a4cd537..21ff688f6dd 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -74,13 +74,13 @@ module TestEnv end def disable_mailer - allow_any_instance_of(NotificationService).to receive(:mailer). - and_return(double.as_null_object) + allow_any_instance_of(NotificationService).to receive(:mailer) + .and_return(double.as_null_object) end def enable_mailer - allow_any_instance_of(NotificationService).to receive(:mailer). - and_call_original + allow_any_instance_of(NotificationService).to receive(:mailer) + .and_call_original end def disable_pre_receive diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index df8a47893f9..85c34a00b11 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -47,24 +47,24 @@ describe 'gitlab:app namespace rake task' do allow(Kernel).to receive(:system).and_return(true) allow(FileUtils).to receive(:cp_r).and_return(true) allow(FileUtils).to receive(:mv).and_return(true) - allow(Rake::Task["gitlab:shell:setup"]). - to receive(:invoke).and_return(true) + allow(Rake::Task["gitlab:shell:setup"]) + .to receive(:invoke).and_return(true) ENV['force'] = 'yes' end let(:gitlab_version) { Gitlab::VERSION } it 'fails on mismatch' do - allow(YAML).to receive(:load_file). - and_return({ gitlab_version: "not #{gitlab_version}" }) + allow(YAML).to receive(:load_file) + .and_return({ gitlab_version: "not #{gitlab_version}" }) - expect { run_rake_task('gitlab:backup:restore') }. - to raise_error(SystemExit) + expect { run_rake_task('gitlab:backup:restore') } + .to raise_error(SystemExit) end it 'invokes restoration on match' do - allow(YAML).to receive(:load_file). - and_return({ gitlab_version: gitlab_version }) + allow(YAML).to receive(:load_file) + .and_return({ gitlab_version: gitlab_version }) expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke) expect(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke) expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke) @@ -320,8 +320,8 @@ describe 'gitlab:app namespace rake task' do end it 'does not invoke repositories restore' do - allow(Rake::Task['gitlab:shell:setup']). - to receive(:invoke).and_return(true) + allow(Rake::Task['gitlab:shell:setup']) + .to receive(:invoke).and_return(true) allow($stdout).to receive :write expect(Rake::Task['gitlab:db:drop_tables']).to receive :invoke diff --git a/spec/tasks/gitlab/check_rake_spec.rb b/spec/tasks/gitlab/check_rake_spec.rb index a808ef7dcc0..538ff952bf4 100644 --- a/spec/tasks/gitlab/check_rake_spec.rb +++ b/spec/tasks/gitlab/check_rake_spec.rb @@ -23,8 +23,8 @@ describe 'gitlab:ldap:check rake task' do let(:adapter) { ldap_adapter('ldapmain', ldap) } before do - allow(Gitlab::LDAP::Config). - to receive_messages( + allow(Gitlab::LDAP::Config) + .to receive_messages( enabled?: true, providers: ['ldapmain'] ) diff --git a/spec/tasks/gitlab/shell_rake_spec.rb b/spec/tasks/gitlab/shell_rake_spec.rb index 0787894ad2c..226d34fe2c9 100644 --- a/spec/tasks/gitlab/shell_rake_spec.rb +++ b/spec/tasks/gitlab/shell_rake_spec.rb @@ -17,8 +17,8 @@ describe 'gitlab:shell rake tasks' do describe 'create_hooks task' do it 'calls gitlab-shell bin/create_hooks' do - expect_any_instance_of(Object).to receive(:system). - with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) + expect_any_instance_of(Object).to receive(:system) + .with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) run_rake_task('gitlab:shell:create_hooks') end diff --git a/spec/tasks/gitlab/task_helpers_spec.rb b/spec/tasks/gitlab/task_helpers_spec.rb index 86e42d845ce..528fdbaaa74 100644 --- a/spec/tasks/gitlab/task_helpers_spec.rb +++ b/spec/tasks/gitlab/task_helpers_spec.rb @@ -41,8 +41,8 @@ describe Gitlab::TaskHelpers do describe '#clone_repo' do it 'clones the repo in the target dir' do - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{clone_path}]) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{clone_path}]) subject.clone_repo(repo, clone_path) end @@ -50,10 +50,10 @@ describe Gitlab::TaskHelpers do describe '#checkout_tag' do it 'clones the repo in the target dir' do - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --tags --quiet]) - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}]) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --tags --quiet]) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}]) subject.checkout_tag(tag, clone_path) end @@ -62,21 +62,21 @@ describe Gitlab::TaskHelpers do describe '#reset_to_tag' do let(:tag) { 'v1.1.0' } before do - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}]) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}]) end context 'when the tag is not checked out locally' do before do - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_raise(Gitlab::TaskFailedError) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_raise(Gitlab::TaskFailedError) end it 'fetch origin, ensure the tag exists, and resets --hard to the given tag' do - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch origin]) - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- origin/#{tag}]).and_return(tag) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch origin]) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- origin/#{tag}]).and_return(tag) subject.reset_to_tag(tag, clone_path) end @@ -84,8 +84,8 @@ describe Gitlab::TaskHelpers do context 'when the tag is checked out locally' do before do - expect(subject). - to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_return(tag) + expect(subject) + .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_return(tag) end it 'resets --hard to the given tag' do diff --git a/spec/tasks/gitlab/workhorse_rake_spec.rb b/spec/tasks/gitlab/workhorse_rake_spec.rb index 6de66c3cf07..da4b408023c 100644 --- a/spec/tasks/gitlab/workhorse_rake_spec.rb +++ b/spec/tasks/gitlab/workhorse_rake_spec.rb @@ -23,8 +23,8 @@ describe 'gitlab:workhorse namespace rake task' do context 'when an underlying Git command fail' do it 'aborts and display a help message' do - expect_any_instance_of(Object). - to receive(:checkout_or_clone_tag).and_raise 'Git error' + expect_any_instance_of(Object) + .to receive(:checkout_or_clone_tag).and_raise 'Git error' expect { run_rake_task('gitlab:workhorse:install', clone_path) }.to raise_error 'Git error' end @@ -36,8 +36,8 @@ describe 'gitlab:workhorse namespace rake task' do end it 'calls checkout_or_clone_tag with the right arguments' do - expect_any_instance_of(Object). - to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path) + expect_any_instance_of(Object) + .to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path) run_rake_task('gitlab:workhorse:install', clone_path) end diff --git a/spec/views/devise/shared/_signin_box.html.haml_spec.rb b/spec/views/devise/shared/_signin_box.html.haml_spec.rb index 1397bfa5864..9adbb0476be 100644 --- a/spec/views/devise/shared/_signin_box.html.haml_spec.rb +++ b/spec/views/devise/shared/_signin_box.html.haml_spec.rb @@ -31,7 +31,7 @@ describe 'devise/shared/_signin_box' do def enable_crowd allow(view).to receive(:form_based_providers).and_return([:crowd]) allow(view).to receive(:crowd_enabled?).and_return(true) - allow(view).to receive(:omniauth_authorize_path).with(:user, :crowd). - and_return('/crowd') + allow(view).to receive(:omniauth_authorize_path).with(:user, :crowd) + .and_return('/crowd') end end diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb index 254672a5612..8020faa1f9c 100644 --- a/spec/views/layouts/_head.html.haml_spec.rb +++ b/spec/views/layouts/_head.html.haml_spec.rb @@ -26,7 +26,7 @@ describe 'layouts/_head' do end def stub_helper_with_safe_string(method) - allow_any_instance_of(PageLayoutHelper).to receive(method). - and_return(%q{foo" http-equiv="refresh}.html_safe) + allow_any_instance_of(PageLayoutHelper).to receive(method) + .and_return(%q{foo" http-equiv="refresh}.html_safe) end end diff --git a/spec/views/projects/merge_requests/edit.html.haml_spec.rb b/spec/views/projects/merge_requests/edit.html.haml_spec.rb index 2e4390d6797..3650b22c389 100644 --- a/spec/views/projects/merge_requests/edit.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/edit.html.haml_spec.rb @@ -23,8 +23,8 @@ describe 'projects/merge_requests/edit.html.haml' do assign(:merge_request, closed_merge_request) allow(view).to receive(:can?).and_return(true) - allow(view).to receive(:current_user). - and_return(User.find(closed_merge_request.author_id)) + allow(view).to receive(:current_user) + .and_return(User.find(closed_merge_request.author_id)) end context 'when a merge request without fork' do diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index 8ebf00374a1..ba20488f663 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildCoverageWorker do let!(:build) { create(:ci_build) } it 'updates code coverage' do - expect_any_instance_of(Ci::Build). - to receive(:update_coverage) + expect_any_instance_of(Ci::Build) + .to receive(:update_coverage) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildCoverageWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index f8119913116..2868167c7d4 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -6,15 +6,15 @@ describe BuildFinishedWorker do let(:build) { create(:ci_build) } it 'calculates coverage and calls hooks' do - expect(BuildCoverageWorker). - to receive(:new).ordered.and_call_original - expect(BuildHooksWorker). - to receive(:new).ordered.and_call_original + expect(BuildCoverageWorker) + .to receive(:new).ordered.and_call_original + expect(BuildHooksWorker) + .to receive(:new).ordered.and_call_original - expect_any_instance_of(BuildCoverageWorker). - to receive(:perform) - expect_any_instance_of(BuildHooksWorker). - to receive(:perform) + expect_any_instance_of(BuildCoverageWorker) + .to receive(:perform) + expect_any_instance_of(BuildHooksWorker) + .to receive(:perform) described_class.new.perform(build.id) end @@ -22,8 +22,8 @@ describe BuildFinishedWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index 51abc1d89a1..97654a93f5c 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildHooksWorker do let!(:build) { create(:ci_build) } it 'calls build hooks' do - expect_any_instance_of(Ci::Build). - to receive(:execute_hooks) + expect_any_instance_of(Ci::Build) + .to receive(:execute_hooks) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildHooksWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb index d016ecbb738..dba70883130 100644 --- a/spec/workers/build_success_worker_spec.rb +++ b/spec/workers/build_success_worker_spec.rb @@ -7,8 +7,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, environment: 'production') } it 'executes deployment service' do - expect_any_instance_of(CreateDeploymentService). - to receive(:execute) + expect_any_instance_of(CreateDeploymentService) + .to receive(:execute) described_class.new.perform(build.id) end @@ -18,8 +18,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, project: nil) } it 'does not create deployment' do - expect_any_instance_of(CreateDeploymentService). - not_to receive(:execute) + expect_any_instance_of(CreateDeploymentService) + .not_to receive(:execute) described_class.new.perform(build.id) end @@ -28,8 +28,8 @@ describe BuildSuccessWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/delete_user_worker_spec.rb b/spec/workers/delete_user_worker_spec.rb index 0765573408c..06b470f68f2 100644 --- a/spec/workers/delete_user_worker_spec.rb +++ b/spec/workers/delete_user_worker_spec.rb @@ -5,15 +5,15 @@ describe DeleteUserWorker do let!(:current_user) { create(:user) } it "calls the DeleteUserWorker with the params it was given" do - expect_any_instance_of(Users::DestroyService).to receive(:execute). - with(user, {}) + expect_any_instance_of(Users::DestroyService).to receive(:execute) + .with(user, {}) DeleteUserWorker.new.perform(current_user.id, user.id) end it "uses symbolized keys" do - expect_any_instance_of(Users::DestroyService).to receive(:execute). - with(user, test: "test") + expect_any_instance_of(Users::DestroyService).to receive(:execute) + .with(user, test: "test") DeleteUserWorker.new.perform(current_user.id, user.id, "test" => "test") end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index fc9adf47c1e..30908534eb3 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -5,8 +5,8 @@ describe 'Every Sidekiq worker' do root = Rails.root.join('app', 'workers') concerns = root.join('concerns').to_s - workers = Dir[root.join('**', '*.rb')]. - reject { |path| path.start_with?(concerns) } + workers = Dir[root.join('**', '*.rb')] + .reject { |path| path.start_with?(concerns) } workers.map do |path| ns = Pathname.new(path).relative_path_from(root).to_s.gsub('.rb', '') @@ -22,9 +22,9 @@ describe 'Every Sidekiq worker' do end it 'uses the cronjob queue when the worker runs as a cronjob' do - cron_workers = Settings.cron_jobs. - map { |job_name, options| options['job_class'].constantize }. - to_set + cron_workers = Settings.cron_jobs + .map { |job_name, options| options['job_class'].constantize } + .to_set workers.each do |worker| next unless cron_workers.include?(worker) diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb index a60af574a08..e4c4a9ac17a 100644 --- a/spec/workers/git_garbage_collect_worker_spec.rb +++ b/spec/workers/git_garbage_collect_worker_spec.rb @@ -11,8 +11,8 @@ describe GitGarbageCollectWorker do describe "#perform" do it "flushes ref caches when the task is 'gc'" do expect(subject).to receive(:command).with(:gc).and_return([:the, :command]) - expect(Gitlab::Popen).to receive(:popen). - with([:the, :command], project.repository.path_to_repo).and_return(["", 0]) + expect(Gitlab::Popen).to receive(:popen) + .with([:the, :command], project.repository.path_to_repo).and_return(["", 0]) expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original expect_any_instance_of(Repository).to receive(:branch_names).and_call_original diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb index 8fdbb35afd0..575361c93d4 100644 --- a/spec/workers/new_note_worker_spec.rb +++ b/spec/workers/new_note_worker_spec.rb @@ -24,8 +24,8 @@ describe NewNoteWorker do let(:unexistent_note_id) { 999 } it 'logs NewNoteWorker process skipping' do - expect(Rails.logger).to receive(:error). - with("NewNoteWorker: couldn't find note with ID=999, skipping job") + expect(Rails.logger).to receive(:error) + .with("NewNoteWorker: couldn't find note with ID=999, skipping job") described_class.new.perform(unexistent_note_id) end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index 061f4bda36c..035e329839f 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe PipelineHooksWorker do let(:pipeline) { create(:ci_pipeline) } it 'executes hooks for the pipeline' do - expect_any_instance_of(Ci::Pipeline). - to receive(:execute_hooks) + expect_any_instance_of(Ci::Pipeline) + .to receive(:execute_hooks) described_class.new.perform(pipeline.id) end @@ -15,8 +15,8 @@ describe PipelineHooksWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index 603ae52ed1e..b9bd234d168 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -56,8 +56,8 @@ describe PipelineNotificationWorker do context 'with success pipeline notification on' do before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: true) + watcher.global_notification_setting + .update(level: 'custom', success_pipeline: true) end it_behaves_like 'sending emails' @@ -67,8 +67,8 @@ describe PipelineNotificationWorker do let(:receivers) { [pusher] } before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: false) + watcher.global_notification_setting + .update(level: 'custom', success_pipeline: false) end it_behaves_like 'sending emails' @@ -87,8 +87,8 @@ describe PipelineNotificationWorker do context 'with failed pipeline notification on' do before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: true) + watcher.global_notification_setting + .update(level: 'custom', failed_pipeline: true) end it_behaves_like 'sending emails' @@ -98,8 +98,8 @@ describe PipelineNotificationWorker do let(:receivers) { [pusher] } before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: false) + watcher.global_notification_setting + .update(level: 'custom', failed_pipeline: false) end it_behaves_like 'sending emails' @@ -117,8 +117,8 @@ describe PipelineNotificationWorker do before do pipeline.project.team << [watcher, Gitlab::Access::GUEST] - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: true) + watcher.global_notification_setting + .update(level: 'custom', failed_pipeline: true) perform_enqueued_jobs do subject.perform(pipeline.id) diff --git a/spec/workers/pipeline_proccess_worker_spec.rb b/spec/workers/pipeline_proccess_worker_spec.rb index fd6ee0714ea..86e9d7f6684 100644 --- a/spec/workers/pipeline_proccess_worker_spec.rb +++ b/spec/workers/pipeline_proccess_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineProcessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_success_worker_spec.rb b/spec/workers/pipeline_success_worker_spec.rb index f6c56465feb..d1c84adda6f 100644 --- a/spec/workers/pipeline_success_worker_spec.rb +++ b/spec/workers/pipeline_success_worker_spec.rb @@ -16,8 +16,8 @@ describe PipelineSuccessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index 24d78aae112..0b456cfd0da 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineUpdateWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 5919b99a6ed..e0bdbab3f15 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -79,9 +79,9 @@ describe PostReceive do end it "does not run if the author is not in the project" do - allow_any_instance_of(Gitlab::GitPostReceive). - to receive(:identify_using_ssh_key). - and_return(nil) + allow_any_instance_of(Gitlab::GitPostReceive) + .to receive(:identify_using_ssh_key) + .and_return(nil) expect(project).not_to receive(:execute_hooks) diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb index 75c7fc1efd2..dfa0ffb1314 100644 --- a/spec/workers/process_commit_worker_spec.rb +++ b/spec/workers/process_commit_worker_spec.rb @@ -36,11 +36,11 @@ describe ProcessCommitWorker do describe '#process_commit_message' do context 'when pushing to the default branch' do it 'closes issues that should be closed per the commit message' do - allow(commit).to receive(:safe_message). - and_return("Closes #{issue.to_reference}") + allow(commit).to receive(:safe_message) + .and_return("Closes #{issue.to_reference}") - expect(worker).to receive(:close_issues). - with(project, user, user, commit, [issue]) + expect(worker).to receive(:close_issues) + .with(project, user, user, commit, [issue]) worker.process_commit_message(project, commit, user, user, true) end @@ -48,8 +48,8 @@ describe ProcessCommitWorker do context 'when pushing to a non-default branch' do it 'does not close any issues' do - allow(commit).to receive(:safe_message). - and_return("Closes #{issue.to_reference}") + allow(commit).to receive(:safe_message) + .and_return("Closes #{issue.to_reference}") expect(worker).not_to receive(:close_issues) @@ -90,8 +90,8 @@ describe ProcessCommitWorker do describe '#update_issue_metrics' do it 'updates any existing issue metrics' do - allow(commit).to receive(:safe_message). - and_return("Closes #{issue.to_reference}") + allow(commit).to receive(:safe_message) + .and_return("Closes #{issue.to_reference}") worker.update_issue_metrics(commit, user) @@ -109,8 +109,8 @@ describe ProcessCommitWorker do end it 'parses date strings into Time instances' do - commit = worker. - build_commit(project, id: '123', authored_date: Time.now.to_s) + commit = worker + .build_commit(project, id: '123', authored_date: Time.now.to_s) expect(commit.authored_date).to be_an_instance_of(Time) end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index 0fc274f1a01..da9136282e4 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -7,8 +7,8 @@ describe ProjectCacheWorker do describe '#perform' do before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). - and_return(true) + allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) + .and_return(true) end context 'with a non-existing project' do @@ -31,17 +31,17 @@ describe ProjectCacheWorker do context 'with an existing project' do it 'updates the project statistics' do - expect(worker).to receive(:update_statistics). - with(kind_of(Project), %i(repository_size)). - and_call_original + expect(worker).to receive(:update_statistics) + .with(kind_of(Project), %i(repository_size)) + .and_call_original worker.perform(project.id, [], %w(repository_size)) end it 'refreshes the method caches' do - expect_any_instance_of(Repository).to receive(:refresh_method_caches). - with(%i(readme)). - and_call_original + expect_any_instance_of(Repository).to receive(:refresh_method_caches) + .with(%i(readme)) + .and_call_original worker.perform(project.id, %w(readme)) end @@ -51,9 +51,9 @@ describe ProjectCacheWorker do describe '#update_statistics' do context 'when a lease could not be obtained' do it 'does not update the repository size' do - allow(worker).to receive(:try_obtain_lease_for). - with(project.id, :update_statistics). - and_return(false) + allow(worker).to receive(:try_obtain_lease_for) + .with(project.id, :update_statistics) + .and_return(false) expect(statistics).not_to receive(:refresh!) @@ -63,13 +63,13 @@ describe ProjectCacheWorker do context 'when a lease could be obtained' do it 'updates the project statistics' do - allow(worker).to receive(:try_obtain_lease_for). - with(project.id, :update_statistics). - and_return(true) + allow(worker).to receive(:try_obtain_lease_for) + .with(project.id, :update_statistics) + .and_return(true) - expect(statistics).to receive(:refresh!). - with(only: %i(repository_size)). - and_call_original + expect(statistics).to receive(:refresh!) + .with(only: %i(repository_size)) + .and_call_original worker.update_statistics(project, %i(repository_size)) end diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb index 60605460adb..b9d8af4d8b0 100644 --- a/spec/workers/repository_fork_worker_spec.rb +++ b/spec/workers/repository_fork_worker_spec.rb @@ -35,11 +35,11 @@ describe RepositoryForkWorker do fork_project.namespace.path ).and_return(true) - expect_any_instance_of(Repository).to receive(:expire_emptiness_caches). - and_call_original + expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) + .and_call_original - expect_any_instance_of(Repository).to receive(:expire_exists_cache). - and_call_original + expect_any_instance_of(Repository).to receive(:expire_exists_cache) + .and_call_original subject.perform(project.id, '/test/path', project.path_with_namespace, fork_project.namespace.path) diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb index 9b0e6635844..59cb168f51d 100644 --- a/spec/workers/repository_import_worker_spec.rb +++ b/spec/workers/repository_import_worker_spec.rb @@ -8,8 +8,8 @@ describe RepositoryImportWorker do describe '#perform' do context 'when the import was successful' do it 'imports a project' do - expect_any_instance_of(Projects::ImportService).to receive(:execute). - and_return({ status: :ok }) + expect_any_instance_of(Projects::ImportService).to receive(:execute) + .and_return({ status: :ok }) expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) expect_any_instance_of(Project).to receive(:import_finish) @@ -21,8 +21,8 @@ describe RepositoryImportWorker do context 'when the import has failed' do it 'hide the credentials that were used in the import URL' do error = %{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found } - expect_any_instance_of(Projects::ImportService).to receive(:execute). - and_return({ status: :error, message: error }) + expect_any_instance_of(Projects::ImportService).to receive(:execute) + .and_return({ status: :error, message: error }) subject.perform(project.id) diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb index f8752c42a49..e50c788b82a 100644 --- a/spec/workers/use_key_worker_spec.rb +++ b/spec/workers/use_key_worker_spec.rb @@ -8,8 +8,8 @@ describe UseKeyWorker do current_time = Time.zone.now Timecop.freeze(current_time) do - expect { worker.perform(key.id) }. - to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) + expect { worker.perform(key.id) } + .to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) end end From f3a83dc8fc377357291fd25d333f5b5a3616fae9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:14:22 -0600 Subject: [PATCH 223/247] Regenerate .rubocop_todo.yml --- .rubocop_todo.yml | 331 ++++++++-------------------------------------- 1 file changed, 58 insertions(+), 273 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 78fceb74881..2d94861058f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,21 +1,20 @@ # This configuration was generated by -# `rubocop --auto-gen-config` -# on 2017-02-21 18:00:50 -0600 using RuboCop version 0.46.0. +# `rubocop --auto-gen-config --exclude-limit 0` +# on 2017-02-22 10:58:40 -0600 using RuboCop version 0.46.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. +# Offense count: 1 +# Cop supports --auto-correct. +Performance/RedundantBlockCall: + Enabled: false + # Offense count: 15 # Configuration parameters: CustomIncludeMethods. RSpec/EmptyExampleGroup: - Exclude: - - 'spec/features/issues_spec.rb' - - 'spec/features/notes_on_merge_requests_spec.rb' - - 'spec/lib/gitlab/git_access_spec.rb' - - 'spec/models/project_snippet_spec.rb' - - 'spec/models/protected_branch_spec.rb' - - 'spec/routing/routing_spec.rb' + Enabled: false # Offense count: 63 # Configuration parameters: EnforcedStyle, SupportedStyles. @@ -27,27 +26,28 @@ RSpec/HookArgument: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: is_expected, should RSpec/ImplicitExpect: - Exclude: - - 'spec/lib/banzai/renderer_spec.rb' - - 'spec/models/project_group_link_spec.rb' - - 'spec/models/project_services/external_wiki_service_spec.rb' - - 'spec/models/project_spec.rb' + Enabled: false # Offense count: 1 RSpec/SingleArgumentMessageChain: - Exclude: - - 'spec/requests/api/internal_spec.rb' + Enabled: false + +# Offense count: 8 +# Cop supports --auto-correct. +Style/AlignArray: + Enabled: false + +# Offense count: 11 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles. +# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit +Style/AlignHash: + Enabled: false # Offense count: 6 # Cop supports --auto-correct. Style/EachWithObject: - Exclude: - - 'app/services/merge_requests/get_urls_service.rb' - - 'lib/ci/ansi2html.rb' - - 'lib/expand_variables.rb' - - 'lib/gitlab/ee_compat_check.rb' - - 'lib/gitlab/import_export/members_mapper.rb' - - 'lib/gitlab/import_export/relation_factory.rb' + Enabled: false # Offense count: 24 # Cop supports --auto-correct. @@ -59,11 +59,7 @@ Style/EmptyElse: # Offense count: 4 # Cop supports --auto-correct. Style/EmptyLiteral: - Exclude: - - 'features/steps/project/commits/commits.rb' - - 'lib/gitlab/fogbugz_import/importer.rb' - - 'lib/gitlab/git/diff_collection.rb' - - 'spec/lib/gitlab/workhorse_spec.rb' + Enabled: false # Offense count: 55 # Cop supports --auto-correct. @@ -82,35 +78,18 @@ Style/ExtraSpacing: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: format, sprintf, percent Style/FormatString: - Exclude: - - 'app/models/ci/pipeline.rb' - - 'app/services/gravatar_service.rb' - - 'config/initializers/rack_lineprof.rb' - - 'lib/gitlab/version_info.rb' - - 'spec/factories/lfs_objects.rb' - - 'spec/services/issues/move_service_spec.rb' + Enabled: false -# Offense count: 261 +# Offense count: 263 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false # Offense count: 12 Style/IfInsideElse: - Exclude: - - 'app/controllers/projects/forks_controller.rb' - - 'app/controllers/projects/imports_controller.rb' - - 'app/helpers/milestones_helper.rb' - - 'app/helpers/projects_helper.rb' - - 'app/services/system_note_service.rb' - - 'config/initializers/1_settings.rb' - - 'lib/gitlab/auth.rb' - - 'lib/gitlab/checks/change_access.rb' - - 'lib/gitlab/database.rb' - - 'spec/controllers/projects/merge_requests_controller_spec.rb' - - 'spec/support/import_export/export_file_helper.rb' + Enabled: false -# Offense count: 178 +# Offense count: 177 # Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: @@ -123,7 +102,7 @@ Style/IfUnlessModifier: Style/IndentArray: Enabled: false -# Offense count: 110 +# Offense count: 108 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces @@ -140,98 +119,40 @@ Style/Lambda: # Offense count: 7 # Cop supports --auto-correct. Style/LineEndConcatenation: - Exclude: - - 'app/helpers/tree_helper.rb' - - 'app/models/merge_request.rb' - - 'app/services/git_operation_service.rb' - - 'spec/lib/gitlab/gfm/reference_rewriter_spec.rb' - - 'spec/lib/gitlab/incoming_email_spec.rb' + Enabled: false # Offense count: 22 # Cop supports --auto-correct. Style/MethodCallParentheses: - Exclude: - - 'lib/ci/ansi2html.rb' - - 'spec/controllers/projects/issues_controller_spec.rb' - - 'spec/controllers/projects/merge_requests_controller_spec.rb' - - 'spec/controllers/projects/snippets_controller_spec.rb' - - 'spec/features/dashboard/datetime_on_tooltips_spec.rb' - - 'spec/features/issues/filtered_search/dropdown_assignee_spec.rb' - - 'spec/features/issues/filtered_search/dropdown_author_spec.rb' - - 'spec/features/issues/filtered_search/dropdown_milestone_spec.rb' - - 'spec/features/issues/filtered_search/filter_issues_spec.rb' - - 'spec/helpers/submodule_helper_spec.rb' - - 'spec/lib/gitlab/git/repository_spec.rb' - - 'spec/requests/api/internal_spec.rb' + Enabled: false # Offense count: 9 Style/MethodMissing: - Exclude: - - 'app/controllers/projects/application_controller.rb' - - 'app/models/commit.rb' - - 'app/models/network/commit.rb' - - 'app/models/repository.rb' - - 'config/initializers/gollum.rb' - - 'lib/bitbucket/collection.rb' - - 'lib/gitlab/github_import/client.rb' - - 'lib/gitlab/lazy.rb' - - 'lib/uploaded_file.rb' + Enabled: false # Offense count: 3 # Cop supports --auto-correct. Style/MultilineIfModifier: - Exclude: - - 'app/helpers/snippets_helper.rb' - - 'app/models/project_wiki.rb' - - 'lib/gitlab/workhorse.rb' + Enabled: false # Offense count: 8 # Cop supports --auto-correct. Style/NestedParenthesizedCalls: - Exclude: - - 'app/helpers/commits_helper.rb' - - 'app/workers/irker_worker.rb' - - 'spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb' - - 'spec/lib/gitlab/email/message/repository_push_spec.rb' + Enabled: false # Offense count: 15 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. # SupportedStyles: skip_modifier_ifs, always Style/Next: - Exclude: - - 'app/models/namespace.rb' - - 'app/models/user.rb' - - 'app/services/merge_requests/refresh_service.rb' - - 'config/initializers/secret_token.rb' - - 'db/migrate/20161220141214_remove_dot_git_from_group_names.rb' - - 'db/migrate/20161226122833_remove_dot_git_from_usernames.rb' - - 'lib/banzai/filter/math_filter.rb' - - 'lib/banzai/filter/table_of_contents_filter.rb' - - 'lib/gitlab/fogbugz_import/importer.rb' - - 'lib/gitlab/metrics/instrumentation.rb' - - 'lib/gitlab/metrics/sampler.rb' - - 'lib/gitlab/project_search_results.rb' + Enabled: false # Offense count: 19 # Cop supports --auto-correct. # Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles. # SupportedOctalStyles: zero_with_o, zero_only Style/NumericLiteralPrefix: - Exclude: - - 'config/initializers/1_settings.rb' - - 'config/initializers/secret_token.rb' - - 'lib/gitlab/import_export/command_line_util.rb' - - 'lib/gitlab/shell.rb' - - 'lib/gitlab/workhorse.rb' - - 'spec/features/projects/import_export/export_file_spec.rb' - - 'spec/lib/gitlab/git/blob_spec.rb' - - 'spec/lib/gitlab/git/hook_spec.rb' - - 'spec/lib/gitlab/git/repository_spec.rb' - - 'spec/lib/gitlab/workhorse_spec.rb' - - 'spec/support/import_export/export_file_helper.rb' - - 'spec/support/test_env.rb' - - 'spec/tasks/gitlab/backup_rake_spec.rb' + Enabled: false # Offense count: 68 # Cop supports --auto-correct. @@ -245,39 +166,16 @@ Style/NumericPredicate: Style/ParallelAssignment: Enabled: false -# Offense count: 459 +# Offense count: 463 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: Enabled: false -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: lower_case_q, upper_case_q -Style/PercentQLiterals: - Exclude: - - 'spec/lib/gitlab/diff/highlight_spec.rb' - - 'spec/models/project_services/bamboo_service_spec.rb' - - 'spec/models/project_services/buildkite_service_spec.rb' - - 'spec/models/project_services/drone_ci_service_spec.rb' - - 'spec/models/project_services/teamcity_service_spec.rb' - - 'spec/workers/repository_import_worker_spec.rb' - # Offense count: 13 # Cop supports --auto-correct. Style/PerlBackrefs: - Exclude: - - 'app/controllers/projects/application_controller.rb' - - 'app/helpers/submodule_helper.rb' - - 'lib/banzai/filter/abstract_reference_filter.rb' - - 'lib/banzai/filter/autolink_filter.rb' - - 'lib/banzai/filter/emoji_filter.rb' - - 'lib/banzai/filter/gollum_tags_filter.rb' - - 'lib/expand_variables.rb' - - 'lib/gitlab/diff/highlight.rb' - - 'lib/gitlab/search_results.rb' - - 'lib/gitlab/sherlock/query.rb' + Enabled: false # Offense count: 72 # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. @@ -297,13 +195,7 @@ Style/PreferredHashMethods: # Offense count: 8 # Cop supports --auto-correct. Style/Proc: - Exclude: - - 'app/mailers/base_mailer.rb' - - 'app/models/milestone.rb' - - 'app/models/service.rb' - - 'lib/api/api_guard.rb' - - 'lib/gitlab/ldap/config.rb' - - 'spec/initializers/trusted_proxies_spec.rb' + Enabled: false # Offense count: 62 # Cop supports --auto-correct. @@ -315,44 +207,18 @@ Style/RaiseArgs: # Offense count: 3 # Cop supports --auto-correct. Style/RedundantBegin: - Exclude: - - 'app/models/merge_request.rb' - - 'app/services/projects/import_service.rb' - - 'lib/gitlab/git/commit.rb' + Enabled: false # Offense count: 32 # Cop supports --auto-correct. Style/RedundantFreeze: - Exclude: - - 'app/models/commit.rb' - - 'app/models/merge_request.rb' - - 'app/validators/color_validator.rb' - - 'app/validators/line_code_validator.rb' - - 'lib/api/templates.rb' - - 'lib/api/v3/templates.rb' - - 'lib/banzai/filter/blockquote_fence_filter.rb' - - 'lib/banzai/filter/gollum_tags_filter.rb' - - 'lib/banzai/filter/yaml_front_matter_filter.rb' - - 'lib/gitlab/diff/inline_diff.rb' - - 'lib/gitlab/ee_compat_check.rb' - - 'lib/gitlab/import_export/relation_factory.rb' - - 'lib/gitlab/middleware/static.rb' - - 'lib/gitlab/regex.rb' + Enabled: false # Offense count: 15 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/concerns/issuable_actions.rb' - - 'app/controllers/groups/application_controller.rb' - - 'app/controllers/groups_controller.rb' - - 'app/controllers/omniauth_callbacks_controller.rb' - - 'app/controllers/profiles/keys_controller.rb' - - 'app/controllers/projects/labels_controller.rb' - - 'app/controllers/projects/milestones_controller.rb' - - 'app/services/access_token_validation_service.rb' + Enabled: false # Offense count: 365 # Cop supports --auto-correct. @@ -374,29 +240,21 @@ Style/RescueModifier: # Offense count: 7 # Cop supports --auto-correct. Style/SelfAssignment: - Exclude: - - 'app/models/project_team.rb' - - 'app/services/notification_service.rb' - - 'lib/api/runners.rb' - - 'spec/features/merge_requests/diff_notes_resolve_spec.rb' - - 'spec/support/import_export/configuration_helper.rb' + Enabled: false # Offense count: 2 # Configuration parameters: Methods. # Methods: {"reduce"=>["acc", "elem"]}, {"inject"=>["acc", "elem"]} Style/SingleLineBlockParams: - Exclude: - - 'app/models/commit.rb' - - 'spec/support/services_shared_context.rb' + Enabled: false # Offense count: 50 # Cop supports --auto-correct. # Configuration parameters: AllowIfMethodIsEmpty. Style/SingleLineMethods: - Exclude: - - 'lib/ci/ansi2html.rb' + Enabled: false -# Offense count: 150 +# Offense count: 153 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space @@ -407,36 +265,16 @@ Style/SpaceBeforeBlockBraces: # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment. Style/SpaceBeforeFirstArg: - Exclude: - - 'config/routes/project.rb' - - 'features/steps/project/source/browse_files.rb' - - 'features/steps/project/source/markdown_render.rb' - - 'spec/routing/project_routing_spec.rb' - - 'spec/services/system_note_service_spec.rb' + Enabled: false # Offense count: 38 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: require_no_space, require_space Style/SpaceInLambdaLiteral: - Exclude: - - 'app/models/commit_status.rb' - - 'app/models/concerns/mentionable.rb' - - 'app/models/issue.rb' - - 'app/models/member.rb' - - 'lib/api/entities.rb' - - 'lib/file_size_validator.rb' - - 'lib/gitlab/visibility_level.rb' - - 'spec/models/concerns/participable_spec.rb' - - 'spec/models/cycle_analytics/code_spec.rb' - - 'spec/models/cycle_analytics/issue_spec.rb' - - 'spec/models/cycle_analytics/plan_spec.rb' - - 'spec/models/cycle_analytics/production_spec.rb' - - 'spec/models/cycle_analytics/review_spec.rb' - - 'spec/models/cycle_analytics/staging_spec.rb' - - 'spec/models/cycle_analytics/test_spec.rb' + Enabled: false -# Offense count: 205 +# Offense count: 201 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space @@ -451,8 +289,7 @@ Style/SpaceInsideParens: # Offense count: 4 # Cop supports --auto-correct. Style/SpaceInsidePercentLiteralDelimiters: - Exclude: - - 'lib/gitlab/git_access.rb' + Enabled: false # Offense count: 52 # Cop supports --auto-correct. @@ -466,21 +303,7 @@ Style/SpecialGlobalVars: # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: single_quotes, double_quotes Style/StringLiteralsInInterpolation: - Exclude: - - 'app/helpers/labels_helper.rb' - - 'app/helpers/time_helper.rb' - - 'app/helpers/todos_helper.rb' - - 'app/models/application_setting.rb' - - 'app/models/project_services/campfire_service.rb' - - 'app/models/project_services/jira_service.rb' - - 'db/migrate/20161017125927_add_unique_index_to_labels.rb' - - 'features/steps/groups.rb' - - 'features/steps/project/merge_requests.rb' - - 'lib/banzai/filter/abstract_reference_filter.rb' - - 'lib/ci/gitlab_ci_yaml_processor.rb' - - 'lib/gitlab/google_code_import/importer.rb' - - 'spec/lib/banzai/filter/issue_reference_filter_spec.rb' - - 'spec/models/project_services/hipchat_service_spec.rb' + Enabled: false # Offense count: 57 # Cop supports --auto-correct. @@ -494,12 +317,7 @@ Style/SymbolProc: # Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment. # SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex Style/TernaryParentheses: - Exclude: - - 'features/support/capybara.rb' - - 'lib/api/v3/projects.rb' - - 'lib/banzai/filter/table_of_contents_filter.rb' - - 'lib/gitlab/ci/build/artifacts/metadata/entry.rb' - - 'spec/support/capybara.rb' + Enabled: false # Offense count: 43 # Cop supports --auto-correct. @@ -512,15 +330,9 @@ Style/TrailingCommaInArguments: # Cop supports --auto-correct. # Configuration parameters: AllowNamedUnderscoreVariables. Style/TrailingUnderscoreVariable: - Exclude: - - 'app/controllers/admin/background_jobs_controller.rb' - - 'app/controllers/invites_controller.rb' - - 'app/controllers/projects/git_http_client_controller.rb' - - 'app/helpers/tab_helper.rb' - - 'lib/gitlab/git/repository.rb' - - 'lib/gitlab/logger.rb' + Enabled: false -# Offense count: 76 +# Offense count: 69 # Cop supports --auto-correct. Style/TrailingWhitespace: Enabled: false @@ -530,46 +342,19 @@ Style/TrailingWhitespace: # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist. # Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym Style/TrivialAccessors: - Exclude: - - 'app/models/external_issue.rb' - - 'app/serializers/base_serializer.rb' - - 'lib/gitlab/ldap/person.rb' + Enabled: false # Offense count: 2 # Cop supports --auto-correct. Style/UnlessElse: - Exclude: - - 'lib/gitlab/project_search_results.rb' - - 'spec/features/issues/award_emoji_spec.rb' + Enabled: false # Offense count: 19 # Cop supports --auto-correct. Style/UnneededInterpolation: - Exclude: - - 'app/helpers/boards_helper.rb' - - 'app/helpers/projects_helper.rb' - - 'app/helpers/search_helper.rb' - - 'app/helpers/time_helper.rb' - - 'app/models/merge_request.rb' - - 'app/models/project_services/pushover_service.rb' - - 'features/steps/project/forked_merge_requests.rb' - - 'spec/controllers/admin/services_controller_spec.rb' - - 'spec/features/admin/admin_projects_spec.rb' - - 'spec/features/issues_spec.rb' - - 'spec/features/projects/branches_spec.rb' - - 'spec/features/projects/issuable_templates_spec.rb' - - 'spec/lib/banzai/filter/issue_reference_filter_spec.rb' - - 'spec/requests/api/issues_spec.rb' - - 'spec/views/projects/commit/_commit_box.html.haml_spec.rb' + Enabled: false # Offense count: 8 # Cop supports --auto-correct. Style/ZeroLengthPredicate: - Exclude: - - 'app/models/deploy_key.rb' - - 'app/models/merge_request.rb' - - 'app/models/network/commit.rb' - - 'app/models/network/graph.rb' - - 'app/models/project_services/asana_service.rb' - - 'app/models/repository.rb' - - 'lib/extracts_path.rb' + Enabled: false From f74ca33a32fbf810b377cf480e996fb383d8f400 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:25:50 -0600 Subject: [PATCH 224/247] Enable Style/ClassCheck --- .rubocop.yml | 2 +- app/helpers/issuables_helper.rb | 2 +- app/helpers/namespaces_helper.rb | 2 +- app/models/ci/build.rb | 2 +- app/models/commit.rb | 2 +- app/services/system_note_service.rb | 2 +- lib/file_size_validator.rb | 4 ++-- lib/gitlab/changes_list.rb | 2 +- spec/support/login_helpers.rb | 2 +- spec/support/matchers/access_matchers.rb | 2 +- spec/support/select2_helper.rb | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2ce32ca5002..af26abec80f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -110,7 +110,7 @@ Style/ClassAndModuleChildren: # Enforces consistent use of `Object#is_a?` or `Object#kind_of?`. Style/ClassCheck: - Enabled: false + Enabled: true # Use self when defining module/class methods. Style/ClassMethods: diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index b65edb4049c..715072290c6 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -23,7 +23,7 @@ module IssuablesHelper def issuable_json_path(issuable) project = issuable.project - if issuable.kind_of?(MergeRequest) + if issuable.is_a?(MergeRequest) namespace_project_merge_request_path(project.namespace, project, issuable.iid, :json) else namespace_project_issue_path(project.namespace, project, issuable.iid, :json) diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb index dc5ae8edbb2..2e3a15bc1b9 100644 --- a/app/helpers/namespaces_helper.rb +++ b/app/helpers/namespaces_helper.rb @@ -33,7 +33,7 @@ module NamespacesHelper end def namespace_icon(namespace, size = 40) - if namespace.kind_of?(Group) + if namespace.is_a?(Group) group_icon(namespace) else avatar_icon(namespace.owner.email, size) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index de9fe352059..7e21eb22e27 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -257,7 +257,7 @@ module Ci return unless regex matches = text.scan(Regexp.new(regex)).last - matches = matches.last if matches.kind_of?(Array) + matches = matches.last if matches.is_a?(Array) coverage = matches.gsub(/\d+(\.\d+)?/).first if coverage.present? diff --git a/app/models/commit.rb b/app/models/commit.rb index 8f6179f183e..dc971e710ff 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -27,7 +27,7 @@ class Commit class << self def decorate(commits, project) commits.map do |commit| - if commit.kind_of?(Commit) + if commit.is_a?(Commit) commit else self.new(commit, project) diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 5cb4401d69d..55b548a12f9 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -356,7 +356,7 @@ module SystemNoteService note: cross_reference_note_content(gfm_reference) } - if noteable.kind_of?(Commit) + if noteable.is_a?(Commit) note_options.merge!(noteable_type: 'Commit', commit_id: noteable.id) else note_options[:noteable] = noteable diff --git a/lib/file_size_validator.rb b/lib/file_size_validator.rb index 440dd44ece7..eb19ab45ac3 100644 --- a/lib/file_size_validator.rb +++ b/lib/file_size_validator.rb @@ -32,9 +32,9 @@ class FileSizeValidator < ActiveModel::EachValidator end def validate_each(record, attribute, value) - raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base + raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.is_a? CarrierWave::Uploader::Base - value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String) + value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.is_a?(String) CHECKS.each do |key, validity_check| next unless check_value = options[key] diff --git a/lib/gitlab/changes_list.rb b/lib/gitlab/changes_list.rb index 95308aca95f..5b32fca00a4 100644 --- a/lib/gitlab/changes_list.rb +++ b/lib/gitlab/changes_list.rb @@ -5,7 +5,7 @@ module Gitlab attr_reader :raw_changes def initialize(changes) - @raw_changes = changes.kind_of?(String) ? changes.lines : changes + @raw_changes = changes.is_a?(String) ? changes.lines : changes end def each(&block) diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index dd4c7287655..9ffb00be0b8 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -16,7 +16,7 @@ module LoginHelpers # login_as(user) def login_as(user_or_role) @user = - if user_or_role.kind_of?(User) + if user_or_role.is_a?(User) user_or_role else create(user_or_role) diff --git a/spec/support/matchers/access_matchers.rb b/spec/support/matchers/access_matchers.rb index ceddb656596..7d238850520 100644 --- a/spec/support/matchers/access_matchers.rb +++ b/spec/support/matchers/access_matchers.rb @@ -38,7 +38,7 @@ module AccessMatchers end def description_for(user, type) - if user.kind_of?(User) + if user.is_a?(User) # User#inspect displays too much information for RSpec's descriptions "be #{type} for the specified user" else diff --git a/spec/support/select2_helper.rb b/spec/support/select2_helper.rb index d30cc8ff9f2..0d526045012 100644 --- a/spec/support/select2_helper.rb +++ b/spec/support/select2_helper.rb @@ -12,7 +12,7 @@ module Select2Helper def select2(value, options = {}) - raise ArgumentError, 'options must be a Hash' unless options.kind_of?(Hash) + raise ArgumentError, 'options must be a Hash' unless options.is_a?(Hash) selector = options.fetch(:from) From 6023fbfd0fc6fb4ea22dfb6f5d89e83189861784 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:27:21 -0600 Subject: [PATCH 225/247] Enable Style/EmptyLineBetweenDefs --- .rubocop.yml | 2 +- app/helpers/javascript_helper.rb | 1 + lib/ci/ansi2html.rb | 44 +++++++++++++++++++ lib/gitlab/database/median.rb | 1 + .../gitlab/metrics/instrumentation_spec.rb | 2 + 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index af26abec80f..0392ffe9595 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -146,7 +146,7 @@ Style/ElseAlignment: # Use empty lines between defs. Style/EmptyLineBetweenDefs: - Enabled: false + Enabled: true # Don't use several empty lines in a row. Style/EmptyLines: diff --git a/app/helpers/javascript_helper.rb b/app/helpers/javascript_helper.rb index 320dd89c9d3..68c09c922a6 100644 --- a/app/helpers/javascript_helper.rb +++ b/app/helpers/javascript_helper.rb @@ -2,6 +2,7 @@ module JavascriptHelper def page_specific_javascript_tag(js) javascript_include_tag asset_path(js) end + def page_specific_javascript_bundle_tag(js) javascript_include_tag(*webpack_asset_paths(js)) end diff --git a/lib/ci/ansi2html.rb b/lib/ci/ansi2html.rb index bab02268139..b3ccad7b28d 100644 --- a/lib/ci/ansi2html.rb +++ b/lib/ci/ansi2html.rb @@ -29,59 +29,103 @@ module Ci class Converter def on_0(s) reset() end + def on_1(s) enable(STYLE_SWITCHES[:bold]) end + def on_3(s) enable(STYLE_SWITCHES[:italic]) end + def on_4(s) enable(STYLE_SWITCHES[:underline]) end + def on_8(s) enable(STYLE_SWITCHES[:conceal]) end + def on_9(s) enable(STYLE_SWITCHES[:cross]) end def on_21(s) disable(STYLE_SWITCHES[:bold]) end + def on_22(s) disable(STYLE_SWITCHES[:bold]) end + def on_23(s) disable(STYLE_SWITCHES[:italic]) end + def on_24(s) disable(STYLE_SWITCHES[:underline]) end + def on_28(s) disable(STYLE_SWITCHES[:conceal]) end + def on_29(s) disable(STYLE_SWITCHES[:cross]) end def on_30(s) set_fg_color(0) end + def on_31(s) set_fg_color(1) end + def on_32(s) set_fg_color(2) end + def on_33(s) set_fg_color(3) end + def on_34(s) set_fg_color(4) end + def on_35(s) set_fg_color(5) end + def on_36(s) set_fg_color(6) end + def on_37(s) set_fg_color(7) end + def on_38(s) set_fg_color_256(s) end + def on_39(s) set_fg_color(9) end def on_40(s) set_bg_color(0) end + def on_41(s) set_bg_color(1) end + def on_42(s) set_bg_color(2) end + def on_43(s) set_bg_color(3) end + def on_44(s) set_bg_color(4) end + def on_45(s) set_bg_color(5) end + def on_46(s) set_bg_color(6) end + def on_47(s) set_bg_color(7) end + def on_48(s) set_bg_color_256(s) end + def on_49(s) set_bg_color(9) end def on_90(s) set_fg_color(0, 'l') end + def on_91(s) set_fg_color(1, 'l') end + def on_92(s) set_fg_color(2, 'l') end + def on_93(s) set_fg_color(3, 'l') end + def on_94(s) set_fg_color(4, 'l') end + def on_95(s) set_fg_color(5, 'l') end + def on_96(s) set_fg_color(6, 'l') end + def on_97(s) set_fg_color(7, 'l') end + def on_99(s) set_fg_color(9, 'l') end def on_100(s) set_bg_color(0, 'l') end + def on_101(s) set_bg_color(1, 'l') end + def on_102(s) set_bg_color(2, 'l') end + def on_103(s) set_bg_color(3, 'l') end + def on_104(s) set_bg_color(4, 'l') end + def on_105(s) set_bg_color(5, 'l') end + def on_106(s) set_bg_color(6, 'l') end + def on_107(s) set_bg_color(7, 'l') end + def on_109(s) set_bg_color(9, 'l') end attr_accessor :offset, :n_open_tags, :fg_color, :bg_color, :style_mask diff --git a/lib/gitlab/database/median.rb b/lib/gitlab/database/median.rb index 4e4ddf32754..e265d22a989 100644 --- a/lib/gitlab/database/median.rb +++ b/lib/gitlab/database/median.rb @@ -108,6 +108,7 @@ module Gitlab Arel.sql(%{EXTRACT(EPOCH FROM (#{diff.to_sql}))}) end + # Need to cast '0' to an INTERVAL before we can check if the interval is positive def zero_interval Arel::Nodes::NamedFunction.new("CAST", [Arel.sql("'0' AS INTERVAL")]) diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb index 09131003388..4b19ee19103 100644 --- a/spec/lib/gitlab/metrics/instrumentation_spec.rb +++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb @@ -197,11 +197,13 @@ describe Gitlab::Metrics::Instrumentation do @child1 = Class.new(@dummy) do def self.child1_foo; end + def child1_bar; end end @child2 = Class.new(@child1) do def self.child2_foo; end + def child2_bar; end end end From 99a34a52d7e329f41bf43dd4d1d3ada3aca641b2 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:35:20 -0600 Subject: [PATCH 226/247] Enable Style/MultilineArrayBraceLayout --- .rubocop.yml | 3 +- config/initializers/1_settings.rb | 20 +-- lib/api/award_emoji.rb | 5 +- lib/api/projects.rb | 3 +- lib/api/v3/projects.rb | 3 +- lib/gitlab/sanitizers/svg/whitelist.rb | 25 ++-- spec/lib/gitlab/o_auth/user_spec.rb | 16 +- spec/lib/gitlab/saml/user_spec.rb | 9 +- .../gitlab/serializer/ci/variables_spec.rb | 3 +- spec/lib/gitlab/upgrader_spec.rb | 3 +- spec/requests/lfs_http_spec.rb | 139 +++++++++++------- 11 files changed, 133 insertions(+), 96 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 0392ffe9595..2383697f9ea 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -204,6 +204,7 @@ Style/For: # Checks if there is a magic comment to enforce string literals Style/FrozenStringLiteralComment: Enabled: false + # Do not introduce global variables. Style/GlobalVars: Enabled: true @@ -262,7 +263,7 @@ Style/ModuleFunction: # Checks that the closing brace in an array literal is either on the same line # as the last array element, or a new line. Style/MultilineArrayBraceLayout: - Enabled: false + Enabled: true EnforcedStyle: symmetrical # Avoid multi-line chains of blocks. diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index ac89fb9e9cf..21cc03113ae 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -20,11 +20,12 @@ class Settings < Settingslogic else ":#{gitlab.port}" end - [gitlab.protocol, - "://", - gitlab.host, - custom_port, - gitlab.relative_url_root + [ + gitlab.protocol, + "://", + gitlab.host, + custom_port, + gitlab.relative_url_root ].join('') end @@ -81,10 +82,11 @@ class Settings < Settingslogic def base_url(config) custom_port = on_standard_port?(config) ? nil : ":#{config.port}" - [config.protocol, - "://", - config.host, - custom_port + [ + config.protocol, + "://", + config.host, + custom_port ] end diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb index d6352920f57..301271118d4 100644 --- a/lib/api/award_emoji.rb +++ b/lib/api/award_emoji.rb @@ -15,8 +15,9 @@ module API requires :"#{awardable_id_string}", type: Integer, desc: "The ID of an Issue, Merge Request or Snippet" end - [":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", - ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji" + [ + ":id/#{awardable_string}/:#{awardable_id_string}/award_emoji", + ":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji" ].each do |endpoint| desc 'Get a list of project +awardable+ award emoji' do diff --git a/lib/api/projects.rb b/lib/api/projects.rb index b2ea2ab0b99..e7b891bd92e 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -19,7 +19,8 @@ module API optional :visibility_level, type: Integer, values: [ Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL, - Gitlab::VisibilityLevel::PUBLIC], desc: 'Create a public project. The same as visibility_level = 20.' + Gitlab::VisibilityLevel::PUBLIC + ], desc: 'Create a public project. The same as visibility_level = 20.' optional :public_builds, type: Boolean, desc: 'Perform public builds' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :only_allow_merge_if_build_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed' diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb index f84f2ce5d42..c3821555452 100644 --- a/lib/api/v3/projects.rb +++ b/lib/api/v3/projects.rb @@ -20,7 +20,8 @@ module API optional :visibility_level, type: Integer, values: [ Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL, - Gitlab::VisibilityLevel::PUBLIC], desc: 'Create a public project. The same as visibility_level = 20.' + Gitlab::VisibilityLevel::PUBLIC + ], desc: 'Create a public project. The same as visibility_level = 20.' optional :public_builds, type: Boolean, desc: 'Perform public builds' optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access' optional :only_allow_merge_if_build_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed' diff --git a/lib/gitlab/sanitizers/svg/whitelist.rb b/lib/gitlab/sanitizers/svg/whitelist.rb index 7b6b70d8dbc..d50f826f924 100644 --- a/lib/gitlab/sanitizers/svg/whitelist.rb +++ b/lib/gitlab/sanitizers/svg/whitelist.rb @@ -6,18 +6,19 @@ module Gitlab module SVG class Whitelist ALLOWED_ELEMENTS = %w[ - a altGlyph altGlyphDef altGlyphItem animate - animateColor animateMotion animateTransform circle clipPath color-profile - cursor defs desc ellipse feBlend feColorMatrix feComponentTransfer - feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap - feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur - feImage feMerge feMergeNode feMorphology feOffset fePointLight - feSpecularLighting feSpotLight feTile feTurbulence filter font font-face - font-face-format font-face-name font-face-src font-face-uri foreignObject - g glyph glyphRef hkern image line linearGradient marker mask metadata - missing-glyph mpath path pattern polygon polyline radialGradient rect - script set stop style svg switch symbol text textPath title tref tspan use - view vkern].freeze + a altGlyph altGlyphDef altGlyphItem animate + animateColor animateMotion animateTransform circle clipPath color-profile + cursor defs desc ellipse feBlend feColorMatrix feComponentTransfer + feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap + feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur + feImage feMerge feMergeNode feMorphology feOffset fePointLight + feSpecularLighting feSpotLight feTile feTurbulence filter font font-face + font-face-format font-face-name font-face-src font-face-uri foreignObject + g glyph glyphRef hkern image line linearGradient marker mask metadata + missing-glyph mpath path pattern polygon polyline radialGradient rect + script set stop style svg switch symbol text textPath title tref tspan use + view vkern + ].freeze ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS = %w[svg].freeze diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 09c11462afd..c49d2b286ff 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -151,9 +151,11 @@ describe Gitlab::OAuth::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( - [{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'twitter', extern_uid: uid } - ]) + [ + { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + { provider: 'twitter', extern_uid: uid } + ] + ) end end @@ -170,9 +172,11 @@ describe Gitlab::OAuth::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array( - [{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'twitter', extern_uid: uid } - ]) + [ + { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, + { provider: 'twitter', extern_uid: uid } + ] + ) end end diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index 00dd29f3e5d..6e075edc5ed 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -158,8 +158,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'saml', extern_uid: uid } - ]) + { provider: 'saml', extern_uid: uid }]) end end @@ -181,8 +180,7 @@ describe Gitlab::Saml::User, lib: true do expect(gl_user.identities.length).to eql 2 identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'saml', extern_uid: uid } - ]) + { provider: 'saml', extern_uid: uid }]) end it 'saves successfully on subsequent tries, when both identities are present' do @@ -207,8 +205,7 @@ describe Gitlab::Saml::User, lib: true do expect(local_gl_user.identities.length).to eql 2 identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } expect(identities_as_hash).to match_array([{ provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, - { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' } - ]) + { provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' }]) end end end diff --git a/spec/lib/gitlab/serializer/ci/variables_spec.rb b/spec/lib/gitlab/serializer/ci/variables_spec.rb index b810c68ea03..c4b7fda5dbb 100644 --- a/spec/lib/gitlab/serializer/ci/variables_spec.rb +++ b/spec/lib/gitlab/serializer/ci/variables_spec.rb @@ -13,6 +13,7 @@ describe Gitlab::Serializer::Ci::Variables do it 'converts keys into strings' do is_expected.to eq([ { key: 'key', value: 'value', public: true }, - { key: 'wee', value: 1, public: false }]) + { key: 'wee', value: 1, public: false } + ]) end end diff --git a/spec/lib/gitlab/upgrader_spec.rb b/spec/lib/gitlab/upgrader_spec.rb index edadab043d7..fcfd8d58b70 100644 --- a/spec/lib/gitlab/upgrader_spec.rb +++ b/spec/lib/gitlab/upgrader_spec.rb @@ -32,7 +32,8 @@ describe Gitlab::Upgrader, lib: true do '43af3e65a486a9237f29f56d96c3b3da59c24ae0 refs/tags/v7.11.2', 'dac18e7728013a77410e926a1e64225703754a2d refs/tags/v7.11.2^{}', '0bf21fd4b46c980c26fd8c90a14b86a4d90cc950 refs/tags/v7.9.4', - 'b10de29edbaff7219547dc506cb1468ee35065c3 refs/tags/v7.9.4^{}']) + 'b10de29edbaff7219547dc506cb1468ee35065c3 refs/tags/v7.9.4^{}' + ]) expect(upgrader.latest_version_raw).to eq("v7.11.2") end end diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb index c0e7bab8199..ccaf9c2f409 100644 --- a/spec/requests/lfs_http_spec.rb +++ b/spec/requests/lfs_http_spec.rb @@ -374,11 +374,13 @@ describe 'Git LFS API and storage' do describe 'download' do let(:project) { create(:empty_project) } let(:body) do - { 'operation' => 'download', + { + 'operation' => 'download', 'objects' => [ { 'oid' => sample_oid, 'size' => sample_size - }] + } + ] } end @@ -393,16 +395,19 @@ describe 'Git LFS API and storage' do end it 'with href to download' do - expect(json_response).to eq('objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size, - 'actions' => { - 'download' => { - 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", - 'header' => { 'Authorization' => authorization } + expect(json_response).to eq({ + 'objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size, + 'actions' => { + 'download' => { + 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", + 'header' => { 'Authorization' => authorization } + } } } - }]) + ] + }) end end @@ -417,24 +422,29 @@ describe 'Git LFS API and storage' do end it 'with href to download' do - expect(json_response).to eq('objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size, - 'error' => { - 'code' => 404, - 'message' => "Object does not exist on the server or you don't have permissions to access it", + expect(json_response).to eq({ + 'objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size, + 'error' => { + 'code' => 404, + 'message' => "Object does not exist on the server or you don't have permissions to access it", + } } - }]) + ] + }) end end context 'when downloading a lfs object that does not exist' do let(:body) do - { 'operation' => 'download', + { + 'operation' => 'download', 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', 'size' => 1575078 - }] + } + ] } end @@ -443,14 +453,17 @@ describe 'Git LFS API and storage' do end it 'with an 404 for specific object' do - expect(json_response).to eq('objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078, - 'error' => { - 'code' => 404, - 'message' => "Object does not exist on the server or you don't have permissions to access it", + expect(json_response).to eq({ + 'objects' => [ + { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078, + 'error' => { + 'code' => 404, + 'message' => "Object does not exist on the server or you don't have permissions to access it", + } } - }]) + ] + }) end end @@ -477,23 +490,28 @@ describe 'Git LFS API and storage' do end it 'responds with upload hypermedia link for the new object' do - expect(json_response).to eq('objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078, - 'error' => { - 'code' => 404, - 'message' => "Object does not exist on the server or you don't have permissions to access it", - } - }, - { 'oid' => sample_oid, - 'size' => sample_size, - 'actions' => { - 'download' => { - 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", - 'header' => { 'Authorization' => authorization } + expect(json_response).to eq({ + 'objects' => [ + { + 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078, + 'error' => { + 'code' => 404, + 'message' => "Object does not exist on the server or you don't have permissions to access it", + } + }, + { + 'oid' => sample_oid, + 'size' => sample_size, + 'actions' => { + 'download' => { + 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", + 'header' => { 'Authorization' => authorization } + } } } - }]) + ] + }) end end end @@ -597,17 +615,20 @@ describe 'Git LFS API and storage' do end it 'responds with status 200 and href to download' do - expect(json_response).to eq('objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size, - 'authenticated' => true, - 'actions' => { - 'download' => { - 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", - 'header' => {} + expect(json_response).to eq({ + 'objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size, + 'authenticated' => true, + 'actions' => { + 'download' => { + 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", + 'header' => {} + } } } - }]) + ] + }) end end @@ -626,11 +647,13 @@ describe 'Git LFS API and storage' do describe 'upload' do let(:project) { create(:project, :public) } let(:body) do - { 'operation' => 'upload', + { + 'operation' => 'upload', 'objects' => [ { 'oid' => sample_oid, 'size' => sample_size - }] + } + ] } end @@ -665,11 +688,13 @@ describe 'Git LFS API and storage' do context 'when pushing a lfs object that does not exist' do let(:body) do - { 'operation' => 'upload', + { + 'operation' => 'upload', 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', 'size' => 1575078 - }] + } + ] } end @@ -789,11 +814,13 @@ describe 'Git LFS API and storage' do let(:project) { create(:empty_project) } let(:authorization) { authorize_user } let(:body) do - { 'operation' => 'other', + { + 'operation' => 'other', 'objects' => [ { 'oid' => sample_oid, 'size' => sample_size - }] + } + ] } end From eacae00516ffe534f197eeca20655cbc0fdf5694 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:44:44 -0600 Subject: [PATCH 227/247] Enable Style/MultilineHashBraceLayout --- .rubocop.yml | 2 +- app/controllers/jwt_controller.rb | 6 +- app/controllers/snippets_controller.rb | 3 +- .../chat_message/issue_message.rb | 3 +- app/models/project_services/irker_service.rb | 3 +- .../project_services/kubernetes_service.rb | 12 ++-- .../project_services/pushover_service.rb | 6 +- lib/gitlab/ci/config/entry/environment.rb | 6 +- .../merge_requests_controller_spec.rb | 3 +- spec/lib/expand_variables_spec.rb | 27 +++------ .../gitlab/template/issue_template_spec.rb | 3 +- .../template/merge_request_template_spec.rb | 3 +- spec/lib/mattermost/command_spec.rb | 6 +- spec/lib/mattermost/team_spec.rb | 25 ++++---- spec/models/environment_spec.rb | 3 +- .../project_services/drone_ci_service_spec.rb | 6 +- .../mattermost_slash_commands_service_spec.rb | 3 +- spec/requests/lfs_http_spec.rb | 57 ++++++++----------- .../create_deployment_service_spec.rb | 11 ++-- spec/support/kubernetes_helpers.rb | 13 +++-- 20 files changed, 98 insertions(+), 103 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2383697f9ea..fdaa467eb7d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -277,7 +277,7 @@ Style/MultilineBlockLayout: # Checks that the closing brace in a hash literal is either on the same line as # the last hash element, or a new line. Style/MultilineHashBraceLayout: - Enabled: false + Enabled: true EnforcedStyle: symmetrical # Do not use then for multi-line if/unless. diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 3eac6285394..1b40645f2c9 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -39,7 +39,8 @@ class JwtController < ApplicationController message: "HTTP Basic: Access denied\n" \ "You have 2FA enabled, please use a personal access token for Git over HTTP.\n" \ "You can generate one at #{profile_personal_access_tokens_url}" } - ] }, status: 401 + ] + }, status: 401 end def render_unauthorized @@ -47,7 +48,8 @@ class JwtController < ApplicationController errors: [ { code: 'UNAUTHORIZED', message: 'HTTP Basic: Access denied' } - ] }, status: 401 + ] + }, status: 401 end def auth_params diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index d22a0ffd88a..2e0f26ade91 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -28,7 +28,8 @@ class SnippetsController < ApplicationController @snippets = SnippetsFinder.new.execute(current_user, { filter: :by_user, user: @user, - scope: params[:scope] }) + scope: params[:scope] + }) .page(params[:page]) render 'index' diff --git a/app/models/project_services/chat_message/issue_message.rb b/app/models/project_services/chat_message/issue_message.rb index b96aca47e65..791e5b0cec7 100644 --- a/app/models/project_services/chat_message/issue_message.rb +++ b/app/models/project_services/chat_message/issue_message.rb @@ -51,7 +51,8 @@ module ChatMessage title: issue_title, title_link: issue_url, text: format(description), - color: "#C95823" }] + color: "#C95823" + }] end def project_link diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index 5d6862d9faa..c62bb4fa120 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -33,7 +33,8 @@ class IrkerService < Service end def settings - { server_host: server_host.present? ? server_host : 'localhost', + { + server_host: server_host.present? ? server_host : 'localhost', server_port: server_port.present? ? server_port : 6659 } end diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index caf71676837..02e802bad6d 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -62,23 +62,19 @@ class KubernetesService < DeploymentService { type: 'text', name: 'namespace', title: 'Kubernetes namespace', - placeholder: 'Kubernetes namespace', - }, + placeholder: 'Kubernetes namespace' }, { type: 'text', name: 'api_url', title: 'API URL', - placeholder: 'Kubernetes API URL, like https://kube.example.com/', - }, + placeholder: 'Kubernetes API URL, like https://kube.example.com/' }, { type: 'text', name: 'token', title: 'Service token', - placeholder: 'Service token', - }, + placeholder: 'Service token' }, { type: 'textarea', name: 'ca_pem', title: 'Custom CA bundle', - placeholder: 'Certificate Authority bundle (PEM format)', - }, + placeholder: 'Certificate Authority bundle (PEM format)' }, ] end diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index f4106048345..508d3a5f2fa 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -29,8 +29,7 @@ class PushoverService < Service ['Normal Priority', 0], ['High Priority', 1] ], - default_choice: 0 - }, + default_choice: 0 }, { type: 'select', name: 'sound', choices: [ ['Device default sound', nil], @@ -56,8 +55,7 @@ class PushoverService < Service ['Pushover Echo (long)', 'echo'], ['Up Down (long)', 'updown'], ['None (silent)', 'none'] - ] - }, + ]}, ] end diff --git a/lib/gitlab/ci/config/entry/environment.rb b/lib/gitlab/ci/config/entry/environment.rb index 940333b92ef..0c1f9eb7cbf 100644 --- a/lib/gitlab/ci/config/entry/environment.rb +++ b/lib/gitlab/ci/config/entry/environment.rb @@ -21,12 +21,14 @@ module Gitlab validates :name, type: { with: String, - message: Gitlab::Regex.environment_name_regex_message } + message: Gitlab::Regex.environment_name_regex_message + } validates :name, format: { with: Gitlab::Regex.environment_name_regex, - message: Gitlab::Regex.environment_name_regex_message } + message: Gitlab::Regex.environment_name_regex_message + } with_options if: :hash? do validates :config, allowed_keys: ALLOWED_KEYS diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index b990f4dae86..c059038f9f2 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -54,7 +54,8 @@ describe Projects::MergeRequestsController do project_id: fork_project.to_param, merge_request: { source_branch: 'remove-submodule', - target_branch: 'master' }, + target_branch: 'master' + }, format: format end end diff --git a/spec/lib/expand_variables_spec.rb b/spec/lib/expand_variables_spec.rb index 90bc7dad379..9fe15993a7d 100644 --- a/spec/lib/expand_variables_spec.rb +++ b/spec/lib/expand_variables_spec.rb @@ -7,58 +7,49 @@ describe ExpandVariables do tests = [ { value: 'key', result: 'key', - variables: [] - }, + variables: [] }, { value: 'key$variable', result: 'key', - variables: [] - }, + variables: [] }, { value: 'key$variable', result: 'keyvalue', variables: [ { key: 'variable', value: 'value' } - ] - }, + ]}, { value: 'key${variable}', result: 'keyvalue', variables: [ { key: 'variable', value: 'value' } - ] - }, + ]}, { value: 'key$variable$variable2', result: 'keyvalueresult', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' }, - ] - }, + ]}, { value: 'key${variable}${variable2}', result: 'keyvalueresult', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' } - ] - }, + ]}, { value: 'key$variable2$variable', result: 'keyresultvalue', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' }, - ] - }, + ]}, { value: 'key${variable2}${variable}', result: 'keyresultvalue', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' } - ] - }, + ]}, { value: 'review/$CI_BUILD_REF_NAME', result: 'review/feature/add-review-apps', variables: [ { key: 'CI_BUILD_REF_NAME', value: 'feature/add-review-apps' } - ] - }, + ]}, ] tests.each do |test| diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb index 1335a2b8f35..9213ced7b19 100644 --- a/spec/lib/gitlab/template/issue_template_spec.rb +++ b/spec/lib/gitlab/template/issue_template_spec.rb @@ -11,7 +11,8 @@ describe Gitlab::Template::IssueTemplate do create_template: { user: user, access: Gitlab::Access::MASTER, - path: 'issue_templates' }) + path: 'issue_templates' + }) end describe '.all' do diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb index 320b870309a..77dd3079e22 100644 --- a/spec/lib/gitlab/template/merge_request_template_spec.rb +++ b/spec/lib/gitlab/template/merge_request_template_spec.rb @@ -11,7 +11,8 @@ describe Gitlab::Template::MergeRequestTemplate do create_template: { user: user, access: Gitlab::Access::MASTER, - path: 'merge_request_templates' }) + path: 'merge_request_templates' + }) end describe '.all' do diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb index c0393eafca9..369e7b181b9 100644 --- a/spec/lib/mattermost/command_spec.rb +++ b/spec/lib/mattermost/command_spec.rb @@ -13,8 +13,7 @@ describe Mattermost::Command do describe '#create' do let(:params) do { team_id: 'abc', - trigger: 'gitlab' - } + trigger: 'gitlab' } end subject { described_class.new(nil).create(params) } @@ -24,7 +23,8 @@ describe Mattermost::Command do stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') .with(body: { team_id: 'abc', - trigger: 'gitlab' }.to_json) + trigger: 'gitlab' + }.to_json) .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb index 4435e3c24b7..339178954ea 100644 --- a/spec/lib/mattermost/team_spec.rb +++ b/spec/lib/mattermost/team_spec.rb @@ -14,18 +14,19 @@ describe Mattermost::Team do context 'for valid request' do let(:response) do [{ - "id" => "xiyro8huptfhdndadpz8r3wnbo", - "create_at" => 1482174222155, - "update_at" => 1482174222155, - "delete_at" => 0, - "display_name" => "chatops", - "name" => "chatops", - "email" => "admin@example.com", - "type" => "O", - "company_name" => "", - "allowed_domains" => "", - "invite_id" => "o4utakb9jtb7imctdfzbf9r5ro", - "allow_open_invite" => false }] + "id" => "xiyro8huptfhdndadpz8r3wnbo", + "create_at" => 1482174222155, + "update_at" => 1482174222155, + "delete_at" => 0, + "display_name" => "chatops", + "name" => "chatops", + "email" => "admin@example.com", + "type" => "O", + "company_name" => "", + "allowed_domains" => "", + "invite_id" => "o4utakb9jtb7imctdfzbf9r5ro", + "allow_open_invite" => false + }] end before do diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 1dd66c52437..3198f67a041 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -76,7 +76,8 @@ describe Environment, models: true do end describe '#update_merge_request_metrics?' do - { 'production' => true, + { + 'production' => true, 'production/eu' => true, 'production/www.gitlab.com' => true, 'productioneu' => false, diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb index 3b5b215513d..82d80206afb 100644 --- a/spec/models/project_services/drone_ci_service_spec.rb +++ b/spec/models/project_services/drone_ci_service_spec.rb @@ -95,12 +95,12 @@ describe DroneCiService, models: true, caching: true do is_expected.to eq(:error) end - { "killed" => :canceled, + { + "killed" => :canceled, "failure" => :failed, "error" => :failed, - "success" => "success", + "success" => "success" }.each do |drone_status, our_status| - it "sets commit status to #{our_status.inspect} when returned status is #{drone_status.inspect}" do stub_request(body: %({"status":"#{drone_status}"})) diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb index 0ee24ac1b5f..9082156788e 100644 --- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb +++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb @@ -36,7 +36,8 @@ describe MattermostSlashCommandsService, :models do description: "Perform common operations on: #{project.name_with_namespace}", display_name: "GitLab / #{project.name_with_namespace}", method: 'P', - username: 'GitLab' }.to_json) + username: 'GitLab' + }.to_json) .to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb index ccaf9c2f409..5d495bc9e7d 100644 --- a/spec/requests/lfs_http_spec.rb +++ b/spec/requests/lfs_http_spec.rb @@ -25,11 +25,9 @@ describe 'Git LFS API and storage' do { 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - }, + 'size' => 1575078 }, { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ], 'operation' => 'upload' } @@ -53,11 +51,9 @@ describe 'Git LFS API and storage' do { 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - }, + 'size' => 1575078 }, { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ], 'operation' => 'upload' } @@ -378,8 +374,7 @@ describe 'Git LFS API and storage' do 'operation' => 'download', 'objects' => [ { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ] } end @@ -397,7 +392,8 @@ describe 'Git LFS API and storage' do it 'with href to download' do expect(json_response).to eq({ 'objects' => [ - { 'oid' => sample_oid, + { + 'oid' => sample_oid, 'size' => sample_size, 'actions' => { 'download' => { @@ -424,7 +420,8 @@ describe 'Git LFS API and storage' do it 'with href to download' do expect(json_response).to eq({ 'objects' => [ - { 'oid' => sample_oid, + { + 'oid' => sample_oid, 'size' => sample_size, 'error' => { 'code' => 404, @@ -442,8 +439,7 @@ describe 'Git LFS API and storage' do 'operation' => 'download', 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - } + 'size' => 1575078 } ] } end @@ -455,7 +451,8 @@ describe 'Git LFS API and storage' do it 'with an 404 for specific object' do expect(json_response).to eq({ 'objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + { + 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', 'size' => 1575078, 'error' => { 'code' => 404, @@ -469,14 +466,13 @@ describe 'Git LFS API and storage' do context 'when downloading one new and one existing lfs object' do let(:body) do - { 'operation' => 'download', + { + 'operation' => 'download', 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - }, + 'size' => 1575078 }, { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ] } end @@ -617,7 +613,8 @@ describe 'Git LFS API and storage' do it 'responds with status 200 and href to download' do expect(json_response).to eq({ 'objects' => [ - { 'oid' => sample_oid, + { + 'oid' => sample_oid, 'size' => sample_size, 'authenticated' => true, 'actions' => { @@ -651,8 +648,7 @@ describe 'Git LFS API and storage' do 'operation' => 'upload', 'objects' => [ { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ] } end @@ -692,8 +688,7 @@ describe 'Git LFS API and storage' do 'operation' => 'upload', 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - } + 'size' => 1575078 } ] } end @@ -713,14 +708,13 @@ describe 'Git LFS API and storage' do context 'when pushing one new and one existing lfs object' do let(:body) do - { 'operation' => 'upload', + { + 'operation' => 'upload', 'objects' => [ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - }, + 'size' => 1575078 }, { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ] } end @@ -818,8 +812,7 @@ describe 'Git LFS API and storage' do 'operation' => 'other', 'objects' => [ { 'oid' => sample_oid, - 'size' => sample_size - } + 'size' => sample_size } ] } end diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb index 6fb4d517115..18b964e2453 100644 --- a/spec/services/create_deployment_service_spec.rb +++ b/spec/services/create_deployment_service_spec.rb @@ -9,7 +9,8 @@ describe CreateDeploymentService, services: true do describe '#execute' do let(:options) { nil } let(:params) do - { environment: 'production', + { + environment: 'production', ref: 'master', tag: false, sha: '97de212e80737a608d939f648d959671fb0a0142', @@ -83,10 +84,11 @@ describe CreateDeploymentService, services: true do context 'for environment with invalid name' do let(:params) do - { environment: 'name,with,commas', + { + environment: 'name,with,commas', ref: 'master', tag: false, - sha: '97de212e80737a608d939f648d959671fb0a0142', + sha: '97de212e80737a608d939f648d959671fb0a0142' } end @@ -101,7 +103,8 @@ describe CreateDeploymentService, services: true do context 'when variables are used' do let(:params) do - { environment: 'review-apps/$CI_BUILD_REF_NAME', + { + environment: 'review-apps/$CI_BUILD_REF_NAME', ref: 'master', tag: false, sha: '97de212e80737a608d939f648d959671fb0a0142', diff --git a/spec/support/kubernetes_helpers.rb b/spec/support/kubernetes_helpers.rb index 41c40eb5084..b5ed71ba3be 100644 --- a/spec/support/kubernetes_helpers.rb +++ b/spec/support/kubernetes_helpers.rb @@ -2,23 +2,24 @@ module KubernetesHelpers include Gitlab::Kubernetes def kube_discovery_body - { "kind" => "APIResourceList", + { + "kind" => "APIResourceList", "resources" => [ { "name" => "pods", "namespaced" => true, "kind" => "Pod" }, - ], + ] } end def kube_pods_body(*pods) { "kind" => "PodList", - "items" => [kube_pod], - } + "items" => [kube_pod] } end # This is a partial response, it will have many more elements in reality but # these are the ones we care about at the moment def kube_pod(app: "valid-pod-label") - { "metadata" => { + { + "metadata" => { "name" => "kube-pod", "creationTimestamp" => "2016-11-25T19:55:19Z", "labels" => { "app" => app }, @@ -29,7 +30,7 @@ module KubernetesHelpers { "name" => "container-1" }, ], }, - "status" => { "phase" => "Running" }, + "status" => { "phase" => "Running" } } end From 7d4b52b27dcbe30d85d4fad27e983cee51cf6677 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:46:57 -0600 Subject: [PATCH 228/247] Enable Style/WordArray --- .rubocop.yml | 2 +- app/finders/todos_finder.rb | 2 +- app/helpers/emails_helper.rb | 2 +- app/helpers/tab_helper.rb | 2 +- app/helpers/todos_helper.rb | 2 +- app/models/concerns/issuable.rb | 2 +- app/models/diff_note.rb | 2 +- app/models/event.rb | 2 +- app/models/note.rb | 2 +- .../project_services/drone_ci_service.rb | 2 +- .../project_services/hipchat_service.rb | 2 +- .../project_services/pushover_service.rb | 22 ++++++------ app/services/projects/download_service.rb | 2 +- config/initializers/health_check.rb | 4 +-- config/initializers/metrics.rb | 14 ++++---- ...161128142110_remove_unnecessary_indexes.rb | 4 +-- features/steps/project/builds/artifacts.rb | 2 +- lib/api/commit_statuses.rb | 2 +- lib/api/commits.rb | 2 +- lib/api/pipelines.rb | 2 +- lib/api/runners.rb | 2 +- lib/api/v3/commits.rb | 2 +- lib/ci/api/helpers.rb | 2 +- lib/gitlab/template/gitlab_ci_yml_template.rb | 2 +- lib/gitlab/url_sanitizer.rb | 2 +- .../profiles/personal_access_tokens_spec.rb | 4 +-- .../merge_requests_controller_spec.rb | 2 +- .../issues/bulk_assignment_labels_spec.rb | 6 ++-- spec/features/issues_spec.rb | 2 +- .../labels/issues_sorted_by_priority_spec.rb | 4 +-- spec/helpers/auth_helper_spec.rb | 2 +- spec/helpers/issuables_helper_spec.rb | 2 +- spec/helpers/issues_helper_spec.rb | 2 +- spec/lib/bitbucket/collection_spec.rb | 2 +- .../lib/bitbucket/representation/repo_spec.rb | 2 +- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 34 +++++++++--------- spec/lib/extracts_path_spec.rb | 4 +-- .../gitlab/ci/config/entry/commands_spec.rb | 2 +- .../gitlab/ci/config/entry/factory_spec.rb | 10 +++--- .../lib/gitlab/ci/config/entry/global_spec.rb | 10 +++--- .../lib/gitlab/ci/config/entry/script_spec.rb | 2 +- spec/lib/gitlab/conflict/file_spec.rb | 4 +-- spec/lib/gitlab/git/blob_snippet_spec.rb | 2 +- spec/lib/gitlab/git_access_spec.rb | 2 +- .../attribute_configuration_spec.rb | 2 +- .../import_export/model_configuration_spec.rb | 2 +- .../import_export/project_tree_saver_spec.rb | 2 +- spec/lib/gitlab/import_sources_spec.rb | 36 +++++++++---------- spec/lib/gitlab/ldap/auth_hash_spec.rb | 2 +- spec/models/application_setting_spec.rb | 6 ++-- spec/models/ci/build_spec.rb | 2 +- spec/models/ci/pipeline_spec.rb | 16 ++++----- spec/models/ci/runner_spec.rb | 8 ++--- spec/models/merge_request_diff_spec.rb | 2 +- .../project_services/irker_service_spec.rb | 2 +- spec/requests/api/issues_spec.rb | 2 +- spec/requests/api/labels_spec.rb | 9 +++-- spec/requests/api/merge_requests_spec.rb | 2 +- spec/requests/api/projects_spec.rb | 2 +- spec/requests/api/v3/issues_spec.rb | 2 +- spec/requests/api/v3/labels_spec.rb | 9 +++-- spec/requests/api/v3/merge_requests_spec.rb | 2 +- spec/requests/api/v3/projects_spec.rb | 2 +- spec/requests/ci/api/builds_spec.rb | 2 +- spec/requests/ci/api/runners_spec.rb | 2 +- ...er_registry_authentication_service_spec.rb | 2 +- .../merge_requests/resolve_service_spec.rb | 8 ++--- spec/services/system_note_service_spec.rb | 2 +- spec/support/repo_helpers.rb | 13 ++++--- 69 files changed, 159 insertions(+), 164 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fdaa467eb7d..21d692c2859 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -491,7 +491,7 @@ Style/WhileUntilModifier: # Use %w or %W for arrays of words. Style/WordArray: - Enabled: false + Enabled: true # Metrics ##################################################################### diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb index 10a1f948f93..b7f091f334d 100644 --- a/app/finders/todos_finder.rb +++ b/app/finders/todos_finder.rb @@ -99,7 +99,7 @@ class TodosFinder end def type? - type.present? && ['Issue', 'MergeRequest'].include?(type) + type.present? && %w(Issue MergeRequest).include?(type) end def type diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index a6d9e37ac76..f927cfc998f 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -24,7 +24,7 @@ module EmailsHelper def action_title(url) return unless url - ["merge_requests", "issues", "commit"].each do |action| + %w(merge_requests issues commit).each do |action| if url.split("/").include?(action) return "View #{action.humanize.singularize}" end diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 547f6258909..1a55ee05996 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -99,7 +99,7 @@ module TabHelper return 'active' end - if ['services', 'hooks', 'deploy_keys', 'protected_branches'].include? controller.controller_name + if %w(services hooks deploy_keys protected_branches).include? controller.controller_name "active" end end diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index c52afd6db1c..7f8efb0a4ac 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -150,6 +150,6 @@ module TodosHelper private def show_todo_state?(todo) - (todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && ['closed', 'merged'].include?(todo.target.state) + (todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && %w(closed merged).include?(todo.target.state) end end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 303d4910ee1..8b33e776e87 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -182,7 +182,7 @@ module Issuable def grouping_columns(sort) grouping_columns = [arel_table[:id]] - if ["milestone_due_desc", "milestone_due_asc"].include?(sort) + if %w(milestone_due_desc milestone_due_asc).include?(sort) milestone_table = Milestone.arel_table grouping_columns << milestone_table[:id] grouping_columns << milestone_table[:due_date] diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb index 559b3075905..895a91139c9 100644 --- a/app/models/diff_note.rb +++ b/app/models/diff_note.rb @@ -8,7 +8,7 @@ class DiffNote < Note validates :position, presence: true validates :diff_line, presence: true validates :line_code, presence: true, line_code: true - validates :noteable_type, inclusion: { in: ['Commit', 'MergeRequest'] } + validates :noteable_type, inclusion: { in: %w(Commit MergeRequest) } validates :resolved_by, presence: true, if: :resolved? validate :positions_complete validate :verify_supported diff --git a/app/models/event.rb b/app/models/event.rb index 42c4a233ce3..b8918fcda21 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -47,7 +47,7 @@ class Event < ActiveRecord::Base def contributions where("action = ? OR (target_type IN (?) AND action IN (?)) OR (target_type = ? AND action = ?)", Event::PUSHED, - ["MergeRequest", "Issue"], [Event::CREATED, Event::CLOSED, Event::MERGED], + %w(MergeRequest Issue), [Event::CREATED, Event::CLOSED, Event::MERGED], "Note", Event::COMMENTED) end diff --git a/app/models/note.rb b/app/models/note.rb index 4f87b9a4dc2..c6406f644e0 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -72,7 +72,7 @@ class Note < ActiveRecord::Base scope :inc_author, ->{ includes(:author) } scope :inc_relations_for_view, ->{ includes(:project, :author, :updated_by, :resolved_by, :award_emoji) } - scope :diff_notes, ->{ where(type: ['LegacyDiffNote', 'DiffNote']) } + scope :diff_notes, ->{ where(type: %w(LegacyDiffNote DiffNote)) } scope :non_diff_notes, ->{ where(type: ['Note', nil]) } scope :with_associations, -> do diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb index cd55194e291..2717c240f05 100644 --- a/app/models/project_services/drone_ci_service.rb +++ b/app/models/project_services/drone_ci_service.rb @@ -114,7 +114,7 @@ class DroneCiService < CiService end def merge_request_valid?(data) - ['opened', 'reopened'].include?(data[:object_attributes][:state]) && + %w(opened reopened).include?(data[:object_attributes][:state]) && data[:object_attributes][:merge_status] == 'unchecked' end end diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index 3fdcee26bf3..c4142c38b2f 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -36,7 +36,7 @@ class HipchatService < Service { type: 'text', name: 'token', placeholder: 'Room token' }, { type: 'text', name: 'room', placeholder: 'Room name or ID' }, { type: 'checkbox', name: 'notify' }, - { type: 'select', name: 'color', choices: ['yellow', 'red', 'green', 'purple', 'gray', 'random'] }, + { type: 'select', name: 'color', choices: %w(yellow red green purple gray random) }, { type: 'text', name: 'api_version', placeholder: 'Leave blank for default (v2)' }, { type: 'text', name: 'server', diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index 508d3a5f2fa..689bf03f469 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -34,19 +34,19 @@ class PushoverService < Service [ ['Device default sound', nil], ['Pushover (default)', 'pushover'], - ['Bike', 'bike'], - ['Bugle', 'bugle'], + %w(Bike bike), + %w(Bugle bugle), ['Cash Register', 'cashregister'], - ['Classical', 'classical'], - ['Cosmic', 'cosmic'], - ['Falling', 'falling'], - ['Gamelan', 'gamelan'], - ['Incoming', 'incoming'], - ['Intermission', 'intermission'], - ['Magic', 'magic'], - ['Mechanical', 'mechanical'], + %w(Classical classical), + %w(Cosmic cosmic), + %w(Falling falling), + %w(Gamelan gamelan), + %w(Incoming incoming), + %w(Intermission intermission), + %w(Magic magic), + %w(Mechanical mechanical), ['Piano Bar', 'pianobar'], - ['Siren', 'siren'], + %w(Siren siren), ['Space Alarm', 'spacealarm'], ['Tug Boat', 'tugboat'], ['Alien Alarm (long)', 'alien'], diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb index 3948df955ed..604747e39d0 100644 --- a/app/services/projects/download_service.rb +++ b/app/services/projects/download_service.rb @@ -25,7 +25,7 @@ module Projects end def http?(url) - url =~ /\A#{URI.regexp(['http', 'https'])}\z/ + url =~ /\A#{URI.regexp(%w(http https))}\z/ end def valid_domain?(url) diff --git a/config/initializers/health_check.rb b/config/initializers/health_check.rb index 4c91a61fb4a..959daa93f78 100644 --- a/config/initializers/health_check.rb +++ b/config/initializers/health_check.rb @@ -1,4 +1,4 @@ HealthCheck.setup do |config| - config.standard_checks = ['database', 'migrations', 'cache'] - config.full_checks = ['database', 'migrations', 'cache'] + config.standard_checks = %w(database migrations cache) + config.full_checks = %w(database migrations cache) end diff --git a/config/initializers/metrics.rb b/config/initializers/metrics.rb index 2dcaaa09242..76ce7479a41 100644 --- a/config/initializers/metrics.rb +++ b/config/initializers/metrics.rb @@ -20,13 +20,13 @@ def instrument_classes(instrumentation) # Path to search => prefix to strip from constant paths_to_instrument = { - ['app', 'finders'] => ['app', 'finders'], - ['app', 'mailers', 'emails'] => ['app', 'mailers'], - ['app', 'services', '**'] => ['app', 'services'], - ['lib', 'gitlab', 'conflicts'] => ['lib'], - ['lib', 'gitlab', 'diff'] => ['lib'], - ['lib', 'gitlab', 'email', 'message'] => ['lib'], - ['lib', 'gitlab', 'checks'] => ['lib'] + %w(app finders) => %w(app finders), + %w(app mailers emails) => %w(app mailers), + ['app', 'services', '**'] => %w(app services), + %w(lib gitlab conflicts) => ['lib'], + %w(lib gitlab diff) => ['lib'], + %w(lib gitlab email message) => ['lib'], + %w(lib gitlab checks) => ['lib'] } paths_to_instrument.each do |(path, prefix)| diff --git a/db/migrate/20161128142110_remove_unnecessary_indexes.rb b/db/migrate/20161128142110_remove_unnecessary_indexes.rb index 9deab19782e..8100287ef48 100644 --- a/db/migrate/20161128142110_remove_unnecessary_indexes.rb +++ b/db/migrate/20161128142110_remove_unnecessary_indexes.rb @@ -12,7 +12,7 @@ class RemoveUnnecessaryIndexes < ActiveRecord::Migration remove_index :award_emoji, column: :user_id if index_exists?(:award_emoji, :user_id) remove_index :ci_builds, column: :commit_id if index_exists?(:ci_builds, :commit_id) remove_index :deployments, column: :project_id if index_exists?(:deployments, :project_id) - remove_index :deployments, column: ["project_id", "environment_id"] if index_exists?(:deployments, ["project_id", "environment_id"]) + remove_index :deployments, column: %w(project_id environment_id) if index_exists?(:deployments, %w(project_id environment_id)) remove_index :lists, column: :board_id if index_exists?(:lists, :board_id) remove_index :milestones, column: :project_id if index_exists?(:milestones, :project_id) remove_index :notes, column: :project_id if index_exists?(:notes, :project_id) @@ -24,7 +24,7 @@ class RemoveUnnecessaryIndexes < ActiveRecord::Migration add_concurrent_index :award_emoji, :user_id add_concurrent_index :ci_builds, :commit_id add_concurrent_index :deployments, :project_id - add_concurrent_index :deployments, ["project_id", "environment_id"] + add_concurrent_index :deployments, %w(project_id environment_id) add_concurrent_index :lists, :board_id add_concurrent_index :milestones, :project_id add_concurrent_index :notes, :project_id diff --git a/features/steps/project/builds/artifacts.rb b/features/steps/project/builds/artifacts.rb index 055fca036d3..be0f6eee55a 100644 --- a/features/steps/project/builds/artifacts.rb +++ b/features/steps/project/builds/artifacts.rb @@ -76,7 +76,7 @@ class Spinach::Features::ProjectBuildsArtifacts < Spinach::FeatureSteps base64_params = send_data.sub(/\Aartifacts\-entry:/, '') params = JSON.parse(Base64.urlsafe_decode64(base64_params)) - expect(params.keys).to eq(['Archive', 'Entry']) + expect(params.keys).to eq(%w(Archive Entry)) expect(params['Archive']).to end_with('build_artifacts.zip') expect(params['Entry']).to eq(Base64.encode64('ci_artifacts.txt')) end diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 0b6076bd28c..dba0831664c 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -40,7 +40,7 @@ module API requires :id, type: String, desc: 'The ID of a project' requires :sha, type: String, desc: 'The commit hash' requires :state, type: String, desc: 'The state of the status', - values: ['pending', 'running', 'success', 'failed', 'canceled'] + values: %w(pending running success failed canceled) optional :ref, type: String, desc: 'The ref' optional :target_url, type: String, desc: 'The target URL to associate with this status' optional :description, type: String, desc: 'A short description of the status' diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 0cd817f9352..9ce396d4660 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -157,7 +157,7 @@ module API optional :path, type: String, desc: 'The file path' given :path do requires :line, type: Integer, desc: 'The line number' - requires :line_type, type: String, values: ['new', 'old'], default: 'new', desc: 'The type of the line' + requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line' end end post ':id/repository/commits/:sha/comments' do diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index f59f7959173..3afc1e385fe 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -14,7 +14,7 @@ module API end params do use :pagination - optional :scope, type: String, values: ['running', 'branches', 'tags'], + optional :scope, type: String, values: %w(running branches tags), desc: 'Either running, branches, or tags' end get ':id/pipelines' do diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 4fbd4096533..252e59bfa58 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -14,7 +14,7 @@ module API use :pagination end get do - runners = filter_runners(current_user.ci_authorized_runners, params[:scope], without: ['specific', 'shared']) + runners = filter_runners(current_user.ci_authorized_runners, params[:scope], without: %w(specific shared)) present paginate(runners), with: Entities::Runner end diff --git a/lib/api/v3/commits.rb b/lib/api/v3/commits.rb index 477e22fd25e..126cc95fc3d 100644 --- a/lib/api/v3/commits.rb +++ b/lib/api/v3/commits.rb @@ -162,7 +162,7 @@ module API optional :path, type: String, desc: 'The file path' given :path do requires :line, type: Integer, desc: 'The line number' - requires :line_type, type: String, values: ['new', 'old'], default: 'new', desc: 'The type of the line' + requires :line_type, type: String, values: %w(new old), default: 'new', desc: 'The type of the line' end end post ':id/repository/commits/:sha/comments' do diff --git a/lib/ci/api/helpers.rb b/lib/ci/api/helpers.rb index a2e6387dbe5..996990b464f 100644 --- a/lib/ci/api/helpers.rb +++ b/lib/ci/api/helpers.rb @@ -73,7 +73,7 @@ module Ci def get_runner_version_from_params return unless params["info"].present? - attributes_for_keys(["name", "version", "revision", "platform", "architecture"], params["info"]) + attributes_for_keys(%w(name version revision platform architecture), params["info"]) end def max_artifacts_size diff --git a/lib/gitlab/template/gitlab_ci_yml_template.rb b/lib/gitlab/template/gitlab_ci_yml_template.rb index 9d2ecee9756..fd040148a1e 100644 --- a/lib/gitlab/template/gitlab_ci_yml_template.rb +++ b/lib/gitlab/template/gitlab_ci_yml_template.rb @@ -28,7 +28,7 @@ module Gitlab end def dropdown_names(context) - categories = context == 'autodeploy' ? ['Auto deploy'] : ['General', 'Pages'] + categories = context == 'autodeploy' ? ['Auto deploy'] : %w(General Pages) super().slice(*categories) end end diff --git a/lib/gitlab/url_sanitizer.rb b/lib/gitlab/url_sanitizer.rb index 19dad699edf..1f0d96088cf 100644 --- a/lib/gitlab/url_sanitizer.rb +++ b/lib/gitlab/url_sanitizer.rb @@ -1,7 +1,7 @@ module Gitlab class UrlSanitizer def self.sanitize(content) - regexp = URI::Parser.new.make_regexp(['http', 'https', 'ssh', 'git']) + regexp = URI::Parser.new.make_regexp(%w(http https ssh git)) content.gsub(regexp) { |url| new(url).masked_url } rescue Addressable::URI::InvalidURIError diff --git a/spec/controllers/profiles/personal_access_tokens_spec.rb b/spec/controllers/profiles/personal_access_tokens_spec.rb index 45534a3a587..9d5f4c99f6d 100644 --- a/spec/controllers/profiles/personal_access_tokens_spec.rb +++ b/spec/controllers/profiles/personal_access_tokens_spec.rb @@ -32,10 +32,10 @@ describe Profiles::PersonalAccessTokensController do context "scopes" do it "allows creation of a token with scopes" do - post :create, personal_access_token: { name: FFaker::Product.brand, scopes: ['api', 'read_user'] } + post :create, personal_access_token: { name: FFaker::Product.brand, scopes: %w(api read_user) } expect(created_token).not_to be_nil - expect(created_token.scopes).to eq(['api', 'read_user']) + expect(created_token.scopes).to eq(%w(api read_user)) end it "allows creation of a token with no scopes" do diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index c059038f9f2..e6a8b9f6618 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -773,7 +773,7 @@ describe Projects::MergeRequestsController do section['lines'].each do |line| if section['conflict'] - expect(line['type']).to be_in(['old', 'new']) + expect(line['type']).to be_in(%w(old new)) expect(line.values_at('old_line', 'new_line')).to contain_exactly(nil, a_kind_of(Integer)) else if line['type'].nil? diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb index 832757b24d4..2f59630b4fb 100644 --- a/spec/features/issues/bulk_assignment_labels_spec.rb +++ b/spec/features/issues/bulk_assignment_labels_spec.rb @@ -55,7 +55,7 @@ feature 'Issues > Labels bulk assignment', feature: true do context 'to all issues' do before do check 'check_all_issues' - open_labels_dropdown ['bug', 'feature'] + open_labels_dropdown %w(bug feature) update_issues end @@ -70,7 +70,7 @@ feature 'Issues > Labels bulk assignment', feature: true do context 'to a issue' do before do check "selected_issue_#{issue1.id}" - open_labels_dropdown ['bug', 'feature'] + open_labels_dropdown %w(bug feature) update_issues end @@ -112,7 +112,7 @@ feature 'Issues > Labels bulk assignment', feature: true do visit namespace_project_issues_path(project.namespace, project) check 'check_all_issues' - unmark_labels_in_dropdown ['bug', 'feature'] + unmark_labels_in_dropdown %w(bug feature) update_issues end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index ed3826bd46e..1e0db4a0499 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -150,7 +150,7 @@ describe 'Issues', feature: true do describe 'Filter issue' do before do - ['foobar', 'barbaz', 'gitlab'].each do |title| + %w(foobar barbaz gitlab).each do |title| create(:issue, author: @user, assignee: @user, diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb index 81b0c991d4f..7414ce21f59 100644 --- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb +++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb @@ -37,7 +37,7 @@ feature 'Issue prioritization', feature: true do page.within('.issues-holder') do issue_titles = all('.issues-list .issue-title-text').map(&:text) - expect(issue_titles).to eq(['issue_4', 'issue_3', 'issue_5', 'issue_2', 'issue_1']) + expect(issue_titles).to eq(%w(issue_4 issue_3 issue_5 issue_2 issue_1)) end end end @@ -77,7 +77,7 @@ feature 'Issue prioritization', feature: true do expect(issue_titles[0..1]).to contain_exactly('issue_5', 'issue_8') expect(issue_titles[2..4]).to contain_exactly('issue_1', 'issue_3', 'issue_7') - expect(issue_titles[5..-1]).to eq(['issue_2', 'issue_4', 'issue_6']) + expect(issue_titles[5..-1]).to eq(%w(issue_2 issue_4 issue_6)) end end end diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb index 49ea4fa6d3e..cd3281d6f51 100644 --- a/spec/helpers/auth_helper_spec.rb +++ b/spec/helpers/auth_helper_spec.rb @@ -55,7 +55,7 @@ describe AuthHelper do context 'all the button based providers are disabled via application_setting' do it 'returns false' do stub_application_setting( - disabled_oauth_sign_in_sources: ['github', 'twitter'] + disabled_oauth_sign_in_sources: %w(github twitter) ) expect(helper.button_based_providers_enabled?).to be false diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 69e30913d1c..f3bbb539d2b 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -51,7 +51,7 @@ describe IssuablesHelper do utf8: '✓', author_id: '11', assignee_id: '18', - label_name: ['bug', 'discussion', 'documentation'], + label_name: %w(bug discussion documentation), milestone_title: 'v4.0', sort: 'due_date_asc', namespace_id: 'gitlab-org', diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 5a466e3f743..b61cebe6c8a 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -113,7 +113,7 @@ describe IssuesHelper do describe "awards_sort" do it "sorts a hash so thumbsup and thumbsdown are always on top" do data = { "thumbsdown" => "some value", "lifter" => "some value", "thumbsup" => "some value" } - expect(awards_sort(data).keys).to eq(["thumbsup", "thumbsdown", "lifter"]) + expect(awards_sort(data).keys).to eq(%w(thumbsup thumbsdown lifter)) end end diff --git a/spec/lib/bitbucket/collection_spec.rb b/spec/lib/bitbucket/collection_spec.rb index 015a7f80e03..9008cb3e870 100644 --- a/spec/lib/bitbucket/collection_spec.rb +++ b/spec/lib/bitbucket/collection_spec.rb @@ -19,6 +19,6 @@ describe Bitbucket::Collection do it "iterates paginator" do collection = described_class.new(TestPaginator.new) - expect(collection.to_a).to match(["result_1_page_1", "result_2_page_1", "result_1_page_2", "result_2_page_2"]) + expect(collection.to_a).to match(%w(result_1_page_1 result_2_page_1 result_1_page_2 result_2_page_2)) end end diff --git a/spec/lib/bitbucket/representation/repo_spec.rb b/spec/lib/bitbucket/representation/repo_spec.rb index d9228230145..405265cc669 100644 --- a/spec/lib/bitbucket/representation/repo_spec.rb +++ b/spec/lib/bitbucket/representation/repo_spec.rb @@ -29,7 +29,7 @@ describe Bitbucket::Representation::Repo do end describe '#owner_and_slug' do - it { expect(described_class.new({ 'full_name' => 'ben/test' }).owner_and_slug).to eq(['ben', 'test']) } + it { expect(described_class.new({ 'full_name' => 'ben/test' }).owner_and_slug).to eq(%w(ben test)) } end describe '#owner' do diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index a1bde4a0518..7145f0da1d3 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -96,7 +96,7 @@ module Ci it "returns builds if only has a list of branches including specified" do config = YAML.dump({ before_script: ["pwd"], - rspec: { script: "rspec", type: type, only: ["master", "deploy"] } + rspec: { script: "rspec", type: type, only: %w(master deploy) } }) config_processor = GitlabCiYamlProcessor.new(config, path) @@ -173,8 +173,8 @@ module Ci it "returns build only for specified type" do config = YAML.dump({ before_script: ["pwd"], - rspec: { script: "rspec", type: "test", only: ["master", "deploy"] }, - staging: { script: "deploy", type: "deploy", only: ["master", "deploy"] }, + rspec: { script: "rspec", type: "test", only: %w(master deploy) }, + staging: { script: "deploy", type: "deploy", only: %w(master deploy) }, production: { script: "deploy", type: "deploy", only: ["master@path", "deploy"] }, }) @@ -252,7 +252,7 @@ module Ci it "does not return builds if except has a list of branches including specified" do config = YAML.dump({ before_script: ["pwd"], - rspec: { script: "rspec", type: type, except: ["master", "deploy"] } + rspec: { script: "rspec", type: type, except: %w(master deploy) } }) config_processor = GitlabCiYamlProcessor.new(config, path) @@ -580,7 +580,7 @@ module Ci context 'when syntax is incorrect' do context 'when variables defined but invalid' do let(:variables) do - ['VAR1', 'value1', 'VAR2', 'value2'] + %w(VAR1 value1 VAR2 value2) end it 'raises error' do @@ -909,7 +909,7 @@ module Ci end context 'dependencies to builds' do - let(:dependencies) { ['build1', 'build2'] } + let(:dependencies) { %w(build1 build2) } it { expect { subject }.not_to raise_error } end @@ -1215,7 +1215,7 @@ EOT end it "returns errors if job stage is not a defined stage" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", type: "acceptance" } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", type: "acceptance" } }) expect do GitlabCiYamlProcessor.new(config, path) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: stage parameter should be build, test") @@ -1257,42 +1257,42 @@ EOT end it "returns errors if job artifacts:name is not an a string" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { name: 1 } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { name: 1 } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:artifacts name should be a string") end it "returns errors if job artifacts:when is not an a predefined value" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { when: 1 } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { when: 1 } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:artifacts when should be on_success, on_failure or always") end it "returns errors if job artifacts:expire_in is not an a string" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { expire_in: 1 } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { expire_in: 1 } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:artifacts expire in should be a duration") end it "returns errors if job artifacts:expire_in is not an a valid duration" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { expire_in: "7 elephants" } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { expire_in: "7 elephants" } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:artifacts expire in should be a duration") end it "returns errors if job artifacts:untracked is not an array of strings" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { untracked: "string" } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { untracked: "string" } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:artifacts untracked should be a boolean value") end it "returns errors if job artifacts:paths is not an array of strings" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { paths: "string" } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", artifacts: { paths: "string" } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:artifacts paths should be an array of strings") @@ -1320,28 +1320,28 @@ EOT end it "returns errors if job cache:key is not an a string" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { key: 1 } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { key: 1 } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:cache:key config should be a string or symbol") end it "returns errors if job cache:untracked is not an array of strings" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { untracked: "string" } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { untracked: "string" } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:cache:untracked config should be a boolean value") end it "returns errors if job cache:paths is not an array of strings" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { paths: "string" } } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", cache: { paths: "string" } } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec:cache:paths config should be an array of strings") end it "returns errors if job dependencies is not an array of strings" do - config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", dependencies: "string" } }) + config = YAML.dump({ types: %w(build test), rspec: { script: "test", dependencies: "string" } }) expect do GitlabCiYamlProcessor.new(config) end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs:rspec dependencies should be an array of strings") diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb index 78ac4da8dfe..27f4a968321 100644 --- a/spec/lib/extracts_path_spec.rb +++ b/spec/lib/extracts_path_spec.rb @@ -177,12 +177,12 @@ describe ExtractsPath, lib: true do it "extracts a valid commit SHA" do expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG')).to eq( - ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG'] + %w(f4b14494ef6abf3d144c28e4af0c20143383e062 CHANGELOG) ) end it "falls back to a primitive split for an invalid ref" do - expect(extract_ref('stable/CHANGELOG')).to eq(['stable', 'CHANGELOG']) + expect(extract_ref('stable/CHANGELOG')).to eq(%w(stable CHANGELOG)) end end end diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb index b8b0825a1c7..afa4a089418 100644 --- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::Ci::Config::Entry::Commands do let(:entry) { described_class.new(config) } context 'when entry config value is an array' do - let(:config) { ['ls', 'pwd'] } + let(:config) { %w(ls pwd) } describe '#value' do it 'returns array of strings' do diff --git a/spec/lib/gitlab/ci/config/entry/factory_spec.rb b/spec/lib/gitlab/ci/config/entry/factory_spec.rb index 00dad5d9591..3395b3c645b 100644 --- a/spec/lib/gitlab/ci/config/entry/factory_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/factory_spec.rb @@ -8,20 +8,20 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting a concrete value' do it 'creates entry with valid value' do entry = factory - .value(['ls', 'pwd']) + .value(%w(ls pwd)) .create! - expect(entry.value).to eq ['ls', 'pwd'] + expect(entry.value).to eq %w(ls pwd) end context 'when setting description' do it 'creates entry with description' do entry = factory - .value(['ls', 'pwd']) + .value(%w(ls pwd)) .with(description: 'test description') .create! - expect(entry.value).to eq ['ls', 'pwd'] + expect(entry.value).to eq %w(ls pwd) expect(entry.description).to eq 'test description' end end @@ -29,7 +29,7 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting key' do it 'creates entry with custom key' do entry = factory - .value(['ls', 'pwd']) + .value(%w(ls pwd)) .with(key: 'test key') .create! diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 8a74743eda8..d9e48715984 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -21,12 +21,12 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when configuration is valid' do context 'when some entries defined' do let(:hash) do - { before_script: ['ls', 'pwd'], + { before_script: %w(ls pwd), image: 'ruby:2.2', services: ['postgres:9.1', 'mysql:5.5'], variables: { VAR: 'value' }, after_script: ['make clean'], - stages: ['build', 'pages'], + stages: %w(build pages), cache: { key: 'k', untracked: true, paths: ['public/'] }, rspec: { script: %w[rspec ls] }, spinach: { before_script: [], variables: {}, script: 'spinach' } } @@ -89,7 +89,7 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#before_script_value' do it 'returns correct script' do - expect(global.before_script_value).to eq ['ls', 'pwd'] + expect(global.before_script_value).to eq %w(ls pwd) end end @@ -126,7 +126,7 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when deprecated types key defined' do let(:hash) do - { types: ['test', 'deploy'], + { types: %w(test deploy), rspec: { script: 'rspec' } } end @@ -148,7 +148,7 @@ describe Gitlab::Ci::Config::Entry::Global do expect(global.jobs_value).to eq( rspec: { name: :rspec, script: %w[rspec ls], - before_script: ['ls', 'pwd'], + before_script: %w(ls pwd), commands: "ls\npwd\nrspec\nls", image: 'ruby:2.2', services: ['postgres:9.1', 'mysql:5.5'], diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb index aa99cee2690..069eaa26422 100644 --- a/spec/lib/gitlab/ci/config/entry/script_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb @@ -5,7 +5,7 @@ describe Gitlab::Ci::Config::Entry::Script do describe 'validations' do context 'when entry config value is correct' do - let(:config) { ['ls', 'pwd'] } + let(:config) { %w(ls pwd) } describe '#value' do it 'returns array of strings' do diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb index 3a24aff7fa9..b3e107dca72 100644 --- a/spec/lib/gitlab/conflict/file_spec.rb +++ b/spec/lib/gitlab/conflict/file_spec.rb @@ -44,7 +44,7 @@ describe Gitlab::Conflict::File, lib: true do it 'returns a file containing only the chosen parts of the resolved sections' do expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first)) - .to eq(['both', 'new', 'both', 'old', 'both', 'new', 'both']) + .to eq(%w(both new both old both new both)) end end @@ -123,7 +123,7 @@ describe Gitlab::Conflict::File, lib: true do it 'sets conflict to true for sections with only changed lines' do conflict_file.sections.select { |section| section[:conflict] }.each do |section| section[:lines].each do |line| - expect(line.type).to be_in(['new', 'old']) + expect(line.type).to be_in(%w(new old)) end end end diff --git a/spec/lib/gitlab/git/blob_snippet_spec.rb b/spec/lib/gitlab/git/blob_snippet_spec.rb index 79b1311ac91..17d6be470ac 100644 --- a/spec/lib/gitlab/git/blob_snippet_spec.rb +++ b/spec/lib/gitlab/git/blob_snippet_spec.rb @@ -11,7 +11,7 @@ describe Gitlab::Git::BlobSnippet, seed_helper: true do end context 'present lines' do - let(:snippet) { Gitlab::Git::BlobSnippet.new('master', ['wow', 'much'], 1, 'wow.rb') } + let(:snippet) { Gitlab::Git::BlobSnippet.new('master', %w(wow much), 1, 'wow.rb') } it { expect(snippet.data).to eq("wow\nmuch") } end diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index a55bd4387e0..a12b4d393d7 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -301,7 +301,7 @@ describe Gitlab::GitAccess, lib: true do } } - [['feature', 'exact'], ['feat*', 'wildcard']].each do |protected_branch_name, protected_branch_type| + [%w(feature exact), ['feat*', 'wildcard']].each do |protected_branch_name, protected_branch_type| context do before { create(:protected_branch, name: protected_branch_name, project: project) } diff --git a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb index ea65a5dfed1..e24d070706a 100644 --- a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb @@ -17,7 +17,7 @@ describe 'Import/Export attribute configuration', lib: true do # Remove duplicated or add missing models # - project is not part of the tree, so it has to be added manually. # - milestone, labels have both singular and plural versions in the tree, so remove the duplicates. - names.flatten.uniq - ['milestones', 'labels'] + ['project'] + names.flatten.uniq - %w(milestones labels) + ['project'] end let(:safe_attributes_file) { 'spec/lib/gitlab/import_export/safe_model_attributes.yml' } diff --git a/spec/lib/gitlab/import_export/model_configuration_spec.rb b/spec/lib/gitlab/import_export/model_configuration_spec.rb index 9b492d1b9c7..2ede5cdd2ad 100644 --- a/spec/lib/gitlab/import_export/model_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/model_configuration_spec.rb @@ -14,7 +14,7 @@ describe 'Import/Export model configuration', lib: true do # - project is not part of the tree, so it has to be added manually. # - milestone, labels have both singular and plural versions in the tree, so remove the duplicates. # - User, Author... Models we do not care about for checking models - names.flatten.uniq - ['milestones', 'labels', 'user', 'author'] + ['project'] + names.flatten.uniq - %w(milestones labels user author) + ['project'] end let(:all_models_yml) { 'spec/lib/gitlab/import_export/all_models.yml' } diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb index 8579239f225..012c22ec5ad 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -114,7 +114,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do it 'has project and group labels' do label_types = saved_project_json['issues'].first['label_links'].map { |link| link['label']['type'] } - expect(label_types).to match_array(['ProjectLabel', 'GroupLabel']) + expect(label_types).to match_array(%w(ProjectLabel GroupLabel)) end it 'has priorities associated to labels' do diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb index 8cea38e9ff8..962af8bdf42 100644 --- a/spec/lib/gitlab/import_sources_spec.rb +++ b/spec/lib/gitlab/import_sources_spec.rb @@ -22,16 +22,15 @@ describe Gitlab::ImportSources do describe '.values' do it 'returns an array' do expected = - [ - 'github', - 'bitbucket', - 'gitlab', - 'google_code', - 'fogbugz', - 'git', - 'gitlab_project', - 'gitea' - ] + %w( +github +bitbucket +gitlab +google_code +fogbugz +git +gitlab_project +gitea) expect(described_class.values).to eq(expected) end @@ -40,15 +39,14 @@ describe Gitlab::ImportSources do describe '.importer_names' do it 'returns an array of importer names' do expected = - [ - 'github', - 'bitbucket', - 'gitlab', - 'google_code', - 'fogbugz', - 'gitlab_project', - 'gitea' - ] + %w( +github +bitbucket +gitlab +google_code +fogbugz +gitlab_project +gitea) expect(described_class.importer_names).to eq(expected) end diff --git a/spec/lib/gitlab/ldap/auth_hash_spec.rb b/spec/lib/gitlab/ldap/auth_hash_spec.rb index 69c49051156..7a2f774b948 100644 --- a/spec/lib/gitlab/ldap/auth_hash_spec.rb +++ b/spec/lib/gitlab/ldap/auth_hash_spec.rb @@ -44,7 +44,7 @@ describe Gitlab::LDAP::AuthHash, lib: true do context "with overridden attributes" do let(:attributes) do { - 'username' => ['mail', 'email'], + 'username' => %w(mail email), 'name' => 'fullName' } end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index b950fcdd81a..4086e00e363 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -62,9 +62,9 @@ describe ApplicationSetting, models: true do describe 'inclusion' do it { is_expected.to allow_value('custom1').for(:repository_storages) } - it { is_expected.to allow_value(['custom2', 'custom3']).for(:repository_storages) } + it { is_expected.to allow_value(%w(custom2 custom3)).for(:repository_storages) } it { is_expected.not_to allow_value('alternative').for(:repository_storages) } - it { is_expected.not_to allow_value(['alternative', 'custom1']).for(:repository_storages) } + it { is_expected.not_to allow_value(%w(alternative custom1)).for(:repository_storages) } end describe 'presence' do @@ -83,7 +83,7 @@ describe ApplicationSetting, models: true do describe '#repository_storage' do it 'returns the first storage' do - setting.repository_storages = ['good', 'bad'] + setting.repository_storages = %w(good bad) expect(setting.repository_storage).to eq('good') end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 9a03485201b..355b8bf3af8 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1420,7 +1420,7 @@ describe Ci::Build, :models do end context 'when runner is assigned to build' do - let(:runner) { create(:ci_runner, description: 'description', tag_list: ['docker', 'linux']) } + let(:runner) { create(:ci_runner, description: 'description', tag_list: %w(docker linux)) } before do build.update(runner: runner) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 714a3123efd..9eff58880e3 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -168,9 +168,9 @@ describe Ci::Pipeline, models: true do end it 'returns list of stages with correct statuses' do - expect(statuses).to eq([['build', 'failed'], - ['test', 'success'], - ['deploy', 'running']]) + expect(statuses).to eq([%w(build failed), + %w(test success), + %w(deploy running)]) end context 'when commit status is retried' do @@ -183,9 +183,9 @@ describe Ci::Pipeline, models: true do end it 'ignores the previous state' do - expect(statuses).to eq([['build', 'success'], - ['test', 'success'], - ['deploy', 'running']]) + expect(statuses).to eq([%w(build success), + %w(test success), + %w(deploy running)]) end end end @@ -199,7 +199,7 @@ describe Ci::Pipeline, models: true do describe '#stages_name' do it 'returns a valid names of stages' do - expect(pipeline.stages_name).to eq(['build', 'test', 'deploy']) + expect(pipeline.stages_name).to eq(%w(build test deploy)) end end end @@ -767,7 +767,7 @@ describe Ci::Pipeline, models: true do end it 'cancels created builds' do - expect(latest_status).to eq ['canceled', 'canceled'] + expect(latest_status).to eq %w(canceled canceled) end end end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index f8513ac8b1c..76ce558eea0 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -113,7 +113,7 @@ describe Ci::Runner, models: true do context 'when runner has tags' do before do - runner.tag_list = ['bb', 'cc'] + runner.tag_list = %w(bb cc) end shared_examples 'tagged build picker' do @@ -169,7 +169,7 @@ describe Ci::Runner, models: true do context 'when having runner tags' do before do - runner.tag_list = ['bb', 'cc'] + runner.tag_list = %w(bb cc) end it 'cannot handle it for builds without matching tags' do @@ -189,7 +189,7 @@ describe Ci::Runner, models: true do context 'when having runner tags' do before do - runner.tag_list = ['bb', 'cc'] + runner.tag_list = %w(bb cc) build.tag_list = ['bb'] end @@ -212,7 +212,7 @@ describe Ci::Runner, models: true do context 'when having runner tags' do before do - runner.tag_list = ['bb', 'cc'] + runner.tag_list = %w(bb cc) build.tag_list = ['bb'] end diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index 6d599e148a2..0a10ee01506 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -109,7 +109,7 @@ describe MergeRequestDiff, models: true do { id: 'sha2' } ] - expect(subject.commits_sha).to eq(['sha1', 'sha2']) + expect(subject.commits_sha).to eq(%w(sha1 sha2)) end end diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb index dd5400f937b..d5a16226d9d 100644 --- a/spec/models/project_services/irker_service_spec.rb +++ b/spec/models/project_services/irker_service_spec.rb @@ -60,7 +60,7 @@ describe IrkerService, models: true do conn = @irker_server.accept conn.readlines.each do |line| msg = JSON.parse(line.chomp("\n")) - expect(msg.keys).to match_array(['to', 'privmsg']) + expect(msg.keys).to match_array(%w(to privmsg)) expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits", "irc://test.net/#test"]) end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 56ca4c04e7d..7cb75310204 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -775,7 +775,7 @@ describe API::Issues, api: true do expect(response).to have_http_status(201) expect(json_response['title']).to eq('new issue') expect(json_response['description']).to be_nil - expect(json_response['labels']).to eq(['label', 'label2']) + expect(json_response['labels']).to eq(%w(label label2)) expect(json_response['confidential']).to be_falsy end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index 566d11bba57..eb3553d3b71 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -21,11 +21,10 @@ describe API::Labels, api: true do create(:labeled_issue, project: project, labels: [label1], author: user, state: :closed) create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project ) - expected_keys = [ - 'id', 'name', 'color', 'description', - 'open_issues_count', 'closed_issues_count', 'open_merge_requests_count', - 'subscribed', 'priority' - ] + expected_keys = %w( +id name color description +open_issues_count closed_issues_count open_merge_requests_count +subscribed priority) get api("/projects/#{project.id}/labels", user) diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 61b3906d134..9f26560be78 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -250,7 +250,7 @@ describe API::MergeRequests, api: true do expect(response).to have_http_status(201) expect(json_response['title']).to eq('Test merge_request') - expect(json_response['labels']).to eq(['label', 'label2']) + expect(json_response['labels']).to eq(%w(label label2)) expect(json_response['milestone']['id']).to eq(milestone.id) expect(json_response['force_remove_source_branch']).to be_truthy end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index e78bc896ce8..30247b3bcc8 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -121,7 +121,7 @@ describe API::Projects, api: true do context 'and with simple=true' do it 'returns a simplified version of all the projects' do - expected_keys = ["id", "http_url_to_repo", "web_url", "name", "name_with_namespace", "path", "path_with_namespace"] + expected_keys = %w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace) get api('/projects?simple=true', user) diff --git a/spec/requests/api/v3/issues_spec.rb b/spec/requests/api/v3/issues_spec.rb index 8e6732fe23e..803acd55470 100644 --- a/spec/requests/api/v3/issues_spec.rb +++ b/spec/requests/api/v3/issues_spec.rb @@ -722,7 +722,7 @@ describe API::V3::Issues, api: true do expect(response).to have_http_status(201) expect(json_response['title']).to eq('new issue') expect(json_response['description']).to be_nil - expect(json_response['labels']).to eq(['label', 'label2']) + expect(json_response['labels']).to eq(%w(label label2)) expect(json_response['confidential']).to be_falsy end diff --git a/spec/requests/api/v3/labels_spec.rb b/spec/requests/api/v3/labels_spec.rb index bcb0c6b9449..a0fc9215c6e 100644 --- a/spec/requests/api/v3/labels_spec.rb +++ b/spec/requests/api/v3/labels_spec.rb @@ -21,11 +21,10 @@ describe API::V3::Labels, api: true do create(:labeled_issue, project: project, labels: [label1], author: user, state: :closed) create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project ) - expected_keys = [ - 'id', 'name', 'color', 'description', - 'open_issues_count', 'closed_issues_count', 'open_merge_requests_count', - 'subscribed', 'priority' - ] + expected_keys = %w( +id name color description +open_issues_count closed_issues_count open_merge_requests_count +subscribed priority) get v3_api("/projects/#{project.id}/labels", user) diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb index ce96ad0684f..cb370418e9c 100644 --- a/spec/requests/api/v3/merge_requests_spec.rb +++ b/spec/requests/api/v3/merge_requests_spec.rb @@ -237,7 +237,7 @@ describe API::MergeRequests, api: true do expect(response).to have_http_status(201) expect(json_response['title']).to eq('Test merge_request') - expect(json_response['labels']).to eq(['label', 'label2']) + expect(json_response['labels']).to eq(%w(label label2)) expect(json_response['milestone']['id']).to eq(milestone.id) expect(json_response['force_remove_source_branch']).to be_truthy end diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb index fc7da939b34..273a4a58224 100644 --- a/spec/requests/api/v3/projects_spec.rb +++ b/spec/requests/api/v3/projects_spec.rb @@ -84,7 +84,7 @@ describe API::V3::Projects, api: true do context 'GET /projects?simple=true' do it 'returns a simplified version of all the projects' do - expected_keys = ["id", "http_url_to_repo", "web_url", "name", "name_with_namespace", "path", "path_with_namespace"] + expected_keys = %w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace) get v3_api('/projects?simple=true', user) diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index ecdcdb677f4..5ba1209af5d 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Ci::API::Builds do include ApiHelpers - let(:runner) { FactoryGirl.create(:ci_runner, tag_list: ["mysql", "ruby"]) } + let(:runner) { FactoryGirl.create(:ci_runner, tag_list: %w(mysql ruby)) } let(:project) { FactoryGirl.create(:empty_project, shared_runners_enabled: false) } let(:last_update) { nil } diff --git a/spec/requests/ci/api/runners_spec.rb b/spec/requests/ci/api/runners_spec.rb index bd55934d0c8..8719313783e 100644 --- a/spec/requests/ci/api/runners_spec.rb +++ b/spec/requests/ci/api/runners_spec.rb @@ -41,7 +41,7 @@ describe Ci::API::Runners do it 'creates runner' do expect(response).to have_http_status 201 - expect(Ci::Runner.first.tag_list.sort).to eq(["tag1", "tag2"]) + expect(Ci::Runner.first.tag_list.sort).to eq(%w(tag1 tag2)) end end diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb index bb26513103d..b91234ddb1e 100644 --- a/spec/services/auth/container_registry_authentication_service_spec.rb +++ b/spec/services/auth/container_registry_authentication_service_spec.rb @@ -72,7 +72,7 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do shared_examples 'a pullable and pushable' do it_behaves_like 'a accessible' do - let(:actions) { ['pull', 'push'] } + let(:actions) { %w(pull push) } end end diff --git a/spec/services/merge_requests/resolve_service_spec.rb b/spec/services/merge_requests/resolve_service_spec.rb index 71e46969265..26cf0bbffdf 100644 --- a/spec/services/merge_requests/resolve_service_spec.rb +++ b/spec/services/merge_requests/resolve_service_spec.rb @@ -59,8 +59,8 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request.source_branch_head.parents.map(&:id)) - .to eq(['1450cd639e0bc6721eb02800169e464f212cde06', - '824be604a34828eb682305f0d963056cfac87b2d']) + .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 +824be604a34828eb682305f0d963056cfac87b2d)) end end @@ -125,8 +125,8 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request.source_branch_head.parents.map(&:id)) - .to eq(['1450cd639e0bc6721eb02800169e464f212cde06', - '824be604a34828eb682305f0d963056cfac87b2d']) + .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 +824be604a34828eb682305f0d963056cfac87b2d)) end it 'sets the content to the content given' do diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index d7712804125..dfa5175b7d8 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -631,7 +631,7 @@ describe SystemNoteService, services: true do jira_service_settings end - noteable_types = ["merge_requests", "commit"] + noteable_types = %w(merge_requests commit) noteable_types.each do |type| context "when noteable is a #{type}" do diff --git a/spec/support/repo_helpers.rb b/spec/support/repo_helpers.rb index 73f375c481b..aab5d32ff36 100644 --- a/spec/support/repo_helpers.rb +++ b/spec/support/repo_helpers.rb @@ -100,13 +100,12 @@ eos } ] - commits = [ - '5937ac0a7beb003549fc5fd26fc247adbce4a52e', - '570e7b2abdd848b95f2f578043fc23bd6f6fd24d', - '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', - 'd14d6c0abdd253381df51a723d58691b2ee1ab08', - 'c1acaa58bbcbc3eafe538cb8274ba387047b69f8', - ].reverse # last commit is recent one + commits = %w( +5937ac0a7beb003549fc5fd26fc247adbce4a52e +570e7b2abdd848b95f2f578043fc23bd6f6fd24d +6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 +d14d6c0abdd253381df51a723d58691b2ee1ab08 +c1acaa58bbcbc3eafe538cb8274ba387047b69f8).reverse # last commit is recent one OpenStruct.new( source_branch: 'master', From 75f5fa997de148c9bc0e5bd6e6f6050526a0b164 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 11:51:46 -0600 Subject: [PATCH 229/247] Enable Rails/Delegate --- .rubocop.yml | 2 +- app/helpers/application_settings_helper.rb | 25 +++++-------------- app/helpers/visibility_level_helper.rb | 10 +++----- app/models/ci/build.rb | 4 +-- app/models/ci/pipeline.rb | 4 +-- app/models/project.rb | 8 ++---- app/models/project_wiki.rb | 8 ++---- app/models/repository.rb | 8 ++---- app/policies/base_policy.rb | 4 +-- app/services/base_service.rb | 4 +-- .../ci/create_pipeline_builds_service.rb | 4 +-- app/views/layouts/nav/_admin.html.haml | 2 +- lib/bitbucket/connection.rb | 4 +-- lib/gitlab/access.rb | 4 +-- .../ci/build/artifacts/metadata/entry.rb | 4 +-- lib/gitlab/current_settings.rb | 4 +-- lib/gitlab/git/commit.rb | 4 +-- lib/gitlab/git/repository.rb | 14 +++-------- .../github_import/issuable_formatter.rb | 4 +-- lib/gitlab/ldap/person.rb | 4 +-- lib/gitlab/redis.rb | 8 ++---- lib/gitlab/visibility_level.rb | 4 +-- spec/lib/gitlab/utils_spec.rb | 4 +-- spec/models/user_spec.rb | 4 +-- .../ci/process_pipeline_service_spec.rb | 4 +-- 25 files changed, 39 insertions(+), 110 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 21d692c2859..e07282dd894 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -763,7 +763,7 @@ Rails/Date: # Prefer delegate method for delegations. Rails/Delegate: - Enabled: false + Enabled: true # Prefer `find_by` over `where.first`. Rails/FindBy: diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 60485160495..4b025669f69 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -1,28 +1,15 @@ module ApplicationSettingsHelper - def gravatar_enabled? - current_application_settings.gravatar_enabled? - end - - def signup_enabled? - current_application_settings.signup_enabled? - end - - def signin_enabled? - current_application_settings.signin_enabled? - end + delegate :gravatar_enabled?, + :signup_enabled?, + :signin_enabled?, + :akismet_enabled?, + :koding_enabled?, + to: :current_application_settings def user_oauth_applications? current_application_settings.user_oauth_applications end - def askimet_enabled? - current_application_settings.akismet_enabled? - end - - def koding_enabled? - current_application_settings.koding_enabled? - end - def allowed_protocols_present? current_application_settings.enabled_git_access_protocol.present? end diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb index fc93acfe63e..169cedeb796 100644 --- a/app/helpers/visibility_level_helper.rb +++ b/app/helpers/visibility_level_helper.rb @@ -89,13 +89,9 @@ module VisibilityLevelHelper current_application_settings.restricted_visibility_levels || [] end - def default_project_visibility - current_application_settings.default_project_visibility - end - - def default_group_visibility - current_application_settings.default_group_visibility - end + delegate :default_project_visibility, + :default_group_visibility, + to: :current_application_settings def skip_level?(form_model, level) form_model.is_a?(Project) && !form_model.visibility_level_allowed?(level) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 7e21eb22e27..d2a53315f1d 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -233,9 +233,7 @@ module Ci gl_project_id end - def project_name - project.name - end + delegate :name, to: :project, prefix: true def repo_url auth = "gitlab-ci-token:#{ensure_token!}@" diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 999720d2ea3..d2312215f85 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -153,9 +153,7 @@ module Ci builds.latest.with_artifacts_not_expired.includes(project: [:namespace]) end - def project_id - project.id - end + delegate :id, to: :project, prefix: true # For now the only user who participates is the user who triggered def participants(_current_user = nil) diff --git a/app/models/project.rb b/app/models/project.rb index f2be9e6a80c..a1b29d335b3 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -838,9 +838,7 @@ class Project < ActiveRecord::Base false end - def empty_repo? - repository.empty_repo? - end + delegate :empty_repo?, to: :repository def repo repository.raw @@ -1029,9 +1027,7 @@ class Project < ActiveRecord::Base forked? && project == forked_from_project end - def forks_count - forks.count - end + delegate :count, to: :forks, prefix: true def origin_merge_requests merge_requests.where(source_project_id: self.id) diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index de36fd3b252..2f55b853232 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -60,9 +60,7 @@ class ProjectWiki !!repository.exists? end - def empty? - pages.empty? - end + delegate :empty?, to: :pages # Returns an Array of Gitlab WikiPage instances or an # empty Array if this Wiki has no pages. @@ -160,9 +158,7 @@ class ProjectWiki } end - def repository_storage_path - project.repository_storage_path - end + delegate :repository_storage_path, to: :project private diff --git a/app/models/repository.rb b/app/models/repository.rb index 7113879417e..d1dd900d597 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -487,9 +487,7 @@ class Repository end cache_method :exists? - def empty? - raw_repository.empty? - end + delegate :empty?, to: :raw_repository cache_method :empty? # The size of this repository in megabytes. @@ -508,9 +506,7 @@ class Repository end cache_method :branch_names, fallback: [] - def tag_names - raw_repository.tag_names - end + delegate :tag_names, to: :raw_repository cache_method :tag_names, fallback: [] def branch_count diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb index b9f1c29c32e..e07b144355a 100644 --- a/app/policies/base_policy.rb +++ b/app/policies/base_policy.rb @@ -6,9 +6,7 @@ class BasePolicy @cannot_set = cannot_set end - def size - to_set.size - end + delegate :size, to: :to_set def self.empty new(Set.new, Set.new) diff --git a/app/services/base_service.rb b/app/services/base_service.rb index fa45506317e..745c2c4b681 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -28,9 +28,7 @@ class BaseService SystemHooksService.new end - def repository - project.repository - end + delegate :repository, to: :project # Add an error to the specified model for restricted visibility levels def deny_visibility_level(model, denied_visibility_level = nil) diff --git a/app/services/ci/create_pipeline_builds_service.rb b/app/services/ci/create_pipeline_builds_service.rb index c5da757c840..4cbbd366cc4 100644 --- a/app/services/ci/create_pipeline_builds_service.rb +++ b/app/services/ci/create_pipeline_builds_service.rb @@ -10,9 +10,7 @@ module Ci end end - def project - pipeline.project - end + delegate :project, to: :pipeline private diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index 19a947af4ca..d068c895fa3 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -33,7 +33,7 @@ Abuse Reports %span.badge.count= number_with_delimiter(AbuseReport.count(:all)) - - if askimet_enabled? + - if akismet_enabled? = nav_link(controller: :spam_logs) do = link_to admin_spam_logs_path, title: "Spam Logs" do %span diff --git a/lib/bitbucket/connection.rb b/lib/bitbucket/connection.rb index 287410bf46f..b9279c33f5b 100644 --- a/lib/bitbucket/connection.rb +++ b/lib/bitbucket/connection.rb @@ -24,9 +24,7 @@ module Bitbucket response.parsed end - def expired? - connection.expired? - end + delegate :expired?, to: :connection def refresh! response = connection.refresh! diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb index 9b484a2ecfd..3b210eeda9d 100644 --- a/lib/gitlab/access.rb +++ b/lib/gitlab/access.rb @@ -21,9 +21,7 @@ module Gitlab PROTECTION_DEV_CAN_MERGE = 3 class << self - def values - options.values - end + delegate :values, to: :options def all_values options_with_owner.values diff --git a/lib/gitlab/ci/build/artifacts/metadata/entry.rb b/lib/gitlab/ci/build/artifacts/metadata/entry.rb index 7f4c750b6fd..c1d4d541efb 100644 --- a/lib/gitlab/ci/build/artifacts/metadata/entry.rb +++ b/lib/gitlab/ci/build/artifacts/metadata/entry.rb @@ -91,9 +91,7 @@ module Gitlab blank_node? || @entries.include?(@path) end - def empty? - children.empty? - end + delegate :empty?, to: :children def total_size descendant_pattern = %r{^#{Regexp.escape(@path)}} diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index e20f5f6f514..82576d197fe 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -25,9 +25,7 @@ module Gitlab settings || in_memory_application_settings end - def sidekiq_throttling_enabled? - current_application_settings.sidekiq_throttling_enabled? - end + delegate :sidekiq_throttling_enabled?, to: :current_application_settings def in_memory_application_settings @in_memory_application_settings ||= ::ApplicationSetting.new(::ApplicationSetting.defaults) diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb index d785516ebdd..fd2b26c4a63 100644 --- a/lib/gitlab/git/commit.rb +++ b/lib/gitlab/git/commit.rb @@ -218,9 +218,7 @@ module Gitlab raw_commit.parents.map { |c| Gitlab::Git::Commit.new(c) } end - def tree - raw_commit.tree - end + delegate :tree, to: :raw_commit def stats Gitlab::Git::CommitStats.new(self) diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 7068e68a855..e1fabff4e29 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -162,13 +162,9 @@ module Gitlab !empty? end - def empty? - rugged.empty? - end - - def bare? - rugged.bare? - end + delegate :empty?, + :bare?, + to: :rugged def repo_exists? !!rugged @@ -565,9 +561,7 @@ module Gitlab # will trigger a +:mixed+ reset and the working directory will be # replaced with the content of the index. (Untracked and ignored files # will be left alone) - def reset(ref, reset_type) - rugged.reset(ref, reset_type) - end + delegate :reset, to: :rugged # Mimic the `git clean` command and recursively delete untracked files. # Valid keys that can be passed in the +options+ hash are: diff --git a/lib/gitlab/github_import/issuable_formatter.rb b/lib/gitlab/github_import/issuable_formatter.rb index 29fb0f9d333..27b171d6ddb 100644 --- a/lib/gitlab/github_import/issuable_formatter.rb +++ b/lib/gitlab/github_import/issuable_formatter.rb @@ -7,9 +7,7 @@ module Gitlab raise NotImplementedError end - def number - raw_data.number - end + delegate :number, to: :raw_data def find_condition { iid: number } diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb index 7084fd1767d..43eb73250b7 100644 --- a/lib/gitlab/ldap/person.rb +++ b/lib/gitlab/ldap/person.rb @@ -43,9 +43,7 @@ module Gitlab attribute_value(:email) end - def dn - entry.dn - end + delegate :dn, to: :entry private diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb index 53665c8375e..e9c07095042 100644 --- a/lib/gitlab/redis.rb +++ b/lib/gitlab/redis.rb @@ -13,15 +13,11 @@ module Gitlab class << self # Do NOT cache in an instance variable. Result may be mutated by caller. - def params - new.params - end + delegate :params, to: :new # Do NOT cache in an instance variable. Result may be mutated by caller. # @deprecated Use .params instead to get sentinel support - def url - new.url - end + delegate :url, to: :new def with @pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) } diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb index a4e966e4016..b28708c34e1 100644 --- a/lib/gitlab/visibility_level.rb +++ b/lib/gitlab/visibility_level.rb @@ -33,9 +33,7 @@ module Gitlab PUBLIC = 20 unless const_defined?(:PUBLIC) class << self - def values - options.values - end + delegate :values, to: :options def options { diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb index d5d87310874..56772409989 100644 --- a/spec/lib/gitlab/utils_spec.rb +++ b/spec/lib/gitlab/utils_spec.rb @@ -1,7 +1,5 @@ describe Gitlab::Utils, lib: true do - def to_boolean(value) - described_class.to_boolean(value) - end + delegate :to_boolean, to: :described_class describe '.to_boolean' do it 'accepts booleans' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index be9847f37b3..2c03a485823 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -693,9 +693,7 @@ describe User, models: true do end describe '.search_with_secondary_emails' do - def search_with_secondary_emails(query) - described_class.search_with_secondary_emails(query) - end + delegate :search_with_secondary_emails, to: :described_class let!(:user) { create(:user) } let!(:email) { create(:email) } diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index ef2ddc4b1d7..b818dfdd50c 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -377,9 +377,7 @@ describe Ci::ProcessPipelineService, :services do builds.pending.update_all(status: 'success') end - def manual_actions - pipeline.manual_actions - end + delegate :manual_actions, to: :pipeline def create_build(name, stage_idx, when_value = nil) create(:ci_build, From e2bbbb1a9aea72e4313cdc257460eb416fe8dc0b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 12:03:32 -0600 Subject: [PATCH 230/247] Fix new offenses --- app/controllers/concerns/spammable_actions.rb | 2 +- .../project_services/pushover_service.rb | 2 +- app/models/user.rb | 2 +- config/initializers/metrics.rb | 14 ++++---- lib/gitlab/ci/config/entry/global.rb | 2 +- lib/gitlab/ci/config/entry/jobs.rb | 2 +- spec/lib/expand_variables_spec.rb | 14 ++++---- .../gitlab/bitbucket_import/importer_spec.rb | 4 +-- .../lib/gitlab/ci/config/entry/global_spec.rb | 4 +-- spec/lib/gitlab/ci/config/entry/job_spec.rb | 10 +++--- .../gitlab/ci/status/build/factory_spec.rb | 2 +- spec/lib/gitlab/import_sources_spec.rb | 32 ++++++++++--------- spec/lib/gitlab/incoming_email_spec.rb | 4 +-- spec/requests/api/labels_spec.rb | 7 ++-- spec/requests/api/v3/labels_spec.rb | 7 ++-- .../merge_requests/resolve_service_spec.rb | 6 ++-- spec/support/repo_helpers.rb | 13 ++++---- spec/support/stub_gitlab_calls.rb | 2 +- 18 files changed, 67 insertions(+), 62 deletions(-) diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb index da225d8f1c7..d0a692070d9 100644 --- a/app/controllers/concerns/spammable_actions.rb +++ b/app/controllers/concerns/spammable_actions.rb @@ -27,7 +27,7 @@ module SpammableActions render :verify else - fallback.call + yield end end diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index 689bf03f469..3e618a8dbf1 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -55,7 +55,7 @@ class PushoverService < Service ['Pushover Echo (long)', 'echo'], ['Up Down (long)', 'updown'], ['None (silent)', 'none'] - ]}, + ] }, ] end diff --git a/app/models/user.rb b/app/models/user.rb index 296bcc699a9..801c84dc011 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -581,7 +581,7 @@ class User < ActiveRecord::Base if project.repository.branch_exists?(event.branch_name) merge_requests = MergeRequest.where("created_at >= ?", event.created_at) .where(source_project_id: project.id, - source_branch: event.branch_name) + source_branch: event.branch_name) merge_requests.empty? end end diff --git a/config/initializers/metrics.rb b/config/initializers/metrics.rb index 76ce7479a41..f082495cd7d 100644 --- a/config/initializers/metrics.rb +++ b/config/initializers/metrics.rb @@ -20,13 +20,13 @@ def instrument_classes(instrumentation) # Path to search => prefix to strip from constant paths_to_instrument = { - %w(app finders) => %w(app finders), - %w(app mailers emails) => %w(app mailers), - ['app', 'services', '**'] => %w(app services), - %w(lib gitlab conflicts) => ['lib'], - %w(lib gitlab diff) => ['lib'], - %w(lib gitlab email message) => ['lib'], - %w(lib gitlab checks) => ['lib'] + %w(app finders) => %w(app finders), + %w(app mailers emails) => %w(app mailers), + %w(app services **) => %w(app services), + %w(lib gitlab conflicts) => ['lib'], + %w(lib gitlab diff) => ['lib'], + %w(lib gitlab email message) => ['lib'], + %w(lib gitlab checks) => ['lib'] } paths_to_instrument.each do |(path, prefix)| diff --git a/lib/gitlab/ci/config/entry/global.rb b/lib/gitlab/ci/config/entry/global.rb index ac771662b2f..a4ec8f0ff2f 100644 --- a/lib/gitlab/ci/config/entry/global.rb +++ b/lib/gitlab/ci/config/entry/global.rb @@ -49,7 +49,7 @@ module Gitlab factory = Entry::Factory.new(Entry::Jobs) .value(@config.except(*self.class.nodes.keys)) .with(key: :jobs, parent: self, - description: 'Jobs definition for this pipeline') + description: 'Jobs definition for this pipeline') @entries[:jobs] = factory.create! end diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb index a487a3a06d6..5671a09480b 100644 --- a/lib/gitlab/ci/config/entry/jobs.rb +++ b/lib/gitlab/ci/config/entry/jobs.rb @@ -35,7 +35,7 @@ module Gitlab .value(config || {}) .metadata(name: name) .with(key: name, parent: self, - description: "#{name} job definition.") + description: "#{name} job definition.") @entries[name] = factory.create! end diff --git a/spec/lib/expand_variables_spec.rb b/spec/lib/expand_variables_spec.rb index 9fe15993a7d..730ca1f7c0a 100644 --- a/spec/lib/expand_variables_spec.rb +++ b/spec/lib/expand_variables_spec.rb @@ -15,41 +15,41 @@ describe ExpandVariables do result: 'keyvalue', variables: [ { key: 'variable', value: 'value' } - ]}, + ] }, { value: 'key${variable}', result: 'keyvalue', variables: [ { key: 'variable', value: 'value' } - ]}, + ] }, { value: 'key$variable$variable2', result: 'keyvalueresult', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' }, - ]}, + ] }, { value: 'key${variable}${variable2}', result: 'keyvalueresult', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' } - ]}, + ] }, { value: 'key$variable2$variable', result: 'keyresultvalue', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' }, - ]}, + ] }, { value: 'key${variable2}${variable}', result: 'keyresultvalue', variables: [ { key: 'variable', value: 'value' }, { key: 'variable2', value: 'result' } - ]}, + ] }, { value: 'review/$CI_BUILD_REF_NAME', result: 'review/feature/add-review-apps', variables: [ { key: 'CI_BUILD_REF_NAME', value: 'feature/add-review-apps' } - ]}, + ] }, ] tests.each do |test| diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb index 9e557d06ef0..aceb6bf871c 100644 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -89,8 +89,8 @@ describe Gitlab::BitbucketImport::Importer, lib: true do stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on") .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }) .to_return(status: 200, - body: "", - headers: {}) + body: "", + headers: {}) sample_issues_statuses.each_with_index do |issue, index| stub_request( diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index d9e48715984..ebd80ac5e1d 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::Ci::Config::Entry::Global do it 'contains the expected node names' do expect(described_class.nodes.keys) .to match_array(%i[before_script image services - after_script variables stages - types cache]) + after_script variables stages + types cache]) end end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 7a733e6a4a7..d20f4ec207d 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -140,11 +140,11 @@ describe Gitlab::Ci::Config::Entry::Job do it 'returns correct value' do expect(entry.value) .to eq(name: :rspec, - before_script: %w[ls pwd], - script: %w[rspec], - commands: "ls\npwd\nrspec", - stage: 'test', - after_script: %w[cleanup]) + before_script: %w[ls pwd], + script: %w[rspec], + commands: "ls\npwd\nrspec", + stage: 'test', + after_script: %w[cleanup]) end end end diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index 16f0a7b5388..0c40fca0c1a 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -69,7 +69,7 @@ describe Gitlab::Ci::Status::Build::Factory do it 'matches correct extended statuses' do expect(factory.extended_statuses) .to eq [Gitlab::Ci::Status::Build::Retryable, - Gitlab::Ci::Status::Build::FailedAllowed] + Gitlab::Ci::Status::Build::FailedAllowed] end it 'fabricates a failed but allowed build status' do diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb index 962af8bdf42..b3b5e5e7e33 100644 --- a/spec/lib/gitlab/import_sources_spec.rb +++ b/spec/lib/gitlab/import_sources_spec.rb @@ -23,14 +23,15 @@ describe Gitlab::ImportSources do it 'returns an array' do expected = %w( -github -bitbucket -gitlab -google_code -fogbugz -git -gitlab_project -gitea) + github + bitbucket + gitlab + google_code + fogbugz + git + gitlab_project + gitea + ) expect(described_class.values).to eq(expected) end @@ -40,13 +41,14 @@ gitea) it 'returns an array of importer names' do expected = %w( -github -bitbucket -gitlab -google_code -fogbugz -gitlab_project -gitea) + github + bitbucket + gitlab + google_code + fogbugz + gitlab_project + gitea + ) expect(described_class.importer_names).to eq(expected) end diff --git a/spec/lib/gitlab/incoming_email_spec.rb b/spec/lib/gitlab/incoming_email_spec.rb index 66fc3ad0c3b..698bd72d0f8 100644 --- a/spec/lib/gitlab/incoming_email_spec.rb +++ b/spec/lib/gitlab/incoming_email_spec.rb @@ -101,8 +101,8 @@ describe Gitlab::IncomingEmail, lib: true do it 'returns reply key' do expect(described_class.scan_fallback_references(references)) .to eq(%w[issue_1@localhost - reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost - exchange@microsoft.com]) + reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost + exchange@microsoft.com]) end end end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index eb3553d3b71..af271dbd4f5 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -22,9 +22,10 @@ describe API::Labels, api: true do create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project ) expected_keys = %w( -id name color description -open_issues_count closed_issues_count open_merge_requests_count -subscribed priority) + id name color description + open_issues_count closed_issues_count open_merge_requests_count + subscribed priority + ) get api("/projects/#{project.id}/labels", user) diff --git a/spec/requests/api/v3/labels_spec.rb b/spec/requests/api/v3/labels_spec.rb index a0fc9215c6e..f44403374e9 100644 --- a/spec/requests/api/v3/labels_spec.rb +++ b/spec/requests/api/v3/labels_spec.rb @@ -22,9 +22,10 @@ describe API::V3::Labels, api: true do create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project ) expected_keys = %w( -id name color description -open_issues_count closed_issues_count open_merge_requests_count -subscribed priority) + id name color description + open_issues_count closed_issues_count open_merge_requests_count + subscribed priority + ) get v3_api("/projects/#{project.id}/labels", user) diff --git a/spec/services/merge_requests/resolve_service_spec.rb b/spec/services/merge_requests/resolve_service_spec.rb index 26cf0bbffdf..b7f475597b4 100644 --- a/spec/services/merge_requests/resolve_service_spec.rb +++ b/spec/services/merge_requests/resolve_service_spec.rb @@ -60,7 +60,7 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request.source_branch_head.parents.map(&:id)) .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 -824be604a34828eb682305f0d963056cfac87b2d)) + 824be604a34828eb682305f0d963056cfac87b2d)) end end @@ -86,7 +86,7 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request_from_fork.source_branch_head.parents.map(&:id)) .to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', - target_head]) + target_head]) end end end @@ -126,7 +126,7 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request.source_branch_head.parents.map(&:id)) .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 -824be604a34828eb682305f0d963056cfac87b2d)) + 824be604a34828eb682305f0d963056cfac87b2d)) end it 'sets the content to the content given' do diff --git a/spec/support/repo_helpers.rb b/spec/support/repo_helpers.rb index aab5d32ff36..e9d5c7b12ae 100644 --- a/spec/support/repo_helpers.rb +++ b/spec/support/repo_helpers.rb @@ -42,7 +42,7 @@ Signed-off-by: Dmitriy Zaporozhets eos ) end - + def another_sample_commit OpenStruct.new( id: "e56497bb5f03a90a51293fc6d516788730953899", @@ -101,11 +101,12 @@ eos ] commits = %w( -5937ac0a7beb003549fc5fd26fc247adbce4a52e -570e7b2abdd848b95f2f578043fc23bd6f6fd24d -6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 -d14d6c0abdd253381df51a723d58691b2ee1ab08 -c1acaa58bbcbc3eafe538cb8274ba387047b69f8).reverse # last commit is recent one + 5937ac0a7beb003549fc5fd26fc247adbce4a52e + 570e7b2abdd848b95f2f578043fc23bd6f6fd24d + 6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 + d14d6c0abdd253381df51a723d58691b2ee1ab08 + c1acaa58bbcbc3eafe538cb8274ba387047b69f8 + ).reverse # last commit is recent one OpenStruct.new( source_branch: 'master', diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 641b11d51bf..69e1ad18b15 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -53,7 +53,7 @@ module StubGitlabCalls stub_request(:post, "#{gitlab_url}api/v3/session.json") .with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}", - headers: { 'Content-Type' => 'application/json' }) + headers: { 'Content-Type' => 'application/json' }) .to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' }) end From 87c9df29ce8835da5d68dbf3e59674bd4524ee96 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 12:18:40 -0600 Subject: [PATCH 231/247] =?UTF-8?q?Don=E2=80=99t=20exclude=20some=20file?= =?UTF-8?q?=20in=20lib=20from=20rubocop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .rubocop.yml | 21 +++++--- lib/backup/database.rb | 70 ++++++++++++++------------ lib/backup/files.rb | 8 +-- lib/backup/manager.rb | 26 +++++----- lib/backup/repository.rb | 15 +++--- lib/backup/uploads.rb | 1 - lib/gitlab/seeder.rb | 2 +- lib/gitlab/upgrader.rb | 10 ++-- lib/tasks/brakeman.rake | 2 +- lib/tasks/cache.rake | 2 +- lib/tasks/dev.rake | 2 +- lib/tasks/downtime_check.rake | 10 ++-- lib/tasks/flay.rake | 2 +- lib/tasks/gemojione.rake | 6 +-- lib/tasks/gitlab/assets.rake | 2 +- lib/tasks/gitlab/check.rake | 58 +++++++++------------ lib/tasks/gitlab/cleanup.rake | 11 ++-- lib/tasks/gitlab/db.rake | 8 +-- lib/tasks/gitlab/git.rake | 2 - lib/tasks/gitlab/import.rake | 2 +- lib/tasks/gitlab/import_export.rake | 2 +- lib/tasks/gitlab/info.rake | 19 +++---- lib/tasks/gitlab/shell.rake | 6 +-- lib/tasks/gitlab/sidekiq.rake | 6 +-- lib/tasks/gitlab/task_helpers.rb | 44 +++++++--------- lib/tasks/gitlab/test.rake | 12 ++--- lib/tasks/gitlab/track_deployment.rake | 4 +- lib/tasks/gitlab/update_templates.rake | 2 +- lib/tasks/gitlab/web_hook.rake | 6 +-- lib/tasks/lint.rake | 1 - lib/tasks/migrate/migrate_iids.rake | 2 +- lib/tasks/services.rake | 10 ++-- lib/tasks/sidekiq.rake | 8 +-- lib/tasks/spec.rake | 30 +++++------ lib/tasks/spinach.rake | 2 +- 35 files changed, 201 insertions(+), 213 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index e07282dd894..86f5df61724 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -22,13 +22,6 @@ AllCops: - 'db/fixtures/**/*' - 'tmp/**/*' - 'bin/**/*' - - 'lib/backup/**/*' - - 'lib/ci/backup/**/*' - - 'lib/tasks/**/*' - - 'lib/ci/migrate/**/*' - - 'lib/email_validator.rb' - - 'lib/gitlab/upgrader.rb' - - 'lib/gitlab/seeder.rb' - 'generator_templates/**/*' # Style ####################################################################### @@ -208,6 +201,9 @@ Style/FrozenStringLiteralComment: # Do not introduce global variables. Style/GlobalVars: Enabled: true + Exclude: + - 'lib/backup/**/*' + - 'lib/tasks/**/*' # Prefer Ruby 1.9 hash syntax `{ a: 1, b: 2 }` # over 1.8 syntax `{ :a => 1, :b => 2 }`. @@ -780,6 +776,11 @@ Rails/HasAndBelongsToMany: # Checks for calls to puts, print, etc. Rails/Output: Enabled: true + Exclude: + - lib/gitlab/seeder.rb + - lib/gitlab/upgrader.rb + - 'lib/backup/**/*' + - 'lib/tasks/**/*' # Checks for incorrect grammar when using methods like `3.day.ago`. Rails/PluralizationGrammar: @@ -971,3 +972,9 @@ Style/ConditionalAssignment: Style/DoubleNegation: Enabled: false + +Rails/Exit: + Enabled: true + Exclude: + - lib/gitlab/upgrader.rb + - 'lib/backup/**/*' diff --git a/lib/backup/database.rb b/lib/backup/database.rb index 22319ec6623..4016ac76348 100644 --- a/lib/backup/database.rb +++ b/lib/backup/database.rb @@ -5,7 +5,7 @@ module Backup attr_reader :config, :db_file_name def initialize - @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] + @config = YAML.load_file(File.join(Rails.root, 'config', 'database.yml'))[Rails.env] @db_file_name = File.join(Gitlab.config.backup.path, 'db', 'database.sql.gz') end @@ -13,28 +13,32 @@ module Backup FileUtils.mkdir_p(File.dirname(db_file_name)) FileUtils.rm_f(db_file_name) compress_rd, compress_wr = IO.pipe - compress_pid = spawn(*%W(gzip -1 -c), in: compress_rd, out: [db_file_name, 'w', 0600]) + compress_pid = spawn(*%w(gzip -1 -c), in: compress_rd, out: [db_file_name, 'w', 0600]) compress_rd.close - dump_pid = case config["adapter"] - when /^mysql/ then - $progress.print "Dumping MySQL database #{config['database']} ... " - # Workaround warnings from MySQL 5.6 about passwords on cmd line - ENV['MYSQL_PWD'] = config["password"].to_s if config["password"] - spawn('mysqldump', *mysql_args, config['database'], out: compress_wr) - when "postgresql" then - $progress.print "Dumping PostgreSQL database #{config['database']} ... " - pg_env - pgsql_args = ["--clean"] # Pass '--clean' to include 'DROP TABLE' statements in the DB dump. - if Gitlab.config.backup.pg_schema - pgsql_args << "-n" - pgsql_args << Gitlab.config.backup.pg_schema + dump_pid = + case config["adapter"] + when /^mysql/ then + $progress.print "Dumping MySQL database #{config['database']} ... " + # Workaround warnings from MySQL 5.6 about passwords on cmd line + ENV['MYSQL_PWD'] = config["password"].to_s if config["password"] + spawn('mysqldump', *mysql_args, config['database'], out: compress_wr) + when "postgresql" then + $progress.print "Dumping PostgreSQL database #{config['database']} ... " + pg_env + pgsql_args = ["--clean"] # Pass '--clean' to include 'DROP TABLE' statements in the DB dump. + if Gitlab.config.backup.pg_schema + pgsql_args << "-n" + pgsql_args << Gitlab.config.backup.pg_schema + end + spawn('pg_dump', *pgsql_args, config['database'], out: compress_wr) end - spawn('pg_dump', *pgsql_args, config['database'], out: compress_wr) - end compress_wr.close - success = [compress_pid, dump_pid].all? { |pid| Process.waitpid(pid); $?.success? } + success = [compress_pid, dump_pid].all? do |pid| + Process.waitpid(pid) + $?.success? + end report_success(success) abort 'Backup failed' unless success @@ -42,23 +46,27 @@ module Backup def restore decompress_rd, decompress_wr = IO.pipe - decompress_pid = spawn(*%W(gzip -cd), out: decompress_wr, in: db_file_name) + decompress_pid = spawn(*%w(gzip -cd), out: decompress_wr, in: db_file_name) decompress_wr.close - restore_pid = case config["adapter"] - when /^mysql/ then - $progress.print "Restoring MySQL database #{config['database']} ... " - # Workaround warnings from MySQL 5.6 about passwords on cmd line - ENV['MYSQL_PWD'] = config["password"].to_s if config["password"] - spawn('mysql', *mysql_args, config['database'], in: decompress_rd) - when "postgresql" then - $progress.print "Restoring PostgreSQL database #{config['database']} ... " - pg_env - spawn('psql', config['database'], in: decompress_rd) - end + restore_pid = + case config["adapter"] + when /^mysql/ then + $progress.print "Restoring MySQL database #{config['database']} ... " + # Workaround warnings from MySQL 5.6 about passwords on cmd line + ENV['MYSQL_PWD'] = config["password"].to_s if config["password"] + spawn('mysql', *mysql_args, config['database'], in: decompress_rd) + when "postgresql" then + $progress.print "Restoring PostgreSQL database #{config['database']} ... " + pg_env + spawn('psql', config['database'], in: decompress_rd) + end decompress_rd.close - success = [decompress_pid, restore_pid].all? { |pid| Process.waitpid(pid); $?.success? } + success = [decompress_pid, restore_pid].all? do |pid| + Process.waitpid(pid) + $?.success? + end report_success(success) abort 'Restore failed' unless success diff --git a/lib/backup/files.rb b/lib/backup/files.rb index 247c32c1c0a..30a91647b77 100644 --- a/lib/backup/files.rb +++ b/lib/backup/files.rb @@ -26,10 +26,10 @@ module Backup abort 'Backup failed' end - run_pipeline!([%W(tar -C #{@backup_files_dir} -cf - .), %W(gzip -c -1)], out: [backup_tarball, 'w', 0600]) + run_pipeline!([%W(tar -C #{@backup_files_dir} -cf - .), %w(gzip -c -1)], out: [backup_tarball, 'w', 0600]) FileUtils.rm_rf(@backup_files_dir) else - run_pipeline!([%W(tar -C #{app_files_dir} -cf - .), %W(gzip -c -1)], out: [backup_tarball, 'w', 0600]) + run_pipeline!([%W(tar -C #{app_files_dir} -cf - .), %w(gzip -c -1)], out: [backup_tarball, 'w', 0600]) end end @@ -37,7 +37,7 @@ module Backup backup_existing_files_dir create_files_dir - run_pipeline!([%W(gzip -cd), %W(tar -C #{app_files_dir} -xf -)], in: backup_tarball) + run_pipeline!([%w(gzip -cd), %W(tar -C #{app_files_dir} -xf -)], in: backup_tarball) end def backup_existing_files_dir @@ -47,7 +47,7 @@ module Backup end end - def run_pipeline!(cmd_list, options={}) + def run_pipeline!(cmd_list, options = {}) status_list = Open3.pipeline(*cmd_list, options) abort 'Backup failed' unless status_list.compact.all?(&:success?) end diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index f099c0651ac..5cc164a6325 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -1,8 +1,8 @@ module Backup class Manager - ARCHIVES_TO_BACKUP = %w[uploads builds artifacts pages lfs registry] - FOLDERS_TO_BACKUP = %w[repositories db] - FILE_NAME_SUFFIX = '_gitlab_backup.tar' + ARCHIVES_TO_BACKUP = %w[uploads builds artifacts pages lfs registry].freeze + FOLDERS_TO_BACKUP = %w[repositories db].freeze + FILE_NAME_SUFFIX = '_gitlab_backup.tar'.freeze def pack # Make sure there is a connection @@ -20,13 +20,13 @@ module Backup Dir.chdir(Gitlab.config.backup.path) do File.open("#{Gitlab.config.backup.path}/backup_information.yml", "w+") do |file| - file << s.to_yaml.gsub(/^---\n/,'') + file << s.to_yaml.gsub(/^---\n/, '') end # create archive $progress.print "Creating backup archive: #{tar_file} ... " # Set file permissions on open to prevent chmod races. - tar_system_options = {out: [tar_file, 'w', Gitlab.config.backup.archive_permissions]} + tar_system_options = { out: [tar_file, 'w', Gitlab.config.backup.archive_permissions] } if Kernel.system('tar', '-cf', '-', *backup_contents, tar_system_options) $progress.puts "done".color(:green) else @@ -50,8 +50,8 @@ module Backup directory = connect_to_remote_directory(connection_settings) if directory.files.create(key: tar_file, body: File.open(tar_file), public: false, - multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size, - encryption: Gitlab.config.backup.upload.encryption) + multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size, + encryption: Gitlab.config.backup.upload.encryption) $progress.puts "done".color(:green) else puts "uploading backup to #{remote_directory} failed".color(:red) @@ -123,11 +123,11 @@ module Backup exit 1 end - if ENV['BACKUP'].present? - tar_file = "#{ENV['BACKUP']}#{FILE_NAME_SUFFIX}" - else - tar_file = file_list.first - end + tar_file = if ENV['BACKUP'].present? + "#{ENV['BACKUP']}#{FILE_NAME_SUFFIX}" + else + file_list.first + end unless File.exist?(tar_file) $progress.puts "The backup file #{tar_file} does not exist!" @@ -158,7 +158,7 @@ module Backup end def tar_version - tar_version, _ = Gitlab::Popen.popen(%W(tar --version)) + tar_version, _ = Gitlab::Popen.popen(%w(tar --version)) tar_version.force_encoding('locale').split("\n").first end diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb index 91e43dcb114..d16d5ba4960 100644 --- a/lib/backup/repository.rb +++ b/lib/backup/repository.rb @@ -2,7 +2,7 @@ require 'yaml' module Backup class Repository - + # rubocop:disable Metrics/AbcSize def dump prepare @@ -85,11 +85,11 @@ module Backup project.ensure_dir_exist - if File.exists?(path_to_project_bundle) - cmd = %W(#{Gitlab.config.git.bin_path} clone --bare #{path_to_project_bundle} #{path_to_project_repo}) - else - cmd = %W(#{Gitlab.config.git.bin_path} init --bare #{path_to_project_repo}) - end + cmd = if File.exist?(path_to_project_bundle) + %W(#{Gitlab.config.git.bin_path} clone --bare #{path_to_project_bundle} #{path_to_project_repo}) + else + %W(#{Gitlab.config.git.bin_path} init --bare #{path_to_project_repo}) + end output, status = Gitlab::Popen.popen(cmd) if status.zero? @@ -150,6 +150,7 @@ module Backup puts output end end + # rubocop:enable Metrics/AbcSize protected @@ -193,7 +194,7 @@ module Backup end def silent - {err: '/dev/null', out: '/dev/null'} + { err: '/dev/null', out: '/dev/null' } end private diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb index 9261f77f3c9..35118375499 100644 --- a/lib/backup/uploads.rb +++ b/lib/backup/uploads.rb @@ -2,7 +2,6 @@ require 'backup/files' module Backup class Uploads < Files - def initialize super('uploads', Rails.root.join('public/uploads')) end diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb index 7cf506ebe64..6fb0be493e8 100644 --- a/lib/gitlab/seeder.rb +++ b/lib/gitlab/seeder.rb @@ -18,7 +18,7 @@ def Notify.deliver_later self end eos - eval(code) + eval(code) # rubocop:disable Lint/Eval end end end diff --git a/lib/gitlab/upgrader.rb b/lib/gitlab/upgrader.rb index 4cc34e34460..961df0468a4 100644 --- a/lib/gitlab/upgrader.rb +++ b/lib/gitlab/upgrader.rb @@ -46,7 +46,7 @@ module Gitlab git_tags = fetch_git_tags git_tags = git_tags.select { |version| version =~ /v\d+\.\d+\.\d+\Z/ } git_versions = git_tags.map { |tag| Gitlab::VersionInfo.parse(tag.match(/v\d+\.\d+\.\d+/).to_s) } - "v#{git_versions.sort.last.to_s}" + "v#{git_versions.sort.last}" end def fetch_git_tags @@ -59,10 +59,10 @@ module Gitlab "Stash changed files" => %W(#{Gitlab.config.git.bin_path} stash), "Get latest code" => %W(#{Gitlab.config.git.bin_path} fetch), "Switch to new version" => %W(#{Gitlab.config.git.bin_path} checkout v#{latest_version}), - "Install gems" => %W(bundle), - "Migrate DB" => %W(bundle exec rake db:migrate), - "Recompile assets" => %W(bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile), - "Clear cache" => %W(bundle exec rake cache:clear) + "Install gems" => %w(bundle), + "Migrate DB" => %w(bundle exec rake db:migrate), + "Recompile assets" => %w(bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile), + "Clear cache" => %w(bundle exec rake cache:clear) } end diff --git a/lib/tasks/brakeman.rake b/lib/tasks/brakeman.rake index d5a402907d8..2301ec9b228 100644 --- a/lib/tasks/brakeman.rake +++ b/lib/tasks/brakeman.rake @@ -2,7 +2,7 @@ desc 'Security check via brakeman' task :brakeman do # We get 0 warnings at level 'w3' but we would like to reach 'w2'. Merge # requests are welcome! - if system(*%W(brakeman --no-progress --skip-files lib/backup/repository.rb -w3 -z)) + if system(*%w(brakeman --no-progress --skip-files lib/backup/repository.rb -w3 -z)) puts 'Security check succeed' else puts 'Security check failed' diff --git a/lib/tasks/cache.rake b/lib/tasks/cache.rake index 78ae187817a..d55923673b1 100644 --- a/lib/tasks/cache.rake +++ b/lib/tasks/cache.rake @@ -1,7 +1,7 @@ namespace :cache do namespace :clear do REDIS_CLEAR_BATCH_SIZE = 1000 # There seems to be no speedup when pushing beyond 1,000 - REDIS_SCAN_START_STOP = '0' # Magic value, see http://redis.io/commands/scan + REDIS_SCAN_START_STOP = '0'.freeze # Magic value, see http://redis.io/commands/scan desc "GitLab | Clear redis cache" task redis: :environment do diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index 5e94fba97bf..e65609d7001 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -2,7 +2,7 @@ task dev: ["dev:setup"] namespace :dev do desc "GitLab | Setup developer environment (db, fixtures)" - task :setup => :environment do + task setup: :environment do ENV['force'] = 'yes' Rake::Task["gitlab:setup"].invoke Rake::Task["gitlab:shell:setup"].invoke diff --git a/lib/tasks/downtime_check.rake b/lib/tasks/downtime_check.rake index afe5d42910c..557f4fef10b 100644 --- a/lib/tasks/downtime_check.rake +++ b/lib/tasks/downtime_check.rake @@ -1,10 +1,10 @@ desc 'Checks if migrations in a branch require downtime' task downtime_check: :environment do - if defined?(Gitlab::License) - repo = 'gitlab-ee' - else - repo = 'gitlab-ce' - end + repo = if defined?(Gitlab::License) + 'gitlab-ee' + else + 'gitlab-ce' + end `git fetch https://gitlab.com/gitlab-org/#{repo}.git --depth 1` diff --git a/lib/tasks/flay.rake b/lib/tasks/flay.rake index e9587595fef..7ad2b2e4d39 100644 --- a/lib/tasks/flay.rake +++ b/lib/tasks/flay.rake @@ -1,6 +1,6 @@ desc 'Code duplication analyze via flay' task :flay do - output = %x(bundle exec flay --mass 35 app/ lib/gitlab/) + output = `bundle exec flay --mass 35 app/ lib/gitlab/` if output.include? "Similar code found" puts output diff --git a/lib/tasks/gemojione.rake b/lib/tasks/gemojione.rake index 993112aee3b..f5ff29415e8 100644 --- a/lib/tasks/gemojione.rake +++ b/lib/tasks/gemojione.rake @@ -81,9 +81,9 @@ namespace :gemojione do # SpriteFactory's SCSS is a bit too verbose for our purposes here, so # let's simplify it - system(%Q(sed -i '' "s/width: #{SIZE}px; height: #{SIZE}px; background: image-url('emoji.png')/background-position:/" #{style_path})) - system(%Q(sed -i '' "s/ no-repeat//" #{style_path})) - system(%Q(sed -i '' "s/ 0px/ 0/" #{style_path})) + system(%(sed -i '' "s/width: #{SIZE}px; height: #{SIZE}px; background: image-url('emoji.png')/background-position:/" #{style_path})) + system(%(sed -i '' "s/ no-repeat//" #{style_path})) + system(%(sed -i '' "s/ 0px/ 0/" #{style_path})) # Append a generic rule that applies to all Emojis File.open(style_path, 'a') do |f| diff --git a/lib/tasks/gitlab/assets.rake b/lib/tasks/gitlab/assets.rake index 3eb5fc07b3c..098f9851b45 100644 --- a/lib/tasks/gitlab/assets.rake +++ b/lib/tasks/gitlab/assets.rake @@ -20,7 +20,7 @@ namespace :gitlab do desc 'GitLab | Assets | Fix all absolute url references in CSS' task :fix_urls do css_files = Dir['public/assets/*.css'] - css_files.each do | file | + css_files.each do |file| # replace url(/assets/*) with url(./*) puts "Fixing #{file}" system "sed", "-i", "-e", 's/url(\([\"\']\?\)\/assets\//url(\1.\//g', file diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 6102517e730..38edd49b6ed 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -6,8 +6,6 @@ namespace :gitlab do gitlab:ldap:check gitlab:app:check} - - namespace :app do desc "GitLab | Check the configuration of the GitLab Rails app" task check: :environment do @@ -34,7 +32,6 @@ namespace :gitlab do finished_checking "GitLab" end - # Checks ######################## @@ -194,7 +191,7 @@ namespace :gitlab do def check_migrations_are_up print "All migrations up? ... " - migration_status, _ = Gitlab::Popen.popen(%W(bundle exec rake db:migrate:status)) + migration_status, _ = Gitlab::Popen.popen(%w(bundle exec rake db:migrate:status)) unless migration_status =~ /down\s+\d{14}/ puts "yes".color(:green) @@ -279,7 +276,7 @@ namespace :gitlab do upload_path_tmp = File.join(upload_path, 'tmp') if File.stat(upload_path).mode == 040700 - unless Dir.exists?(upload_path_tmp) + unless Dir.exist?(upload_path_tmp) puts 'skipped (no tmp uploads folder yet)'.color(:magenta) return end @@ -316,7 +313,7 @@ namespace :gitlab do min_redis_version = "2.8.0" print "Redis version >= #{min_redis_version}? ... " - redis_version = run_command(%W(redis-cli --version)) + redis_version = run_command(%w(redis-cli --version)) redis_version = redis_version.try(:match, /redis-cli (\d+\.\d+\.\d+)/) if redis_version && (Gem::Version.new(redis_version[1]) > Gem::Version.new(min_redis_version)) @@ -351,7 +348,6 @@ namespace :gitlab do finished_checking "GitLab Shell" end - # Checks ######################## @@ -387,7 +383,7 @@ namespace :gitlab do unless File.exist?(repo_base_path) puts "can't check because of previous errors".color(:magenta) - return + break end unless File.symlink?(repo_base_path) @@ -410,7 +406,7 @@ namespace :gitlab do unless File.exist?(repo_base_path) puts "can't check because of previous errors".color(:magenta) - return + break end if File.stat(repo_base_path).mode.to_s(8).ends_with?("2770") @@ -440,7 +436,7 @@ namespace :gitlab do unless File.exist?(repo_base_path) puts "can't check because of previous errors".color(:magenta) - return + break end uid = uid_for(gitlab_shell_ssh_user) @@ -493,7 +489,6 @@ namespace :gitlab do ) fix_and_rerun end - end end @@ -565,8 +560,6 @@ namespace :gitlab do end end - - namespace :sidekiq do desc "GitLab | Check the configuration of Sidekiq" task check: :environment do @@ -579,7 +572,6 @@ namespace :gitlab do finished_checking "Sidekiq" end - # Checks ######################## @@ -621,12 +613,11 @@ namespace :gitlab do end def sidekiq_process_count - ps_ux, _ = Gitlab::Popen.popen(%W(ps ux)) + ps_ux, _ = Gitlab::Popen.popen(%w(ps ux)) ps_ux.scan(/sidekiq \d+\.\d+\.\d+/).count end end - namespace :incoming_email do desc "GitLab | Check the configuration of Reply by email" task check: :environment do @@ -649,7 +640,6 @@ namespace :gitlab do finished_checking "Reply by email" end - # Checks ######################## @@ -757,7 +747,7 @@ namespace :gitlab do end def mail_room_running? - ps_ux, _ = Gitlab::Popen.popen(%W(ps ux)) + ps_ux, _ = Gitlab::Popen.popen(%w(ps ux)) ps_ux.include?("mail_room") end end @@ -805,13 +795,13 @@ namespace :gitlab do def check_ldap_auth(adapter) auth = adapter.config.has_auth? - if auth && adapter.ldap.bind - message = 'Success'.color(:green) - elsif auth - message = 'Failed. Check `bind_dn` and `password` configuration values'.color(:red) - else - message = 'Anonymous. No `bind_dn` or `password` configured'.color(:yellow) - end + message = if auth && adapter.ldap.bind + 'Success'.color(:green) + elsif auth + 'Failed. Check `bind_dn` and `password` configuration values'.color(:red) + else + 'Anonymous. No `bind_dn` or `password` configured'.color(:yellow) + end puts "LDAP authentication... #{message}" end @@ -838,11 +828,11 @@ namespace :gitlab do user = User.find_by(username: username) if user repo_dirs = user.authorized_projects.map do |p| - File.join( - p.repository_storage_path, - "#{p.path_with_namespace}.git" - ) - end + File.join( + p.repository_storage_path, + "#{p.path_with_namespace}.git" + ) + end repo_dirs.each { |repo_dir| check_repo_integrity(repo_dir) } else @@ -855,7 +845,7 @@ namespace :gitlab do ########################## def fix_and_rerun - puts " Please #{"fix the error above"} and rerun the checks.".color(:red) + puts " Please fix the error above and rerun the checks.".color(:red) end def for_more_information(*sources) @@ -917,7 +907,7 @@ namespace :gitlab do def check_ruby_version required_version = Gitlab::VersionInfo.new(2, 1, 0) - current_version = Gitlab::VersionInfo.parse(run_command(%W(ruby --version))) + current_version = Gitlab::VersionInfo.parse(run_command(%w(ruby --version))) print "Ruby version >= #{required_version} ? ... " @@ -988,13 +978,13 @@ namespace :gitlab do end def check_config_lock(repo_dir) - config_exists = File.exist?(File.join(repo_dir,'config.lock')) + config_exists = File.exist?(File.join(repo_dir, 'config.lock')) config_output = config_exists ? 'yes'.color(:red) : 'no'.color(:green) puts "'config.lock' file exists?".color(:yellow) + " ... #{config_output}" end def check_ref_locks(repo_dir) - lock_files = Dir.glob(File.join(repo_dir,'refs/heads/*.lock')) + lock_files = Dir.glob(File.join(repo_dir, 'refs/heads/*.lock')) if lock_files.present? puts "Ref lock files exist:".color(:red) lock_files.each do |lock_file| diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake index 967f630ef20..daf7382dd02 100644 --- a/lib/tasks/gitlab/cleanup.rake +++ b/lib/tasks/gitlab/cleanup.rake @@ -25,7 +25,6 @@ namespace :gitlab do end all_dirs.each do |dir_path| - if remove_flag if FileUtils.rm_rf dir_path puts "Removed...#{dir_path}".color(:red) @@ -53,11 +52,11 @@ namespace :gitlab do IO.popen(%W(find #{repo_root} -mindepth 1 -maxdepth 2 -name *.git)) do |find| find.each_line do |path| path.chomp! - repo_with_namespace = path. - sub(repo_root, ''). - sub(%r{^/*}, ''). - chomp('.git'). - chomp('.wiki') + repo_with_namespace = path + .sub(repo_root, '') + .sub(%r{^/*}, '') + .chomp('.git') + .chomp('.wiki') next if Project.find_by_full_path(repo_with_namespace) new_path = path + move_suffix puts path.inspect + ' -> ' + new_path.inspect diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake index 7c96bc864ce..ecf6b6e068b 100644 --- a/lib/tasks/gitlab/db.rake +++ b/lib/tasks/gitlab/db.rake @@ -23,7 +23,7 @@ namespace :gitlab do end desc 'Drop all tables' - task :drop_tables => :environment do + task drop_tables: :environment do connection = ActiveRecord::Base.connection # If MySQL, turn off foreign key checks @@ -62,9 +62,9 @@ namespace :gitlab do ref = Shellwords.escape(args[:ref]) - migrations = `git diff #{ref}.. --name-only -- db/migrate`.lines. - map { |file| Rails.root.join(file.strip).to_s }. - select { |file| File.file?(file) } + migrations = `git diff #{ref}.. --name-only -- db/migrate`.lines + .map { |file| Rails.root.join(file.strip).to_s } + .select { |file| File.file?(file) } Gitlab::DowntimeCheck.new.check_and_print(migrations) end diff --git a/lib/tasks/gitlab/git.rake b/lib/tasks/gitlab/git.rake index a67c1fe1f27..cf82134d97e 100644 --- a/lib/tasks/gitlab/git.rake +++ b/lib/tasks/gitlab/git.rake @@ -1,6 +1,5 @@ namespace :gitlab do namespace :git do - desc "GitLab | Git | Repack" task repack: :environment do failures = perform_git_cmd(%W(#{Gitlab.config.git.bin_path} repack -a --quiet), "Repacking repo") @@ -50,6 +49,5 @@ namespace :gitlab do puts "The following repositories reported errors:".color(:red) failures.each { |f| puts "- #{f}" } end - end end diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index b4015f5238e..66e7b7685f7 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -46,7 +46,7 @@ namespace :gitlab do group = Namespace.find_by(path: group_name) # create group namespace unless group - group = Group.new(:name => group_name) + group = Group.new(name: group_name) group.path = group_name group.owner = user if group.save diff --git a/lib/tasks/gitlab/import_export.rake b/lib/tasks/gitlab/import_export.rake index c2c6031db67..dd1825c8a9e 100644 --- a/lib/tasks/gitlab/import_export.rake +++ b/lib/tasks/gitlab/import_export.rake @@ -7,7 +7,7 @@ namespace :gitlab do desc "GitLab | Display exported DB structure" task data: :environment do - puts YAML.load_file(Gitlab::ImportExport.config_file)['project_tree'].to_yaml(:SortKeys => true) + puts YAML.load_file(Gitlab::ImportExport.config_file)['project_tree'].to_yaml(SortKeys: true) end end end diff --git a/lib/tasks/gitlab/info.rake b/lib/tasks/gitlab/info.rake index f7c831892ee..ae78fe64eb8 100644 --- a/lib/tasks/gitlab/info.rake +++ b/lib/tasks/gitlab/info.rake @@ -2,24 +2,23 @@ namespace :gitlab do namespace :env do desc "GitLab | Show information about GitLab and its environment" task info: :environment do - # check if there is an RVM environment - rvm_version = run_and_match(%W(rvm --version), /[\d\.]+/).try(:to_s) + rvm_version = run_and_match(%w(rvm --version), /[\d\.]+/).try(:to_s) # check Ruby version - ruby_version = run_and_match(%W(ruby --version), /[\d\.p]+/).try(:to_s) + ruby_version = run_and_match(%w(ruby --version), /[\d\.p]+/).try(:to_s) # check Gem version - gem_version = run_command(%W(gem --version)) + gem_version = run_command(%w(gem --version)) # check Bundler version - bunder_version = run_and_match(%W(bundle --version), /[\d\.]+/).try(:to_s) + bunder_version = run_and_match(%w(bundle --version), /[\d\.]+/).try(:to_s) # check Rake version - rake_version = run_and_match(%W(rake --version), /[\d\.]+/).try(:to_s) + rake_version = run_and_match(%w(rake --version), /[\d\.]+/).try(:to_s) # check redis version - redis_version = run_and_match(%W(redis-cli --version), /redis-cli (\d+\.\d+\.\d+)/).to_a + redis_version = run_and_match(%w(redis-cli --version), /redis-cli (\d+\.\d+\.\d+)/).to_a puts "" puts "System information".color(:yellow) puts "System:\t\t#{os_name || "unknown".color(:red)}" - puts "Current User:\t#{run_command(%W(whoami))}" + puts "Current User:\t#{run_command(%w(whoami))}" puts "Using RVM:\t#{rvm_version.present? ? "yes".color(:green) : "no"}" puts "RVM Version:\t#{rvm_version}" if rvm_version.present? puts "Ruby Version:\t#{ruby_version || "unknown".color(:red)}" @@ -29,7 +28,6 @@ namespace :gitlab do puts "Redis Version:\t#{redis_version[1] || "unknown".color(:red)}" puts "Sidekiq Version:#{Sidekiq::VERSION}" - # check database adapter database_adapter = ActiveRecord::Base.connection.adapter_name.downcase @@ -54,8 +52,6 @@ namespace :gitlab do puts "Using Omniauth:\t#{Gitlab.config.omniauth.enabled ? "yes".color(:green) : "no"}" puts "Omniauth Providers: #{omniauth_providers.join(', ')}" if Gitlab.config.omniauth.enabled - - # check Gitolite version gitlab_shell_version_file = "#{Gitlab.config.gitlab_shell.hooks_path}/../VERSION" if File.readable?(gitlab_shell_version_file) @@ -71,7 +67,6 @@ namespace :gitlab do end puts "Hooks:\t\t#{Gitlab.config.gitlab_shell.hooks_path}" puts "Git:\t\t#{Gitlab.config.git.bin_path}" - end end end diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake index 5a09cd7ce41..dd2fda54e62 100644 --- a/lib/tasks/gitlab/shell.rake +++ b/lib/tasks/gitlab/shell.rake @@ -20,10 +20,10 @@ namespace :gitlab do config = { user: Gitlab.config.gitlab.user, gitlab_url: gitlab_url, - http_settings: {self_signed_cert: false}.stringify_keys, + http_settings: { self_signed_cert: false }.stringify_keys, auth_file: File.join(user_home, ".ssh", "authorized_keys"), redis: { - bin: %x{which redis-cli}.chomp, + bin: `which redis-cli`.chomp, namespace: "resque:gitlab" }.stringify_keys, log_level: "INFO", @@ -43,7 +43,7 @@ namespace :gitlab do File.open("config.yml", "w+") {|f| f.puts config.to_yaml} # Launch installation process - system(*%W(bin/install) + repository_storage_paths_args) + system(*%w(bin/install) + repository_storage_paths_args) end # (Re)create hooks diff --git a/lib/tasks/gitlab/sidekiq.rake b/lib/tasks/gitlab/sidekiq.rake index f2e12d85045..6cbc83b8973 100644 --- a/lib/tasks/gitlab/sidekiq.rake +++ b/lib/tasks/gitlab/sidekiq.rake @@ -1,9 +1,9 @@ namespace :gitlab do namespace :sidekiq do - QUEUE = 'queue:post_receive' + QUEUE = 'queue:post_receive'.freeze desc 'Drop all Sidekiq PostReceive jobs for a given project' - task :drop_post_receive , [:project] => :environment do |t, args| + task :drop_post_receive, [:project] => :environment do |t, args| unless args.project.present? abort "Please specify the project you want to drop PostReceive jobs for:\n rake gitlab:sidekiq:drop_post_receive[group/project]" end @@ -21,7 +21,7 @@ namespace :gitlab do # new jobs already. We will repopulate it with the old jobs, skipping the # ones we want to drop. dropped = 0 - while (job = redis.lpop(temp_queue)) do + while (job = redis.lpop(temp_queue)) if repo_path(job) == project_path dropped += 1 else diff --git a/lib/tasks/gitlab/task_helpers.rb b/lib/tasks/gitlab/task_helpers.rb index e128738b5f8..e5de3e22165 100644 --- a/lib/tasks/gitlab/task_helpers.rb +++ b/lib/tasks/gitlab/task_helpers.rb @@ -19,23 +19,15 @@ module Gitlab # It will primarily use lsb_relase to determine the OS. # It has fallbacks to Debian, SuSE, OS X and systems running systemd. def os_name - os_name = run_command(%W(lsb_release -irs)) - os_name ||= if File.readable?('/etc/system-release') - File.read('/etc/system-release') - end - os_name ||= if File.readable?('/etc/debian_version') - debian_version = File.read('/etc/debian_version') - "Debian #{debian_version}" - end - os_name ||= if File.readable?('/etc/SuSE-release') - File.read('/etc/SuSE-release') - end - os_name ||= if os_x_version = run_command(%W(sw_vers -productVersion)) - "Mac OS X #{os_x_version}" - end - os_name ||= if File.readable?('/etc/os-release') - File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1] - end + os_name = run_command(%w(lsb_release -irs)) + os_name ||= File.read('/etc/system-release') if File.readable?('/etc/system-release') + os_name ||= "Debian #{File.read('/etc/debian_version')}" if File.readable?('/etc/debian_version') + os_name ||= File.read('/etc/SuSE-release') if File.readable?('/etc/SuSE-release') + os_name ||= + if os_x_version = run_command(%w(sw_vers -productVersion)) + "Mac OS X #{os_x_version}" + end + os_name ||= File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1] if File.readable?('/etc/os-release') os_name.try(:squish!) end @@ -104,7 +96,7 @@ module Gitlab def warn_user_is_not_gitlab unless @warned_user_not_gitlab gitlab_user = Gitlab.config.gitlab.user - current_user = run_command(%W(whoami)).chomp + current_user = run_command(%w(whoami)).chomp unless current_user == gitlab_user puts " Warning ".color(:black).background(:yellow) puts " You are running as user #{current_user.color(:magenta)}, we hope you know what you are doing." @@ -171,14 +163,14 @@ module Gitlab def reset_to_tag(tag_wanted, target_dir) tag = - begin - # First try to checkout without fetching - # to avoid stalling tests if the Internet is down. - run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- #{tag_wanted}]) - rescue Gitlab::TaskFailedError - run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch origin]) - run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- origin/#{tag_wanted}]) - end + begin + # First try to checkout without fetching + # to avoid stalling tests if the Internet is down. + run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- #{tag_wanted}]) + rescue Gitlab::TaskFailedError + run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch origin]) + run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- origin/#{tag_wanted}]) + end if tag run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} reset --hard #{tag.strip}]) diff --git a/lib/tasks/gitlab/test.rake b/lib/tasks/gitlab/test.rake index 84810b489ce..523b0fa055b 100644 --- a/lib/tasks/gitlab/test.rake +++ b/lib/tasks/gitlab/test.rake @@ -2,15 +2,15 @@ namespace :gitlab do desc "GitLab | Run all tests" task :test do cmds = [ - %W(rake brakeman), - %W(rake rubocop), - %W(rake spinach), - %W(rake spec), - %W(rake karma) + %w(rake brakeman), + %w(rake rubocop), + %w(rake spinach), + %w(rake spec), + %w(rake karma) ] cmds.each do |cmd| - system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) or raise("#{cmd} failed!") + system({ 'RAILS_ENV' => 'test', 'force' => 'yes' }, *cmd) || raise("#{cmd} failed!") end end end diff --git a/lib/tasks/gitlab/track_deployment.rake b/lib/tasks/gitlab/track_deployment.rake index 84aa2e8507a..6f101aea303 100644 --- a/lib/tasks/gitlab/track_deployment.rake +++ b/lib/tasks/gitlab/track_deployment.rake @@ -1,8 +1,8 @@ namespace :gitlab do desc 'GitLab | Tracks a deployment in GitLab Performance Monitoring' task track_deployment: :environment do - metric = Gitlab::Metrics::Metric. - new('deployments', version: Gitlab::VERSION) + metric = Gitlab::Metrics::Metric + .new('deployments', version: Gitlab::VERSION) Gitlab::Metrics.submit_metrics([metric.to_hash]) end diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index b77a5bb62d1..dbdfb335a5c 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -46,7 +46,7 @@ namespace :gitlab do "https://gitlab.com/gitlab-org/gitlab-ci-yml.git", /(\.{1,2}|LICENSE|Pages|autodeploy|\.gitlab-ci.yml)\z/ ) - ] + ].freeze def vendor_directory Rails.root.join('vendor') diff --git a/lib/tasks/gitlab/web_hook.rake b/lib/tasks/gitlab/web_hook.rake index 49530e7a372..5a1c8006052 100644 --- a/lib/tasks/gitlab/web_hook.rake +++ b/lib/tasks/gitlab/web_hook.rake @@ -1,7 +1,7 @@ namespace :gitlab do namespace :web_hook do desc "GitLab | Adds a webhook to the projects" - task :add => :environment do + task add: :environment do web_hook_url = ENV['URL'] namespace_path = ENV['NAMESPACE'] @@ -21,7 +21,7 @@ namespace :gitlab do end desc "GitLab | Remove a webhook from the projects" - task :rm => :environment do + task rm: :environment do web_hook_url = ENV['URL'] namespace_path = ENV['NAMESPACE'] @@ -34,7 +34,7 @@ namespace :gitlab do end desc "GitLab | List webhooks" - task :list => :environment do + task list: :environment do namespace_path = ENV['NAMESPACE'] projects = find_projects(namespace_path) diff --git a/lib/tasks/lint.rake b/lib/tasks/lint.rake index 32b668df3bf..7b63e93db0e 100644 --- a/lib/tasks/lint.rake +++ b/lib/tasks/lint.rake @@ -6,4 +6,3 @@ unless Rails.env.production? end end end - diff --git a/lib/tasks/migrate/migrate_iids.rake b/lib/tasks/migrate/migrate_iids.rake index 4f2486157b7..fc2cea8c016 100644 --- a/lib/tasks/migrate/migrate_iids.rake +++ b/lib/tasks/migrate/migrate_iids.rake @@ -24,7 +24,7 @@ task migrate_iids: :environment do else print 'F' end - rescue => ex + rescue print 'F' end end diff --git a/lib/tasks/services.rake b/lib/tasks/services.rake index 39541c0b9c6..56b81106c5f 100644 --- a/lib/tasks/services.rake +++ b/lib/tasks/services.rake @@ -76,23 +76,23 @@ namespace :services do end param_hash - end.sort_by { |p| p[:required] ? 0 : 1 } + end + service_hash[:params].sort_by! { |p| p[:required] ? 0 : 1 } - puts "Collected data for: #{service.title}, #{Time.now-service_start}" + puts "Collected data for: #{service.title}, #{Time.now - service_start}" service_hash end doc_start = Time.now doc_path = File.join(Rails.root, 'doc', 'api', 'services.md') - result = ERB.new(services_template, 0 , '>') + result = ERB.new(services_template, 0, '>') .result(OpenStruct.new(services: services).instance_eval { binding }) File.open(doc_path, 'w') do |f| f.write result end - puts "write a new service.md to: #{doc_path.to_s}, #{Time.now-doc_start}" - + puts "write a new service.md to: #{doc_path}, #{Time.now - doc_start}" end end diff --git a/lib/tasks/sidekiq.rake b/lib/tasks/sidekiq.rake index d1f6ed87704..dd9ce86f7ca 100644 --- a/lib/tasks/sidekiq.rake +++ b/lib/tasks/sidekiq.rake @@ -1,21 +1,21 @@ namespace :sidekiq do desc "GitLab | Stop sidekiq" task :stop do - system *%W(bin/background_jobs stop) + system(*%w(bin/background_jobs stop)) end desc "GitLab | Start sidekiq" task :start do - system *%W(bin/background_jobs start) + system(*%w(bin/background_jobs start)) end desc 'GitLab | Restart sidekiq' task :restart do - system *%W(bin/background_jobs restart) + system(*%w(bin/background_jobs restart)) end desc "GitLab | Start sidekiq with launchd on Mac OS X" task :launchd do - system *%W(bin/background_jobs start_no_deamonize) + system(*%w(bin/background_jobs start_no_deamonize)) end end diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 2cf7a25a0fd..602c60be828 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -4,8 +4,8 @@ namespace :spec do desc 'GitLab | Rspec | Run request specs' task :api do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @api) + %w(rake gitlab:setup), + %w(rspec spec --tag @api) ] run_commands(cmds) end @@ -13,8 +13,8 @@ namespace :spec do desc 'GitLab | Rspec | Run feature specs' task :feature do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @feature) + %w(rake gitlab:setup), + %w(rspec spec --tag @feature) ] run_commands(cmds) end @@ -22,8 +22,8 @@ namespace :spec do desc 'GitLab | Rspec | Run model specs' task :models do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @models) + %w(rake gitlab:setup), + %w(rspec spec --tag @models) ] run_commands(cmds) end @@ -31,8 +31,8 @@ namespace :spec do desc 'GitLab | Rspec | Run service specs' task :services do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @services) + %w(rake gitlab:setup), + %w(rspec spec --tag @services) ] run_commands(cmds) end @@ -40,8 +40,8 @@ namespace :spec do desc 'GitLab | Rspec | Run lib specs' task :lib do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @lib) + %w(rake gitlab:setup), + %w(rspec spec --tag @lib) ] run_commands(cmds) end @@ -49,8 +49,8 @@ namespace :spec do desc 'GitLab | Rspec | Run other specs' task :other do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag ~@api --tag ~@feature --tag ~@models --tag ~@lib --tag ~@services) + %w(rake gitlab:setup), + %w(rspec spec --tag ~@api --tag ~@feature --tag ~@models --tag ~@lib --tag ~@services) ] run_commands(cmds) end @@ -59,14 +59,14 @@ end desc "GitLab | Run specs" task :spec do cmds = [ - %W(rake gitlab:setup), - %W(rspec spec), + %w(rake gitlab:setup), + %w(rspec spec), ] run_commands(cmds) end def run_commands(cmds) cmds.each do |cmd| - system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) or raise("#{cmd} failed!") + system({ 'RAILS_ENV' => 'test', 'force' => 'yes' }, *cmd) || raise("#{cmd} failed!") end end diff --git a/lib/tasks/spinach.rake b/lib/tasks/spinach.rake index 8dbfa7751dc..19ff13f06c0 100644 --- a/lib/tasks/spinach.rake +++ b/lib/tasks/spinach.rake @@ -35,7 +35,7 @@ task :spinach do end def run_system_command(cmd) - system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) + system({ 'RAILS_ENV' => 'test', 'force' => 'yes' }, *cmd) end def run_spinach_command(args) From 2afb65468d688caa64ea53abfed35d0f4081102b Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 12:37:01 -0600 Subject: [PATCH 232/247] Order cops alphabetically --- .rubocop.yml | 252 ++++++++++++++++++++++++++------------------------- 1 file changed, 127 insertions(+), 125 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 86f5df61724..4515bc431f1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -24,6 +24,9 @@ AllCops: - 'bin/**/*' - 'generator_templates/**/*' +Bundler/OrderedGems: + Enabled: false + # Style ####################################################################### # Check indentation of private/protected visibility modifiers. @@ -47,6 +50,9 @@ Style/AlignArray: Style/AlignHash: Enabled: true +Style/AlignParameters: + Enabled: false + # Whether `and` and `or` are banned only in conditionals (conditionals) # or completely (always). Style/AndOr: @@ -68,6 +74,9 @@ Style/AsciiIdentifiers: Style/Attr: Enabled: true +Style/BarePercentLiterals: + Enabled: true + # Avoid the use of BEGIN blocks. Style/BeginBlock: Enabled: true @@ -76,15 +85,21 @@ Style/BeginBlock: Style/BlockComments: Enabled: true -# Put end statement of multiline block on its own line. -Style/BlockEndNewline: - Enabled: true - # Avoid using {...} for multi-line blocks (multiline chaining is # always # ugly). Prefer {...} over do...end for single-line blocks. Style/BlockDelimiters: Enabled: true +# Put end statement of multiline block on its own line. +Style/BlockEndNewline: + Enabled: true + +Style/BracesAroundHashParameters: + Enabled: false + +Style/CaseEquality: + Enabled: false + # Indentation of when in a case/when/[else/]end. Style/CaseIndentation: Enabled: true @@ -113,10 +128,19 @@ Style/ClassMethods: Style/ClassVars: Enabled: true +Style/ColonMethodCall: + Enabled: true + +Style/CommentAnnotation: + Enabled: false + # Indentation of comments. Style/CommentIndentation: Enabled: true +Style/ConditionalAssignment: + Enabled: true + # Constants should use SCREAMING_SNAKE_CASE. Style/ConstantName: Enabled: true @@ -133,6 +157,9 @@ Style/DotPosition: Enabled: true EnforcedStyle: leading +Style/DoubleNegation: + Enabled: false + # Align elses and elsifs correctly. Style/ElseAlignment: Enabled: true @@ -157,14 +184,14 @@ Style/EmptyLinesAroundBlockBody: Style/EmptyLinesAroundClassBody: Enabled: true -# Keeps track of empty lines around module bodies. -Style/EmptyLinesAroundModuleBody: - Enabled: true - # Keeps track of empty lines around method bodies. Style/EmptyLinesAroundMethodBody: Enabled: true +# Keeps track of empty lines around module bodies. +Style/EmptyLinesAroundModuleBody: + Enabled: true + # Avoid the use of END blocks. Style/EndBlock: Enabled: true @@ -210,15 +237,15 @@ Style/GlobalVars: Style/HashSyntax: Enabled: true -# Do not use if x; .... Use the ternary operator instead. -Style/IfWithSemicolon: - Enabled: true - # Checks that conditional statements do not have an identical line at the # end of each branch, which can validly be moved out of the conditional. Style/IdenticalConditionalBranches: Enabled: true +# Do not use if x; .... Use the ternary operator instead. +Style/IfWithSemicolon: + Enabled: true + # Checks the indentation of the first line of the right-hand-side of a # multi-line assignment. Style/IndentAssignment: @@ -497,6 +524,9 @@ Metrics/AbcSize: Enabled: true Max: 60 +Metrics/BlockLength: + Enabled: false + # Avoid excessive block nesting. Metrics/BlockNesting: Enabled: true @@ -536,20 +566,17 @@ Metrics/PerceivedComplexity: # Lint ######################################################################## -# Checks for useless access modifiers. -Lint/UselessAccessModifier: - Enabled: true - -# Checks for attempts to use `private` or `protected` to set the visibility -# of a class method, which does not work. -Lint/IneffectiveAccessModifier: - Enabled: false - # Checks for ambiguous operators in the first argument of a method invocation # without parentheses. Lint/AmbiguousOperator: Enabled: true +Lint/AmbiguousRegexpLiteral: + Enabled: false + +Lint/AssignmentInCondition: + Enabled: false + # Align block ends correctly. Lint/BlockAlignment: Enabled: true @@ -615,11 +642,19 @@ Lint/FloatOutOfRange: Lint/FormatParameterMismatch: Enabled: true +Lint/HandleExceptions: + Enabled: false + # Checks for adjacent string literals on the same line, which could better be # represented as a single string literal. Lint/ImplicitStringConcatenation: Enabled: true +# Checks for attempts to use `private` or `protected` to set the visibility +# of a class method, which does not work. +Lint/IneffectiveAccessModifier: + Enabled: false + # Checks for invalid character literals with a non-escaped whitespace # character. Lint/InvalidCharacterLiteral: @@ -633,6 +668,9 @@ Lint/LiteralInCondition: Lint/LiteralInInterpolation: Enabled: true +Lint/Loop: + Enabled: false + # Do not use nested method definitions. Lint/NestedMethodDefinition: Enabled: true @@ -662,6 +700,9 @@ Lint/RescueException: Lint/ShadowedException: Enabled: false +Lint/ShadowingOuterLocalVariable: + Enabled: false + # Checks for Object#to_s usage in string interpolation. Lint/StringConversionInInterpolation: Enabled: true @@ -670,19 +711,32 @@ Lint/StringConversionInInterpolation: Lint/UnderscorePrefixedVariableName: Enabled: true +Lint/UnifiedInteger: + Enabled: true + # Checks for rubocop:disable comments that can be removed. # Note: this cop is not disabled when disabling all cops. # It must be explicitly disabled. Lint/UnneededDisable: Enabled: false +Lint/UnneededSplatExpansion: + Enabled: false + # Unreachable code. Lint/UnreachableCode: Enabled: true +Lint/UnusedBlockArgument: + Enabled: false + Lint/UnusedMethodArgument: Enabled: false +# Checks for useless access modifiers. +Lint/UselessAccessModifier: + Enabled: true + # Checks for useless assignment to a local variable. Lint/UselessAssignment: Enabled: true @@ -722,6 +776,16 @@ Performance/LstripRstrip: Performance/RangeInclude: Enabled: true +Performance/RedundantBlockCall: + Enabled: true + +Performance/RedundantMatch: + Enabled: true + +Performance/RedundantMerge: + Enabled: true + MaxKeyValuePairs: 1 + # Use `sort` instead of `sort_by { |x| x }`. Performance/RedundantSortBy: Enabled: true @@ -741,6 +805,11 @@ Performance/StringReplacement: Performance/TimesMap: Enabled: true +# Security #################################################################### + +Security/JSONLoad: + Enabled: true + # Rails ####################################################################### # Enables Rails cops. @@ -761,6 +830,15 @@ Rails/Date: Rails/Delegate: Enabled: true +Rails/DynamicFindBy: + Enabled: false + +Rails/Exit: + Enabled: true + Exclude: + - lib/gitlab/upgrader.rb + - 'lib/backup/**/*' + # Prefer `find_by` over `where.first`. Rails/FindBy: Enabled: true @@ -773,6 +851,9 @@ Rails/FindEach: Rails/HasAndBelongsToMany: Enabled: true +Rails/HttpPositionalArguments: + Enabled: false + # Checks for calls to puts, print, etc. Rails/Output: Enabled: true @@ -782,6 +863,9 @@ Rails/Output: - 'lib/backup/**/*' - 'lib/tasks/**/*' +Rails/OutputSafety: + Enabled: false + # Checks for incorrect grammar when using methods like `3.day.ago`. Rails/PluralizationGrammar: Enabled: true @@ -794,6 +878,12 @@ Rails/ReadWriteAttribute: Rails/ScopeArgs: Enabled: true +Rails/TimeZone: + Enabled: false + +Rails/Validation: + Enabled: true + # RSpec ####################################################################### # Check that instances are not being stubbed globally. @@ -851,17 +941,20 @@ RSpec/Focus: RSpec/InstanceVariable: Enabled: false -# Checks for multiple top-level describes. -RSpec/MultipleDescribes: +RSpec/LeadingSubject: Enabled: false -# Enforces the usage of the same method on all negative message expectations. -RSpec/NotToNot: - EnforcedStyle: not_to - Enabled: true +RSpec/LetSetup: + Enabled: false -# Prefer using verifying doubles over normal doubles. -RSpec/VerifiedDoubles: +RSpec/MessageChain: + Enabled: false + +RSpec/MessageSpies: + Enabled: false + +# Checks for multiple top-level describes. +RSpec/MultipleDescribes: Enabled: false RSpec/MultipleExpectations: @@ -873,36 +966,10 @@ RSpec/NamedSubject: RSpec/NestedGroups: Enabled: false -RSpec/LeadingSubject: - Enabled: false - -Lint/AmbiguousRegexpLiteral: - Enabled: false - -Bundler/OrderedGems: - Enabled: false - -Lint/HandleExceptions: - Enabled: false - -Lint/Loop: - Enabled: false - -Metrics/BlockLength: - Enabled: false - -Performance/RedundantMerge: +# Enforces the usage of the same method on all negative message expectations. +RSpec/NotToNot: + EnforcedStyle: not_to Enabled: true - MaxKeyValuePairs: 1 - -RSpec/LetSetup: - Enabled: false - -RSpec/MessageChain: - Enabled: false - -RSpec/MessageSpies: - Enabled: false RSpec/RepeatedDescription: Enabled: false @@ -910,71 +977,6 @@ RSpec/RepeatedDescription: RSpec/SubjectStub: Enabled: false -Lint/UnifiedInteger: - Enabled: true - -Lint/ShadowingOuterLocalVariable: +# Prefer using verifying doubles over normal doubles. +RSpec/VerifiedDoubles: Enabled: false - -Lint/AssignmentInCondition: - Enabled: false - -Lint/UnneededSplatExpansion: - Enabled: false - -Lint/UnusedBlockArgument: - Enabled: false - -Performance/RedundantBlockCall: - Enabled: true - -Performance/RedundantMatch: - Enabled: true - -Rails/DynamicFindBy: - Enabled: false - -Rails/HttpPositionalArguments: - Enabled: false - -Rails/OutputSafety: - Enabled: false - -Rails/TimeZone: - Enabled: false - -Rails/Validation: - Enabled: true - -Security/JSONLoad: - Enabled: true - -Style/AlignParameters: - Enabled: false - -Style/BarePercentLiterals: - Enabled: true - -Style/BracesAroundHashParameters: - Enabled: false - -Style/CaseEquality: - Enabled: false - -Style/ColonMethodCall: - Enabled: true - -Style/CommentAnnotation: - Enabled: false - -Style/ConditionalAssignment: - Enabled: true - -Style/DoubleNegation: - Enabled: false - -Rails/Exit: - Enabled: true - Exclude: - - lib/gitlab/upgrader.rb - - 'lib/backup/**/*' From ec5a74ecfa4cf5f8a6b3b66526d614d71b192105 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 12:43:48 -0600 Subject: [PATCH 233/247] Update rubocop and rubocop-rspec and regenerate .rubocop_todo.yml --- .rubocop_todo.yml | 111 +++++++++++++++++++++++++++------------------- Gemfile | 4 +- Gemfile.lock | 14 +++--- 3 files changed, 74 insertions(+), 55 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2d94861058f..5b7a35493f8 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,14 +1,13 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 0` -# on 2017-02-22 10:58:40 -0600 using RuboCop version 0.46.0. +# on 2017-02-22 12:40:11 -0600 using RuboCop version 0.47.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 -# Cop supports --auto-correct. -Performance/RedundantBlockCall: +# Offense count: 51 +RSpec/BeforeAfterAll: Enabled: false # Offense count: 15 @@ -16,6 +15,10 @@ Performance/RedundantBlockCall: RSpec/EmptyExampleGroup: Enabled: false +# Offense count: 1 +RSpec/ExpectOutput: + Enabled: false + # Offense count: 63 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: implicit, each, example @@ -28,20 +31,37 @@ RSpec/HookArgument: RSpec/ImplicitExpect: Enabled: false +# Offense count: 36 +RSpec/RepeatedExample: + Enabled: false + +# Offense count: 34 +RSpec/ScatteredSetup: + Enabled: false + # Offense count: 1 RSpec/SingleArgumentMessageChain: Enabled: false -# Offense count: 8 -# Cop supports --auto-correct. -Style/AlignArray: +# Offense count: 163 +Rails/FilePath: Enabled: false -# Offense count: 11 +# Offense count: 2 +# Configuration parameters: Include. +# Include: db/migrate/*.rb +Rails/ReversibleMigration: + Enabled: false + +# Offense count: 278 +# Configuration parameters: Blacklist. +# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters +Rails/SkipsModelValidations: + Enabled: false + +# Offense count: 7 # Cop supports --auto-correct. -# Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles. -# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit -Style/AlignHash: +Security/YAMLLoad: Enabled: false # Offense count: 6 @@ -49,7 +69,7 @@ Style/AlignHash: Style/EachWithObject: Enabled: false -# Offense count: 24 +# Offense count: 25 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: empty, nil, both @@ -61,14 +81,14 @@ Style/EmptyElse: Style/EmptyLiteral: Enabled: false -# Offense count: 55 +# Offense count: 56 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: compact, expanded Style/EmptyMethod: Enabled: false -# Offense count: 173 +# Offense count: 184 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. Style/ExtraSpacing: @@ -80,29 +100,33 @@ Style/ExtraSpacing: Style/FormatString: Enabled: false -# Offense count: 263 +# Offense count: 268 # Configuration parameters: MinBodyLength. Style/GuardClause: Enabled: false -# Offense count: 12 +# Offense count: 2 +Style/IdenticalConditionalBranches: + Enabled: false + +# Offense count: 14 Style/IfInsideElse: Enabled: false -# Offense count: 177 +# Offense count: 179 # Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: Enabled: false -# Offense count: 61 +# Offense count: 57 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_brackets Style/IndentArray: Enabled: false -# Offense count: 108 +# Offense count: 120 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_braces @@ -123,7 +147,7 @@ Style/LineEndConcatenation: # Offense count: 22 # Cop supports --auto-correct. -Style/MethodCallParentheses: +Style/MethodCallWithoutArgsParentheses: Enabled: false # Offense count: 9 @@ -135,26 +159,26 @@ Style/MethodMissing: Style/MultilineIfModifier: Enabled: false -# Offense count: 8 +# Offense count: 22 # Cop supports --auto-correct. Style/NestedParenthesizedCalls: Enabled: false -# Offense count: 15 +# Offense count: 17 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. # SupportedStyles: skip_modifier_ifs, always Style/Next: Enabled: false -# Offense count: 19 +# Offense count: 31 # Cop supports --auto-correct. # Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles. # SupportedOctalStyles: zero_with_o, zero_only Style/NumericLiteralPrefix: Enabled: false -# Offense count: 68 +# Offense count: 77 # Cop supports --auto-correct. # Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles. # SupportedStyles: predicate, comparison @@ -166,13 +190,13 @@ Style/NumericPredicate: Style/ParallelAssignment: Enabled: false -# Offense count: 463 +# Offense count: 477 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: Enabled: false -# Offense count: 13 +# Offense count: 14 # Cop supports --auto-correct. Style/PerlBackrefs: Enabled: false @@ -204,7 +228,7 @@ Style/Proc: Style/RaiseArgs: Enabled: false -# Offense count: 3 +# Offense count: 4 # Cop supports --auto-correct. Style/RedundantBegin: Enabled: false @@ -225,7 +249,7 @@ Style/RedundantReturn: Style/RedundantSelf: Enabled: false -# Offense count: 107 +# Offense count: 108 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. # SupportedStyles: slashes, percent_r, mixed @@ -242,19 +266,13 @@ Style/RescueModifier: Style/SelfAssignment: Enabled: false -# Offense count: 2 -# Configuration parameters: Methods. -# Methods: {"reduce"=>["acc", "elem"]}, {"inject"=>["acc", "elem"]} -Style/SingleLineBlockParams: - Enabled: false - # Offense count: 50 # Cop supports --auto-correct. # Configuration parameters: AllowIfMethodIsEmpty. Style/SingleLineMethods: Enabled: false -# Offense count: 153 +# Offense count: 155 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space @@ -274,14 +292,15 @@ Style/SpaceBeforeFirstArg: Style/SpaceInLambdaLiteral: Enabled: false -# Offense count: 201 +# Offense count: 203 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. +# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space +# SupportedStylesForEmptyBraces: space, no_space Style/SpaceInsideBlockBraces: Enabled: false -# Offense count: 90 +# Offense count: 91 # Cop supports --auto-correct. Style/SpaceInsideParens: Enabled: false @@ -291,14 +310,14 @@ Style/SpaceInsideParens: Style/SpaceInsidePercentLiteralDelimiters: Enabled: false -# Offense count: 52 +# Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: SupportedStyles. # SupportedStyles: use_perl_names, use_english_names Style/SpecialGlobalVars: EnforcedStyle: use_perl_names -# Offense count: 25 +# Offense count: 40 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: single_quotes, double_quotes @@ -321,18 +340,18 @@ Style/TernaryParentheses: # Offense count: 43 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma +# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma Style/TrailingCommaInArguments: Enabled: false -# Offense count: 7 +# Offense count: 13 # Cop supports --auto-correct. # Configuration parameters: AllowNamedUnderscoreVariables. Style/TrailingUnderscoreVariable: Enabled: false -# Offense count: 69 +# Offense count: 70 # Cop supports --auto-correct. Style/TrailingWhitespace: Enabled: false @@ -344,12 +363,12 @@ Style/TrailingWhitespace: Style/TrivialAccessors: Enabled: false -# Offense count: 2 +# Offense count: 6 # Cop supports --auto-correct. Style/UnlessElse: Enabled: false -# Offense count: 19 +# Offense count: 22 # Cop supports --auto-correct. Style/UnneededInterpolation: Enabled: false diff --git a/Gemfile b/Gemfile index 3fc92abf9a7..00f2b6ffbfb 100644 --- a/Gemfile +++ b/Gemfile @@ -301,8 +301,8 @@ group :development, :test do gem 'spring-commands-rspec', '~> 1.0.4' gem 'spring-commands-spinach', '~> 1.1.0' - gem 'rubocop', '~> 0.46.0', require: false - gem 'rubocop-rspec', '~> 1.9.1', require: false + gem 'rubocop', '~> 0.47.1', require: false + gem 'rubocop-rspec', '~> 1.12.0', require: false gem 'scss_lint', '~> 0.47.0', require: false gem 'haml_lint', '~> 0.18.2', require: false gem 'simplecov', '0.12.0', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 9d6100f66ac..34b24a6e23b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -501,7 +501,7 @@ GEM os (0.9.6) paranoia (2.2.0) activerecord (>= 4.0, < 5.1) - parser (2.3.1.4) + parser (2.4.0.0) ast (~> 2.2) pg (0.18.4) poltergeist (1.9.0) @@ -642,13 +642,13 @@ GEM pg rails sqlite3 - rubocop (0.46.0) - parser (>= 2.3.1.1, < 3.0) + rubocop (0.47.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.9.1) + rubocop-rspec (1.12.0) rubocop (>= 0.42.0) ruby-fogbugz (0.2.1) crack (~> 0.4) @@ -776,7 +776,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) - unicode-display_width (1.1.1) + unicode-display_width (1.1.3) unicorn (5.1.0) kgio (~> 2.6) raindrops (~> 0.7) @@ -963,8 +963,8 @@ DEPENDENCIES rspec-rails (~> 3.5.0) rspec-retry (~> 0.4.5) rspec_profiling (~> 0.0.5) - rubocop (~> 0.46.0) - rubocop-rspec (~> 1.9.1) + rubocop (~> 0.47.1) + rubocop-rspec (~> 1.12.0) ruby-fogbugz (~> 0.2.1) ruby-prof (~> 0.16.2) rugged (~> 0.24.0) From ba0d27fe940fc120774c331492a849684ff1f9ad Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 12:43:48 -0600 Subject: [PATCH 234/247] Update rubocop and rubocop-rspec and regenerate .rubocop_todo.yml --- .rubocop.yml | 8 ++++---- .rubocop_todo.yml | 6 +----- lib/gitlab/o_auth/user.rb | 9 +++------ lib/gitlab/seeder.rb | 2 +- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 4515bc431f1..77c4d2c3ea1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -630,10 +630,6 @@ Lint/EndInMethod: Lint/EnsureReturn: Enabled: true -# The use of eval represents a serious security risk. -Lint/Eval: - Enabled: true - # Catches floating-point literals too large or small for Ruby to represent. Lint/FloatOutOfRange: Enabled: true @@ -810,6 +806,10 @@ Performance/TimesMap: Security/JSONLoad: Enabled: true +# This cop checks for the use of *Kernel#eval*. +Security/Eval: + Enabled: true + # Rails ####################################################################### # Enables Rails cops. diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 5b7a35493f8..6cd4e606382 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 0` -# on 2017-02-22 12:40:11 -0600 using RuboCop version 0.47.1. +# on 2017-02-22 13:02:35 -0600 using RuboCop version 0.47.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -105,10 +105,6 @@ Style/FormatString: Style/GuardClause: Enabled: false -# Offense count: 2 -Style/IdenticalConditionalBranches: - Enabled: false - # Offense count: 14 Style/IfInsideElse: Enabled: false diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 96ed20af918..87af76cc122 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -29,12 +29,9 @@ module Gitlab def save(provider = 'OAuth') unauthorized_to_create unless gl_user - if needs_blocking? - gl_user.save! - gl_user.block - else - gl_user.save! - end + gl_user.save! + + gl_user.block if needs_blocking? log.info "(#{provider}) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}" gl_user diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb index 6fb0be493e8..b7f825e8284 100644 --- a/lib/gitlab/seeder.rb +++ b/lib/gitlab/seeder.rb @@ -18,7 +18,7 @@ def Notify.deliver_later self end eos - eval(code) # rubocop:disable Lint/Eval + eval(code) # rubocop:disable Security/Eval end end end From cee2f0d4569d48e5fcab842d56cd325685a16772 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 13:01:31 -0600 Subject: [PATCH 235/247] Add explanations to cops --- .rubocop.yml | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 77c4d2c3ea1..2a8c30eff3f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -24,6 +24,7 @@ AllCops: - 'bin/**/*' - 'generator_templates/**/*' +# Gems in consecutive lines should be alphabetically sorted Bundler/OrderedGems: Enabled: false @@ -50,6 +51,8 @@ Style/AlignArray: Style/AlignHash: Enabled: true +# Here we check if the parameters on a multi-line method call or +# definition are aligned. Style/AlignParameters: Enabled: false @@ -74,6 +77,7 @@ Style/AsciiIdentifiers: Style/Attr: Enabled: true +# This cop checks if usage of %() or %Q() matches configuration. Style/BarePercentLiterals: Enabled: true @@ -94,9 +98,12 @@ Style/BlockDelimiters: Style/BlockEndNewline: Enabled: true + # This cop checks for braces around the last parameter in a method call +# if the last parameter is a hash. Style/BracesAroundHashParameters: Enabled: false +# This cop checks for uses of the case equality operator(===). Style/CaseEquality: Enabled: false @@ -128,9 +135,13 @@ Style/ClassMethods: Style/ClassVars: Enabled: true +# This cop checks for methods invoked via the :: operator instead +# of the . operator (like FileUtils::rmdir instead of FileUtils.rmdir). Style/ColonMethodCall: Enabled: true +# This cop checks that comment annotation keywords are written according +# to guidelines. Style/CommentAnnotation: Enabled: false @@ -138,6 +149,9 @@ Style/CommentAnnotation: Style/CommentIndentation: Enabled: true +# Check for `if` and `case` statements where each branch is used for +# assignment to the same variable when using the return of the +# condition can be used instead. Style/ConditionalAssignment: Enabled: true @@ -153,10 +167,14 @@ Style/DefWithParentheses: Style/Documentation: Enabled: false +# This cop checks the . position in multi-line method calls. Style/DotPosition: Enabled: true EnforcedStyle: leading +# This cop checks for uses of double negation (!!) to convert something +# to a boolean value. As this is both cryptic and usually redundant, it +# should be avoided. Style/DoubleNegation: Enabled: false @@ -332,6 +350,8 @@ Style/MultilineOperationIndentation: Style/MultilineTernaryOperator: Enabled: true +# This cop checks whether some constant value isn't a +# mutable literal (e.g. array or hash). Style/MutableConstant: Enabled: true @@ -437,6 +457,7 @@ Style/SpaceBeforeComment: Style/SpaceBeforeSemicolon: Enabled: true +# Checks for spaces inside square brackets. Style/SpaceInsideBrackets: Enabled: true @@ -476,6 +497,7 @@ Style/Tab: Style/TrailingBlankLines: Enabled: true +# This cop checks for trailing comma in array and hash literals. Style/TrailingCommaInLiteral: Enabled: false @@ -524,6 +546,7 @@ Metrics/AbcSize: Enabled: true Max: 60 +# This cop checks if the length of a block exceeds some maximum value. Metrics/BlockLength: Enabled: false @@ -571,9 +594,13 @@ Metrics/PerceivedComplexity: Lint/AmbiguousOperator: Enabled: true +# This cop checks for ambiguous regexp literals in the first argument of +# a method invocation without parentheses. Lint/AmbiguousRegexpLiteral: Enabled: false +# This cop checks for assignments in the conditions of +# if/while/until. Lint/AssignmentInCondition: Enabled: false @@ -638,6 +665,7 @@ Lint/FloatOutOfRange: Lint/FormatParameterMismatch: Enabled: true +# This cop checks for *rescue* blocks with no body. Lint/HandleExceptions: Enabled: false @@ -664,6 +692,7 @@ Lint/LiteralInCondition: Lint/LiteralInInterpolation: Enabled: true +# This cop checks for uses of *begin...end while/until something*. Lint/Loop: Enabled: false @@ -696,6 +725,8 @@ Lint/RescueException: Lint/ShadowedException: Enabled: false +# This cop looks for use of the same name as outer local variables +# for block arguments or block local variables. Lint/ShadowingOuterLocalVariable: Enabled: false @@ -707,6 +738,7 @@ Lint/StringConversionInInterpolation: Lint/UnderscorePrefixedVariableName: Enabled: true +# This cop checks for using Fixnum or Bignum constant Lint/UnifiedInteger: Enabled: true @@ -716,6 +748,7 @@ Lint/UnifiedInteger: Lint/UnneededDisable: Enabled: false +# This cop checks for unneeded usages of splat expansion Lint/UnneededSplatExpansion: Enabled: false @@ -723,9 +756,11 @@ Lint/UnneededSplatExpansion: Lint/UnreachableCode: Enabled: true +# This cop checks for unused block arguments. Lint/UnusedBlockArgument: Enabled: false +# This cop checks for unused method arguments. Lint/UnusedMethodArgument: Enabled: false @@ -772,12 +807,18 @@ Performance/LstripRstrip: Performance/RangeInclude: Enabled: true +# This cop identifies the use of a `&block` parameter and `block.call` +# where `yield` would do just as well. Performance/RedundantBlockCall: Enabled: true +# This cop identifies use of `Regexp#match` or `String#match in a context +# where the integral return value of `=~` would do just as well. Performance/RedundantMatch: Enabled: true +# This cop identifies places where `Hash#merge!` can be replaced by +# `Hash#[]=`. Performance/RedundantMerge: Enabled: true MaxKeyValuePairs: 1 @@ -803,6 +844,8 @@ Performance/TimesMap: # Security #################################################################### +# This cop checks for the use of JSON class methods which have potential +# security issues. Security/JSONLoad: Enabled: true @@ -830,9 +873,11 @@ Rails/Date: Rails/Delegate: Enabled: true +# This cop checks dynamic `find_by_*` methods. Rails/DynamicFindBy: Enabled: false +# This cop enforces that 'exit' calls are not used within a rails app. Rails/Exit: Enabled: true Exclude: @@ -851,6 +896,9 @@ Rails/FindEach: Rails/HasAndBelongsToMany: Enabled: true +# This cop is used to identify usages of http methods like `get`, `post`, +# `put`, `patch` without the usage of keyword arguments in your tests and +# change them to use keyword args. Rails/HttpPositionalArguments: Enabled: false @@ -863,6 +911,8 @@ Rails/Output: - 'lib/backup/**/*' - 'lib/tasks/**/*' +# This cop checks for the use of output safety calls like html_safe and +# raw. Rails/OutputSafety: Enabled: false @@ -878,9 +928,11 @@ Rails/ReadWriteAttribute: Rails/ScopeArgs: Enabled: true +# This cop checks for the use of Time methods without zone. Rails/TimeZone: Enabled: false +# This cop checks for the use of old-style attribute validation macros. Rails/Validation: Enabled: true @@ -941,15 +993,19 @@ RSpec/Focus: RSpec/InstanceVariable: Enabled: false +# Checks for `subject` definitions that come after `let` definitions. RSpec/LeadingSubject: Enabled: false +# Checks unreferenced `let!` calls being used for test setup. RSpec/LetSetup: Enabled: false +# Check that chains of messages are not being stubbed. RSpec/MessageChain: Enabled: false +# Checks that message expectations are set using spies. RSpec/MessageSpies: Enabled: false @@ -957,12 +1013,15 @@ RSpec/MessageSpies: RSpec/MultipleDescribes: Enabled: false +# Checks if examples contain too many `expect` calls. RSpec/MultipleExpectations: Enabled: false +# Checks for explicitly referenced test subjects. RSpec/NamedSubject: Enabled: false +# Checks for nested example groups. RSpec/NestedGroups: Enabled: false @@ -971,9 +1030,11 @@ RSpec/NotToNot: EnforcedStyle: not_to Enabled: true +# Check for repeated description strings in example groups. RSpec/RepeatedDescription: Enabled: false +# Checks for stubbed test subjects. RSpec/SubjectStub: Enabled: false From 56c5b2114021f395d4507bed8ad328ae2a35aa45 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 15:29:10 -0600 Subject: [PATCH 236/247] Update haml_lint to work with newest rubocop --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 00f2b6ffbfb..8715acba24f 100644 --- a/Gemfile +++ b/Gemfile @@ -304,7 +304,7 @@ group :development, :test do gem 'rubocop', '~> 0.47.1', require: false gem 'rubocop-rspec', '~> 1.12.0', require: false gem 'scss_lint', '~> 0.47.0', require: false - gem 'haml_lint', '~> 0.18.2', require: false + gem 'haml_lint', '~> 0.21.0', require: false gem 'simplecov', '0.12.0', require: false gem 'flay', '~> 2.6.1', require: false gem 'bundler-audit', '~> 0.5.0', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 34b24a6e23b..b46b09c7544 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -319,10 +319,10 @@ GEM multi_json (>= 1.3.2) haml (4.0.7) tilt - haml_lint (0.18.2) + haml_lint (0.21.0) haml (~> 4.0) - rake (>= 10, < 12) - rubocop (>= 0.36.0) + rake (>= 10, < 13) + rubocop (>= 0.47.0) sysexits (~> 1.1) hamlit (2.6.1) temple (~> 0.7.6) @@ -759,7 +759,7 @@ GEM rack (>= 1, < 3) thor (0.19.4) thread_safe (0.3.5) - tilt (2.0.5) + tilt (2.0.6) timecop (0.8.1) timfel-krb5-auth (0.8.3) tool (0.2.3) @@ -888,7 +888,7 @@ DEPENDENCIES google-api-client (~> 0.8.6) grape (~> 0.18.0) grape-entity (~> 0.6.0) - haml_lint (~> 0.18.2) + haml_lint (~> 0.21.0) hamlit (~> 2.6.1) health_check (~> 2.2.0) hipchat (~> 1.5.0) From 32a7041030dcb95d9476b3cbcc5d3c036aae81f3 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 15:36:16 -0600 Subject: [PATCH 237/247] ActiveSupport delegation is preferred over Forwardable --- app/models/concerns/cache_markdown_field.rb | 9 +++++---- lib/gitlab/git/repository.rb | 2 -- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb index 6dc8c88a14d..8ea95beed79 100644 --- a/app/models/concerns/cache_markdown_field.rb +++ b/app/models/concerns/cache_markdown_field.rb @@ -11,14 +11,15 @@ module CacheMarkdownField # Knows about the relationship between markdown and html field names, and # stores the rendering contexts for the latter class FieldData - extend Forwardable - def initialize @data = {} end - def_delegators :@data, :[], :[]= - def_delegator :@data, :keys, :markdown_fields + delegate :[], :[]=, to: :@data + + def markdown_fields + @data.keys + end def html_field(markdown_field) "#{markdown_field}_html" diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index e1fabff4e29..d1dd3da5ed2 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1,5 +1,4 @@ # Gitlab::Git::Repository is a wrapper around native Rugged::Repository object -require 'forwardable' require 'tempfile' require 'forwardable' require "rubygems/package" @@ -7,7 +6,6 @@ require "rubygems/package" module Gitlab module Git class Repository - extend Forwardable include Gitlab::Git::Popen SEARCH_CONTEXT_LINES = 3 From 0a5b670a9392f7f8c02e83f1c2e3ed4d2d67cfde Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 16:34:45 -0600 Subject: [PATCH 238/247] Exclude migrations from Style/MutableConstant --- .rubocop.yml | 3 +++ ...can_merge_to_protected_branches_merge_access.rb | 2 +- ...s_can_push_to_protected_branches_push_access.rb | 2 +- ...60729173930_remove_project_id_from_spam_logs.rb | 2 +- .../20160823081327_change_merge_error_to_text.rb | 2 +- .../20160824124900_add_table_issue_metrics.rb | 2 +- ...160825052008_add_table_merge_request_metrics.rb | 2 +- ...223750_remove_features_enabled_from_projects.rb | 2 +- ...160913162434_remove_projects_pushes_since_gc.rb | 2 +- .../20160913212128_change_artifacts_size_column.rb | 2 +- ...5042921_create_merge_requests_closing_issues.rb | 2 +- db/migrate/20160919144305_add_type_to_labels.rb | 2 +- .../20161014173530_create_label_priorities.rb | 2 +- .../20161017125927_add_unique_index_to_labels.rb | 2 +- .../20161018024215_migrate_labels_priority.rb | 2 +- .../20161018024550_remove_priority_from_labels.rb | 2 +- ...19190736_migrate_sidekiq_queues_from_default.rb | 2 +- ...213545_generate_project_feature_for_projects.rb | 2 +- ...353_add_pipeline_id_to_merge_request_metrics.rb | 2 +- ...24042317_migrate_mailroom_queue_from_default.rb | 2 +- db/migrate/20161025231710_migrate_jira_to_gem.rb | 2 +- ...61031174110_migrate_subscriptions_project_id.rb | 2 +- ...1031181638_add_unique_index_to_subscriptions.rb | 2 +- ...61103171205_rename_repository_storage_column.rb | 2 +- ...124141322_migrate_process_commit_worker_jobs.rb | 2 +- db/migrate/20161130095245_fill_routes_table.rb | 2 +- .../20161130101252_fill_projects_routes_table.rb | 2 +- .../20161201160452_migrate_project_statistics.rb | 2 +- ...1207231620_fixup_environment_name_uniqueness.rb | 10 +++++----- ...7231621_create_environment_name_unique_index.rb | 2 +- db/migrate/20161207231626_add_environment_slug.rb | 2 +- ...153400_add_unique_index_for_environment_slug.rb | 2 +- .../20170124174637_add_foreign_keys_to_timelogs.rb | 2 +- ...2551_remove_inactive_jira_service_properties.rb | 2 +- ..._fix_project_records_with_invalid_visibility.rb | 14 +++++++------- 35 files changed, 47 insertions(+), 44 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2a8c30eff3f..1850c31e344 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -354,6 +354,9 @@ Style/MultilineTernaryOperator: # mutable literal (e.g. array or hash). Style/MutableConstant: Enabled: true + Exclude: + - 'db/migrate/**/*' + - 'db/post_migrate/**/*' # Favor unless over if for negative conditions (or control flow or). Style/NegatedIf: diff --git a/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb b/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb index cd5d4286b31..1db0df92bec 100644 --- a/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb +++ b/db/migrate/20160705055254_move_from_developers_can_merge_to_protected_branches_merge_access.rb @@ -3,7 +3,7 @@ class MoveFromDevelopersCanMergeToProtectedBranchesMergeAccess < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC.freeze + DOWNTIME_REASON = <<-HEREDOC We're creating a `merge_access_level` for each `protected_branch`. If a user creates a `protected_branch` while this is running, we might be left with a `protected_branch` _without_ an associated `merge_access_level`. The `protected_branches` table must not change while this is running, so downtime is required. diff --git a/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb b/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb index 45e3368fa9b..5c3e189bb5b 100644 --- a/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb +++ b/db/migrate/20160705055308_move_from_developers_can_push_to_protected_branches_push_access.rb @@ -3,7 +3,7 @@ class MoveFromDevelopersCanPushToProtectedBranchesPushAccess < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC.freeze + DOWNTIME_REASON = <<-HEREDOC We're creating a `push_access_level` for each `protected_branch`. If a user creates a `protected_branch` while this is running, we might be left with a `protected_branch` _without_ an associated `push_access_level`. The `protected_branches` table must not change while this is running, so downtime is required. diff --git a/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb b/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb index 9995191ed9b..e28ab31d629 100644 --- a/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb +++ b/db/migrate/20160729173930_remove_project_id_from_spam_logs.rb @@ -10,7 +10,7 @@ class RemoveProjectIdFromSpamLogs < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Removing a column that contains data that is not used anywhere.'.freeze + DOWNTIME_REASON = 'Removing a column that contains data that is not used anywhere.' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160823081327_change_merge_error_to_text.rb b/db/migrate/20160823081327_change_merge_error_to_text.rb index 6dbf8a8d5e5..7920389cd83 100644 --- a/db/migrate/20160823081327_change_merge_error_to_text.rb +++ b/db/migrate/20160823081327_change_merge_error_to_text.rb @@ -2,7 +2,7 @@ class ChangeMergeErrorToText < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration requires downtime because it alters a column from varchar(255) to text.'.freeze + DOWNTIME_REASON = 'This migration requires downtime because it alters a column from varchar(255) to text.' def change change_column :merge_requests, :merge_error, :text, limit: 65535 diff --git a/db/migrate/20160824124900_add_table_issue_metrics.rb b/db/migrate/20160824124900_add_table_issue_metrics.rb index 9e52c54a35b..e9bb79b3c62 100644 --- a/db/migrate/20160824124900_add_table_issue_metrics.rb +++ b/db/migrate/20160824124900_add_table_issue_metrics.rb @@ -10,7 +10,7 @@ class AddTableIssueMetrics < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding foreign key'.freeze + DOWNTIME_REASON = 'Adding foreign key' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160825052008_add_table_merge_request_metrics.rb b/db/migrate/20160825052008_add_table_merge_request_metrics.rb index 195baf5f45b..e01cc5038b9 100644 --- a/db/migrate/20160825052008_add_table_merge_request_metrics.rb +++ b/db/migrate/20160825052008_add_table_merge_request_metrics.rb @@ -10,7 +10,7 @@ class AddTableMergeRequestMetrics < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding foreign key'.freeze + DOWNTIME_REASON = 'Adding foreign key' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160831223750_remove_features_enabled_from_projects.rb b/db/migrate/20160831223750_remove_features_enabled_from_projects.rb index 8202c6a7b79..a2c207b49ea 100644 --- a/db/migrate/20160831223750_remove_features_enabled_from_projects.rb +++ b/db/migrate/20160831223750_remove_features_enabled_from_projects.rb @@ -7,7 +7,7 @@ class RemoveFeaturesEnabledFromProjects < ActiveRecord::Migration # Set this constant to true if this migration requires downtime. DOWNTIME = true - DOWNTIME_REASON = "Removing fields from database requires downtine.".freeze + DOWNTIME_REASON = "Removing fields from database requires downtine." def up remove_column :projects, :issues_enabled diff --git a/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb b/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb index 919bfcdd86e..18ea9d43a43 100644 --- a/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb +++ b/db/migrate/20160913162434_remove_projects_pushes_since_gc.rb @@ -5,7 +5,7 @@ class RemoveProjectsPushesSinceGc < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration removes an existing column'.freeze + DOWNTIME_REASON = 'This migration removes an existing column' disable_ddl_transaction! diff --git a/db/migrate/20160913212128_change_artifacts_size_column.rb b/db/migrate/20160913212128_change_artifacts_size_column.rb index 8cda4b66c5a..063bbca537c 100644 --- a/db/migrate/20160913212128_change_artifacts_size_column.rb +++ b/db/migrate/20160913212128_change_artifacts_size_column.rb @@ -3,7 +3,7 @@ class ChangeArtifactsSizeColumn < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = 'Changing an integer column size requires a full table rewrite.'.freeze + DOWNTIME_REASON = 'Changing an integer column size requires a full table rewrite.' def up change_column :ci_builds, :artifacts_size, :integer, limit: 8 diff --git a/db/migrate/20160915042921_create_merge_requests_closing_issues.rb b/db/migrate/20160915042921_create_merge_requests_closing_issues.rb index 105278d49f7..94874a853da 100644 --- a/db/migrate/20160915042921_create_merge_requests_closing_issues.rb +++ b/db/migrate/20160915042921_create_merge_requests_closing_issues.rb @@ -10,7 +10,7 @@ class CreateMergeRequestsClosingIssues < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding foreign keys'.freeze + DOWNTIME_REASON = 'Adding foreign keys' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20160919144305_add_type_to_labels.rb b/db/migrate/20160919144305_add_type_to_labels.rb index f028c9460d1..66172bda6ff 100644 --- a/db/migrate/20160919144305_add_type_to_labels.rb +++ b/db/migrate/20160919144305_add_type_to_labels.rb @@ -2,7 +2,7 @@ class AddTypeToLabels < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.'.freeze + DOWNTIME_REASON = 'Labels will not work as expected until this migration is complete.' def change add_column :labels, :type, :string diff --git a/db/migrate/20161014173530_create_label_priorities.rb b/db/migrate/20161014173530_create_label_priorities.rb index 73c9897631c..2c22841c28a 100644 --- a/db/migrate/20161014173530_create_label_priorities.rb +++ b/db/migrate/20161014173530_create_label_priorities.rb @@ -2,7 +2,7 @@ class CreateLabelPriorities < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration adds foreign keys'.freeze + DOWNTIME_REASON = 'This migration adds foreign keys' disable_ddl_transaction! diff --git a/db/migrate/20161017125927_add_unique_index_to_labels.rb b/db/migrate/20161017125927_add_unique_index_to_labels.rb index 5571160ccb4..f2b56ebfb7b 100644 --- a/db/migrate/20161017125927_add_unique_index_to_labels.rb +++ b/db/migrate/20161017125927_add_unique_index_to_labels.rb @@ -2,7 +2,7 @@ class AddUniqueIndexToLabels < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration removes duplicated labels.'.freeze + DOWNTIME_REASON = 'This migration removes duplicated labels.' disable_ddl_transaction! diff --git a/db/migrate/20161018024215_migrate_labels_priority.rb b/db/migrate/20161018024215_migrate_labels_priority.rb index 9529bd3d494..22bec2382f4 100644 --- a/db/migrate/20161018024215_migrate_labels_priority.rb +++ b/db/migrate/20161018024215_migrate_labels_priority.rb @@ -2,7 +2,7 @@ class MigrateLabelsPriority < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Prioritized labels will not work as expected until this migration is complete.'.freeze + DOWNTIME_REASON = 'Prioritized labels will not work as expected until this migration is complete.' disable_ddl_transaction! diff --git a/db/migrate/20161018024550_remove_priority_from_labels.rb b/db/migrate/20161018024550_remove_priority_from_labels.rb index 4415a2e91af..b7416cca664 100644 --- a/db/migrate/20161018024550_remove_priority_from_labels.rb +++ b/db/migrate/20161018024550_remove_priority_from_labels.rb @@ -2,7 +2,7 @@ class RemovePriorityFromLabels < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration removes an existing column'.freeze + DOWNTIME_REASON = 'This migration removes an existing column' disable_ddl_transaction! diff --git a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb index 3a7acc84028..9f502a8df73 100644 --- a/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb +++ b/db/migrate/20161019190736_migrate_sidekiq_queues_from_default.rb @@ -8,7 +8,7 @@ class MigrateSidekiqQueuesFromDefault < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-EOF.freeze + DOWNTIME_REASON = <<-EOF Moving Sidekiq jobs from queues requires Sidekiq to be stopped. Not stopping Sidekiq will result in the loss of jobs that are scheduled after this migration completes. diff --git a/db/migrate/20161019213545_generate_project_feature_for_projects.rb b/db/migrate/20161019213545_generate_project_feature_for_projects.rb index 6486181575d..4554e14b0df 100644 --- a/db/migrate/20161019213545_generate_project_feature_for_projects.rb +++ b/db/migrate/20161019213545_generate_project_feature_for_projects.rb @@ -1,7 +1,7 @@ class GenerateProjectFeatureForProjects < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC.freeze + DOWNTIME_REASON = <<-HEREDOC Application was eager loading project_feature for all projects generating an extra query everytime a project was fetched. We removed that behavior to avoid the extra query, this migration makes sure all projects have a project_feature record associated. diff --git a/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb b/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb index b396c03ecbf..2abfe47b776 100644 --- a/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb +++ b/db/migrate/20161020083353_add_pipeline_id_to_merge_request_metrics.rb @@ -12,7 +12,7 @@ class AddPipelineIdToMergeRequestMetrics < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Adding a foreign key'.freeze + DOWNTIME_REASON = 'Adding a foreign key' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb index 91d078f6293..fc2e4c12b30 100644 --- a/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb +++ b/db/migrate/20161024042317_migrate_mailroom_queue_from_default.rb @@ -8,7 +8,7 @@ class MigrateMailroomQueueFromDefault < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-EOF.freeze + DOWNTIME_REASON = <<-EOF Moving Sidekiq jobs from queues requires Sidekiq to be stopped. Not stopping Sidekiq will result in the loss of jobs that are scheduled after this migration completes. diff --git a/db/migrate/20161025231710_migrate_jira_to_gem.rb b/db/migrate/20161025231710_migrate_jira_to_gem.rb index 38824ba9fe5..870b00411d2 100644 --- a/db/migrate/20161025231710_migrate_jira_to_gem.rb +++ b/db/migrate/20161025231710_migrate_jira_to_gem.rb @@ -1,7 +1,7 @@ class MigrateJiraToGem < ActiveRecord::Migration DOWNTIME = true - DOWNTIME_REASON = <<-HEREDOC.freeze + DOWNTIME_REASON = <<-HEREDOC Refactor all Jira services properties(serialized field) to use new jira-ruby gem. There were properties on old Jira service that are not needed anymore after the service refactoring: api_url, project_url, new_issue_url, issues_url. diff --git a/db/migrate/20161031174110_migrate_subscriptions_project_id.rb b/db/migrate/20161031174110_migrate_subscriptions_project_id.rb index 130b5f556ff..549145a0a65 100644 --- a/db/migrate/20161031174110_migrate_subscriptions_project_id.rb +++ b/db/migrate/20161031174110_migrate_subscriptions_project_id.rb @@ -2,7 +2,7 @@ class MigrateSubscriptionsProjectId < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Subscriptions will not work as expected until this migration is complete.'.freeze + DOWNTIME_REASON = 'Subscriptions will not work as expected until this migration is complete.' def up execute <<-EOF.strip_heredoc diff --git a/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb b/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb index 1b675a36db7..4b1b29e1265 100644 --- a/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb +++ b/db/migrate/20161031181638_add_unique_index_to_subscriptions.rb @@ -2,7 +2,7 @@ class AddUniqueIndexToSubscriptions < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'This migration requires downtime because it changes a column to not accept null values.'.freeze + DOWNTIME_REASON = 'This migration requires downtime because it changes a column to not accept null values.' disable_ddl_transaction! diff --git a/db/migrate/20161103171205_rename_repository_storage_column.rb b/db/migrate/20161103171205_rename_repository_storage_column.rb index 32d22e630d8..93280573939 100644 --- a/db/migrate/20161103171205_rename_repository_storage_column.rb +++ b/db/migrate/20161103171205_rename_repository_storage_column.rb @@ -10,7 +10,7 @@ class RenameRepositoryStorageColumn < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = 'Renaming the application_settings.repository_storage column'.freeze + DOWNTIME_REASON = 'Renaming the application_settings.repository_storage column' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb index 3865f3e3a08..f4fe8103218 100644 --- a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb +++ b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb @@ -25,7 +25,7 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration end DOWNTIME = true - DOWNTIME_REASON = 'Existing workers will error until they are using a newer version of the code'.freeze + DOWNTIME_REASON = 'Existing workers will error until they are using a newer version of the code' disable_ddl_transaction! diff --git a/db/migrate/20161130095245_fill_routes_table.rb b/db/migrate/20161130095245_fill_routes_table.rb index ccd2cceee0c..c3536d6d911 100644 --- a/db/migrate/20161130095245_fill_routes_table.rb +++ b/db/migrate/20161130095245_fill_routes_table.rb @@ -5,7 +5,7 @@ class FillRoutesTable < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'No new namespaces should be created during data copy'.freeze + DOWNTIME_REASON = 'No new namespaces should be created during data copy' def up execute <<-EOF diff --git a/db/migrate/20161130101252_fill_projects_routes_table.rb b/db/migrate/20161130101252_fill_projects_routes_table.rb index 5e7d0e75ad8..56ba6fcdbe3 100644 --- a/db/migrate/20161130101252_fill_projects_routes_table.rb +++ b/db/migrate/20161130101252_fill_projects_routes_table.rb @@ -5,7 +5,7 @@ class FillProjectsRoutesTable < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'No new projects should be created during data copy'.freeze + DOWNTIME_REASON = 'No new projects should be created during data copy' def up if Gitlab::Database.postgresql? diff --git a/db/migrate/20161201160452_migrate_project_statistics.rb b/db/migrate/20161201160452_migrate_project_statistics.rb index afd5ce95068..3ae3f2c159b 100644 --- a/db/migrate/20161201160452_migrate_project_statistics.rb +++ b/db/migrate/20161201160452_migrate_project_statistics.rb @@ -2,7 +2,7 @@ class MigrateProjectStatistics < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Removes two columns from the projects table'.freeze + DOWNTIME_REASON = 'Removes two columns from the projects table' def up # convert repository_size in float (megabytes) to integer (bytes), diff --git a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb index b31f9699f3d..f73e4f6c99b 100644 --- a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb +++ b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb @@ -2,7 +2,7 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Renaming non-unique environments'.freeze + DOWNTIME_REASON = 'Renaming non-unique environments' def up environments = Arel::Table.new(:environments) @@ -42,10 +42,10 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration conflicts.each do |id, name| update_sql = Arel::UpdateManager.new(ActiveRecord::Base) - .table(environments) - .set(environments[:name] => name + "-" + id.to_s) - .where(environments[:id].eq(id)) - .to_sql + .table(environments) + .set(environments[:name] => name + "-" + id.to_s) + .where(environments[:id].eq(id)) + .to_sql connection.exec_update(update_sql, self.class.name, []) end diff --git a/db/migrate/20161207231621_create_environment_name_unique_index.rb b/db/migrate/20161207231621_create_environment_name_unique_index.rb index 94fa3b6838c..ac680c8d10f 100644 --- a/db/migrate/20161207231621_create_environment_name_unique_index.rb +++ b/db/migrate/20161207231621_create_environment_name_unique_index.rb @@ -4,7 +4,7 @@ class CreateEnvironmentNameUniqueIndex < ActiveRecord::Migration disable_ddl_transaction! DOWNTIME = true - DOWNTIME_REASON = 'Making a non-unique index into a unique index'.freeze + DOWNTIME_REASON = 'Making a non-unique index into a unique index' def up remove_index :environments, [:project_id, :name] diff --git a/db/migrate/20161207231626_add_environment_slug.rb b/db/migrate/20161207231626_add_environment_slug.rb index 1dec96a1299..83cdd484c4c 100644 --- a/db/migrate/20161207231626_add_environment_slug.rb +++ b/db/migrate/20161207231626_add_environment_slug.rb @@ -5,7 +5,7 @@ class AddEnvironmentSlug < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Adding NOT NULL column environments.slug with dependent data'.freeze + DOWNTIME_REASON = 'Adding NOT NULL column environments.slug with dependent data' # Used to generate random suffixes for the slug LETTERS = 'a'..'z' diff --git a/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb b/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb index fbf6e4c2a45..e9fcef1cd45 100644 --- a/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb +++ b/db/migrate/20161209153400_add_unique_index_for_environment_slug.rb @@ -5,7 +5,7 @@ class AddUniqueIndexForEnvironmentSlug < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = 'Adding a *unique* index to environments.slug'.freeze + DOWNTIME_REASON = 'Adding a *unique* index to environments.slug' disable_ddl_transaction! diff --git a/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb b/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb index 2b2b7ab27ce..69bfa2d3fc4 100644 --- a/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb +++ b/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb @@ -9,7 +9,7 @@ class AddForeignKeysToTimelogs < ActiveRecord::Migration # When a migration requires downtime you **must** uncomment the following # constant and define a short and easy to understand explanation as to why the # migration requires downtime. - DOWNTIME_REASON = ''.freeze + DOWNTIME_REASON = '' # When using the methods "add_concurrent_index" or "add_column_with_default" # you must disable the use of transactions as these methods can not run in an diff --git a/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb b/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb index eacc6d1b033..319d86ac159 100644 --- a/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb +++ b/db/post_migrate/20161011222551_remove_inactive_jira_service_properties.rb @@ -2,7 +2,7 @@ class RemoveInactiveJiraServiceProperties < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers DOWNTIME = true - DOWNTIME_REASON = "Removes all inactive jira_service properties".freeze + DOWNTIME_REASON = "Removes all inactive jira_service properties" def up execute("UPDATE services SET properties = '{}' WHERE services.type = 'JiraService' and services.active = false") diff --git a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb index 823274b08c0..69007b8e8ed 100644 --- a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb +++ b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb @@ -14,15 +14,15 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration finder_sql = projects - .join(namespaces, Arel::Nodes::InnerJoin) - .on(projects[:namespace_id].eq(namespaces[:id])) - .where(projects[:visibility_level].gt(namespaces[:visibility_level])) - .project(projects[:id], namespaces[:visibility_level]) - .take(BATCH_SIZE) - .to_sql + .join(namespaces, Arel::Nodes::InnerJoin) + .on(projects[:namespace_id].eq(namespaces[:id])) + .where(projects[:visibility_level].gt(namespaces[:visibility_level])) + .project(projects[:id], namespaces[:visibility_level]) + .take(BATCH_SIZE) + .to_sql # Update matching rows in batches. Each batch can cause up to 3 UPDATE - # statements, in addition to the SELECT: one per visibility_level + # statements, in addition to the SELECT: one per visibility_level loop do to_update = connection.exec_query(finder_sql) break if to_update.rows.count == 0 From b3ff48c9a1d61b22ab4040ebcdc64eeeb797ad44 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 16:35:08 -0600 Subject: [PATCH 239/247] Move up delegate calls --- app/models/ci/build.rb | 4 ++-- app/models/ci/pipeline.rb | 4 ++-- app/models/commit_status.rb | 3 +-- app/models/concerns/issuable.rb | 22 +++++++++++----------- app/models/member.rb | 4 ++-- app/models/project.rb | 6 ++---- app/models/project_wiki.rb | 7 +++---- lib/gitlab/git/commit.rb | 4 ++-- 8 files changed, 25 insertions(+), 29 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index d2a53315f1d..3a17d5c8dbe 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -22,6 +22,8 @@ module Ci serialize :options serialize :yaml_variables, Gitlab::Serializer::Ci::Variables + delegate :name, to: :project, prefix: true + validates :coverage, numericality: true, allow_blank: true validates :ref, presence: true @@ -233,8 +235,6 @@ module Ci gl_project_id end - delegate :name, to: :project, prefix: true - def repo_url auth = "gitlab-ci-token:#{ensure_token!}@" project.http_url_to_repo.sub(/^https?:\/\//) do |prefix| diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index d2312215f85..632178de887 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -14,6 +14,8 @@ module Ci has_many :builds, foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id + delegate :id, to: :project, prefix: true + validates :sha, presence: { unless: :importing? } validates :ref, presence: { unless: :importing? } validates :status, presence: { unless: :importing? } @@ -153,8 +155,6 @@ module Ci builds.latest.with_artifacts_not_expired.includes(project: [:namespace]) end - delegate :id, to: :project, prefix: true - # For now the only user who participates is the user who triggered def participants(_current_user = nil) Array(user) diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index df835b99189..fc750a3e5e9 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -10,6 +10,7 @@ class CommitStatus < ActiveRecord::Base belongs_to :user delegate :commit, to: :pipeline + delegate :sha, :short_sha, to: :pipeline validates :pipeline, presence: true, unless: :importing? @@ -102,8 +103,6 @@ class CommitStatus < ActiveRecord::Base end end - delegate :sha, :short_sha, to: :pipeline - def before_sha pipeline.before_sha || Gitlab::Git::BLANK_SHA end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 8b33e776e87..fcb335e48d1 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -46,6 +46,17 @@ module Issuable has_one :metrics + delegate :name, + :email, + to: :author, + prefix: true + + delegate :name, + :email, + to: :assignee, + allow_nil: true, + prefix: true + validates :author, presence: true validates :title, presence: true, length: { maximum: 255 } @@ -72,17 +83,6 @@ module Issuable scope :references_project, -> { references(:project) } scope :non_archived, -> { join_project.where(projects: { archived: false }) } - delegate :name, - :email, - to: :author, - prefix: true - - delegate :name, - :email, - to: :assignee, - allow_nil: true, - prefix: true - attr_mentionable :title, pipeline: :single_line attr_mentionable :description diff --git a/app/models/member.rb b/app/models/member.rb index 2ea4abacea4..f198fbe9056 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -10,6 +10,8 @@ class Member < ActiveRecord::Base belongs_to :user belongs_to :source, polymorphic: true + delegate :name, :username, :email, to: :user, prefix: true + validates :user, presence: true, unless: :invite? validates :source, presence: true validates :user_id, uniqueness: { scope: [:source_type, :source_id], @@ -73,8 +75,6 @@ class Member < ActiveRecord::Base after_destroy :post_destroy_hook, unless: :pending? after_commit :refresh_member_authorized_projects - delegate :name, :username, :email, to: :user, prefix: true - default_value_for :notification_level, NotificationSetting.levels[:global] class << self diff --git a/app/models/project.rb b/app/models/project.rb index a1b29d335b3..698e742de48 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -172,9 +172,11 @@ class Project < ActiveRecord::Base accepts_nested_attributes_for :project_feature delegate :name, to: :owner, allow_nil: true, prefix: true + delegate :count, to: :forks, prefix: true delegate :members, to: :team, prefix: true delegate :add_user, to: :team delegate :add_guest, :add_reporter, :add_developer, :add_master, to: :team + delegate :empty_repo?, to: :repository # Validations validates :creator, presence: true, on: :create @@ -838,8 +840,6 @@ class Project < ActiveRecord::Base false end - delegate :empty_repo?, to: :repository - def repo repository.raw end @@ -1027,8 +1027,6 @@ class Project < ActiveRecord::Base forked? && project == forked_from_project end - delegate :count, to: :forks, prefix: true - def origin_merge_requests merge_requests.where(source_project_id: self.id) end diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index 2f55b853232..9891f5edf41 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -19,6 +19,9 @@ class ProjectWiki @user = user end + delegate :empty?, to: :pages + delegate :repository_storage_path, to: :project + def path @project.path + '.wiki' end @@ -60,8 +63,6 @@ class ProjectWiki !!repository.exists? end - delegate :empty?, to: :pages - # Returns an Array of Gitlab WikiPage instances or an # empty Array if this Wiki has no pages. def pages @@ -158,8 +159,6 @@ class ProjectWiki } end - delegate :repository_storage_path, to: :project - private def init_repo(path_with_namespace) diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb index fd2b26c4a63..3a73697dc5d 100644 --- a/lib/gitlab/git/commit.rb +++ b/lib/gitlab/git/commit.rb @@ -14,6 +14,8 @@ module Gitlab attr_accessor *SERIALIZE_KEYS # rubocop:disable Lint/AmbiguousOperator + delegate :tree, to: :raw_commit + def ==(other) return false unless other.is_a?(Gitlab::Git::Commit) @@ -218,8 +220,6 @@ module Gitlab raw_commit.parents.map { |c| Gitlab::Git::Commit.new(c) } end - delegate :tree, to: :raw_commit - def stats Gitlab::Git::CommitStats.new(self) end From 0beba0251ca5bfbbc0c1a60c5b0b44c972f252cd Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 16:35:45 -0600 Subject: [PATCH 240/247] Manually correct autocorrect --- app/workers/prune_old_events_worker.rb | 4 ++-- config/initializers/1_settings.rb | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb index 2b43bb19ad1..cee05b42dd7 100644 --- a/app/workers/prune_old_events_worker.rb +++ b/app/workers/prune_old_events_worker.rb @@ -12,7 +12,7 @@ class PruneOldEventsWorker 'created_at < ?', (12.months + 1.day).ago) .select(:id) - .limit(10_000)) - .delete_all + .limit(10_000) + ).delete_all end end diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 21cc03113ae..c64ae15fa92 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -20,6 +20,7 @@ class Settings < Settingslogic else ":#{gitlab.port}" end + [ gitlab.protocol, "://", @@ -82,6 +83,7 @@ class Settings < Settingslogic def base_url(config) custom_port = on_standard_port?(config) ? nil : ":#{config.port}" + [ config.protocol, "://", From bdbc7d967a0c3d95d5e4ea19a2a5be41268d3540 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 16:39:43 -0600 Subject: [PATCH 241/247] Revert "Enable Style/BarePercentLiterals" This reverts commit 96bef54154e669f9a3e92c3a4bc76c0be3a52e48. --- .rubocop.yml | 4 ---- .rubocop_todo.yml | 7 +++++++ app/helpers/commits_helper.rb | 2 +- app/models/commit.rb | 2 +- ...0160610201627_migrate_users_notification_level.rb | 4 ++-- .../20160831214543_migrate_project_features.rb | 4 ++-- features/steps/project/badges/build.rb | 2 +- lib/banzai/filter/autolink_filter.rb | 2 +- lib/banzai/filter/reference_filter.rb | 4 ++-- lib/banzai/filter/table_of_contents_filter.rb | 6 +++--- lib/gitlab/database/median.rb | 4 ++-- spec/features/projects/badges/coverage_spec.rb | 2 +- spec/features/projects/issuable_templates_spec.rb | 2 +- spec/features/projects/pipelines/pipelines_spec.rb | 2 +- spec/helpers/blob_helper_spec.rb | 2 +- spec/helpers/gitlab_markdown_helper_spec.rb | 4 ++-- spec/lib/banzai/filter/external_link_filter_spec.rb | 6 +++--- .../lib/banzai/filter/label_reference_filter_spec.rb | 2 +- .../banzai/filter/milestone_reference_filter_spec.rb | 2 +- spec/lib/banzai/filter/user_reference_filter_spec.rb | 2 +- spec/lib/banzai/pipeline/full_pipeline_spec.rb | 2 +- spec/lib/gitlab/diff/highlight_spec.rb | 12 ++++++------ spec/lib/gitlab/gfm/reference_rewriter_spec.rb | 8 ++++---- spec/lib/gitlab/highlight_spec.rb | 6 +++--- spec/lib/gitlab/reference_extractor_spec.rb | 2 +- spec/lib/gitlab/url_sanitizer_spec.rb | 2 +- spec/models/project_label_spec.rb | 4 ++-- spec/models/project_services/bamboo_service_spec.rb | 4 ++-- .../project_services/buildkite_service_spec.rb | 4 ++-- .../models/project_services/drone_ci_service_spec.rb | 4 ++-- .../models/project_services/teamcity_service_spec.rb | 6 +++--- spec/workers/repository_import_worker_spec.rb | 2 +- 32 files changed, 62 insertions(+), 59 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1850c31e344..a7d4222b9b2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -77,10 +77,6 @@ Style/AsciiIdentifiers: Style/Attr: Enabled: true -# This cop checks if usage of %() or %Q() matches configuration. -Style/BarePercentLiterals: - Enabled: true - # Avoid the use of BEGIN blocks. Style/BeginBlock: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6cd4e606382..8bc7d568c10 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -63,6 +63,13 @@ Rails/SkipsModelValidations: # Cop supports --auto-correct. Security/YAMLLoad: Enabled: false + +# Offense count: 55 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: percent_q, bare_percent +Style/BarePercentLiterals: + Enabled: false # Offense count: 6 # Cop supports --auto-correct. diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 4e1fbc57575..8aad39e148b 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -155,7 +155,7 @@ module CommitsHelper text = if options[:avatar] - %{#{person_name}} + %Q{#{person_name}} else person_name end diff --git a/app/models/commit.rb b/app/models/commit.rb index dc971e710ff..0a18986ef26 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -256,7 +256,7 @@ class Commit end def revert_message(user) - %{Revert "#{title.strip}"\n\n#{revert_description(user)}} + %Q{Revert "#{title.strip}"\n\n#{revert_description(user)}} end def reverts_commit?(commit, user) diff --git a/db/migrate/20160610201627_migrate_users_notification_level.rb b/db/migrate/20160610201627_migrate_users_notification_level.rb index 9da67b59dd1..ce4f00e25fa 100644 --- a/db/migrate/20160610201627_migrate_users_notification_level.rb +++ b/db/migrate/20160610201627_migrate_users_notification_level.rb @@ -5,7 +5,7 @@ class MigrateUsersNotificationLevel < ActiveRecord::Migration DOWNTIME = false def up - execute(%{ + execute(%Q{ INSERT INTO notification_settings (user_id, level, created_at, updated_at) (SELECT id, notification_level, created_at, updated_at FROM users WHERE notification_level != 1) @@ -15,7 +15,7 @@ class MigrateUsersNotificationLevel < ActiveRecord::Migration # Migrates from notification settings back to user notification_level # If no value is found the default level of 1 will be used def down - execute(%{ + execute(%Q{ UPDATE users u SET notification_level = COALESCE((SELECT level FROM notification_settings WHERE user_id = u.id AND source_type IS NULL), 1) }) diff --git a/db/migrate/20160831214543_migrate_project_features.rb b/db/migrate/20160831214543_migrate_project_features.rb index a2f2267773c..79a5fb29d64 100644 --- a/db/migrate/20160831214543_migrate_project_features.rb +++ b/db/migrate/20160831214543_migrate_project_features.rb @@ -10,7 +10,7 @@ class MigrateProjectFeatures < ActiveRecord::Migration def up sql = - %{ + %Q{ INSERT INTO project_features(project_id, issues_access_level, merge_requests_access_level, wiki_access_level, builds_access_level, snippets_access_level, created_at, updated_at) SELECT @@ -29,7 +29,7 @@ class MigrateProjectFeatures < ActiveRecord::Migration end def down - sql = %{ + sql = %Q{ UPDATE projects SET issues_enabled = COALESCE((SELECT CASE WHEN issues_access_level = 20 THEN true ELSE false END AS issues_enabled FROM project_features WHERE project_features.project_id = projects.id), true), diff --git a/features/steps/project/badges/build.rb b/features/steps/project/badges/build.rb index 12a49779edb..96c59322f9b 100644 --- a/features/steps/project/badges/build.rb +++ b/features/steps/project/badges/build.rb @@ -27,6 +27,6 @@ class Spinach::Features::ProjectBadgesBuild < Spinach::FeatureSteps def expect_badge(status) svg = Nokogiri::XML.parse(page.body) expect(page.response_headers['Content-Type']).to include('image/svg+xml') - expect(svg.at(%{text:contains("#{status}")})).to be_truthy + expect(svg.at(%Q{text:contains("#{status}")})).to be_truthy end end diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index e84b7c2c0c3..b8d2673c1a6 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -32,7 +32,7 @@ module Banzai IGNORE_PARENTS = %w(a code kbd pre script style).to_set # The XPath query to use for finding text nodes to parse. - TEXT_QUERY = %(descendant-or-self::text()[ + TEXT_QUERY = %Q(descendant-or-self::text()[ not(#{IGNORE_PARENTS.map { |p| "ancestor::#{p}" }.join(' or ')}) and contains(., '://') and not(starts-with(., 'http')) diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb index 6281fa7e401..6640168bfa2 100644 --- a/lib/banzai/filter/reference_filter.rb +++ b/lib/banzai/filter/reference_filter.rb @@ -32,7 +32,7 @@ module Banzai attributes[:reference_type] ||= self.class.reference_type attributes.delete(:original) if context[:no_original_data] attributes.map do |key, value| - %(data-#{key.to_s.dasherize}="#{escape_once(value)}") + %Q(data-#{key.to_s.dasherize}="#{escape_once(value)}") end.join(' ') end @@ -76,7 +76,7 @@ module Banzai def each_node return to_enum(__method__) unless block_given? - query = %{descendant-or-self::text()[not(#{ignore_ancestor_query})] + query = %Q{descendant-or-self::text()[not(#{ignore_ancestor_query})] | descendant-or-self::a[ not(contains(concat(" ", @class, " "), " gfm ")) and not(@href = "") ]} diff --git a/lib/banzai/filter/table_of_contents_filter.rb b/lib/banzai/filter/table_of_contents_filter.rb index d460110b974..8e7084f2543 100644 --- a/lib/banzai/filter/table_of_contents_filter.rb +++ b/lib/banzai/filter/table_of_contents_filter.rb @@ -43,7 +43,7 @@ module Banzai end end - result[:toc] = %{
      \n#{result[:toc]}
    } unless result[:toc].empty? + result[:toc] = %Q{
      \n#{result[:toc]}
    } unless result[:toc].empty? doc end @@ -51,11 +51,11 @@ module Banzai private def anchor_tag(id, href) - %{} + %Q{} end def push_toc(href, text) - result[:toc] << %{
  • #{text}
  • \n} + result[:toc] << %Q{
  • #{text}
  • \n} end end end diff --git a/lib/gitlab/database/median.rb b/lib/gitlab/database/median.rb index e265d22a989..059054ac9ff 100644 --- a/lib/gitlab/database/median.rb +++ b/lib/gitlab/database/median.rb @@ -100,13 +100,13 @@ module Gitlab end def extract_epoch(arel_attribute) - Arel.sql(%{EXTRACT(EPOCH FROM "#{arel_attribute.relation.name}"."#{arel_attribute.name}")}) + Arel.sql(%Q{EXTRACT(EPOCH FROM "#{arel_attribute.relation.name}"."#{arel_attribute.name}")}) end def extract_diff_epoch(diff) return diff unless Gitlab::Database.postgresql? - Arel.sql(%{EXTRACT(EPOCH FROM (#{diff.to_sql}))}) + Arel.sql(%Q{EXTRACT(EPOCH FROM (#{diff.to_sql}))}) end # Need to cast '0' to an INTERVAL before we can check if the interval is positive diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb index 1fefcb916f6..01a95bf49ac 100644 --- a/spec/features/projects/badges/coverage_spec.rb +++ b/spec/features/projects/badges/coverage_spec.rb @@ -77,6 +77,6 @@ feature 'test coverage badge' do def expect_coverage_badge(coverage) svg = Nokogiri::XML.parse(page.body) expect(page.response_headers['Content-Type']).to include('image/svg+xml') - expect(svg.at(%{text:contains("#{coverage}")})).to be_truthy + expect(svg.at(%Q{text:contains("#{coverage}")})).to be_truthy end end diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb index 3fe5a6ec818..e90a033b8c4 100644 --- a/spec/features/projects/issuable_templates_spec.rb +++ b/spec/features/projects/issuable_templates_spec.rb @@ -13,7 +13,7 @@ feature 'issuable templates', feature: true, js: true do context 'user creates an issue using templates' do let(:template_content) { 'this is a test "bug" template' } - let(:longtemplate_content) { %(this\n\n\n\n\nis\n\n\n\n\na\n\n\n\n\nbug\n\n\n\n\ntemplate) } + let(:longtemplate_content) { %Q(this\n\n\n\n\nis\n\n\n\n\na\n\n\n\n\nbug\n\n\n\n\ntemplate) } let(:issue) { create(:issue, author: user, assignee: user, project: project) } let(:description_addition) { ' appending to description' } diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 0e12618b629..592dc4483d2 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -154,7 +154,7 @@ describe 'Pipelines', :feature, :js do it 'contains badge with tooltip which contains error' do expect(pipeline).to have_yaml_errors expect(page).to have_selector( - %{span[data-original-title="#{pipeline.yaml_errors}"]}) + %Q{span[data-original-title="#{pipeline.yaml_errors}"]}) end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index 3e1b29dde75..fa516f9903e 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -23,7 +23,7 @@ describe BlobHelper do end it 'highlights single block' do - expected = %[
    (make-pathname :defaults name
    +      expected = %Q[
    (make-pathname :defaults name
     :type "assem"))
    ] expect(helper.highlight(blob_name, blob_content)).to eq(expected) diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 908e1a65c55..7daf03bcc54 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -107,13 +107,13 @@ describe GitlabMarkdownHelper do it 'ignores reference links when they are the entire body' do text = issues[0].to_reference act = helper.link_to_gfm(text, '/foo') - expect(act).to eq %(#{issues[0].to_reference}) + expect(act).to eq %Q(#{issues[0].to_reference}) end it 'replaces commit message with emoji to link' do actual = link_to_gfm(':book:Book', '/foo') expect(actual) - .to eq %(:book:Book) + .to eq %Q(:book:Book) end end diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb index 5ffbab0f12f..d9e4525cb28 100644 --- a/spec/lib/banzai/filter/external_link_filter_spec.rb +++ b/spec/lib/banzai/filter/external_link_filter_spec.rb @@ -15,7 +15,7 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do it 'skips internal links' do internal = Gitlab.config.gitlab.url - exp = act = %(Login) + exp = act = %Q(Login) expect(filter(act).to_html).to eq exp end @@ -70,8 +70,8 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do it 'skips internal links' do internal_link = Gitlab.config.gitlab.url + "/sign_in" url = internal_link.gsub(/\Ahttp/, 'HtTp') - act = %(Login) - exp = %(Login) + act = %Q(Login) + exp = %Q(Login) expect(filter(act).to_html).to eq(exp) end diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index 80fa940f330..cb3cf982351 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -282,7 +282,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do end describe 'referencing a label in a link href' do - let(:reference) { %{Label} } + let(:reference) { %Q{Label} } it 'links to a valid reference' do doc = reference_filter("See #{reference}") diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index 0f4619a6dfb..fe88b9cb73e 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -117,7 +117,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do end describe 'referencing a milestone in a link href' do - let(:reference) { %{Milestone} } + let(:reference) { %Q{Milestone} } it 'links to a valid reference' do doc = reference_filter("See #{reference}") diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index 6d6a00a3b1f..d5d128c1907 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -144,7 +144,7 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do end context 'referencing a user in a link href' do - let(:reference) { %{User} } + let(:reference) { %Q{User} } it 'links to a User' do doc = reference_filter("Hey #{reference}") diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb index c24a0e4d2b6..2501b638774 100644 --- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb @@ -20,7 +20,7 @@ describe Banzai::Pipeline::FullPipeline do end it 'escapes the data-original attribute on a reference' do - markdown = %{[">bad things](#{issue.to_reference})} + markdown = %Q{[">bad things](#{issue.to_reference})} result = described_class.to_html(markdown, project: project) expect(result).to include(%{data-original='\">bad things'}) end diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb index 1cb6f66ced5..0e9309d278e 100644 --- a/spec/lib/gitlab/diff/highlight_spec.rb +++ b/spec/lib/gitlab/diff/highlight_spec.rb @@ -22,19 +22,19 @@ describe Gitlab::Diff::Highlight, lib: true do end it 'highlights and marks unchanged lines' do - code = %{ def popen(cmd, path=nil)\n} + code = %Q{ def popen(cmd, path=nil)\n} expect(subject[2].text).to eq(code) end it 'highlights and marks removed lines' do - code = %{- raise "System commands must be given as an array of strings"\n} + code = %Q{- raise "System commands must be given as an array of strings"\n} expect(subject[4].text).to eq(code) end it 'highlights and marks added lines' do - code = %{+ raise RuntimeError, "System commands must be given as an array of strings"\n} + code = %Q{+ raise RuntimeError, "System commands must be given as an array of strings"\n} expect(subject[5].text).to eq(code) end @@ -53,21 +53,21 @@ describe Gitlab::Diff::Highlight, lib: true do end it 'marks unchanged lines' do - code = %{ def popen(cmd, path=nil)} + code = %q{ def popen(cmd, path=nil)} expect(subject[2].text).to eq(code) expect(subject[2].text).not_to be_html_safe end it 'marks removed lines' do - code = %{- raise "System commands must be given as an array of strings"} + code = %q{- raise "System commands must be given as an array of strings"} expect(subject[4].text).to eq(code) expect(subject[4].text).not_to be_html_safe end it 'marks added lines' do - code = %{+ raise RuntimeError, "System commands must be given as an array of strings"} + code = %q{+ raise RuntimeError, "System commands must be given as an array of strings"} expect(subject[5].text).to eq(code) expect(subject[5].text).to be_html_safe diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb index 8625dd7b711..5d416c9eec3 100644 --- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb @@ -68,12 +68,12 @@ describe Gitlab::Gfm::ReferenceRewriter do context 'label referenced by id' do let(:text) { '#1 and ~123' } - it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~123} } + it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~123} } end context 'label referenced by text' do let(:text) { '#1 and ~"test"' } - it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~123} } + it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~123} } end end @@ -88,12 +88,12 @@ describe Gitlab::Gfm::ReferenceRewriter do context 'label referenced by id' do let(:text) { '#1 and ~321' } - it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~321} } + it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~321} } end context 'label referenced by text' do let(:text) { '#1 and ~"group label"' } - it { is_expected.to eq %{#{project_ref}#1 and #{project_ref}~321} } + it { is_expected.to eq %Q{#{project_ref}#1 and #{project_ref}~321} } end end end diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb index fc2733691be..e177d883158 100644 --- a/spec/lib/gitlab/highlight_spec.rb +++ b/spec/lib/gitlab/highlight_spec.rb @@ -13,9 +13,9 @@ describe Gitlab::Highlight, lib: true do end it 'highlights all the lines properly' do - expect(lines[4]).to eq(%{ extend self\n}) - expect(lines[21]).to eq(%{ unless File.directory?(path)\n}) - expect(lines[26]).to eq(%{ @cmd_status = 0\n}) + expect(lines[4]).to eq(%Q{ extend self\n}) + expect(lines[21]).to eq(%Q{ unless File.directory?(path)\n}) + expect(lines[26]).to eq(%Q{ @cmd_status = 0\n}) end describe 'with CRLF' do diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 0a2cab6888d..84cfd934fa0 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -29,7 +29,7 @@ describe Gitlab::ReferenceExtractor, lib: true do project.team << [@u_foo, :reporter] project.team << [@u_bar, :guest] - subject.analyze(%{ + subject.analyze(%Q{ Inline code: `@foo` Code block: diff --git a/spec/lib/gitlab/url_sanitizer_spec.rb b/spec/lib/gitlab/url_sanitizer_spec.rb index f3533947c1c..2cb74629da8 100644 --- a/spec/lib/gitlab/url_sanitizer_spec.rb +++ b/spec/lib/gitlab/url_sanitizer_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::UrlSanitizer, lib: true do describe '.sanitize' do def sanitize_url(url) # We want to try with multi-line content because is how error messages are formatted - described_class.sanitize(%{ + described_class.sanitize(%Q{ remote: Not Found fatal: repository '#{url}' not found }) diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb index f5596227c81..9cdbfa44e5b 100644 --- a/spec/models/project_label_spec.rb +++ b/spec/models/project_label_spec.rb @@ -105,14 +105,14 @@ describe ProjectLabel, models: true do context 'using name' do it 'returns cross reference with label name' do expect(label.to_reference(project, format: :name)) - .to eq %(#{label.project.path_with_namespace}~"#{label.name}") + .to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") end end context 'using id' do it 'returns cross reference with label id' do expect(label.to_reference(project, format: :id)) - .to eq %(#{label.project.path_with_namespace}~#{label.id}) + .to eq %Q(#{label.project.path_with_namespace}~#{label.id}) end end end diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb index e30b62ddb61..4014d6129ee 100644 --- a/spec/models/project_services/bamboo_service_spec.rb +++ b/spec/models/project_services/bamboo_service_spec.rb @@ -181,7 +181,7 @@ describe BambooService, models: true, caching: true do end it 'sets commit status to "pending" when response has no results' do - stub_request(body: %({"results":{"results":{"size":"0"}}})) + stub_request(body: %q({"results":{"results":{"size":"0"}}})) is_expected.to eq('pending') end @@ -223,6 +223,6 @@ describe BambooService, models: true, caching: true do end def bamboo_response(result_key: 42, build_state: 'success', size: 1) - %({"results":{"results":{"size":"#{size}","result":{"buildState":"#{build_state}","planResultKey":{"key":"#{result_key}"}}}}}) + %Q({"results":{"results":{"size":"#{size}","result":{"buildState":"#{build_state}","planResultKey":{"key":"#{result_key}"}}}}}) end end diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb index 59c04c32cf0..05b602d8106 100644 --- a/spec/models/project_services/buildkite_service_spec.rb +++ b/spec/models/project_services/buildkite_service_spec.rb @@ -92,7 +92,7 @@ describe BuildkiteService, models: true, caching: true do end it 'passes through build status untouched when status is 200' do - stub_request(body: %({"status":"Great Success"})) + stub_request(body: %q({"status":"Great Success"})) is_expected.to eq('Great Success') end @@ -101,7 +101,7 @@ describe BuildkiteService, models: true, caching: true do end def stub_request(status: 200, body: nil) - body ||= %({"status":"success"}) + body ||= %q({"status":"success"}) buildkite_full_url = 'https://gitlab.buildkite.com/status/secret-sauce-status-token.json?commit=123' WebMock.stub_request(:get, buildkite_full_url).to_return( diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb index 82d80206afb..47ca802ebc2 100644 --- a/spec/models/project_services/drone_ci_service_spec.rb +++ b/spec/models/project_services/drone_ci_service_spec.rb @@ -50,7 +50,7 @@ describe DroneCiService, models: true, caching: true do end def stub_request(status: 200, body: nil) - body ||= %({"status":"success"}) + body ||= %q({"status":"success"}) WebMock.stub_request(:get, commit_status_path).to_return( status: status, @@ -102,7 +102,7 @@ describe DroneCiService, models: true, caching: true do "success" => "success" }.each do |drone_status, our_status| it "sets commit status to #{our_status.inspect} when returned status is #{drone_status.inspect}" do - stub_request(body: %({"status":"#{drone_status}"})) + stub_request(body: %Q({"status":"#{drone_status}"})) is_expected.to eq(our_status) end diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb index 2b76897e4eb..77b18e1c7d0 100644 --- a/spec/models/project_services/teamcity_service_spec.rb +++ b/spec/models/project_services/teamcity_service_spec.rb @@ -143,7 +143,7 @@ describe TeamcityService, models: true, caching: true do end it 'returns a build URL when teamcity_url has no trailing slash' do - stub_request(body: %({"build":{"id":"666"}})) + stub_request(body: %q({"build":{"id":"666"}})) is_expected.to eq('http://gitlab.com/teamcity/viewLog.html?buildId=666&buildTypeId=foo') end @@ -152,7 +152,7 @@ describe TeamcityService, models: true, caching: true do let(:teamcity_url) { 'http://gitlab.com/teamcity/' } it 'returns a build URL' do - stub_request(body: %({"build":{"id":"666"}})) + stub_request(body: %q({"build":{"id":"666"}})) is_expected.to eq('http://gitlab.com/teamcity/viewLog.html?buildId=666&buildTypeId=foo') end @@ -202,7 +202,7 @@ describe TeamcityService, models: true, caching: true do def stub_request(status: 200, body: nil, build_status: 'success') teamcity_full_url = 'http://mic:password@gitlab.com/teamcity/httpAuth/app/rest/builds/branch:unspecified:any,number:123' - body ||= %({"build":{"status":"#{build_status}","id":"666"}}) + body ||= %Q({"build":{"status":"#{build_status}","id":"666"}}) WebMock.stub_request(:get, teamcity_full_url).to_return( status: status, diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb index 59cb168f51d..0faf9bff9c3 100644 --- a/spec/workers/repository_import_worker_spec.rb +++ b/spec/workers/repository_import_worker_spec.rb @@ -20,7 +20,7 @@ describe RepositoryImportWorker do context 'when the import has failed' do it 'hide the credentials that were used in the import URL' do - error = %{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found } + error = %q{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found } expect_any_instance_of(Projects::ImportService).to receive(:execute) .and_return({ status: :error, message: error }) From 1fe7501b49f896b74102c4b970310aa9ae34da85 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 16:50:15 -0600 Subject: [PATCH 242/247] Revert "Prefer leading style for Style/DotPosition" This reverts commit cb10b725c8929b8b4460f89c9d96c773af39ba6b. --- .rubocop.yml | 2 +- .../admin/application_settings_controller.rb | 6 +- app/controllers/concerns/creates_commit.rb | 4 +- app/controllers/concerns/issues_action.rb | 6 +- .../concerns/membership_actions.rb | 4 +- .../concerns/merge_requests_action.rb | 4 +- .../import/bitbucket_controller.rb | 6 +- app/controllers/jwt_controller.rb | 4 +- .../omniauth_callbacks_controller.rb | 4 +- app/controllers/profiles_controller.rb | 6 +- app/controllers/projects/badges_controller.rb | 8 +- app/controllers/projects/blob_controller.rb | 4 +- .../projects/boards/issues_controller.rb | 8 +- .../projects/branches_controller.rb | 4 +- app/controllers/projects/builds_controller.rb | 4 +- app/controllers/projects/commit_controller.rb | 6 +- .../projects/commits_controller.rb | 8 +- .../projects/compare_controller.rb | 8 +- .../projects/environments_controller.rb | 22 +-- app/controllers/projects/issues_controller.rb | 10 +- .../projects/merge_requests_controller.rb | 36 ++-- .../projects/pipelines_controller.rb | 24 +-- .../projects/project_members_controller.rb | 4 +- .../projects/settings/ci_cd_controller.rb | 4 +- .../projects/settings/members_controller.rb | 8 +- app/controllers/projects/tags_controller.rb | 4 +- .../projects/uploads_controller.rb | 4 +- app/controllers/projects_controller.rb | 4 +- app/controllers/sessions_controller.rb | 4 +- .../sherlock/application_controller.rb | 4 +- app/controllers/snippets_controller.rb | 4 +- app/controllers/users_controller.rb | 14 +- app/finders/environments_finder.rb | 10 +- app/finders/group_members_finder.rb | 6 +- app/helpers/form_helper.rb | 8 +- app/helpers/search_helper.rb | 4 +- app/helpers/wiki_helper.rb | 6 +- app/models/award_emoji.rb | 6 +- app/models/ci/build.rb | 22 +-- app/models/ci/pipeline.rb | 44 ++--- app/models/ci/runner.rb | 8 +- app/models/ci/stage.rb | 6 +- app/models/commit_status.rb | 10 +- app/models/concerns/issuable.rb | 6 +- app/models/concerns/mentionable.rb | 4 +- app/models/concerns/milestoneish.rb | 4 +- app/models/concerns/presentable.rb | 6 +- app/models/concerns/routable.rb | 8 +- app/models/concerns/sortable.rb | 12 +- app/models/concerns/subscribable.rb | 26 +-- app/models/deployment.rb | 22 +-- app/models/environment.rb | 6 +- app/models/event.rb | 6 +- app/models/generic_commit_status.rb | 6 +- app/models/global_milestone.rb | 4 +- app/models/group.rb | 10 +- app/models/issue_collection.rb | 6 +- app/models/label.rb | 18 +- app/models/lfs_object.rb | 6 +- app/models/member.rb | 12 +- app/models/merge_request.rb | 18 +- app/models/merge_request_diff.rb | 4 +- app/models/merge_requests_closing_issues.rb | 6 +- app/models/milestone.rb | 14 +- app/models/namespace.rb | 14 +- app/models/network/commit.rb | 4 +- app/models/network/graph.rb | 12 +- app/models/note.rb | 10 +- app/models/project.rb | 22 +-- .../project_services/kubernetes_service.rb | 6 +- .../mattermost_slash_commands_service.rb | 4 +- app/models/project_team.rb | 8 +- app/models/repository.rb | 12 +- app/models/todo.rb | 6 +- app/models/user.rb | 56 +++--- app/models/wiki_page.rb | 10 +- app/serializers/base_serializer.rb | 6 +- app/serializers/environment_serializer.rb | 6 +- app/services/after_branch_delete_service.rb | 6 +- app/services/boards/issues/list_service.rb | 8 +- app/services/boards/lists/destroy_service.rb | 4 +- app/services/boards/lists/move_service.rb | 12 +- .../ci/create_pipeline_builds_service.rb | 4 +- app/services/ci/create_pipeline_service.rb | 6 +- .../ci/create_trigger_request_service.rb | 4 +- app/services/ci/process_pipeline_service.rb | 6 +- app/services/ci/register_build_service.rb | 14 +- app/services/ci/retry_build_service.rb | 10 +- app/services/ci/retry_pipeline_service.rb | 10 +- app/services/commits/change_service.rb | 4 +- app/services/create_branch_service.rb | 4 +- app/services/files/base_service.rb | 4 +- app/services/files/update_service.rb | 4 +- app/services/git_push_service.rb | 14 +- app/services/issuable_base_service.rb | 4 +- app/services/issues/create_service.rb | 4 +- app/services/issues/move_service.rb | 4 +- app/services/labels/promote_service.rb | 28 +-- app/services/labels/transfer_service.rb | 20 +- app/services/merge_requests/base_service.rb | 10 +- app/services/merge_requests/merge_service.rb | 4 +- .../merge_requests/refresh_service.rb | 16 +- app/services/notes/slash_commands_service.rb | 4 +- app/services/tags/create_service.rb | 4 +- .../refresh_authorized_projects_service.rb | 10 +- app/workers/build_coverage_worker.rb | 4 +- app/workers/build_hooks_worker.rb | 4 +- app/workers/emails_on_push_worker.rb | 8 +- .../expire_build_instance_artifacts_worker.rb | 8 +- app/workers/merge_worker.rb | 4 +- app/workers/pipeline_hooks_worker.rb | 4 +- app/workers/pipeline_process_worker.rb | 4 +- app/workers/pipeline_success_worker.rb | 6 +- app/workers/pipeline_update_worker.rb | 4 +- app/workers/process_commit_worker.rb | 8 +- app/workers/project_cache_worker.rb | 6 +- app/workers/prune_old_events_worker.rb | 8 +- app/workers/repository_check/batch_worker.rb | 8 +- config/initializers/metrics.rb | 4 +- ...1322_migrate_process_commit_worker_jobs.rb | 6 +- ...31620_fixup_environment_name_uniqueness.rb | 32 ++-- .../20161207231626_add_environment_slug.rb | 8 +- ...project_records_with_invalid_visibility.rb | 22 +-- ...221153951_rename_reserved_project_names.rb | 12 +- ...4150317_requeue_pending_delete_projects.rb | 12 +- ...20170106142508_fill_authorized_projects.rb | 4 +- lib/api/access_requests.rb | 4 +- lib/api/branches.rb | 8 +- lib/api/entities.rb | 6 +- lib/api/issues.rb | 6 +- lib/api/merge_requests.rb | 18 +- lib/api/notes.rb | 4 +- lib/api/pipelines.rb | 4 +- lib/api/tags.rb | 16 +- lib/api/users.rb | 30 +-- lib/api/v3/issues.rb | 6 +- lib/api/v3/merge_requests.rb | 18 +- lib/banzai/pipeline/wiki_pipeline.rb | 4 +- lib/banzai/reference_extractor.rb | 8 +- lib/banzai/reference_parser/issue_parser.rb | 4 +- lib/banzai/reference_parser/user_parser.rb | 4 +- lib/ci/charts.rb | 26 +-- lib/ci/gitlab_ci_yaml_processor.rb | 4 +- lib/gitlab/badge/build/status.rb | 6 +- lib/gitlab/badge/coverage/report.rb | 6 +- lib/gitlab/bitbucket_import/importer.rb | 8 +- lib/gitlab/checks/matching_merge_request.rb | 8 +- lib/gitlab/ci/config/entry/configurable.rb | 10 +- lib/gitlab/ci/config/entry/global.rb | 8 +- lib/gitlab/ci/config/entry/jobs.rb | 10 +- lib/gitlab/ci/pipeline_duration.rb | 4 +- lib/gitlab/ci/status/factory.rb | 8 +- lib/gitlab/ci/trace_reader.rb | 4 +- lib/gitlab/contributions_calendar.rb | 46 ++--- lib/gitlab/cycle_analytics/base_query.rb | 18 +- lib/gitlab/database/median.rb | 22 +-- lib/gitlab/database/migration_helpers.rb | 18 +- lib/gitlab/downtime_check.rb | 4 +- lib/gitlab/git/encoding_helper.rb | 6 +- lib/gitlab/github_import/importer.rb | 6 +- lib/gitlab/github_import/user_formatter.rb | 14 +- lib/gitlab/highlight.rb | 4 +- lib/gitlab/ldap/user.rb | 6 +- lib/gitlab/metrics.rb | 4 +- lib/gitlab/metrics/system.rb | 8 +- lib/gitlab/other_markup.rb | 4 +- lib/gitlab/shell.rb | 4 +- lib/gitlab/sherlock/line_profiler.rb | 4 +- lib/gitlab/sherlock/query.rb | 8 +- rubocop/cop/gem_fetcher.rb | 12 +- rubocop/migration_helpers.rb | 4 +- .../admin/users_controller_spec.rb | 4 +- spec/controllers/blob_controller_spec.rb | 4 +- .../ci/projects_controller_spec.rb | 4 +- .../import/bitbucket_controller_spec.rb | 46 ++--- .../import/github_controller_spec.rb | 8 +- .../import/gitlab_controller_spec.rb | 46 ++--- .../projects/branches_controller_spec.rb | 12 +- .../projects/commit_controller_spec.rb | 4 +- .../projects/environments_controller_spec.rb | 14 +- .../projects/issues_controller_spec.rb | 12 +- .../projects/mattermosts_controller_spec.rb | 4 +- .../merge_requests_controller_spec.rb | 24 +-- .../projects/raw_controller_spec.rb | 4 +- .../projects/snippets_controller_spec.rb | 32 ++-- .../projects/tree_controller_spec.rb | 12 +- .../sent_notifications_controller_spec.rb | 8 +- spec/controllers/sessions_controller_spec.rb | 28 +-- spec/controllers/snippets_controller_spec.rb | 32 ++-- spec/factories/projects.rb | 4 +- spec/features/admin/admin_projects_spec.rb | 4 +- spec/features/admin/admin_users_spec.rb | 8 +- spec/features/atom/dashboard_spec.rb | 4 +- spec/features/atom/issues_spec.rb | 8 +- spec/features/atom/users_spec.rb | 4 +- spec/features/environments_spec.rb | 4 +- .../features/gitlab_flavored_markdown_spec.rb | 4 +- spec/features/login_spec.rb | 4 +- spec/features/markdown_spec.rb | 16 +- .../merge_requests/created_from_fork_spec.rb | 4 +- spec/features/notes_on_merge_requests_spec.rb | 12 +- .../projects/pipelines/pipelines_spec.rb | 4 +- spec/finders/environments_finder_spec.rb | 44 ++--- spec/helpers/application_helper_spec.rb | 32 ++-- .../helpers/broadcast_messages_helper_spec.rb | 4 +- spec/helpers/commits_helper_spec.rb | 8 +- spec/helpers/form_helper_spec.rb | 12 +- spec/helpers/gitlab_markdown_helper_spec.rb | 16 +- spec/helpers/groups_helper_spec.rb | 4 +- spec/helpers/import_helper_spec.rb | 20 +- spec/helpers/issuables_helper_spec.rb | 40 ++-- spec/helpers/issues_helper_spec.rb | 12 +- spec/helpers/labels_helper_spec.rb | 4 +- spec/helpers/merge_requests_helper_spec.rb | 4 +- spec/helpers/page_layout_helper_spec.rb | 8 +- spec/helpers/preferences_helper_spec.rb | 16 +- spec/helpers/visibility_level_helper_spec.rb | 32 ++-- spec/lib/api/helpers/pagination_spec.rb | 12 +- .../banzai/cross_project_reference_spec.rb | 4 +- .../filter/abstract_reference_filter_spec.rb | 28 +-- .../commit_range_reference_filter_spec.rb | 36 ++-- .../filter/commit_reference_filter_spec.rb | 8 +- .../external_issue_reference_filter_spec.rb | 8 +- .../filter/issue_reference_filter_spec.rb | 70 +++---- .../filter/label_reference_filter_spec.rb | 104 +++++------ .../merge_request_reference_filter_spec.rb | 20 +- .../filter/milestone_reference_filter_spec.rb | 68 +++---- .../lib/banzai/filter/redactor_filter_spec.rb | 6 +- .../banzai/filter/reference_filter_spec.rb | 4 +- .../filter/relative_link_filter_spec.rb | 48 ++--- .../banzai/filter/sanitization_filter_spec.rb | 4 +- .../filter/snippet_reference_filter_spec.rb | 20 +- .../banzai/filter/upload_link_filter_spec.rb | 24 +-- .../filter/user_reference_filter_spec.rb | 4 +- spec/lib/banzai/note_renderer_spec.rb | 12 +- spec/lib/banzai/object_renderer_spec.rb | 20 +- spec/lib/banzai/redactor_spec.rb | 22 +-- .../reference_parser/base_parser_spec.rb | 110 +++++------ .../reference_parser/commit_parser_spec.rb | 32 ++-- .../commit_range_parser_spec.rb | 24 +-- .../reference_parser/issue_parser_spec.rb | 12 +- .../reference_parser/user_parser_spec.rb | 24 +-- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 20 +- spec/lib/container_registry/blob_spec.rb | 20 +- .../lib/container_registry/repository_spec.rb | 6 +- spec/lib/container_registry/tag_spec.rb | 40 ++-- spec/lib/extracts_path_spec.rb | 4 +- spec/lib/gitlab/asciidoc_spec.rb | 8 +- spec/lib/gitlab/auth_spec.rb | 8 +- spec/lib/gitlab/backup/manager_spec.rb | 16 +- spec/lib/gitlab/badge/build/status_spec.rb | 4 +- .../gitlab/bitbucket_import/importer_spec.rb | 10 +- .../ci/build/artifacts/metadata_spec.rb | 12 +- .../gitlab/ci/config/entry/artifacts_spec.rb | 8 +- .../ci/config/entry/attributable_spec.rb | 12 +- .../gitlab/ci/config/entry/boolean_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/cache_spec.rb | 12 +- .../gitlab/ci/config/entry/commands_spec.rb | 4 +- .../ci/config/entry/configurable_spec.rb | 4 +- .../ci/config/entry/environment_spec.rb | 16 +- .../gitlab/ci/config/entry/factory_spec.rb | 52 +++--- .../lib/gitlab/ci/config/entry/global_spec.rb | 48 ++--- spec/lib/gitlab/ci/config/entry/image_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/job_spec.rb | 18 +- spec/lib/gitlab/ci/config/entry/jobs_spec.rb | 16 +- spec/lib/gitlab/ci/config/entry/key_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/paths_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/script_spec.rb | 4 +- .../gitlab/ci/config/entry/services_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/stage_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/stages_spec.rb | 4 +- .../gitlab/ci/config/entry/trigger_spec.rb | 4 +- .../ci/config/entry/validatable_spec.rb | 4 +- .../gitlab/ci/config/entry/validator_spec.rb | 4 +- .../gitlab/ci/config/entry/variables_spec.rb | 4 +- .../lib/gitlab/ci/status/build/common_spec.rb | 6 +- .../gitlab/ci/status/build/factory_spec.rb | 34 ++-- spec/lib/gitlab/ci/status/extended_spec.rb | 4 +- .../gitlab/ci/status/external/common_spec.rb | 6 +- spec/lib/gitlab/ci/status/factory_spec.rb | 16 +- .../gitlab/ci/status/pipeline/common_spec.rb | 10 +- .../gitlab/ci/status/pipeline/factory_spec.rb | 8 +- .../lib/gitlab/ci/status/stage/common_spec.rb | 12 +- .../gitlab/ci/status/stage/factory_spec.rb | 4 +- .../gitlab/closing_issue_extractor_spec.rb | 32 ++-- spec/lib/gitlab/conflict/file_spec.rb | 24 +-- spec/lib/gitlab/conflict/parser_spec.rb | 60 +++--- spec/lib/gitlab/data_builder/note_spec.rb | 36 ++-- spec/lib/gitlab/data_builder/push_spec.rb | 4 +- .../gitlab/database/migration_helpers_spec.rb | 64 +++---- spec/lib/gitlab/database_spec.rb | 12 +- spec/lib/gitlab/downtime_check_spec.rb | 32 ++-- spec/lib/gitlab/email/reply_parser_spec.rb | 36 ++-- spec/lib/gitlab/file_detector_spec.rb | 8 +- spec/lib/gitlab/git/attributes_spec.rb | 44 ++--- spec/lib/gitlab/git/blob_spec.rb | 6 +- spec/lib/gitlab/git/diff_collection_spec.rb | 16 +- spec/lib/gitlab/git/diff_spec.rb | 8 +- spec/lib/gitlab/git/repository_spec.rb | 4 +- .../lib/gitlab/gitlab_import/importer_spec.rb | 4 +- spec/lib/gitlab/identifier_spec.rb | 12 +- .../import_export/avatar_restorer_spec.rb | 4 +- spec/lib/gitlab/incoming_email_spec.rb | 8 +- spec/lib/gitlab/job_waiter_spec.rb | 10 +- spec/lib/gitlab/ldap/adapter_spec.rb | 4 +- spec/lib/gitlab/ldap/authentication_spec.rb | 12 +- spec/lib/gitlab/ldap/user_spec.rb | 4 +- .../gitlab/metrics/instrumentation_spec.rb | 32 ++-- .../gitlab/metrics/rack_middleware_spec.rb | 12 +- spec/lib/gitlab/metrics/sampler_spec.rb | 54 +++--- .../gitlab/metrics/sidekiq_middleware_spec.rb | 36 ++-- .../metrics/subscribers/action_view_spec.rb | 8 +- .../metrics/subscribers/active_record_spec.rb | 18 +- .../metrics/subscribers/rails_cache_spec.rb | 80 ++++---- spec/lib/gitlab/metrics/transaction_spec.rb | 28 +-- spec/lib/gitlab/metrics_spec.rb | 48 ++--- spec/lib/gitlab/o_auth/user_spec.rb | 4 +- spec/lib/gitlab/route_map_spec.rb | 24 +-- spec/lib/gitlab/serializer/pagination_spec.rb | 8 +- spec/lib/gitlab/sherlock/file_sample_spec.rb | 4 +- .../lib/gitlab/sherlock/line_profiler_spec.rb | 6 +- spec/lib/gitlab/sherlock/middleware_spec.rb | 4 +- spec/lib/gitlab/sherlock/query_spec.rb | 4 +- spec/lib/gitlab/sherlock/transaction_spec.rb | 28 +-- .../sidekiq_status/client_middleware_spec.rb | 4 +- .../sidekiq_status/server_middleware_spec.rb | 4 +- spec/lib/gitlab/url_builder_spec.rb | 4 +- .../gitlab/view/presenter/delegated_spec.rb | 4 +- spec/lib/light_url_builder_spec.rb | 4 +- spec/lib/mattermost/command_spec.rb | 16 +- spec/lib/mattermost/session_spec.rb | 14 +- spec/lib/mattermost/team_spec.rb | 12 +- spec/mailers/abuse_report_mailer_spec.rb | 4 +- ...migrate_process_commit_worker_jobs_spec.rb | 54 +++--- spec/models/ability_spec.rb | 56 +++--- spec/models/abuse_report_spec.rb | 4 +- spec/models/application_setting_spec.rb | 6 +- spec/models/ci/build_spec.rb | 20 +- spec/models/ci/pipeline_spec.rb | 12 +- spec/models/ci/variable_spec.rb | 4 +- spec/models/commit_range_spec.rb | 6 +- spec/models/commit_status_spec.rb | 4 +- spec/models/concerns/case_sensitivity_spec.rb | 148 +++++++-------- spec/models/concerns/has_status_spec.rb | 4 +- spec/models/concerns/issuable_spec.rb | 36 ++-- spec/models/discussion_spec.rb | 12 +- spec/models/email_spec.rb | 4 +- spec/models/environment_spec.rb | 6 +- spec/models/event_spec.rb | 4 +- spec/models/group_label_spec.rb | 4 +- spec/models/group_spec.rb | 4 +- spec/models/issue_collection_spec.rb | 4 +- spec/models/issue_spec.rb | 8 +- spec/models/key_spec.rb | 8 +- spec/models/lfs_objects_project_spec.rb | 8 +- spec/models/member_spec.rb | 8 +- spec/models/members/group_member_spec.rb | 8 +- spec/models/merge_request_diff_spec.rb | 8 +- spec/models/merge_request_spec.rb | 72 ++++---- spec/models/milestone_spec.rb | 8 +- spec/models/namespace_spec.rb | 4 +- spec/models/note_spec.rb | 16 +- spec/models/project_authorization_spec.rb | 4 +- spec/models/project_label_spec.rb | 12 +- .../mattermost_slash_commands_service_spec.rb | 24 +-- spec/models/project_spec.rb | 56 +++--- spec/models/project_wiki_spec.rb | 24 +-- spec/models/repository_spec.rb | 174 +++++++++--------- spec/models/user_spec.rb | 16 +- spec/models/wiki_page_spec.rb | 4 +- spec/policies/project_policy_spec.rb | 4 +- spec/presenters/ci/build_presenter_spec.rb | 4 +- spec/requests/api/broadcast_messages_spec.rb | 12 +- spec/requests/api/commit_statuses_spec.rb | 4 +- spec/requests/api/files_spec.rb | 4 +- spec/requests/api/groups_spec.rb | 12 +- spec/requests/api/internal_spec.rb | 4 +- spec/requests/api/merge_requests_spec.rb | 4 +- spec/requests/api/notes_spec.rb | 4 +- spec/requests/api/project_snippets_spec.rb | 32 ++-- spec/requests/api/projects_spec.rb | 24 +-- spec/requests/api/runners_spec.rb | 8 +- spec/requests/api/snippets_spec.rb | 32 ++-- spec/requests/api/users_spec.rb | 32 ++-- spec/requests/api/v3/files_spec.rb | 4 +- spec/requests/api/v3/merge_requests_spec.rb | 4 +- spec/requests/api/v3/project_snippets_spec.rb | 32 ++-- spec/requests/api/v3/projects_spec.rb | 24 +-- spec/requests/ci/api/builds_spec.rb | 16 +- spec/requests/git_http_spec.rb | 8 +- .../analytics_build_serializer_spec.rb | 4 +- .../analytics_issue_serializer_spec.rb | 6 +- ...analytics_merge_request_serializer_spec.rb | 6 +- .../analytics_summary_serializer_spec.rb | 8 +- .../serializers/build_artifact_entity_spec.rb | 4 +- spec/serializers/commit_entity_spec.rb | 4 +- .../environment_serializer_spec.rb | 32 ++-- spec/serializers/pipeline_entity_spec.rb | 12 +- spec/serializers/pipeline_serializer_spec.rb | 10 +- spec/serializers/request_aware_entity_spec.rb | 4 +- spec/serializers/stage_entity_spec.rb | 8 +- .../ci/process_pipeline_service_spec.rb | 8 +- spec/services/ci/retry_build_service_spec.rb | 12 +- .../ci/retry_pipeline_service_spec.rb | 8 +- .../ci/stop_environments_service_spec.rb | 16 +- .../ci/update_build_queue_service_spec.rb | 16 +- spec/services/files/update_service_spec.rb | 4 +- spec/services/git_push_service_spec.rb | 42 ++--- .../issuable/bulk_update_service_spec.rb | 20 +- spec/services/issues/close_service_spec.rb | 16 +- spec/services/issues/move_service_spec.rb | 20 +- spec/services/labels/promote_service_spec.rb | 6 +- spec/services/members/destroy_service_spec.rb | 4 +- .../add_todo_when_build_fails_service_spec.rb | 16 +- .../merge_requests/close_service_spec.rb | 4 +- .../merge_requests/merge_service_spec.rb | 6 +- ...rge_when_pipeline_succeeds_service_spec.rb | 20 +- .../merge_requests/refresh_service_spec.rb | 12 +- .../merge_requests/reopen_service_spec.rb | 4 +- .../merge_requests/resolve_service_spec.rb | 24 +-- .../merge_requests/update_service_spec.rb | 8 +- .../projects/housekeeping_service_spec.rb | 12 +- spec/services/projects/import_service_spec.rb | 18 +- .../projects/transfer_service_spec.rb | 14 +- .../projects/unlink_fork_service_spec.rb | 6 +- spec/services/system_note_service_spec.rb | 76 ++++---- spec/services/tags/create_service_spec.rb | 12 +- spec/services/todo_service_spec.rb | 8 +- ...ser_project_access_changed_service_spec.rb | 4 +- ...efresh_authorized_projects_service_spec.rb | 20 +- ...ubish_import_controller_shared_examples.rb | 64 +++---- spec/support/ldap_helpers.rb | 8 +- spec/support/mentionable_shared_examples.rb | 12 +- spec/support/reactive_caching_helpers.rb | 6 +- spec/support/services_shared_context.rb | 6 +- ...attermost_notifications_shared_examples.rb | 42 ++--- spec/support/stub_configuration.rb | 4 +- spec/support/stub_gitlab_calls.rb | 38 ++-- spec/support/test_env.rb | 8 +- spec/tasks/gitlab/backup_rake_spec.rb | 20 +- spec/tasks/gitlab/check_rake_spec.rb | 4 +- spec/tasks/gitlab/shell_rake_spec.rb | 4 +- spec/tasks/gitlab/task_helpers_spec.rb | 32 ++-- spec/tasks/gitlab/workhorse_rake_spec.rb | 8 +- .../shared/_signin_box.html.haml_spec.rb | 4 +- spec/views/layouts/_head.html.haml_spec.rb | 4 +- .../merge_requests/edit.html.haml_spec.rb | 4 +- spec/workers/build_coverage_worker_spec.rb | 8 +- spec/workers/build_finished_worker_spec.rb | 20 +- spec/workers/build_hooks_worker_spec.rb | 8 +- spec/workers/build_success_worker_spec.rb | 12 +- spec/workers/delete_user_worker_spec.rb | 8 +- spec/workers/every_sidekiq_worker_spec.rb | 10 +- .../git_garbage_collect_worker_spec.rb | 4 +- spec/workers/new_note_worker_spec.rb | 4 +- spec/workers/pipeline_hooks_worker_spec.rb | 8 +- .../pipeline_notification_worker_spec.rb | 20 +- spec/workers/pipeline_proccess_worker_spec.rb | 4 +- spec/workers/pipeline_success_worker_spec.rb | 4 +- spec/workers/pipeline_update_worker_spec.rb | 4 +- spec/workers/post_receive_spec.rb | 6 +- spec/workers/process_commit_worker_spec.rb | 20 +- spec/workers/project_cache_worker_spec.rb | 34 ++-- spec/workers/repository_fork_worker_spec.rb | 8 +- spec/workers/repository_import_worker_spec.rb | 8 +- spec/workers/use_key_worker_spec.rb | 4 +- 466 files changed, 3227 insertions(+), 3227 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a7d4222b9b2..2eebe73313b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -166,7 +166,7 @@ Style/Documentation: # This cop checks the . position in multi-line method calls. Style/DotPosition: Enabled: true - EnforcedStyle: leading + EnforcedStyle: trailing # This cop checks for uses of double negation (!!) to convert something # to a boolean value. As this is both cryptic and usually redundant, it diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index b0f5d4a9933..f801fac1839 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -5,9 +5,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end def update - successful = ApplicationSettings::UpdateService - .new(@application_setting, current_user, application_setting_params) - .execute + successful = ApplicationSettings::UpdateService. + new(@application_setting, current_user, application_setting_params). + execute if successful redirect_to admin_application_settings_path, diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 41c660be378..2fe03020d2d 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -83,8 +83,8 @@ module CreatesCommit def merge_request_exists? return @merge_request if defined?(@merge_request) - @merge_request = MergeRequestsFinder.new(current_user, project_id: @mr_target_project.id).execute.opened - .find_by(source_branch: @mr_source_branch, target_branch: @mr_target_branch, source_project_id: @mr_source_project) + @merge_request = MergeRequestsFinder.new(current_user, project_id: @mr_target_project.id).execute.opened. + find_by(source_branch: @mr_source_branch, target_branch: @mr_target_branch, source_project_id: @mr_source_project) end def different_project? diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index b17c138d5c7..8b985b6d003 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -5,9 +5,9 @@ module IssuesAction def issues @label = issues_finder.labels.first - @issues = issues_collection - .non_archived - .page(params[:page]) + @issues = issues_collection. + non_archived. + page(params[:page]) @collection_type = "Issue" @issuable_meta_data = issuable_meta_data(@issues, @collection_type) diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index 43ca4b6ac02..c13333641d3 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -15,8 +15,8 @@ module MembershipActions end def leave - member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id) - .execute(:all) + member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id). + execute(:all) source_type = membershipable.class.to_s.humanize(capitalize: false) notice = diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index d3c8e4888bc..28e34cffc24 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -5,8 +5,8 @@ module MergeRequestsAction def merge_requests @label = merge_requests_finder.labels.first - @merge_requests = merge_requests_collection - .page(params[:page]) + @merge_requests = merge_requests_collection. + page(params[:page]) @collection_type = "MergeRequest" @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index 8e42cdf415f..cd5cef2c20f 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -29,9 +29,9 @@ class Import::BitbucketController < Import::BaseController end def jobs - render json: current_user.created_projects - .where(import_type: 'bitbucket') - .to_json(only: [:id, :import_status]) + render json: current_user.created_projects. + where(import_type: 'bitbucket'). + to_json(only: [:id, :import_status]) end def create diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 1b40645f2c9..3109439b2ff 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -11,8 +11,8 @@ class JwtController < ApplicationController service = SERVICES[params[:service]] return head :not_found unless service - result = service.new(@authentication_result.project, @authentication_result.actor, auth_params) - .execute(authentication_abilities: @authentication_result.authentication_abilities) + result = service.new(@authentication_result.project, @authentication_result.actor, auth_params). + execute(authentication_abilities: @authentication_result.authentication_abilities) render json: result, status: result[:http_status] end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 0faa446aff9..58d50ad647b 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -144,7 +144,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end def log_audit_event(user, options = {}) - AuditEventService.new(user, user, options) - .for_authentication.security_event + AuditEventService.new(user, user, options). + for_authentication.security_event end end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index cc500af81db..f0c71725ea8 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -41,9 +41,9 @@ class ProfilesController < Profiles::ApplicationController end def audit_log - @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id) - .order("created_at DESC") - .page(params[:page]) + @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id). + order("created_at DESC"). + page(params[:page]) end def update_username diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index 6c25cd83a24..c1727d9fa28 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -4,15 +4,15 @@ class Projects::BadgesController < Projects::ApplicationController before_action :no_cache_headers, except: [:index] def build - build_status = Gitlab::Badge::Build::Status - .new(project, params[:ref]) + build_status = Gitlab::Badge::Build::Status. + new(project, params[:ref]) render_badge build_status end def coverage - coverage_report = Gitlab::Badge::Coverage::Report - .new(project, params[:ref], params[:job]) + coverage_report = Gitlab::Badge::Coverage::Report. + new(project, params[:ref], params[:job]) render_badge coverage_report end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 647faca40a0..39ba815cfca 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -164,7 +164,7 @@ class Projects::BlobController < Projects::ApplicationController end def set_last_commit_sha - @last_commit_sha = Gitlab::Git::Commit - .last_for_path(@repository, @ref, @path).sha + @last_commit_sha = Gitlab::Git::Commit. + last_for_path(@repository, @ref, @path).sha end end diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb index 61fef4dc133..8bcf18642cf 100644 --- a/app/controllers/projects/boards/issues_controller.rb +++ b/app/controllers/projects/boards/issues_controller.rb @@ -40,10 +40,10 @@ module Projects def issue @issue ||= - IssuesFinder.new(current_user, project_id: project.id) - .execute - .where(iid: params[:id]) - .first! + IssuesFinder.new(current_user, project_id: project.id). + execute. + where(iid: params[:id]). + first! end def authorize_read_issue! diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index c37a0653ff9..89d84809e3a 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -32,8 +32,8 @@ class Projects::BranchesController < Projects::ApplicationController branch_name = sanitize(strip_tags(params[:branch_name])) branch_name = Addressable::URI.unescape(branch_name) - result = CreateBranchService.new(project, current_user) - .execute(branch_name, ref) + result = CreateBranchService.new(project, current_user). + execute(branch_name, ref) if params[:issue_iid] issue = IssuesFinder.new(current_user, project_id: @project.id).find_by(iid: params[:issue_iid]) diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index 0db18d444f7..886934a3f67 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -48,8 +48,8 @@ class Projects::BuildsController < Projects::ApplicationController respond_to do |format| format.json do state = params[:state].presence - render json: @build.trace_with_state(state: state) - .merge!(id: @build.id, status: @build.status) + render json: @build.trace_with_state(state: state). + merge!(id: @build.id, status: @build.status) end end end diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index e10d7992db7..23466dda981 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -35,9 +35,9 @@ class Projects::CommitController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: PipelineSerializer - .new(project: @project, user: @current_user) - .represent(@pipelines) + render json: PipelineSerializer. + new(project: @project, user: @current_user). + represent(@pipelines) end end end diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index 855147c8984..ad92f05a42d 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -18,11 +18,11 @@ class Projects::CommitsController < Projects::ApplicationController @repository.commits(@ref, path: @path, limit: @limit, offset: @offset) end - @note_counts = project.notes.where(commit_id: @commits.map(&:id)) - .group(:commit_id).count + @note_counts = project.notes.where(commit_id: @commits.map(&:id)). + group(:commit_id).count - @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened - .find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref) + @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened. + find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref) respond_to do |format| format.html diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 7ef2f90ef01..99204c82784 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -46,8 +46,8 @@ class Projects::CompareController < Projects::ApplicationController end def define_diff_vars - @compare = CompareService.new(@project, @head_ref) - .execute(@project, @start_ref) + @compare = CompareService.new(@project, @head_ref). + execute(@project, @start_ref) if @compare @commits = @compare.commits @@ -66,7 +66,7 @@ class Projects::CompareController < Projects::ApplicationController end def merge_request - @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened - .find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref) + @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened. + find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref) end end diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index fed75396d6e..2bbd8c6d046 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -9,18 +9,18 @@ class Projects::EnvironmentsController < Projects::ApplicationController before_action :verify_api_request!, only: :terminal_websocket_authorize def index - @environments = project.environments - .with_state(params[:scope] || :available) + @environments = project.environments. + with_state(params[:scope] || :available) respond_to do |format| format.html format.json do render json: { - environments: EnvironmentSerializer - .new(project: @project, user: @current_user) - .with_pagination(request, response) - .within_folders - .represent(@environments), + environments: EnvironmentSerializer. + new(project: @project, user: @current_user). + with_pagination(request, response). + within_folders. + represent(@environments), available_count: project.environments.available.count, stopped_count: project.environments.stopped.count } @@ -36,10 +36,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController format.html format.json do render json: { - environments: EnvironmentSerializer - .new(project: @project, user: @current_user) - .with_pagination(request, response) - .represent(@environments), + environments: EnvironmentSerializer. + new(project: @project, user: @current_user). + with_pagination(request, response). + represent(@environments), available_count: folder_environments.available.count, stopped_count: folder_environments.stopped.count } diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 4c009dd238c..ca5e81100da 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -77,8 +77,8 @@ class Projects::IssuesController < Projects::ApplicationController def show raw_notes = @issue.notes.inc_relations_for_view.fresh - @notes = Banzai::NoteRenderer - .render(raw_notes, @project, current_user, @path, @project_wiki, @ref) + @notes = Banzai::NoteRenderer. + render(raw_notes, @project, current_user, @path, @project_wiki, @ref) @note = @project.notes.new(noteable: @issue) @noteable = @issue @@ -189,9 +189,9 @@ class Projects::IssuesController < Projects::ApplicationController def merge_request_for_resolving_discussions return unless merge_request_iid = params[:merge_request_for_resolving_discussions] - @merge_request_for_resolving_discussions ||= MergeRequestsFinder.new(current_user, project_id: project.id) - .execute - .find_by(iid: merge_request_iid) + @merge_request_for_resolving_discussions ||= MergeRequestsFinder.new(current_user, project_id: project.id). + execute. + find_by(iid: merge_request_iid) end def authorize_read_issue! diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 1f228d28f80..5ee7972e29e 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -162,8 +162,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController # Get commits from repository # or from cache if already merged @commits = @merge_request.commits - @note_counts = Note.where(commit_id: @commits.map(&:id)) - .group(:commit_id).count + @note_counts = Note.where(commit_id: @commits.map(&:id)). + group(:commit_id).count render json: { html: view_to_html_string('projects/merge_requests/show/_commits') } end @@ -232,9 +232,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end format.json do - render json: PipelineSerializer - .new(project: @project, user: @current_user) - .represent(@pipelines) + render json: PipelineSerializer. + new(project: @project, user: @current_user). + represent(@pipelines) end end end @@ -245,9 +245,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController format.json do define_pipelines_vars - render json: PipelineSerializer - .new(project: @project, user: @current_user) - .represent(@pipelines) + render json: PipelineSerializer. + new(project: @project, user: @current_user). + represent(@pipelines) end end end @@ -332,9 +332,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController return access_denied! end - MergeRequests::MergeWhenPipelineSucceedsService - .new(@project, current_user) - .cancel(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService. + new(@project, current_user). + cancel(@merge_request) end def merge @@ -361,9 +361,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end if @merge_request.head_pipeline.active? - MergeRequests::MergeWhenPipelineSucceedsService - .new(@project, current_user, merge_params) - .execute(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService. + new(@project, current_user, merge_params). + execute(@merge_request) @status = :merge_when_build_succeeds elsif @merge_request.head_pipeline.success? @@ -624,8 +624,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController @commit = @merge_request.diff_head_commit @base_commit = @merge_request.diff_base_commit - @note_counts = Note.where(commit_id: @commits.map(&:id)) - .group(:commit_id).count + @note_counts = Note.where(commit_id: @commits.map(&:id)). + group(:commit_id).count @labels = LabelsFinder.new(current_user, project_id: @project.id).execute @@ -640,8 +640,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_request_params - params.require(:merge_request) - .permit(merge_request_params_ce) + params.require(:merge_request). + permit(merge_request_params_ce) end def merge_request_params_ce diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index e436c6666c3..0f2b7b2a4c8 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -7,11 +7,11 @@ class Projects::PipelinesController < Projects::ApplicationController def index @scope = params[:scope] - @pipelines = PipelinesFinder - .new(project) - .execute(scope: @scope) - .page(params[:page]) - .per(30) + @pipelines = PipelinesFinder. + new(project). + execute(scope: @scope). + page(params[:page]). + per(30) @running_count = PipelinesFinder. .new(project).execute(scope: 'running').count @@ -29,10 +29,10 @@ class Projects::PipelinesController < Projects::ApplicationController format.html format.json do render json: { - pipelines: PipelineSerializer - .new(project: @project, user: @current_user) - .with_pagination(request, response) - .represent(@pipelines), + pipelines: PipelineSerializer. + new(project: @project, user: @current_user). + with_pagination(request, response). + represent(@pipelines), count: { all: @pipelines_count, running: @running_count, @@ -49,9 +49,9 @@ class Projects::PipelinesController < Projects::ApplicationController end def create - @pipeline = Ci::CreatePipelineService - .new(project, current_user, create_params) - .execute(ignore_skip_ci: true, save_on_errors: false) + @pipeline = Ci::CreatePipelineService. + new(project, current_user, create_params). + execute(ignore_skip_ci: true, save_on_errors: false) unless @pipeline.persisted? render 'new' return diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 3c582d15a4c..6e158e685e9 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -31,8 +31,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController end def destroy - Members::DestroyService.new(@project, current_user, params) - .execute(:all) + Members::DestroyService.new(@project, current_user, params). + execute(:all) respond_to do |format| format.html do diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 24fe78bc1bd..6f009d61950 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -14,8 +14,8 @@ module Projects def define_runners_variables @project_runners = @project.runners.ordered - @assignable_runners = current_user.ci_authorized_runners - .assignable_for(project).ordered.page(params[:page]).per(20) + @assignable_runners = current_user.ci_authorized_runners. + assignable_for(project).ordered.page(params[:page]).per(20) @shared_runners = Ci::Runner.shared.active @shared_runners_count = @shared_runners.count(:all) end diff --git a/app/controllers/projects/settings/members_controller.rb b/app/controllers/projects/settings/members_controller.rb index f4c79b796fd..5735e281f66 100644 --- a/app/controllers/projects/settings/members_controller.rb +++ b/app/controllers/projects/settings/members_controller.rb @@ -41,10 +41,10 @@ module Projects wheres = ["members.id IN (#{@project_members.select(:id).to_sql})"] wheres << "members.id IN (#{group_members.select(:id).to_sql})" if group_members - @project_members = Member - .where(wheres.join(' OR ')) - .sort(@sort) - .page(params[:page]) + @project_members = Member. + where(wheres.join(' OR ')). + sort(@sort). + page(params[:page]) @requesters = AccessRequestsFinder.new(@project).execute(current_user) diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index 5aaec97a082..33379659d73 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -27,8 +27,8 @@ class Projects::TagsController < Projects::ApplicationController end def create - result = Tags::CreateService.new(@project, current_user) - .execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) + result = Tags::CreateService.new(@project, current_user). + execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) if result[:status] == :success @tag = result[:tag] diff --git a/app/controllers/projects/uploads_controller.rb b/app/controllers/projects/uploads_controller.rb index 1e7d72f5faa..61686499bd3 100644 --- a/app/controllers/projects/uploads_controller.rb +++ b/app/controllers/projects/uploads_controller.rb @@ -5,8 +5,8 @@ class Projects::UploadsController < Projects::ApplicationController before_action :authorize_upload_file!, only: [:create] def create - link_to_file = ::Projects::UploadService.new(project, params[:file]) - .execute + link_to_file = ::Projects::UploadService.new(project, params[:file]). + execute respond_to do |format| if link_to_file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index acca821782c..9ffb8152e32 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -293,8 +293,8 @@ class ProjectsController < Projects::ApplicationController end def project_params - params.require(:project) - .permit(project_params_ce) + params.require(:project). + permit(project_params_ce) end def project_params_ce diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b632bbaaf78..7d81c96262f 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -119,8 +119,8 @@ class SessionsController < Devise::SessionsController end def log_audit_event(user, options = {}) - AuditEventService.new(user, user, options) - .for_authentication.security_event + AuditEventService.new(user, user, options). + for_authentication.security_event end def load_recaptcha diff --git a/app/controllers/sherlock/application_controller.rb b/app/controllers/sherlock/application_controller.rb index 6bdd3568a78..682ca5e3821 100644 --- a/app/controllers/sherlock/application_controller.rb +++ b/app/controllers/sherlock/application_controller.rb @@ -4,8 +4,8 @@ module Sherlock def find_transaction if params[:transaction_id] - @transaction = Gitlab::Sherlock.collection - .find_transaction(params[:transaction_id]) + @transaction = Gitlab::Sherlock.collection. + find_transaction(params[:transaction_id]) end end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 2e0f26ade91..f3fd3da8b20 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -83,8 +83,8 @@ class SnippetsController < ApplicationController @snippet ||= if current_user PersonalSnippet.where("author_id = ? OR visibility_level IN (?)", current_user.id, - [Snippet::PUBLIC, Snippet::INTERNAL]) - .find(params[:id]) + [Snippet::PUBLIC, Snippet::INTERNAL]). + find(params[:id]) else PersonalSnippet.find(params[:id]) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 73056df5bef..c92594d4097 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -109,17 +109,17 @@ class UsersController < ApplicationController def load_events # Get user activity feed for projects common for both users - @events = user.recent_events - .merge(projects_for_current_user) - .references(:project) - .with_associations - .limit_recent(20, params[:offset]) + @events = user.recent_events. + merge(projects_for_current_user). + references(:project). + with_associations. + limit_recent(20, params[:offset]) end def load_projects @projects = - PersonalProjectsFinder.new(user).execute(current_user) - .page(params[:page]) + PersonalProjectsFinder.new(user).execute(current_user). + page(params[:page]) end def load_contributed_projects diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb index a59f8c1efa3..52c73abc31d 100644 --- a/app/finders/environments_finder.rb +++ b/app/finders/environments_finder.rb @@ -17,12 +17,12 @@ class EnvironmentsFinder deployments.none end - environment_ids = deployments - .group(:environment_id) - .select(:environment_id) + environment_ids = deployments. + group(:environment_id). + select(:environment_id) - environments = project.environments.available - .where(id: environment_ids).order_by_last_deployed_at.to_a + environments = project.environments.available. + where(id: environment_ids).order_by_last_deployed_at.to_a environments.select! do |environment| Ability.allowed?(current_user, :read_environment, environment) diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb index 873a253e2b5..9f2206346ce 100644 --- a/app/finders/group_members_finder.rb +++ b/app/finders/group_members_finder.rb @@ -8,9 +8,9 @@ class GroupMembersFinder < Projects::ApplicationController return group_members unless @group.parent - parents_members = GroupMember.non_request - .where(source_id: @group.ancestors.select(:id)) - .where.not(user_id: @group.users.select(:id)) + parents_members = GroupMember.non_request. + where(source_id: @group.ancestors.select(:id)). + where.not(user_id: @group.users.select(:id)) wheres = ["members.id IN (#{group_members.select(:id).to_sql})"] wheres << "members.id IN (#{parents_members.select(:id).to_sql})" diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb index 913db3a3e26..1182939f656 100644 --- a/app/helpers/form_helper.rb +++ b/app/helpers/form_helper.rb @@ -8,10 +8,10 @@ module FormHelper content_tag(:div, class: 'alert alert-danger', id: 'error_explanation') do content_tag(:h4, headline) << content_tag(:ul) do - model.errors.full_messages - .map { |msg| content_tag(:li, msg) } - .join - .html_safe + model.errors.full_messages. + map { |msg| content_tag(:li, msg) }. + join. + html_safe end end end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 7a164cfd26d..8ff8db16514 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -97,8 +97,8 @@ module SearchHelper # Autocomplete results for the current user's projects def projects_autocomplete(term, limit = 5) - current_user.authorized_projects.search_by_title(term) - .sorted_by_stars.non_archived.limit(limit).map do |p| + current_user.authorized_projects.search_by_title(term). + sorted_by_stars.non_archived.limit(limit).map do |p| { category: "Projects", id: p.id, diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 99212a3438f..3e3f6246fc5 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -6,8 +6,8 @@ module WikiHelper # Returns a String composed of the capitalized name of each directory and the # capitalized name of the page itself. def breadcrumb(page_slug) - page_slug.split('/') - .map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize } - .join(' / ') + page_slug.split('/'). + map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize }. + join(' / ') end end diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb index 2eedbf3ffde..6937ad3bdd9 100644 --- a/app/models/award_emoji.rb +++ b/app/models/award_emoji.rb @@ -18,9 +18,9 @@ class AwardEmoji < ActiveRecord::Base class << self def votes_for_collection(ids, type) - select('name', 'awardable_id', 'COUNT(*) as count') - .where('name IN (?) AND awardable_type = ? AND awardable_id IN (?)', [DOWNVOTE_NAME, UPVOTE_NAME], type, ids) - .group('name', 'awardable_id') + select('name', 'awardable_id', 'COUNT(*) as count'). + where('name IN (?) AND awardable_type = ? AND awardable_id IN (?)', [DOWNVOTE_NAME, UPVOTE_NAME], type, ids). + group('name', 'awardable_id') end end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 3a17d5c8dbe..2689078c771 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -65,9 +65,9 @@ module Ci end def retry(build, current_user) - Ci::RetryBuildService - .new(build.project, current_user) - .execute(build) + Ci::RetryBuildService. + new(build.project, current_user). + execute(build) end end @@ -98,9 +98,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Build::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Build::Factory. + new(self, current_user). + fabricate! end def manual? @@ -222,9 +222,9 @@ module Ci end def merge_request - merge_requests = MergeRequest.includes(:merge_request_diff) - .where(source_branch: ref, source_project_id: pipeline.gl_project_id) - .reorder(iid: :asc) + merge_requests = MergeRequest.includes(:merge_request_diff). + where(source_branch: ref, source_project_id: pipeline.gl_project_id). + reorder(iid: :asc) merge_requests.find do |merge_request| merge_request.commits_sha.include?(pipeline.sha) @@ -276,8 +276,8 @@ module Ci def raw_trace(last_lines: nil) if File.exist?(trace_file_path) - Gitlab::Ci::TraceReader.new(trace_file_path) - .read(last_lines: last_lines) + Gitlab::Ci::TraceReader.new(trace_file_path). + read(last_lines: last_lines) else # backward compatibility read_attribute :trace diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 632178de887..04d43ca3c5c 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -91,9 +91,9 @@ module Ci # ref can't be HEAD or SHA, can only be branch/tag name scope :latest, ->(ref = nil) do - max_id = unscope(:select) - .select("max(#{quoted_table_name}.id)") - .group(:ref, :sha) + max_id = unscope(:select). + select("max(#{quoted_table_name}.id)"). + group(:ref, :sha) if ref where(ref: ref, id: max_id.where(ref: ref)) @@ -128,23 +128,23 @@ module Ci end def stages_name - statuses.order(:stage_idx).distinct - .pluck(:stage, :stage_idx).map(&:first) + statuses.order(:stage_idx).distinct. + pluck(:stage, :stage_idx).map(&:first) end def stages # TODO, this needs refactoring, see gitlab-ce#26481. - stages_query = statuses - .group('stage').select(:stage).order('max(stage_idx)') + stages_query = statuses. + group('stage').select(:stage).order('max(stage_idx)') status_sql = statuses.latest.where('stage=sg.stage').status_sql - warnings_sql = statuses.latest.select('COUNT(*) > 0') - .where('stage=sg.stage').failed_but_allowed.to_sql + warnings_sql = statuses.latest.select('COUNT(*) > 0'). + where('stage=sg.stage').failed_but_allowed.to_sql - stages_with_statuses = CommitStatus.from(stages_query, :sg) - .pluck('sg.stage', status_sql, "(#{warnings_sql})") + stages_with_statuses = CommitStatus.from(stages_query, :sg). + pluck('sg.stage', status_sql, "(#{warnings_sql})") stages_with_statuses.map do |stage| Ci::Stage.new(self, Hash[%i[name status warnings].zip(stage)]) @@ -220,8 +220,8 @@ module Ci end def retry_failed(current_user) - Ci::RetryPipelineService.new(project, current_user) - .execute(self) + Ci::RetryPipelineService.new(project, current_user). + execute(self) end def mark_as_processable_after_stage(stage_idx) @@ -253,9 +253,9 @@ module Ci def config_builds_attributes return [] unless config_processor - config_processor - .builds_for_ref(ref, tag?, trigger_requests.first) - .sort_by { |build| build[:stage_idx] } + config_processor. + builds_for_ref(ref, tag?, trigger_requests.first). + sort_by { |build| build[:stage_idx] } end def has_warnings? @@ -353,15 +353,15 @@ module Ci # Merge requests for which the current pipeline is running against # the merge request's latest commit. def merge_requests - @merge_requests ||= project.merge_requests - .where(source_branch: self.ref) - .select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } + @merge_requests ||= project.merge_requests. + where(source_branch: self.ref). + select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } end def detailed_status(current_user) - Gitlab::Ci::Status::Pipeline::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Pipeline::Factory. + new(self, current_user). + fabricate! end private diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 9cf6164e8dd..a120112e882 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -23,15 +23,15 @@ module Ci scope :ordered, ->() { order(id: :desc) } scope :owned_or_shared, ->(project_id) do - joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id') - .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) + joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id'). + where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end scope :assignable_for, ->(project) do # FIXME: That `to_sql` is needed to workaround a weird Rails bug. # Without that, placeholders would miss one and couldn't match. - where(locked: false) - .where.not("id IN (#{project.runners.select(:id).to_sql})").specific + where(locked: false). + where.not("id IN (#{project.runners.select(:id).to_sql})").specific end validate :tag_constraints diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index ca74c91b062..0751ab1b7d8 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -28,9 +28,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Stage::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Stage::Factory. + new(self, current_user). + fabricate! end def statuses diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index fc750a3e5e9..1349beafb76 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -97,8 +97,8 @@ class CommitStatus < ActiveRecord::Base after_transition any => :failed do |commit_status| commit_status.run_after_commit do - MergeRequests::AddTodoWhenBuildFailsService - .new(pipeline.project, nil).execute(self) + MergeRequests::AddTodoWhenBuildFailsService. + new(pipeline.project, nil).execute(self) end end end @@ -132,9 +132,9 @@ class CommitStatus < ActiveRecord::Base end def detailed_status(current_user) - Gitlab::Ci::Status::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::Factory. + new(self, current_user). + fabricate! end def sortable_name diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index fcb335e48d1..37c727b5d9f 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -162,9 +162,9 @@ module Issuable highest_priority = highest_label_priority(params).to_sql - select("#{table_name}.*, (#{highest_priority}) AS highest_priority") - .group(arel_table[:id]) - .reorder(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')) + select("#{table_name}.*, (#{highest_priority}) AS highest_priority"). + group(arel_table[:id]). + reorder(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')) end def with_label(title, sort = nil) diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index a8ce36e51fc..7e56e371b27 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -48,8 +48,8 @@ module Mentionable if extractor @extractor = extractor else - @extractor ||= Gitlab::ReferenceExtractor - .new(project, current_user) + @extractor ||= Gitlab::ReferenceExtractor. + new(project, current_user) @extractor.reset_memoized_values end diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index f449229864d..870a6fbaa90 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -39,8 +39,8 @@ module Milestoneish def issues_visible_to_user(user) memoize_per_user(user, :issues_visible_to_user) do - IssuesFinder.new(user, issues_finder_params) - .execute.where(milestone_id: milestoneish_ids) + IssuesFinder.new(user, issues_finder_params). + execute.where(milestone_id: milestoneish_ids) end end diff --git a/app/models/concerns/presentable.rb b/app/models/concerns/presentable.rb index 7b33b837004..d0f84831d71 100644 --- a/app/models/concerns/presentable.rb +++ b/app/models/concerns/presentable.rb @@ -1,7 +1,7 @@ module Presentable def present(**attributes) - Gitlab::View::Presenter::Factory - .new(self, attributes) - .fabricate! + Gitlab::View::Presenter::Factory. + new(self, attributes). + fabricate! end end diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index c2373de32c5..9f6d215ceb3 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -75,11 +75,11 @@ module Routable # # Returns an ActiveRecord::Relation. def member_descendants(user_id) - joins(:route) - .joins("INNER JOIN routes r2 ON routes.path LIKE CONCAT(r2.path, '/%') + joins(:route). + joins("INNER JOIN routes r2 ON routes.path LIKE CONCAT(r2.path, '/%') INNER JOIN members ON members.source_id = r2.source_id - AND members.source_type = r2.source_type") - .where('members.user_id = ?', user_id) + AND members.source_type = r2.source_type"). + where('members.user_id = ?', user_id) end end diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index a155a064032..b9a2d812edd 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -39,12 +39,12 @@ module Sortable private def highest_label_priority(target_type_column: nil, target_type: nil, target_column:, project_column:, excluded_labels: []) - query = Label.select(LabelPriority.arel_table[:priority].minimum) - .left_join_priorities - .joins(:label_links) - .where("label_priorities.project_id = #{project_column}") - .where("label_links.target_id = #{target_column}") - .reorder(nil) + query = Label.select(LabelPriority.arel_table[:priority].minimum). + left_join_priorities. + joins(:label_links). + where("label_priorities.project_id = #{project_column}"). + where("label_links.target_id = #{target_column}"). + reorder(nil) query = if target_type_column diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index f60a0f8f438..e4f5818d0e3 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -27,30 +27,30 @@ module Subscribable end def subscribers(project) - subscriptions_available(project) - .where(subscribed: true) - .map(&:user) + subscriptions_available(project). + where(subscribed: true). + map(&:user) end def toggle_subscription(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project) - .update(subscribed: !subscribed?(user, project)) + find_or_initialize_subscription(user, project). + update(subscribed: !subscribed?(user, project)) end def subscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project) - .update(subscribed: true) + find_or_initialize_subscription(user, project). + update(subscribed: true) end def unsubscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project) - .update(subscribed: false) + find_or_initialize_subscription(user, project). + update(subscribed: false) end private @@ -69,14 +69,14 @@ module Subscribable end def find_or_initialize_subscription(user, project) - subscriptions - .find_or_initialize_by(user_id: user.id, project_id: project.try(:id)) + subscriptions. + find_or_initialize_by(user_id: user.id, project_id: project.try(:id)) end def subscriptions_available(project) t = Subscription.arel_table - subscriptions - .where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id)))) + subscriptions. + where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id)))) end end diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 43f7460bd5d..afad001d50f 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -53,10 +53,10 @@ class Deployment < ActiveRecord::Base def update_merge_request_metrics! return unless environment.update_merge_request_metrics? - merge_requests = project.merge_requests - .joins(:metrics) - .where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil }) - .where("merge_request_metrics.merged_at <= ?", self.created_at) + merge_requests = project.merge_requests. + joins(:metrics). + where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil }). + where("merge_request_metrics.merged_at <= ?", self.created_at) if previous_deployment merge_requests = merge_requests.where("merge_request_metrics.merged_at >= ?", previous_deployment.created_at) @@ -71,17 +71,17 @@ class Deployment < ActiveRecord::Base merge_requests.map(&:id) end - MergeRequest::Metrics - .where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil) - .update_all(first_deployed_to_production_at: self.created_at) + MergeRequest::Metrics. + where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil). + update_all(first_deployed_to_production_at: self.created_at) end def previous_deployment @previous_deployment ||= - project.deployments.joins(:environment) - .where(environments: { name: self.environment.name }, ref: self.ref) - .where.not(id: self.id) - .take + project.deployments.joins(:environment). + where(environments: { name: self.environment.name }, ref: self.ref). + where.not(id: self.id). + take end def stop_action diff --git a/app/models/environment.rb b/app/models/environment.rb index f917f52f832..1a21b5e52b5 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -40,9 +40,9 @@ class Environment < ActiveRecord::Base scope :stopped, -> { with_state(:stopped) } scope :order_by_last_deployed_at, -> do max_deployment_id_sql = - Deployment.select(Deployment.arel_table[:id].maximum) - .where(Deployment.arel_table[:environment_id].eq(arel_table[:id])) - .to_sql + Deployment.select(Deployment.arel_table[:id].maximum). + where(Deployment.arel_table[:environment_id].eq(arel_table[:id])). + to_sql order(Gitlab::Database.nulls_first_order("(#{max_deployment_id_sql})", 'ASC')) end diff --git a/app/models/event.rb b/app/models/event.rb index b8918fcda21..4b8eac9accf 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -343,9 +343,9 @@ class Event < ActiveRecord::Base # At this point it's possible for multiple threads/processes to try to # update the project. Only one query should actually perform the update, # hence we add the extra WHERE clause for last_activity_at. - Project.unscoped.where(id: project_id) - .where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago) - .update_all(last_activity_at: created_at) + Project.unscoped.where(id: project_id). + where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago). + update_all(last_activity_at: created_at) end def authored_by?(user) diff --git a/app/models/generic_commit_status.rb b/app/models/generic_commit_status.rb index 8867ba0d2ff..36b8568871b 100644 --- a/app/models/generic_commit_status.rb +++ b/app/models/generic_commit_status.rb @@ -18,8 +18,8 @@ class GenericCommitStatus < CommitStatus end def detailed_status(current_user) - Gitlab::Ci::Status::External::Factory - .new(self, current_user) - .fabricate! + Gitlab::Ci::Status::External::Factory. + new(self, current_user). + fabricate! end end diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb index b991d78e27f..84deb67ba9b 100644 --- a/app/models/global_milestone.rb +++ b/app/models/global_milestone.rb @@ -76,8 +76,8 @@ class GlobalMilestone end def labels - @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten) - .sort_by!(&:title) + @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten). + sort_by!(&:title) end def due_date diff --git a/app/models/group.rb b/app/models/group.rb index 5ef3f9513fc..1835ce118a1 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -71,9 +71,9 @@ class Group < Namespace def select_for_project_authorization if current_scope.joins_values.include?(:shared_projects) - joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id') - .where('project_namespace.share_with_group_lock = ?', false) - .select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") + joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id'). + where('project_namespace.share_with_group_lock = ?', false). + select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") else super end @@ -197,8 +197,8 @@ class Group < Namespace end def refresh_members_authorized_projects - UserProjectAccessChangedService.new(user_ids_for_project_authorizations) - .execute + UserProjectAccessChangedService.new(user_ids_for_project_authorizations). + execute end def user_ids_for_project_authorizations diff --git a/app/models/issue_collection.rb b/app/models/issue_collection.rb index 49f011c113f..f0b7d9914c8 100644 --- a/app/models/issue_collection.rb +++ b/app/models/issue_collection.rb @@ -17,9 +17,9 @@ class IssueCollection # Given all the issue projects we get a list of projects that the current # user has at least reporter access to. - projects_with_reporter_access = user - .projects_with_reporter_access_limited_to(project_ids) - .pluck(:id) + projects_with_reporter_access = user. + projects_with_reporter_access_limited_to(project_ids). + pluck(:id) collection.select do |issue| if projects_with_reporter_access.include?(issue.project_id) diff --git a/app/models/label.rb b/app/models/label.rb index e97e53301cc..27429e60e4a 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -34,18 +34,18 @@ class Label < ActiveRecord::Base scope :with_title, ->(title) { where(title: title) } def self.prioritized(project) - joins(:priorities) - .where(label_priorities: { project_id: project }) - .reorder('label_priorities.priority ASC, labels.title ASC') + joins(:priorities). + where(label_priorities: { project_id: project }). + reorder('label_priorities.priority ASC, labels.title ASC') end def self.unprioritized(project) labels = Label.arel_table priorities = LabelPriority.arel_table - label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin) - .on(labels[:id].eq(priorities[:label_id]).and(priorities[:project_id].eq(project.id))) - .join_sources + label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin). + on(labels[:id].eq(priorities[:label_id]).and(priorities[:project_id].eq(project.id))). + join_sources joins(label_priorities).where(priorities[:priority].eq(nil)) end @@ -54,9 +54,9 @@ class Label < ActiveRecord::Base labels = Label.arel_table priorities = LabelPriority.arel_table - label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin) - .on(labels[:id].eq(priorities[:label_id])) - .join_sources + label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin). + on(labels[:id].eq(priorities[:label_id])). + join_sources joins(label_priorities) end diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 7712d5783e0..ee9ac282e39 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -19,8 +19,8 @@ class LfsObject < ActiveRecord::Base end def self.destroy_unreferenced - joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id") - .where(lfs_objects_projects: { id: nil }) - .destroy_all + joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id"). + where(lfs_objects_projects: { id: nil }). + destroy_all end end diff --git a/app/models/member.rb b/app/models/member.rb index f198fbe9056..abe9aee3edf 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -41,9 +41,9 @@ class Member < ActiveRecord::Base is_external_invite = arel_table[:user_id].eq(nil).and(arel_table[:invite_token].not_eq(nil)) user_is_active = User.arel_table[:state].eq(:active) - includes(:user).references(:users) - .where(is_external_invite.or(user_is_active)) - .where(requested_at: nil) + includes(:user).references(:users). + where(is_external_invite.or(user_is_active)). + where(requested_at: nil) end scope :invite, -> { where.not(invite_token: nil) } @@ -99,9 +99,9 @@ class Member < ActiveRecord::Base users = User.arel_table members = Member.arel_table - member_users = members.join(users, Arel::Nodes::OuterJoin) - .on(members[:user_id].eq(users[:id])) - .join_sources + member_users = members.join(users, Arel::Nodes::OuterJoin). + on(members[:user_id].eq(users[:id])). + join_sources joins(member_users) end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index c4520c16a43..ea784f77015 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -475,10 +475,10 @@ class MergeRequest < ActiveRecord::Base end def discussions - @discussions ||= self.related_notes - .inc_relations_for_view - .fresh - .discussions + @discussions ||= self.related_notes. + inc_relations_for_view. + fresh. + discussions end def diff_discussions @@ -564,8 +564,8 @@ class MergeRequest < ActiveRecord::Base messages = [title, description] messages.concat(commits.map(&:safe_message)) if merge_request_diff - Gitlab::ClosingIssueExtractor.new(project, current_user) - .closed_by_message(messages.join("\n")) + Gitlab::ClosingIssueExtractor.new(project, current_user). + closed_by_message(messages.join("\n")) else [] end @@ -813,9 +813,9 @@ class MergeRequest < ActiveRecord::Base def all_pipelines return Ci::Pipeline.none unless source_project - @all_pipelines ||= source_project.pipelines - .where(sha: all_commits_sha, ref: source_branch) - .order(id: :desc) + @all_pipelines ||= source_project.pipelines. + where(sha: all_commits_sha, ref: source_branch). + order(id: :desc) end # Note that this could also return SHA from now dangling commits diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index baee00b8fcd..53d08488788 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -169,8 +169,8 @@ class MergeRequestDiff < ActiveRecord::Base # When compare merge request versions we want diff A..B instead of A...B # so we handle cases when user does squash and rebase of the commits between versions. # For this reason we set straight to true by default. - CompareService.new(project, head_commit_sha) - .execute(project, sha, straight: straight) + CompareService.new(project, head_commit_sha). + execute(project, sha, straight: straight) end def commits_count diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb index 7f7c114803d..daafb137be4 100644 --- a/app/models/merge_requests_closing_issues.rb +++ b/app/models/merge_requests_closing_issues.rb @@ -7,9 +7,9 @@ class MergeRequestsClosingIssues < ActiveRecord::Base class << self def count_for_collection(ids) - group(:issue_id) - .where(issue_id: ids) - .pluck('issue_id', 'COUNT(*) as count') + group(:issue_id). + where(issue_id: ids). + pluck('issue_id', 'COUNT(*) as count') end end end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 30e5dfd096e..7331000a9f2 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -98,11 +98,11 @@ class Milestone < ActiveRecord::Base if Gitlab::Database.postgresql? rel.order(:project_id, :due_date).select('DISTINCT ON (project_id) id') else - rel - .group(:project_id) - .having('due_date = MIN(due_date)') - .pluck(:id, :project_id, :due_date) - .map(&:first) + rel. + group(:project_id). + having('due_date = MIN(due_date)'). + pluck(:id, :project_id, :due_date). + map(&:first) end end @@ -177,8 +177,8 @@ class Milestone < ActiveRecord::Base conditions = 'WHEN id = ? THEN ? ' * ids.length - issues.where(id: ids) - .update_all(["position = CASE #{conditions} ELSE position END", *pairs]) + issues.where(id: ids). + update_all(["position = CASE #{conditions} ELSE position END", *pairs]) end private diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 9334b7d9e61..e207ac3db4e 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -48,9 +48,9 @@ class Namespace < ActiveRecord::Base scope :root, -> { where('type IS NULL') } scope :with_statistics, -> do - joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id') - .group('namespaces.id') - .select( + joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id'). + group('namespaces.id'). + select( 'namespaces.*', 'COALESCE(SUM(ps.storage_size), 0) AS storage_size', 'COALESCE(SUM(ps.repository_size), 0) AS repository_size', @@ -251,10 +251,10 @@ class Namespace < ActiveRecord::Base end def refresh_access_of_projects_invited_groups - Group - .joins(project_group_links: :project) - .where(projects: { namespace_id: id }) - .find_each(&:refresh_members_authorized_projects) + Group. + joins(project_group_links: :project). + where(projects: { namespace_id: id }). + find_each(&:refresh_members_authorized_projects) end def remove_exports! diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb index 8417f200e36..a48e872ad84 100644 --- a/app/models/network/commit.rb +++ b/app/models/network/commit.rb @@ -28,8 +28,8 @@ module Network if map.include?(p.id) map[p.id] end - end - .compact + end. + compact end end end diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index 0bbc9451ffd..2a7fa7d0607 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -23,12 +23,12 @@ module Network def collect_notes h = Hash.new(0) - @project - .notes - .where('noteable_type = ?', 'Commit') - .group('notes.commit_id') - .select('notes.commit_id, count(notes.id) as note_count') - .each do |item| + @project. + notes. + where('noteable_type = ?', 'Commit'). + group('notes.commit_id'). + select('notes.commit_id, count(notes.id) as note_count'). + each do |item| h[item.commit_id] = item.note_count.to_i end diff --git a/app/models/note.rb b/app/models/note.rb index c6406f644e0..d6d5396afa5 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -105,14 +105,14 @@ class Note < ActiveRecord::Base def grouped_diff_discussions active_notes = diff_notes.fresh.select(&:active?) - Discussion.for_diff_notes(active_notes) - .map { |d| [d.line_code, d] }.to_h + Discussion.for_diff_notes(active_notes). + map { |d| [d.line_code, d] }.to_h end def count_for_collection(ids, type) - user.select('noteable_id', 'COUNT(*) as count') - .group(:noteable_id) - .where(noteable_type: type, noteable_id: ids) + user.select('noteable_id', 'COUNT(*) as count'). + group(:noteable_id). + where(noteable_type: type, noteable_id: ids) end end diff --git a/app/models/project.rb b/app/models/project.rb index 698e742de48..301ff71cc01 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -235,8 +235,8 @@ class Project < ActiveRecord::Base scope :inside_path, ->(path) do # We need routes alias rs for JOIN so it does not conflict with # includes(:route) which we use in ProjectsFinder. - joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'") - .where('rs.path LIKE ?', "#{path}/%") + joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'"). + where('rs.path LIKE ?', "#{path}/%") end # "enabled" here means "not disabled". It includes private features! @@ -313,9 +313,9 @@ class Project < ActiveRecord::Base pattern = "%#{query}%" projects = select(:id).where( - ptable[:path].matches(pattern) - .or(ptable[:name].matches(pattern)) - .or(ptable[:description].matches(pattern)) + ptable[:path].matches(pattern). + or(ptable[:name].matches(pattern)). + or(ptable[:description].matches(pattern)) ) # We explicitly remove any eager loading clauses as they're: @@ -324,10 +324,10 @@ class Project < ActiveRecord::Base # 2. Combined with .joins(:namespace) lead to all columns from the # projects & namespaces tables being selected, leading to a SQL error # due to the columns of all UNION'd queries no longer being the same. - namespaces = select(:id) - .except(:includes) - .joins(:namespace) - .where(ntable[:name].matches(pattern)) + namespaces = select(:id). + except(:includes). + joins(:namespace). + where(ntable[:name].matches(pattern)) union = Gitlab::SQL::Union.new([projects, namespaces]) @@ -369,8 +369,8 @@ class Project < ActiveRecord::Base end def trending - joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id') - .reorder('trending_projects.id ASC') + joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id'). + reorder('trending_projects.id ASC') end def cached_count diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index 02e802bad6d..9819e723fe8 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -105,9 +105,9 @@ class KubernetesService < DeploymentService def terminals(environment) with_reactive_cache do |data| pods = data.fetch(:pods, nil) - filter_pods(pods, app: environment.slug) - .flat_map { |pod| terminals_for_pod(api_url, namespace, pod) } - .each { |terminal| add_terminal_auth(terminal, terminal_auth) } + filter_pods(pods, app: environment.slug). + flat_map { |pod| terminals_for_pod(api_url, namespace, pod) }. + each { |terminal| add_terminal_auth(terminal, terminal_auth) } end end diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb index 26376fd87ff..56f42d63b2d 100644 --- a/app/models/project_services/mattermost_slash_commands_service.rb +++ b/app/models/project_services/mattermost_slash_commands_service.rb @@ -20,8 +20,8 @@ class MattermostSlashCommandsService < ChatSlashCommandsService end def configure(user, params) - token = Mattermost::Command.new(user) - .create(command(params)) + token = Mattermost::Command.new(user). + create(command(params)) update(active: true, token: token) if token rescue Mattermost::Error => e diff --git a/app/models/project_team.rb b/app/models/project_team.rb index 67cc06642f1..8a53e974b6f 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -169,10 +169,10 @@ class ProjectTeam # Lookup only the IDs we need user_ids = user_ids - access.keys - users_access = project.project_authorizations - .where(user: user_ids) - .group(:user_id) - .maximum(:access_level) + users_access = project.project_authorizations. + where(user: user_ids). + group(:user_id). + maximum(:access_level) access.merge!(users_access) access diff --git a/app/models/repository.rb b/app/models/repository.rb index d1dd900d597..cd2568ad445 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -249,11 +249,11 @@ class Repository cache.fetch(:"diverging_commit_counts_#{branch.name}") do # Rugged seems to throw a `ReferenceError` when given branch_names rather # than SHA-1 hashes - number_commits_behind = raw_repository - .count_commits_between(branch.dereferenced_target.sha, root_ref_hash) + number_commits_behind = raw_repository. + count_commits_between(branch.dereferenced_target.sha, root_ref_hash) - number_commits_ahead = raw_repository - .count_commits_between(root_ref_hash, branch.dereferenced_target.sha) + number_commits_ahead = raw_repository. + count_commits_between(root_ref_hash, branch.dereferenced_target.sha) { behind: number_commits_behind, ahead: number_commits_ahead } end @@ -755,8 +755,8 @@ class Repository check_tree_entry_for_dir(branch_name, path) if start_branch_name - start_project.repository - .check_tree_entry_for_dir(start_branch_name, path) + start_project.repository. + check_tree_entry_for_dir(start_branch_name, path) end commit_file( diff --git a/app/models/todo.rb b/app/models/todo.rb index 32bb9bf2045..47789a21133 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -64,9 +64,9 @@ class Todo < ActiveRecord::Base highest_priority = highest_label_priority(params).to_sql - select("#{table_name}.*, (#{highest_priority}) AS highest_priority") - .order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')) - .order('todos.created_at') + select("#{table_name}.*, (#{highest_priority}) AS highest_priority"). + order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')). + order('todos.created_at') end end diff --git a/app/models/user.rb b/app/models/user.rb index 801c84dc011..fada0e567f0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -197,13 +197,13 @@ class User < ActiveRecord::Base scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('last_sign_in_at', 'ASC')) } def self.with_two_factor - joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id") - .where("u2f.id IS NOT NULL OR otp_required_for_login = ?", true).distinct(arel_table[:id]) + joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id"). + where("u2f.id IS NOT NULL OR otp_required_for_login = ?", true).distinct(arel_table[:id]) end def self.without_two_factor - joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id") - .where("u2f.id IS NULL AND otp_required_for_login = ?", false) + joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id"). + where("u2f.id IS NULL AND otp_required_for_login = ?", false) end # @@ -274,9 +274,9 @@ class User < ActiveRecord::Base pattern = "%#{query}%" where( - table[:name].matches(pattern) - .or(table[:email].matches(pattern)) - .or(table[:username].matches(pattern)) + table[:name].matches(pattern). + or(table[:email].matches(pattern)). + or(table[:username].matches(pattern)) ) end @@ -291,10 +291,10 @@ class User < ActiveRecord::Base matched_by_emails_user_ids = email_table.project(email_table[:user_id]).where(email_table[:email].matches(pattern)) where( - table[:name].matches(pattern) - .or(table[:email].matches(pattern)) - .or(table[:username].matches(pattern)) - .or(table[:id].in(matched_by_emails_user_ids)) + table[:name].matches(pattern). + or(table[:email].matches(pattern)). + or(table[:username].matches(pattern)). + or(table[:id].in(matched_by_emails_user_ids)) ) end @@ -447,8 +447,8 @@ class User < ActiveRecord::Base # Returns the groups a user has access to def authorized_groups - union = Gitlab::SQL::Union - .new([groups.select(:id), authorized_projects.select(:namespace_id)]) + union = Gitlab::SQL::Union. + new([groups.select(:id), authorized_projects.select(:namespace_id)]) Group.where("namespaces.id IN (#{union.to_sql})") end @@ -458,8 +458,8 @@ class User < ActiveRecord::Base end def nested_projects - Project.joins(:namespace).where('namespaces.parent_id IS NOT NULL') - .member_descendants(id) + Project.joins(:namespace).where('namespaces.parent_id IS NOT NULL'). + member_descendants(id) end def refresh_authorized_projects @@ -579,9 +579,9 @@ class User < ActiveRecord::Base next unless project if project.repository.branch_exists?(event.branch_name) - merge_requests = MergeRequest.where("created_at >= ?", event.created_at) - .where(source_project_id: project.id, - source_branch: event.branch_name) + merge_requests = MergeRequest.where("created_at >= ?", event.created_at). + where(source_project_id: project.id, + source_branch: event.branch_name) merge_requests.empty? end end @@ -793,8 +793,8 @@ class User < ActiveRecord::Base def toggle_star(project) UsersStarProject.transaction do - user_star_project = users_star_projects - .where(project: project, user: self).lock(true).first + user_star_project = users_star_projects. + where(project: project, user: self).lock(true).first if user_star_project user_star_project.destroy @@ -830,11 +830,11 @@ class User < ActiveRecord::Base # ms on a database with a similar size to GitLab.com's database. On the other # hand, using a subquery means we can get the exact same data in about 40 ms. def contributed_projects - events = Event.select(:project_id) - .contributions.where(author_id: self) - .where("created_at > ?", Time.now - 1.year) - .uniq - .reorder(nil) + events = Event.select(:project_id). + contributions.where(author_id: self). + where("created_at > ?", Time.now - 1.year). + uniq. + reorder(nil) Project.where(id: events) end @@ -845,9 +845,9 @@ class User < ActiveRecord::Base def ci_authorized_runners @ci_authorized_runners ||= begin - runner_ids = Ci::RunnerProject - .where("ci_runner_projects.gl_project_id IN (#{ci_projects_union.to_sql})") - .select(:runner_id) + runner_ids = Ci::RunnerProject. + where("ci_runner_projects.gl_project_id IN (#{ci_projects_union.to_sql})"). + select(:runner_id) Ci::Runner.specific.where(id: runner_ids) end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 0fa9d77a771..2caebb496db 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -22,16 +22,16 @@ class WikiPage def self.group_by_directory(pages) return [] if pages.blank? - pages.sort_by { |page| [page.directory, page.slug] } - .group_by(&:directory) - .map do |dir, pages| + pages.sort_by { |page| [page.directory, page.slug] }. + group_by(&:directory). + map do |dir, pages| if dir.present? WikiDirectory.new(dir, pages) else pages end - end - .flatten + end. + flatten end def self.unhyphenize(name) diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb index 311ee9c96be..032c44274ef 100644 --- a/app/serializers/base_serializer.rb +++ b/app/serializers/base_serializer.rb @@ -4,9 +4,9 @@ class BaseSerializer end def represent(resource, opts = {}) - self.class.entity_class - .represent(resource, opts.merge(request: @request)) - .as_json + self.class.entity_class. + represent(resource, opts.merge(request: @request)). + as_json end def self.entity(entity_class) diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index d0a60f134da..ffc4fd34c75 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -36,9 +36,9 @@ class EnvironmentSerializer < BaseSerializer private def itemize(resource) - items = resource.order('folder_name ASC') - .group('COALESCE(environment_type, name)') - .select('COALESCE(environment_type, name) AS folder_name', + items = resource.order('folder_name ASC'). + group('COALESCE(environment_type, name)'). + select('COALESCE(environment_type, name) AS folder_name', 'COUNT(*) AS size', 'MAX(id) AS last_id') # It makes a difference when you call `paginate` method, because diff --git a/app/services/after_branch_delete_service.rb b/app/services/after_branch_delete_service.rb index 227e9ea9c6d..95492f709bb 100644 --- a/app/services/after_branch_delete_service.rb +++ b/app/services/after_branch_delete_service.rb @@ -14,8 +14,8 @@ class AfterBranchDeleteService < BaseService private def stop_environments - Ci::StopEnvironmentsService - .new(project, current_user) - .execute(branch_name) + Ci::StopEnvironmentsService. + new(project, current_user). + execute(branch_name) end end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 8a94c54b6ab..2d664f3f0c8 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -57,15 +57,15 @@ module Boards return issues unless board_label_ids.any? issues.where.not( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") - .where(label_id: board_label_ids).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). + where(label_id: board_label_ids).limit(1).arel.exists ) end def with_list_label(issues) issues.where( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") - .where("label_links.label_id = ?", list.label_id).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). + where("label_links.label_id = ?", list.label_id).limit(1).arel.exists ) end end diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index f986e05944c..6c80dd61873 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -17,8 +17,8 @@ module Boards attr_reader :board def decrement_higher_lists(list) - board.lists.movable.where('position > ?', list.position) - .update_all('position = position - 1') + board.lists.movable.where('position > ?', list.position). + update_all('position = position - 1') end def remove_list(list) diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index f2a68865f7b..2f109934ea9 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -33,15 +33,15 @@ module Boards end def decrement_intermediate_lists - board.lists.movable.where('position > ?', old_position) - .where('position <= ?', new_position) - .update_all('position = position - 1') + board.lists.movable.where('position > ?', old_position). + where('position <= ?', new_position). + update_all('position = position - 1') end def increment_intermediate_lists - board.lists.movable.where('position >= ?', new_position) - .where('position < ?', old_position) - .update_all('position = position + 1') + board.lists.movable.where('position >= ?', new_position). + where('position < ?', old_position). + update_all('position = position + 1') end def update_list_position(list) diff --git a/app/services/ci/create_pipeline_builds_service.rb b/app/services/ci/create_pipeline_builds_service.rb index 4cbbd366cc4..70fb2c5e38f 100644 --- a/app/services/ci/create_pipeline_builds_service.rb +++ b/app/services/ci/create_pipeline_builds_service.rb @@ -34,8 +34,8 @@ module Ci end def new_builds - @new_builds ||= pipeline.config_builds_attributes - .reject { |build| existing_build_names.include?(build[:name]) } + @new_builds ||= pipeline.config_builds_attributes. + reject { |build| existing_build_names.include?(build[:name]) } end def existing_build_names diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 38a85e9fc42..b53a467655f 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -48,9 +48,9 @@ module Ci Ci::Pipeline.transaction do pipeline.save - Ci::CreatePipelineBuildsService - .new(project, current_user) - .execute(pipeline) + Ci::CreatePipelineBuildsService. + new(project, current_user). + execute(pipeline) end pipeline.tap(&:process!) diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index 062e7be5be8..6af3c1ca5b1 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -3,8 +3,8 @@ module Ci def execute(project, trigger, ref, variables = nil) trigger_request = trigger.trigger_requests.create(variables: variables) - pipeline = Ci::CreatePipelineService.new(project, nil, ref: ref) - .execute(ignore_skip_ci: true, trigger_request: trigger_request) + pipeline = Ci::CreatePipelineService.new(project, nil, ref: ref). + execute(ignore_skip_ci: true, trigger_request: trigger_request) if pipeline.persisted? trigger_request end diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 79eb97b7b55..442230abe29 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -78,9 +78,9 @@ module Ci def ensure_created_builds! return if created_builds.any? - Ci::CreatePipelineBuildsService - .new(project, current_user) - .execute(pipeline) + Ci::CreatePipelineBuildsService. + new(project, current_user). + execute(pipeline) end end end diff --git a/app/services/ci/register_build_service.rb b/app/services/ci/register_build_service.rb index 9c7abf97b4c..6f03bf2be13 100644 --- a/app/services/ci/register_build_service.rb +++ b/app/services/ci/register_build_service.rb @@ -42,15 +42,15 @@ module Ci def builds_for_shared_runner new_builds. # don't run projects which have not enabled shared runners and builds - joins(:project).where(projects: { shared_runners_enabled: true }) - .joins('LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id') - .where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'). + joins(:project).where(projects: { shared_runners_enabled: true }). + joins('LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id'). + where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'). # Implement fair scheduling # this returns builds that are ordered by number of running builds # we prefer projects that don't use shared runners at all - joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id") - .order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC') + joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id"). + order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC') end def builds_for_specific_runner @@ -58,8 +58,8 @@ module Ci end def running_builds_for_shared_runners - Ci::Build.running.where(runner: Ci::Runner.shared) - .group(:gl_project_id).select(:gl_project_id, 'count(*) AS running_builds') + Ci::Build.running.where(runner: Ci::Runner.shared). + group(:gl_project_id).select(:gl_project_id, 'count(*) AS running_builds') end def new_builds diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index 38ef323f6e5..c1fa9278f0f 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -2,8 +2,8 @@ module Ci class RetryBuildService < ::BaseService CLONE_ATTRIBUTES = %i[pipeline project ref tag options commands name allow_failure stage stage_idx trigger_request - yaml_variables when environment coverage_regex] - .freeze + yaml_variables when environment coverage_regex]. + freeze REJECT_ATTRIBUTES = %i[id status user token coverage trace runner artifacts_expire_at artifacts_file @@ -20,9 +20,9 @@ module Ci new_build.enqueue! - MergeRequests::AddTodoWhenBuildFailsService - .new(project, current_user) - .close(new_build) + MergeRequests::AddTodoWhenBuildFailsService. + new(project, current_user). + close(new_build) end end diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 2c5e130e5aa..6e9781ca8cf 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -8,13 +8,13 @@ module Ci pipeline.builds.failed_or_canceled.find_each do |build| next unless build.retryable? - Ci::RetryBuildService.new(project, current_user) - .reprocess(build) + Ci::RetryBuildService.new(project, current_user). + reprocess(build) end - MergeRequests::AddTodoWhenBuildFailsService - .new(project, current_user) - .close_all(pipeline) + MergeRequests::AddTodoWhenBuildFailsService. + new(project, current_user). + close_all(pipeline) pipeline.process! end diff --git a/app/services/commits/change_service.rb b/app/services/commits/change_service.rb index 25e22f14e60..75281837b09 100644 --- a/app/services/commits/change_service.rb +++ b/app/services/commits/change_service.rb @@ -70,8 +70,8 @@ module Commits # Temporary branch exists and contains the change commit return if repository.find_branch(new_branch) - result = ValidateNewBranchService.new(@project, current_user) - .execute(new_branch) + result = ValidateNewBranchService.new(@project, current_user). + execute(new_branch) if result[:status] == :error raise ChangeError, "There was an error creating the source branch: #{result[:message]}" diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 77459d8779d..1b5e504573a 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -1,7 +1,7 @@ class CreateBranchService < BaseService def execute(branch_name, ref) - result = ValidateNewBranchService.new(project, current_user) - .execute(branch_name) + result = ValidateNewBranchService.new(project, current_user). + execute(branch_name) return result if result[:status] == :error diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb index dcec604b455..0a25f56d24c 100644 --- a/app/services/files/base_service.rb +++ b/app/services/files/base_service.rb @@ -72,8 +72,8 @@ module Files end def validate_target_branch - result = ValidateNewBranchService.new(project, current_user) - .execute(@target_branch) + result = ValidateNewBranchService.new(project, current_user). + execute(@target_branch) if result[:status] == :error raise_error("Something went wrong when we tried to create #{@target_branch} for you: #{result[:message]}") diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb index b1e8d11fdcf..a71fe61a4b6 100644 --- a/app/services/files/update_service.rb +++ b/app/services/files/update_service.rb @@ -24,8 +24,8 @@ module Files end def last_commit - @last_commit ||= Gitlab::Git::Commit - .last_for_path(@start_project.repository, @start_branch, @file_path) + @last_commit ||= Gitlab::Git::Commit. + last_for_path(@start_project.repository, @start_branch, @file_path) end end end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index ee6e695c134..f681f831cbd 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -85,8 +85,8 @@ class GitPushService < BaseService default = is_default_branch? push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit| - ProcessCommitWorker - .perform_async(project.id, current_user.id, commit.to_hash, default) + ProcessCommitWorker. + perform_async(project.id, current_user.id, commit.to_hash, default) end end @@ -96,8 +96,8 @@ class GitPushService < BaseService # Update merge requests that may be affected by this push. A new branch # could cause the last commit of a merge request to change. # - UpdateMergeRequestsWorker - .perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) + UpdateMergeRequestsWorker. + perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) EventCreateService.new.push(@project, current_user, build_push_data) @project.execute_hooks(build_push_data.dup, :push_hooks) @@ -105,9 +105,9 @@ class GitPushService < BaseService Ci::CreatePipelineService.new(@project, current_user, build_push_data).execute if push_remove_branch? - AfterBranchDeleteService - .new(project, current_user) - .execute(branch_name) + AfterBranchDeleteService. + new(project, current_user). + execute(branch_name) end end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 457dcf76995..9500faf2862 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -144,8 +144,8 @@ class IssuableBaseService < BaseService def merge_slash_commands_into_params!(issuable) description, command_params = - SlashCommands::InterpretService.new(project, current_user) - .execute(params[:description], issuable) + SlashCommands::InterpretService.new(project, current_user). + execute(params[:description], issuable) # Avoid a description already set on an issuable to be overwritten by a nil params[:description] = description if params.has_key?(:description) diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb index 9e0c90b56f6..366b3572738 100644 --- a/app/services/issues/create_service.rb +++ b/app/services/issues/create_service.rb @@ -29,8 +29,8 @@ module Issues def resolve_discussions_in_merge_request(issue) Discussions::ResolveService.new(project, current_user, merge_request: merge_request_for_resolving_discussions, - follow_up_issue: issue) - .execute(merge_request_for_resolving_discussions.resolvable_discussions) + follow_up_issue: issue). + execute(merge_request_for_resolving_discussions.resolvable_discussions) end private diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb index a2a5f57d069..17b65947468 100644 --- a/app/services/issues/move_service.rb +++ b/app/services/issues/move_service.rb @@ -61,8 +61,8 @@ module Issues end def cloneable_milestone_id - @new_project.milestones - .find_by(title: @old_issue.milestone.try(:title)).try(:id) + @new_project.milestones. + find_by(title: @old_issue.milestone.try(:title)).try(:id) end def rewrite_notes diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb index 43b539ded53..76d0ba67b07 100644 --- a/app/services/labels/promote_service.rb +++ b/app/services/labels/promote_service.rb @@ -26,29 +26,29 @@ module Labels private def label_ids_for_merge(new_label) - LabelsFinder - .new(current_user, title: new_label.title, group_id: project.group.id) - .execute(skip_authorization: true) - .where.not(id: new_label) - .select(:id) # Can't use pluck() to avoid object-creation because of the batching + LabelsFinder. + new(current_user, title: new_label.title, group_id: project.group.id). + execute(skip_authorization: true). + where.not(id: new_label). + select(:id) # Can't use pluck() to avoid object-creation because of the batching end def update_issuables(new_label, label_ids) - LabelLink - .where(label: label_ids) - .update_all(label_id: new_label) + LabelLink. + where(label: label_ids). + update_all(label_id: new_label) end def update_issue_board_lists(new_label, label_ids) - List - .where(label: label_ids) - .update_all(label_id: new_label) + List. + where(label: label_ids). + update_all(label_id: new_label) end def update_priorities(new_label, label_ids) - LabelPriority - .where(label: label_ids) - .update_all(label_id: new_label) + LabelPriority. + where(label: label_ids). + update_all(label_id: new_label) end def update_project_labels(label_ids) diff --git a/app/services/labels/transfer_service.rb b/app/services/labels/transfer_service.rb index d2ece354efc..514679ed29d 100644 --- a/app/services/labels/transfer_service.rb +++ b/app/services/labels/transfer_service.rb @@ -41,16 +41,16 @@ module Labels end def group_labels_applied_to_issues - Label.joins(:issues) - .where( + Label.joins(:issues). + where( issues: { project_id: project.id }, labels: { type: 'GroupLabel', group_id: old_group.id } ) end def group_labels_applied_to_merge_requests - Label.joins(:merge_requests) - .where( + Label.joins(:merge_requests). + where( merge_requests: { target_project_id: project.id }, labels: { type: 'GroupLabel', group_id: old_group.id } ) @@ -64,15 +64,15 @@ module Labels end def update_label_links(labels, old_label_id:, new_label_id:) - LabelLink.joins(:label) - .merge(labels) - .where(label_id: old_label_id) - .update_all(label_id: new_label_id) + LabelLink.joins(:label). + merge(labels). + where(label_id: old_label_id). + update_all(label_id: new_label_id) end def update_label_priorities(old_label_id:, new_label_id:) - LabelPriority.where(project_id: project.id, label_id: old_label_id) - .update_all(label_id: new_label_id) + LabelPriority.where(project_id: project.id, label_id: old_label_id). + update_all(label_id: new_label_id) end end end diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index 5a53b973059..fd9d7de35f4 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -40,11 +40,11 @@ module MergeRequests # Returns all origin and fork merge requests from `@project` satisfying passed arguments. def merge_requests_for(source_branch, mr_states: [:opened]) - MergeRequest - .with_state(mr_states) - .where(source_branch: source_branch, source_project_id: @project.id) - .preload(:source_project) # we don't need a #includes since we're just preloading for the #select - .select(&:source_project) + MergeRequest. + with_state(mr_states). + where(source_branch: source_branch, source_project_id: @project.id). + preload(:source_project). # we don't need a #includes since we're just preloading for the #select + select(&:source_project) end def pipeline_merge_requests(pipeline) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 1657f8624a7..3da1b657a41 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -63,8 +63,8 @@ module MergeRequests MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) if params[:should_remove_source_branch].present? || @merge_request.force_remove_source_branch? - DeleteBranchService.new(@merge_request.source_project, branch_deletion_user) - .execute(merge_request.source_branch) + DeleteBranchService.new(@merge_request.source_project, branch_deletion_user). + execute(merge_request.source_branch) end end diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index 9277f67e5ae..edee3032683 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -43,9 +43,9 @@ module MergeRequests end filter_merge_requests(merge_requests).each do |merge_request| - MergeRequests::PostMergeService - .new(merge_request.target_project, @current_user) - .execute(merge_request) + MergeRequests::PostMergeService. + new(merge_request.target_project, @current_user). + execute(merge_request) end end @@ -56,13 +56,13 @@ module MergeRequests # Refresh merge request diff if we push to source or target branch of merge request # Note: we should update merge requests from forks too def reload_merge_requests - merge_requests = @project.merge_requests.opened - .by_source_or_target_branch(@branch_name).to_a + merge_requests = @project.merge_requests.opened. + by_source_or_target_branch(@branch_name).to_a # Fork merge requests - merge_requests += MergeRequest.opened - .where(source_branch: @branch_name, source_project: @project) - .where.not(target_project: @project).to_a + merge_requests += MergeRequest.opened. + where(source_branch: @branch_name, source_project: @project). + where.not(target_project: @project).to_a filter_merge_requests(merge_requests).each do |merge_request| if merge_request.source_branch == @branch_name || force_push? diff --git a/app/services/notes/slash_commands_service.rb b/app/services/notes/slash_commands_service.rb index addb6a7e65b..ad1e6f6774a 100644 --- a/app/services/notes/slash_commands_service.rb +++ b/app/services/notes/slash_commands_service.rb @@ -22,8 +22,8 @@ module Notes def extract_commands(note, options = {}) return [note.note, {}] unless supported?(note) - SlashCommands::InterpretService.new(project, current_user, options) - .execute(note.note, note.noteable) + SlashCommands::InterpretService.new(project, current_user, options). + execute(note.note, note.noteable) end def execute(command_params, note) diff --git a/app/services/tags/create_service.rb b/app/services/tags/create_service.rb index 674792f6138..1756da9e519 100644 --- a/app/services/tags/create_service.rb +++ b/app/services/tags/create_service.rb @@ -19,8 +19,8 @@ module Tags if new_tag if release_description - CreateReleaseService.new(@project, @current_user) - .execute(tag_name, release_description) + CreateReleaseService.new(@project, @current_user). + execute(tag_name, release_description) end success.merge(tag: new_tag) diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index 4411eda3b02..fad741531ea 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -103,11 +103,11 @@ module Users end def fresh_authorizations - ProjectAuthorization - .unscoped - .select('project_id, MAX(access_level) AS access_level') - .from("(#{project_authorizations_union.to_sql}) #{ProjectAuthorization.table_name}") - .group(:project_id) + ProjectAuthorization. + unscoped. + select('project_id, MAX(access_level) AS access_level'). + from("(#{project_authorizations_union.to_sql}) #{ProjectAuthorization.table_name}"). + group(:project_id) end private diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index def0ab1dde1..31e2dc448da 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -3,7 +3,7 @@ class BuildCoverageWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id) - .try(:update_coverage) + Ci::Build.find_by(id: build_id). + try(:update_coverage) end end diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index 9965af935d4..ff22313c491 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -3,7 +3,7 @@ class BuildHooksWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id) - .try(:execute_hooks) + Ci::Build.find_by(id: build_id). + try(:execute_hooks) end end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index f5ccc84c160..d4c3f14ec06 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -33,15 +33,15 @@ class EmailsOnPushWorker reverse_compare = false if action == :push - compare = CompareService.new(project, after_sha) - .execute(project, before_sha) + compare = CompareService.new(project, after_sha). + execute(project, before_sha) diff_refs = compare.diff_refs return false if compare.same if compare.commits.empty? - compare = CompareService.new(project, before_sha) - .execute(project, after_sha) + compare = CompareService.new(project, before_sha). + execute(project, after_sha) diff_refs = compare.diff_refs reverse_compare = true diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index eb403c134d1..2c29a9a58e1 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -3,10 +3,10 @@ class ExpireBuildInstanceArtifactsWorker include DedicatedSidekiqQueue def perform(build_id) - build = Ci::Build - .with_expired_artifacts - .reorder(nil) - .find_by(id: build_id) + build = Ci::Build. + with_expired_artifacts. + reorder(nil). + find_by(id: build_id) return unless build.try(:project) diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index 48e2da338f6..79efca4f2f9 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -7,7 +7,7 @@ class MergeWorker current_user = User.find(current_user_id) merge_request = MergeRequest.find(merge_request_id) - MergeRequests::MergeService.new(merge_request.target_project, current_user, params) - .execute(merge_request) + MergeRequests::MergeService.new(merge_request.target_project, current_user, params). + execute(merge_request) end end diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index 7e36eacebf8..7480a055e6a 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -3,7 +3,7 @@ class PipelineHooksWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id) - .try(:execute_hooks) + Ci::Pipeline.find_by(id: pipeline_id). + try(:execute_hooks) end end diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 357e4a9a1c3..5dcb09f553e 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -3,7 +3,7 @@ class PipelineProcessWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id) - .try(:process!) + Ci::Pipeline.find_by(id: pipeline_id). + try(:process!) end end diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb index cc0eb708cf9..ef710f374ca 100644 --- a/app/workers/pipeline_success_worker.rb +++ b/app/workers/pipeline_success_worker.rb @@ -4,9 +4,9 @@ class PipelineSuccessWorker def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| - MergeRequests::MergeWhenPipelineSucceedsService - .new(pipeline.project, nil) - .trigger(pipeline) + MergeRequests::MergeWhenPipelineSucceedsService. + new(pipeline.project, nil). + trigger(pipeline) end end end diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index 96c4152c674..e6d06d0577d 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -3,7 +3,7 @@ class PipelineUpdateWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id) - .try(:update_status) + Ci::Pipeline.find_by(id: pipeline_id). + try(:update_status) end end diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb index 5d7561732f1..e9a5bd7f24e 100644 --- a/app/workers/process_commit_worker.rb +++ b/app/workers/process_commit_worker.rb @@ -45,16 +45,16 @@ class ProcessCommitWorker # therefor we use IssueCollection here and skip the authorization check in # Issues::CloseService#execute. IssueCollection.new(issues).updatable_by_user(user).each do |issue| - Issues::CloseService.new(project, author) - .close_issue(issue, commit: commit) + Issues::CloseService.new(project, author). + close_issue(issue, commit: commit) end end def update_issue_metrics(commit, author) mentioned_issues = commit.all_references(author).issues - Issue::Metrics.where(issue_id: mentioned_issues.map(&:id), first_mentioned_in_commit_at: nil) - .update_all(first_mentioned_in_commit_at: commit.committed_date) + Issue::Metrics.where(issue_id: mentioned_issues.map(&:id), first_mentioned_in_commit_at: nil). + update_all(first_mentioned_in_commit_at: commit.committed_date) end def build_commit(project, hash) diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb index 505ff9e086e..8ff9d07860f 100644 --- a/app/workers/project_cache_worker.rb +++ b/app/workers/project_cache_worker.rb @@ -32,8 +32,8 @@ class ProjectCacheWorker private def try_obtain_lease_for(project_id, section) - Gitlab::ExclusiveLease - .new("project_cache_worker:#{project_id}:#{section}", timeout: LEASE_TIMEOUT) - .try_obtain + Gitlab::ExclusiveLease. + new("project_cache_worker:#{project_id}:#{section}", timeout: LEASE_TIMEOUT). + try_obtain end end diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb index cee05b42dd7..392abb9c21b 100644 --- a/app/workers/prune_old_events_worker.rb +++ b/app/workers/prune_old_events_worker.rb @@ -10,9 +10,9 @@ class PruneOldEventsWorker '(id IN (SELECT id FROM (?) ids_to_remove))', Event.unscoped.where( 'created_at < ?', - (12.months + 1.day).ago) - .select(:id) - .limit(10_000) - ).delete_all + (12.months + 1.day).ago). + select(:id). + limit(10_000)). + delete_all end end diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb index b94d83bd709..c3e7491ec4e 100644 --- a/app/workers/repository_check/batch_worker.rb +++ b/app/workers/repository_check/batch_worker.rb @@ -32,10 +32,10 @@ module RepositoryCheck # has to sit and wait for this query to finish. def project_ids limit = 10_000 - never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago) - .limit(limit).pluck(:id) - old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago) - .reorder('last_repository_check_at ASC').limit(limit).pluck(:id) + never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago). + limit(limit).pluck(:id) + old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago). + reorder('last_repository_check_at ASC').limit(limit).pluck(:id) never_checked_projects + old_check_projects end diff --git a/config/initializers/metrics.rb b/config/initializers/metrics.rb index f082495cd7d..a1517e6afc8 100644 --- a/config/initializers/metrics.rb +++ b/config/initializers/metrics.rb @@ -147,8 +147,8 @@ if Gitlab::Metrics.enabled? ActiveRecord::Querying.public_instance_methods(false).map(&:to_s) ) - Gitlab::Metrics::Instrumentation - .instrument_class_hierarchy(ActiveRecord::Base) do |klass, method| + Gitlab::Metrics::Instrumentation. + instrument_class_hierarchy(ActiveRecord::Base) do |klass, method| # Instrumenting the ApplicationSetting class can lead to an infinite # loop. Since the data is cached any way we don't really need to # instrument it. diff --git a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb index f4fe8103218..3e1f6b1627d 100644 --- a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb +++ b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb @@ -6,9 +6,9 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration class Project < ActiveRecord::Base def self.find_including_path(id) - select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace") - .joins('INNER JOIN namespaces ON namespaces.id = projects.namespace_id') - .find_by(id: id) + select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace"). + joins('INNER JOIN namespaces ON namespaces.id = projects.namespace_id'). + find_by(id: id) end def repository_storage_path diff --git a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb index f73e4f6c99b..a20a903a752 100644 --- a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb +++ b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb @@ -8,11 +8,11 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration environments = Arel::Table.new(:environments) # Get all [project_id, name] pairs that occur more than once - finder_sql = environments - .group(environments[:project_id], environments[:name]) - .having(Arel.sql("COUNT(1)").gt(1)) - .project(environments[:project_id], environments[:name]) - .to_sql + finder_sql = environments. + group(environments[:project_id], environments[:name]). + having(Arel.sql("COUNT(1)").gt(1)). + project(environments[:project_id], environments[:name]). + to_sql conflicting = connection.exec_query(finder_sql) @@ -28,12 +28,12 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration # Rename conflicting environments by appending "-#{id}" to all but the first def fix_duplicates(project_id, name) environments = Arel::Table.new(:environments) - finder_sql = environments - .where(environments[:project_id].eq(project_id)) - .where(environments[:name].eq(name)) - .order(environments[:id].asc) - .project(environments[:id], environments[:name]) - .to_sql + finder_sql = environments. + where(environments[:project_id].eq(project_id)). + where(environments[:name].eq(name)). + order(environments[:id].asc). + project(environments[:id], environments[:name]). + to_sql # Now we have the data for all the conflicting rows conflicts = connection.exec_query(finder_sql).rows @@ -41,11 +41,11 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration conflicts.each do |id, name| update_sql = - Arel::UpdateManager.new(ActiveRecord::Base) - .table(environments) - .set(environments[:name] => name + "-" + id.to_s) - .where(environments[:id].eq(id)) - .to_sql + Arel::UpdateManager.new(ActiveRecord::Base). + table(environments). + set(environments[:name] => name + "-" + id.to_s). + where(environments[:id].eq(id)). + to_sql connection.exec_update(update_sql, self.class.name, []) end diff --git a/db/migrate/20161207231626_add_environment_slug.rb b/db/migrate/20161207231626_add_environment_slug.rb index 83cdd484c4c..8e98ee5b9ba 100644 --- a/db/migrate/20161207231626_add_environment_slug.rb +++ b/db/migrate/20161207231626_add_environment_slug.rb @@ -19,10 +19,10 @@ class AddEnvironmentSlug < ActiveRecord::Migration finder = environments.project(:id, :name) connection.exec_query(finder.to_sql).rows.each do |id, name| - updater = Arel::UpdateManager.new(ActiveRecord::Base) - .table(environments) - .set(environments[:slug] => generate_slug(name)) - .where(environments[:id].eq(id)) + updater = Arel::UpdateManager.new(ActiveRecord::Base). + table(environments). + set(environments[:slug] => generate_slug(name)). + where(environments[:id].eq(id)) connection.exec_update(updater.to_sql, self.class.name, []) end diff --git a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb index 69007b8e8ed..14b5ef476f0 100644 --- a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb +++ b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb @@ -13,13 +13,13 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration namespaces = Arel::Table.new(:namespaces) finder_sql = - projects - .join(namespaces, Arel::Nodes::InnerJoin) - .on(projects[:namespace_id].eq(namespaces[:id])) - .where(projects[:visibility_level].gt(namespaces[:visibility_level])) - .project(projects[:id], namespaces[:visibility_level]) - .take(BATCH_SIZE) - .to_sql + projects. + join(namespaces, Arel::Nodes::InnerJoin). + on(projects[:namespace_id].eq(namespaces[:id])). + where(projects[:visibility_level].gt(namespaces[:visibility_level])). + project(projects[:id], namespaces[:visibility_level]). + take(BATCH_SIZE). + to_sql # Update matching rows in batches. Each batch can cause up to 3 UPDATE # statements, in addition to the SELECT: one per visibility_level @@ -33,10 +33,10 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration end updates.each do |visibility_level, project_ids| - updater = Arel::UpdateManager.new(ActiveRecord::Base) - .table(projects) - .set(projects[:visibility_level] => visibility_level) - .where(projects[:id].in(project_ids)) + updater = Arel::UpdateManager.new(ActiveRecord::Base). + table(projects). + set(projects[:visibility_level] => visibility_level). + where(projects[:id].in(project_ids)) ActiveRecord::Base.connection.exec_update(updater.to_sql, self.class.name, []) end diff --git a/db/post_migrate/20161221153951_rename_reserved_project_names.rb b/db/post_migrate/20161221153951_rename_reserved_project_names.rb index d322844e2fd..49a6bc884a8 100644 --- a/db/post_migrate/20161221153951_rename_reserved_project_names.rb +++ b/db/post_migrate/20161221153951_rename_reserved_project_names.rb @@ -79,17 +79,17 @@ class RenameReservedProjectNames < ActiveRecord::Migration private def reserved_projects - Project.unscoped - .includes(:namespace) - .where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)') - .where('projects.path' => KNOWN_PATHS) + Project.unscoped. + includes(:namespace). + where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)'). + where('projects.path' => KNOWN_PATHS) end def route_exists?(full_path) quoted_path = ActiveRecord::Base.connection.quote_string(full_path) - ActiveRecord::Base.connection - .select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present? + ActiveRecord::Base.connection. + select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present? end # Adds number to the end of the path that is not taken by other route diff --git a/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb b/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb index d7be004d47f..f399950bd5e 100644 --- a/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb +++ b/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb @@ -39,11 +39,11 @@ class RequeuePendingDeleteProjects < ActiveRecord::Migration def find_batch projects = Arel::Table.new(:projects) - projects.project(projects[:id]) - .where(projects[:pending_delete].eq(true)) - .where(projects[:namespace_id].not_eq(nil)) - .skip(@offset * BATCH_SIZE) - .take(BATCH_SIZE) - .to_sql + projects.project(projects[:id]). + where(projects[:pending_delete].eq(true)). + where(projects[:namespace_id].not_eq(nil)). + skip(@offset * BATCH_SIZE). + take(BATCH_SIZE). + to_sql end end diff --git a/db/post_migrate/20170106142508_fill_authorized_projects.rb b/db/post_migrate/20170106142508_fill_authorized_projects.rb index 0ca20587981..314c8440c8b 100644 --- a/db/post_migrate/20170106142508_fill_authorized_projects.rb +++ b/db/post_migrate/20170106142508_fill_authorized_projects.rb @@ -15,8 +15,8 @@ class FillAuthorizedProjects < ActiveRecord::Migration disable_ddl_transaction! def up - relation = User.select(:id) - .where('authorized_projects_populated IS NOT TRUE') + relation = User.select(:id). + where('authorized_projects_populated IS NOT TRUE') relation.find_in_batches(batch_size: 1_000) do |rows| args = rows.map { |row| [row.id] } diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb index 4d4e442cb49..789f45489eb 100644 --- a/lib/api/access_requests.rb +++ b/lib/api/access_requests.rb @@ -68,8 +68,8 @@ module API delete ":id/access_requests/:user_id" do source = find_source(source_type, params[:id]) - ::Members::DestroyService.new(source, current_user, params) - .execute(:requesters) + ::Members::DestroyService.new(source, current_user, params). + execute(:requesters) end end end diff --git a/lib/api/branches.rb b/lib/api/branches.rb index 804fca9b0fb..c65de90cca2 100644 --- a/lib/api/branches.rb +++ b/lib/api/branches.rb @@ -102,8 +102,8 @@ module API end post ":id/repository/branches" do authorize_push_project - result = CreateBranchService.new(user_project, current_user) - .execute(params[:branch], params[:ref]) + result = CreateBranchService.new(user_project, current_user). + execute(params[:branch], params[:ref]) if result[:status] == :success present result[:branch], @@ -121,8 +121,8 @@ module API delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do authorize_push_project - result = DeleteBranchService.new(user_project, current_user) - .execute(params[:branch]) + result = DeleteBranchService.new(user_project, current_user). + execute(params[:branch]) if result[:status] == :success { diff --git a/lib/api/entities.rb b/lib/api/entities.rb index a9429262981..85aa6932f81 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -451,9 +451,9 @@ module API expose :tag_push_events, :note_events, :build_events, :pipeline_events # Expose serialized properties expose :properties do |service, options| - field_names = service.fields - .select { |field| options[:include_passwords] || field[:type] != 'password' } - .map { |field| field[:name] } + field_names = service.fields. + select { |field| options[:include_passwords] || field[:type] != 'password' }. + map { |field| field[:name] } service.properties.slice(*field_names) end end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 0515533b850..6d30c5d81b1 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -128,9 +128,9 @@ module API issue_params = declared_params(include_missing: false) if merge_request_iid = params[:merge_request_for_resolving_discussions] - issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id) - .execute - .find_by(iid: merge_request_iid) + issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id). + execute. + find_by(iid: merge_request_iid) end issue = ::Issues::CreateService.new(user_project, diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index bdd764abfeb..6a2476424a7 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -193,13 +193,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) else - ::MergeRequests::MergeService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) end present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project @@ -213,9 +213,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user) - .cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user). + cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/api/notes.rb b/lib/api/notes.rb index dc47aeafb82..f559a7f74a0 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -33,8 +33,8 @@ module API # paginate() only works with a relation. This could lead to a # mismatch between the pagination headers info and the actual notes # array returned, but this is really a edge-case. - paginate(noteable.notes) - .reject { |n| n.cross_reference_not_visible_for?(current_user) } + paginate(noteable.notes). + reject { |n| n.cross_reference_not_visible_for?(current_user) } present notes, with: Entities::Note else not_found!("Notes") diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index 3afc1e385fe..02e397a681c 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -36,8 +36,8 @@ module API new_pipeline = Ci::CreatePipelineService.new(user_project, current_user, - declared_params(include_missing: false)) - .execute(ignore_skip_ci: true, save_on_errors: false) + declared_params(include_missing: false)). + execute(ignore_skip_ci: true, save_on_errors: false) if new_pipeline.persisted? present new_pipeline, with: Entities::Pipeline else diff --git a/lib/api/tags.rb b/lib/api/tags.rb index 40d37e44db1..86759ab882f 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -44,8 +44,8 @@ module API post ':id/repository/tags' do authorize_push_project - result = ::Tags::CreateService.new(user_project, current_user) - .execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) + result = ::Tags::CreateService.new(user_project, current_user). + execute(params[:tag_name], params[:ref], params[:message], params[:release_description]) if result[:status] == :success present result[:tag], @@ -63,8 +63,8 @@ module API delete ":id/repository/tags/:tag_name", requirements: { tag_name: /.+/ } do authorize_push_project - result = ::Tags::DestroyService.new(user_project, current_user) - .execute(params[:tag_name]) + result = ::Tags::DestroyService.new(user_project, current_user). + execute(params[:tag_name]) if result[:status] == :success { @@ -85,8 +85,8 @@ module API post ':id/repository/tags/:tag_name/release', requirements: { tag_name: /.+/ } do authorize_push_project - result = CreateReleaseService.new(user_project, current_user) - .execute(params[:tag_name], params[:description]) + result = CreateReleaseService.new(user_project, current_user). + execute(params[:tag_name], params[:description]) if result[:status] == :success present result[:release], with: Entities::Release @@ -105,8 +105,8 @@ module API put ':id/repository/tags/:tag_name/release', requirements: { tag_name: /.+/ } do authorize_push_project - result = UpdateReleaseService.new(user_project, current_user) - .execute(params[:tag_name], params[:description]) + result = UpdateReleaseService.new(user_project, current_user). + execute(params[:tag_name], params[:description]) if result[:status] == :success present result[:release], with: Entities::Release diff --git a/lib/api/users.rb b/lib/api/users.rb index 9824f8c2ce6..94b2b6653d2 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -117,13 +117,13 @@ module API if user.save present user, with: Entities::UserPublic else - conflict!('Email has already been taken') if User - .where(email: user.email) - .count > 0 + conflict!('Email has already been taken') if User. + where(email: user.email). + count > 0 - conflict!('Username has already been taken') if User - .where(username: user.username) - .count > 0 + conflict!('Username has already been taken') if User. + where(username: user.username). + count > 0 render_validation_error!(user) end @@ -151,12 +151,12 @@ module API not_found!('User') unless user conflict!('Email has already been taken') if params[:email] && - User.where(email: params[:email]) - .where.not(id: user.id).count > 0 + User.where(email: params[:email]). + where.not(id: user.id).count > 0 conflict!('Username has already been taken') if params[:username] && - User.where(username: params[:username]) - .where.not(id: user.id).count > 0 + User.where(username: params[:username]). + where.not(id: user.id).count > 0 user_params = declared_params(include_missing: false) identity_attrs = user_params.slice(:provider, :extern_uid) @@ -354,11 +354,11 @@ module API user = User.find_by(id: params[:id]) not_found!('User') unless user - events = user.events - .merge(ProjectsFinder.new.execute(current_user)) - .references(:project) - .with_associations - .recent + events = user.events. + merge(ProjectsFinder.new.execute(current_user)). + references(:project). + with_associations. + recent present paginate(events), with: Entities::Event end diff --git a/lib/api/v3/issues.rb b/lib/api/v3/issues.rb index 264ad8d0da5..d0af09f0e1e 100644 --- a/lib/api/v3/issues.rb +++ b/lib/api/v3/issues.rb @@ -141,9 +141,9 @@ module API issue_params = declared_params(include_missing: false) if merge_request_iid = params[:merge_request_for_resolving_discussions] - issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id) - .execute - .find_by(iid: merge_request_iid) + issue_params[:merge_request_for_resolving_discussions] = MergeRequestsFinder.new(current_user, project_id: user_project.id). + execute. + find_by(iid: merge_request_iid) end issue = ::Issues::CreateService.new(user_project, diff --git a/lib/api/v3/merge_requests.rb b/lib/api/v3/merge_requests.rb index 129f9d850e9..5a8dacc9c44 100644 --- a/lib/api/v3/merge_requests.rb +++ b/lib/api/v3/merge_requests.rb @@ -200,13 +200,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) else - ::MergeRequests::MergeService - .new(merge_request.target_project, current_user, merge_params) - .execute(merge_request) + ::MergeRequests::MergeService. + new(merge_request.target_project, current_user, merge_params). + execute(merge_request) end present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project @@ -220,9 +220,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService - .new(merge_request.target_project, current_user) - .cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService. + new(merge_request.target_project, current_user). + cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/banzai/pipeline/wiki_pipeline.rb b/lib/banzai/pipeline/wiki_pipeline.rb index c37b8e71cb0..17b460608d7 100644 --- a/lib/banzai/pipeline/wiki_pipeline.rb +++ b/lib/banzai/pipeline/wiki_pipeline.rb @@ -3,8 +3,8 @@ module Banzai class WikiPipeline < FullPipeline def self.filters @filters ||= begin - super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter) - .insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) + super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter). + insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) end end end diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index 7e6357f8a00..c6426210a92 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -10,8 +10,8 @@ module Banzai end def references(type, project, current_user = nil) - processor = Banzai::ReferenceParser[type] - .new(project, current_user) + processor = Banzai::ReferenceParser[type]. + new(project, current_user) processor.process(html_documents) end @@ -28,8 +28,8 @@ module Banzai # text blobs to parse. return [] if @texts_and_contexts.empty? - @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts) - .map { |html| Nokogiri::HTML.fragment(html) } + @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts). + map { |html| Nokogiri::HTML.fragment(html) } end end end diff --git a/lib/banzai/reference_parser/issue_parser.rb b/lib/banzai/reference_parser/issue_parser.rb index 0ffaf79d9d8..6c20dec5734 100644 --- a/lib/banzai/reference_parser/issue_parser.rb +++ b/lib/banzai/reference_parser/issue_parser.rb @@ -9,8 +9,8 @@ module Banzai issues = issues_for_nodes(nodes) - readable_issues = Ability - .issues_readable_by_user(issues.values, user).to_set + readable_issues = Ability. + issues_readable_by_user(issues.values, user).to_set nodes.select do |node| readable_issues.include?(issue_for_node(issues, node)) diff --git a/lib/banzai/reference_parser/user_parser.rb b/lib/banzai/reference_parser/user_parser.rb index e0125fabcec..7adaffa19c1 100644 --- a/lib/banzai/reference_parser/user_parser.rb +++ b/lib/banzai/reference_parser/user_parser.rb @@ -99,8 +99,8 @@ module Banzai def find_users_for_projects(ids) return [] if ids.empty? - collection_objects_for_ids(Project, ids) - .flat_map { |p| p.team.members.to_a } + collection_objects_for_ids(Project, ids). + flat_map { |p| p.team.members.to_a } end def can_read_reference?(user, ref_project) diff --git a/lib/ci/charts.rb b/lib/ci/charts.rb index 6063d6f45e8..3decc3b1a26 100644 --- a/lib/ci/charts.rb +++ b/lib/ci/charts.rb @@ -2,10 +2,10 @@ module Ci module Charts module DailyInterval def grouped_count(query) - query - .group("DATE(#{Ci::Build.table_name}.created_at)") - .count(:created_at) - .transform_keys { |date| date.strftime(@format) } + query. + group("DATE(#{Ci::Build.table_name}.created_at)"). + count(:created_at). + transform_keys { |date| date.strftime(@format) } end def interval_step @@ -16,14 +16,14 @@ module Ci module MonthlyInterval def grouped_count(query) if Gitlab::Database.postgresql? - query - .group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')") - .count(:created_at) - .transform_keys(&:squish) + query. + group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')"). + count(:created_at). + transform_keys(&:squish) else - query - .group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')") - .count(:created_at) + query. + group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')"). + count(:created_at) end end @@ -46,8 +46,8 @@ module Ci end def collect - query = project.builds - .where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from) + query = project.builds. + where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from) totals_count = grouped_count(query) success_count = grouped_count(query.success) diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 649ee4d018b..04d9756657a 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -115,8 +115,8 @@ module Ci end def yaml_variables(name) - variables = (@variables || {}) - .merge(job_variables(name)) + variables = (@variables || {}). + merge(job_variables(name)) variables.map do |key, value| { key: key.to_s, value: value, public: true } diff --git a/lib/gitlab/badge/build/status.rb b/lib/gitlab/badge/build/status.rb index b762d85b6e5..3c65fd02e4c 100644 --- a/lib/gitlab/badge/build/status.rb +++ b/lib/gitlab/badge/build/status.rb @@ -19,9 +19,9 @@ module Gitlab end def status - @project.pipelines - .where(sha: @sha) - .latest_status(@ref) || 'unknown' + @project.pipelines. + where(sha: @sha). + latest_status(@ref) || 'unknown' end def metadata diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb index 9a0482306b7..8a6564755ab 100644 --- a/lib/gitlab/badge/coverage/report.rb +++ b/lib/gitlab/badge/coverage/report.rb @@ -42,9 +42,9 @@ module Gitlab if @job.blank? @pipeline.coverage else - @pipeline.builds - .find_by(name: @job) - .try(:coverage) + @pipeline.builds. + find_by(name: @job). + try(:coverage) end end end diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb index 44323b47dca..03a7981b1db 100644 --- a/lib/gitlab/bitbucket_import/importer.rb +++ b/lib/gitlab/bitbucket_import/importer.rb @@ -48,10 +48,10 @@ module Gitlab return users[username] if users.key?(username) - users[username] = User.select(:id) - .joins(:identities) - .find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username) - .try(:id) + users[username] = User.select(:id). + joins(:identities). + find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username). + try(:id) end def repo diff --git a/lib/gitlab/checks/matching_merge_request.rb b/lib/gitlab/checks/matching_merge_request.rb index 849848515da..bd295c25194 100644 --- a/lib/gitlab/checks/matching_merge_request.rb +++ b/lib/gitlab/checks/matching_merge_request.rb @@ -8,10 +8,10 @@ module Gitlab end def match? - @project.merge_requests - .with_state(:locked) - .where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name) - .exists? + @project.merge_requests. + with_state(:locked). + where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name). + exists? end end end diff --git a/lib/gitlab/ci/config/entry/configurable.rb b/lib/gitlab/ci/config/entry/configurable.rb index e05aca9881b..deaaf06bbd7 100644 --- a/lib/gitlab/ci/config/entry/configurable.rb +++ b/lib/gitlab/ci/config/entry/configurable.rb @@ -27,9 +27,9 @@ module Gitlab return unless valid? self.class.nodes.each do |key, factory| - factory - .value(@config[key]) - .with(key: key, parent: self) + factory. + value(@config[key]). + with(key: key, parent: self) @entries[key] = factory.create! end @@ -49,8 +49,8 @@ module Gitlab private # rubocop:disable Lint/UselessAccessModifier def entry(key, entry, metadata) - factory = Entry::Factory.new(entry) - .with(description: metadata[:description]) + factory = Entry::Factory.new(entry). + with(description: metadata[:description]) (@nodes ||= {}).merge!(key.to_sym => factory) end diff --git a/lib/gitlab/ci/config/entry/global.rb b/lib/gitlab/ci/config/entry/global.rb index a4ec8f0ff2f..0a404331225 100644 --- a/lib/gitlab/ci/config/entry/global.rb +++ b/lib/gitlab/ci/config/entry/global.rb @@ -46,10 +46,10 @@ module Gitlab private def compose_jobs! - factory = Entry::Factory.new(Entry::Jobs) - .value(@config.except(*self.class.nodes.keys)) - .with(key: :jobs, parent: self, - description: 'Jobs definition for this pipeline') + factory = Entry::Factory.new(Entry::Jobs). + value(@config.except(*self.class.nodes.keys)). + with(key: :jobs, parent: self, + description: 'Jobs definition for this pipeline') @entries[:jobs] = factory.create! end diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb index 5671a09480b..7b83f0f1b69 100644 --- a/lib/gitlab/ci/config/entry/jobs.rb +++ b/lib/gitlab/ci/config/entry/jobs.rb @@ -31,11 +31,11 @@ module Gitlab @config.each do |name, config| node = hidden?(name) ? Entry::Hidden : Entry::Job - factory = Entry::Factory.new(node) - .value(config || {}) - .metadata(name: name) - .with(key: name, parent: self, - description: "#{name} job definition.") + factory = Entry::Factory.new(node). + value(config || {}). + metadata(name: name). + with(key: name, parent: self, + description: "#{name} job definition.") @entries[name] = factory.create! end diff --git a/lib/gitlab/ci/pipeline_duration.rb b/lib/gitlab/ci/pipeline_duration.rb index 3208cc2bef6..a210e76acaa 100644 --- a/lib/gitlab/ci/pipeline_duration.rb +++ b/lib/gitlab/ci/pipeline_duration.rb @@ -87,8 +87,8 @@ module Gitlab def from_pipeline(pipeline) status = %w[success failed running canceled] - builds = pipeline.builds.latest - .where(status: status).where.not(started_at: nil).order(:started_at) + builds = pipeline.builds.latest. + where(status: status).where.not(started_at: nil).order(:started_at) from_builds(builds) end diff --git a/lib/gitlab/ci/status/factory.rb b/lib/gitlab/ci/status/factory.rb index 15836c699c7..efe756cc585 100644 --- a/lib/gitlab/ci/status/factory.rb +++ b/lib/gitlab/ci/status/factory.rb @@ -17,10 +17,10 @@ module Gitlab end def core_status - Gitlab::Ci::Status - .const_get(@status.capitalize) - .new(@subject, @user) - .extend(self.class.common_helpers) + Gitlab::Ci::Status. + const_get(@status.capitalize). + new(@subject, @user). + extend(self.class.common_helpers) end def compound_extended_status diff --git a/lib/gitlab/ci/trace_reader.rb b/lib/gitlab/ci/trace_reader.rb index 1d7ddeb3e0f..dd6a84d7d1c 100644 --- a/lib/gitlab/ci/trace_reader.rb +++ b/lib/gitlab/ci/trace_reader.rb @@ -41,8 +41,8 @@ module Gitlab chunks.unshift(buf) end - chunks.join.lines.last(max_lines).join - .force_encoding(Encoding.default_external) + chunks.join.lines.last(max_lines).join. + force_encoding(Encoding.default_external) end end end diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb index 5d271829f37..15992b77680 100644 --- a/lib/gitlab/contributions_calendar.rb +++ b/lib/gitlab/contributions_calendar.rb @@ -16,14 +16,14 @@ module Gitlab # Can't use Event.contributions here because we need to check 3 different # project_features for the (currently) 3 different contribution types date_from = 1.year.ago - repo_events = event_counts(date_from, :repository) - .having(action: Event::PUSHED) - issue_events = event_counts(date_from, :issues) - .having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue") - mr_events = event_counts(date_from, :merge_requests) - .having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest") - note_events = event_counts(date_from, :merge_requests) - .having(action: [Event::COMMENTED], target_type: "Note") + repo_events = event_counts(date_from, :repository). + having(action: Event::PUSHED) + issue_events = event_counts(date_from, :issues). + having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue") + mr_events = event_counts(date_from, :merge_requests). + having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest") + note_events = event_counts(date_from, :merge_requests). + having(action: [Event::COMMENTED], target_type: "Note") union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events, note_events]) events = Event.find_by_sql(union.to_sql).map(&:attributes) @@ -34,9 +34,9 @@ module Gitlab end def events_by_date(date) - events = Event.contributions.where(author_id: contributor.id) - .where(created_at: date.beginning_of_day..date.end_of_day) - .where(project_id: projects) + events = Event.contributions.where(author_id: contributor.id). + where(created_at: date.beginning_of_day..date.end_of_day). + where(project_id: projects) # Use visible_to_user? instead of the complicated logic in activity_dates # because we're only viewing the events for a single day. @@ -60,20 +60,20 @@ module Gitlab # use IN(project_ids...) instead. It's the intersection of two users so # the list will be (relatively) short @contributed_project_ids ||= projects.uniq.pluck(:id) - authed_projects = Project.where(id: @contributed_project_ids) - .with_feature_available_for_user(feature, current_user) - .reorder(nil) - .select(:id) + authed_projects = Project.where(id: @contributed_project_ids). + with_feature_available_for_user(feature, current_user). + reorder(nil). + select(:id) - conditions = t[:created_at].gteq(date_from.beginning_of_day) - .and(t[:created_at].lteq(Date.today.end_of_day)) - .and(t[:author_id].eq(contributor.id)) + conditions = t[:created_at].gteq(date_from.beginning_of_day). + and(t[:created_at].lteq(Date.today.end_of_day)). + and(t[:author_id].eq(contributor.id)) - Event.reorder(nil) - .select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount') - .group(t[:project_id], t[:target_type], t[:action], 'date(created_at)') - .where(conditions) - .having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql))) + Event.reorder(nil). + select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount'). + group(t[:project_id], t[:target_type], t[:action], 'date(created_at)'). + where(conditions). + having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql))) end end end diff --git a/lib/gitlab/cycle_analytics/base_query.rb b/lib/gitlab/cycle_analytics/base_query.rb index 58729d3ced8..d560dca45c8 100644 --- a/lib/gitlab/cycle_analytics/base_query.rb +++ b/lib/gitlab/cycle_analytics/base_query.rb @@ -12,17 +12,17 @@ module Gitlab end def stage_query - query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])) - .join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id])) - .where(issue_table[:project_id].eq(@project.id)) - .where(issue_table[:deleted_at].eq(nil)) - .where(issue_table[:created_at].gteq(@options[:from])) + query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])). + join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id])). + where(issue_table[:project_id].eq(@project.id)). + where(issue_table[:deleted_at].eq(nil)). + where(issue_table[:created_at].gteq(@options[:from])) # Load merge_requests - query = query.join(mr_table, Arel::Nodes::OuterJoin) - .on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id])) - .join(mr_metrics_table) - .on(mr_table[:id].eq(mr_metrics_table[:merge_request_id])) + query = query.join(mr_table, Arel::Nodes::OuterJoin). + on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id])). + join(mr_metrics_table). + on(mr_table[:id].eq(mr_metrics_table[:merge_request_id])) query end diff --git a/lib/gitlab/database/median.rb b/lib/gitlab/database/median.rb index 059054ac9ff..23890e5f493 100644 --- a/lib/gitlab/database/median.rb +++ b/lib/gitlab/database/median.rb @@ -29,10 +29,10 @@ module Gitlab end def mysql_median_datetime_sql(arel_table, query_so_far, column_sym) - query = arel_table - .from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name)) - .project(average([arel_table[column_sym]], 'median')) - .where( + query = arel_table. + from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name)). + project(average([arel_table[column_sym]], 'median')). + where( Arel::Nodes::Between.new( Arel.sql("(select @row_id := @row_id + 1)"), Arel::Nodes::And.new( @@ -67,8 +67,8 @@ module Gitlab cte_table = Arel::Table.new("ordered_records") cte = Arel::Nodes::As.new( cte_table, - arel_table - .project( + arel_table. + project( arel_table[column_sym].as(column_sym.to_s), Arel::Nodes::Over.new(Arel::Nodes::NamedFunction.new("row_number", []), Arel::Nodes::Window.new.order(arel_table[column_sym])).as('row_id'), @@ -79,8 +79,8 @@ module Gitlab # From the CTE, select either the middle row or the middle two rows (this is accomplished # by 'where cte.row_id between cte.ct / 2.0 AND cte.ct / 2.0 + 1'). Find the average of the # selected rows, and this is the median value. - cte_table.project(average([extract_epoch(cte_table[column_sym])], "median")) - .where( + cte_table.project(average([extract_epoch(cte_table[column_sym])], "median")). + where( Arel::Nodes::Between.new( cte_table[:row_id], Arel::Nodes::And.new( @@ -88,9 +88,9 @@ module Gitlab (cte_table[:ct] / Arel.sql('2.0') + 1)] ) ) - ) - .with(query_so_far, cte) - .to_sql + ). + with(query_so_far, cte). + to_sql end private diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 0c7c77f52e3..fc445ab9483 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -140,19 +140,19 @@ module Gitlab start_id = exec_query(start_arel.to_sql).to_hash.first['id'].to_i loop do - stop_arel = table.project(table[:id]) - .where(table[:id].gteq(start_id)) - .order(table[:id].asc) - .take(1) - .skip(batch_size) + stop_arel = table.project(table[:id]). + where(table[:id].gteq(start_id)). + order(table[:id].asc). + take(1). + skip(batch_size) stop_arel = yield table, stop_arel if block_given? stop_row = exec_query(stop_arel.to_sql).to_hash.first - update_arel = Arel::UpdateManager.new(ActiveRecord::Base) - .table(table) - .set([[table[column], value]]) - .where(table[:id].gteq(start_id)) + update_arel = Arel::UpdateManager.new(ActiveRecord::Base). + table(table). + set([[table[column], value]]). + where(table[:id].gteq(start_id)) if stop_row stop_id = stop_row['id'].to_i diff --git a/lib/gitlab/downtime_check.rb b/lib/gitlab/downtime_check.rb index 941244694e2..ab9537ed7d7 100644 --- a/lib/gitlab/downtime_check.rb +++ b/lib/gitlab/downtime_check.rb @@ -50,8 +50,8 @@ module Gitlab # Returns the class for the given migration file path. def class_for_migration_file(path) - File.basename(path, File.extname(path)).split('_', 2).last.camelize - .constantize + File.basename(path, File.extname(path)).split('_', 2).last.camelize. + constantize end # Returns true if the given migration can be performed without downtime. diff --git a/lib/gitlab/git/encoding_helper.rb b/lib/gitlab/git/encoding_helper.rb index e57d228e688..874fd8fe6e2 100644 --- a/lib/gitlab/git/encoding_helper.rb +++ b/lib/gitlab/git/encoding_helper.rb @@ -49,9 +49,9 @@ module Gitlab private def clean(message) - message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: "") - .encode("UTF-8") - .gsub("\0".encode("UTF-8"), "") + message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: ""). + encode("UTF-8"). + gsub("\0".encode("UTF-8"), "") end end end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index dc73cad93a5..a160869541a 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -178,9 +178,9 @@ module Gitlab def apply_labels(issuable, raw) return unless raw.labels.count > 0 - label_ids = raw.labels - .map { |attrs| @labels[attrs.name] } - .compact + label_ids = raw.labels. + map { |attrs| @labels[attrs.name] }. + compact issuable.update_attribute(:label_ids, label_ids) end diff --git a/lib/gitlab/github_import/user_formatter.rb b/lib/gitlab/github_import/user_formatter.rb index 04c2964da20..7f3bf0052a7 100644 --- a/lib/gitlab/github_import/user_formatter.rb +++ b/lib/gitlab/github_import/user_formatter.rb @@ -25,8 +25,8 @@ module Gitlab def find_by_email return nil unless email - User.find_by_any_email(email) - .try(:id) + User.find_by_any_email(email). + try(:id) end def find_by_external_uid @@ -34,11 +34,11 @@ module Gitlab identities = ::Identity.arel_table - User.select(:id) - .joins(:identities).where(identities[:provider].eq(:github) - .and(identities[:extern_uid].eq(id))) - .first - .try(:id) + User.select(:id). + joins(:identities).where(identities[:provider].eq(:github). + and(identities[:extern_uid].eq(id))). + first. + try(:id) end end end diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb index bfc57544485..9360afedfcb 100644 --- a/lib/gitlab/highlight.rb +++ b/lib/gitlab/highlight.rb @@ -1,8 +1,8 @@ module Gitlab class Highlight def self.highlight(blob_name, blob_content, repository: nil, plain: false) - new(blob_name, blob_content, repository: repository) - .highlight(blob_content, continue: false, plain: plain) + new(blob_name, blob_content, repository: repository). + highlight(blob_content, continue: false, plain: plain) end def self.highlight_lines(repository, ref, file_name) diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 8bf32f9e43f..b84c81f1a6c 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -12,9 +12,9 @@ module Gitlab class << self def find_by_uid_and_provider(uid, provider) # LDAP distinguished name is case-insensitive - identity = ::Identity - .where(provider: provider) - .iwhere(extern_uid: uid).last + identity = ::Identity. + where(provider: provider). + iwhere(extern_uid: uid).last identity && identity.user end end diff --git a/lib/gitlab/metrics.rb b/lib/gitlab/metrics.rb index c5b746a83a6..857e0abf710 100644 --- a/lib/gitlab/metrics.rb +++ b/lib/gitlab/metrics.rb @@ -145,8 +145,8 @@ module Gitlab host = settings[:host] port = settings[:port] - InfluxDB::Client - .new(udp: { host: host, port: port }) + InfluxDB::Client. + new(udp: { host: host, port: port }) end end diff --git a/lib/gitlab/metrics/system.rb b/lib/gitlab/metrics/system.rb index aba3e0df382..3aaebb3e9c3 100644 --- a/lib/gitlab/metrics/system.rb +++ b/lib/gitlab/metrics/system.rb @@ -34,13 +34,13 @@ module Gitlab # THREAD_CPUTIME is not supported on OS X if Process.const_defined?(:CLOCK_THREAD_CPUTIME_ID) def self.cpu_time - Process - .clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond) + Process. + clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond) end else def self.cpu_time - Process - .clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond) + Process. + clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond) end end diff --git a/lib/gitlab/other_markup.rb b/lib/gitlab/other_markup.rb index 7b0e9e4a7b4..e67acf28c94 100644 --- a/lib/gitlab/other_markup.rb +++ b/lib/gitlab/other_markup.rb @@ -12,8 +12,8 @@ module Gitlab # :ref # def self.render(file_name, input, context) - html = GitHub::Markup.render(file_name, input) - .force_encoding(input.encoding) + html = GitHub::Markup.render(file_name, input). + force_encoding(input.encoding) html = Banzai.post_process(html, context) diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 71e798424a5..7374d2bc8b8 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -30,8 +30,8 @@ module Gitlab end def version_required - @version_required ||= File.read(Rails.root - .join('GITLAB_SHELL_VERSION')).strip + @version_required ||= File.read(Rails.root. + join('GITLAB_SHELL_VERSION')).strip end def strip_key(key) diff --git a/lib/gitlab/sherlock/line_profiler.rb b/lib/gitlab/sherlock/line_profiler.rb index b5f9d040047..aa1468bff6b 100644 --- a/lib/gitlab/sherlock/line_profiler.rb +++ b/lib/gitlab/sherlock/line_profiler.rb @@ -77,8 +77,8 @@ module Gitlab line_samples << LineSample.new(duration, events) end - samples << FileSample - .new(file, line_samples, total_duration, total_events) + samples << FileSample. + new(file, line_samples, total_duration, total_events) end samples diff --git a/lib/gitlab/sherlock/query.rb b/lib/gitlab/sherlock/query.rb index 948bf5e6528..99e56e923eb 100644 --- a/lib/gitlab/sherlock/query.rb +++ b/lib/gitlab/sherlock/query.rb @@ -105,10 +105,10 @@ module Gitlab end def format_sql(query) - query.each_line - .map { |line| line.strip } - .join("\n") - .gsub(PREFIX_NEWLINE) { "\n#{$1} " } + query.each_line. + map { |line| line.strip }. + join("\n"). + gsub(PREFIX_NEWLINE) { "\n#{$1} " } end end end diff --git a/rubocop/cop/gem_fetcher.rb b/rubocop/cop/gem_fetcher.rb index e157d8e0791..6a951f5f91a 100644 --- a/rubocop/cop/gem_fetcher.rb +++ b/rubocop/cop/gem_fetcher.rb @@ -25,12 +25,12 @@ module RuboCop private def gemfile?(node) - node - .location - .expression - .source_buffer - .name - .end_with?("Gemfile") + node. + location. + expression. + source_buffer. + name. + end_with?("Gemfile") end end end diff --git a/rubocop/migration_helpers.rb b/rubocop/migration_helpers.rb index 35f1868fcc0..3160a784a04 100644 --- a/rubocop/migration_helpers.rb +++ b/rubocop/migration_helpers.rb @@ -3,8 +3,8 @@ module RuboCop module MigrationHelpers # Returns true if the given node originated from the db/migrate directory. def in_migration?(node) - File.dirname(node.location.expression.source_buffer.name) - .end_with?('db/migrate') + File.dirname(node.location.expression.source_buffer.name). + end_with?('db/migrate') end end end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 03f46f82874..2ab2ca1b667 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -105,8 +105,8 @@ describe Admin::UsersController do it 'displays an alert' do go - expect(flash[:notice]) - .to eq 'Two-factor Authentication has been disabled for this user' + expect(flash[:notice]). + to eq 'Two-factor Authentication has been disabled for this user' end def go diff --git a/spec/controllers/blob_controller_spec.rb b/spec/controllers/blob_controller_spec.rb index 45fbe09c9f7..2fcb4a6a528 100644 --- a/spec/controllers/blob_controller_spec.rb +++ b/spec/controllers/blob_controller_spec.rb @@ -59,8 +59,8 @@ describe Projects::BlobController do context 'redirect to tree' do let(:id) { 'markdown/doc' } it 'redirects' do - expect(subject) - .to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc") + expect(subject). + to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc") end end end diff --git a/spec/controllers/ci/projects_controller_spec.rb b/spec/controllers/ci/projects_controller_spec.rb index 86f01f437a2..3cd955dc9d4 100644 --- a/spec/controllers/ci/projects_controller_spec.rb +++ b/spec/controllers/ci/projects_controller_spec.rb @@ -33,8 +33,8 @@ describe Ci::ProjectsController do shared_examples 'badge provider' do it 'shows badge' do expect(response.status).to eq 200 - expect(response.headers) - .to include('Content-Type' => 'image/svg+xml') + expect(response.headers). + to include('Content-Type' => 'image/svg+xml') end end diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 66b45cf33c1..fa4cc0ebbe0 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -31,8 +31,8 @@ describe Import::BitbucketController do expires_at: expires_at, expires_in: expires_in, refresh_token: refresh_token) - allow_any_instance_of(OAuth2::Client) - .to receive(:get_token).and_return(access_token) + allow_any_instance_of(OAuth2::Client). + to receive(:get_token).and_return(access_token) stub_omniauth_provider('bitbucket') get :callback @@ -93,9 +93,9 @@ describe Import::BitbucketController do context "when the repository owner is the Bitbucket user" do context "when the Bitbucket user and GitLab user's usernames match" do it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -105,9 +105,9 @@ describe Import::BitbucketController do let(:bitbucket_username) { "someone_else" } it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -126,9 +126,9 @@ describe Import::BitbucketController do context "when the namespace is owned by the GitLab user" do it "takes the existing namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -141,8 +141,8 @@ describe Import::BitbucketController do end it "doesn't create a project" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .not_to receive(:new) + expect(Gitlab::BitbucketImport::ProjectCreator). + not_to receive(:new) post :create, format: :js end @@ -152,16 +152,16 @@ describe Import::BitbucketController do context "when a namespace with the Bitbucket user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.to change(Namespace, :count).by(1) end it "takes the new namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -173,16 +173,16 @@ describe Import::BitbucketController do end it "doesn't create the namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.not_to change(Namespace, :count) end it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator) - .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::BitbucketImport::ProjectCreator). + to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb index 45c3fa075ef..95696e14b6c 100644 --- a/spec/controllers/import/github_controller_spec.rb +++ b/spec/controllers/import/github_controller_spec.rb @@ -21,10 +21,10 @@ describe Import::GithubController do describe "GET callback" do it "updates access token" do token = "asdasd12345" - allow_any_instance_of(Gitlab::GithubImport::Client) - .to receive(:get_token).and_return(token) - allow_any_instance_of(Gitlab::GithubImport::Client) - .to receive(:github_options).and_return({}) + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:get_token).and_return(token) + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:github_options).and_return({}) stub_omniauth_provider('github') get :callback diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb index 3ef1bbaa9b7..3f73ea000ae 100644 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ b/spec/controllers/import/gitlab_controller_spec.rb @@ -18,8 +18,8 @@ describe Import::GitlabController do describe "GET callback" do it "updates access token" do - allow_any_instance_of(Gitlab::GitlabImport::Client) - .to receive(:get_token).and_return(token) + allow_any_instance_of(Gitlab::GitlabImport::Client). + to receive(:get_token).and_return(token) stub_omniauth_provider('gitlab') get :callback @@ -78,9 +78,9 @@ describe Import::GitlabController do context "when the repository owner is the GitLab.com user" do context "when the GitLab.com user and GitLab server user's usernames match" do it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).with(gitlab_repo, user.namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).with(gitlab_repo, user.namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -90,9 +90,9 @@ describe Import::GitlabController do let(:gitlab_username) { "someone_else" } it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).with(gitlab_repo, user.namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).with(gitlab_repo, user.namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -112,9 +112,9 @@ describe Import::GitlabController do context "when the namespace is owned by the GitLab server user" do it "takes the existing namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).with(gitlab_repo, existing_namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).with(gitlab_repo, existing_namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -127,8 +127,8 @@ describe Import::GitlabController do end it "doesn't create a project" do - expect(Gitlab::GitlabImport::ProjectCreator) - .not_to receive(:new) + expect(Gitlab::GitlabImport::ProjectCreator). + not_to receive(:new) post :create, format: :js end @@ -138,16 +138,16 @@ describe Import::GitlabController do context "when a namespace with the GitLab.com user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.to change(Namespace, :count).by(1) end it "takes the new namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params). + and_return(double(execute: true)) post :create, format: :js end @@ -159,16 +159,16 @@ describe Import::GitlabController do end it "doesn't create the namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.not_to change(Namespace, :count) end it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator) - .to receive(:new).with(gitlab_repo, user.namespace, user, access_params) - .and_return(double(execute: true)) + expect(Gitlab::GitlabImport::ProjectCreator). + to receive(:new).with(gitlab_repo, user.namespace, user, access_params). + and_return(double(execute: true)) post :create, format: :js end diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 6df654087dc..9de03876755 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -32,8 +32,8 @@ describe Projects::BranchesController do let(:branch) { "merge_branch" } let(:ref) { "master" } it 'redirects' do - expect(subject) - .to redirect_to("/#{project.path_with_namespace}/tree/merge_branch") + expect(subject). + to redirect_to("/#{project.path_with_namespace}/tree/merge_branch") end end @@ -41,8 +41,8 @@ describe Projects::BranchesController do let(:branch) { "" } let(:ref) { "master" } it 'redirects' do - expect(subject) - .to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") + expect(subject). + to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") end end @@ -81,8 +81,8 @@ describe Projects::BranchesController do branch_name: branch, issue_iid: issue.iid - expect(subject) - .to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch") + expect(subject). + to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch") end it 'posts a system note' do diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb index 1b5f6c4b43a..ebd2d0e092b 100644 --- a/spec/controllers/projects/commit_controller_spec.rb +++ b/spec/controllers/projects/commit_controller_spec.rb @@ -66,8 +66,8 @@ describe Projects::CommitController do end it "does not escape Html" do - allow_any_instance_of(Commit).to receive(:"to_#{format}") - .and_return('HTML entities &<>" ') + allow_any_instance_of(Commit).to receive(:"to_#{format}"). + and_return('HTML entities &<>" ') go(id: commit.id, format: format) diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 72a13d77a85..84d119f1867 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -150,14 +150,14 @@ describe Projects::EnvironmentsController do context 'and valid id' do it 'returns the first terminal for the environment' do - expect_any_instance_of(Environment) - .to receive(:terminals) - .and_return([:fake_terminal]) + expect_any_instance_of(Environment). + to receive(:terminals). + and_return([:fake_terminal]) - expect(Gitlab::Workhorse) - .to receive(:terminal_websocket) - .with(:fake_terminal) - .and_return(workhorse: :response) + expect(Gitlab::Workhorse). + to receive(:terminal_websocket). + with(:fake_terminal). + and_return(workhorse: :response) get :terminal_websocket_authorize, environment_params diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 85ad883534a..7871b6a9e10 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -226,8 +226,8 @@ describe Projects::IssuesController do it 'redirect to issue page' do update_verified_issue - expect(response) - .to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + expect(response). + to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) end it 'accepts an issue after recaptcha is verified' do @@ -241,8 +241,8 @@ describe Projects::IssuesController do it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do spam_log = create(:spam_log) - expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) } - .not_to change { SpamLog.last.recaptcha_verified } + expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) }. + not_to change { SpamLog.last.recaptcha_verified } end end end @@ -558,8 +558,8 @@ describe Projects::IssuesController do it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do spam_log = create(:spam_log) - expect { post_new_issue({}, { spam_log_id: spam_log.id, recaptcha_verification: true } ) } - .not_to change { SpamLog.last.recaptcha_verified } + expect { post_new_issue({}, { spam_log_id: spam_log.id, recaptcha_verification: true } ) }. + not_to change { SpamLog.last.recaptcha_verified } end end end diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb index a8c365a209f..cae733f0cfb 100644 --- a/spec/controllers/projects/mattermosts_controller_spec.rb +++ b/spec/controllers/projects/mattermosts_controller_spec.rb @@ -11,8 +11,8 @@ describe Projects::MattermostsController do describe 'GET #new' do before do - allow_any_instance_of(MattermostSlashCommandsService) - .to receive(:list_teams).and_return([]) + allow_any_instance_of(MattermostSlashCommandsService). + to receive(:list_teams).and_return([]) end it 'accepts the request' do diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index e6a8b9f6618..e631e5fa5e7 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -106,8 +106,8 @@ describe Projects::MergeRequestsController do end it "does not escape Html" do - allow_any_instance_of(MergeRequest).to receive(:"to_#{format}") - .and_return('HTML entities &<>" ') + allow_any_instance_of(MergeRequest).to receive(:"to_#{format}"). + and_return('HTML entities &<>" ') get(:show, namespace_id: project.namespace.to_param, @@ -335,9 +335,9 @@ describe Projects::MergeRequestsController do it 'sets the MR to merge when the build succeeds' do service = double(:merge_when_build_succeeds_service) - expect(MergeRequests::MergeWhenPipelineSucceedsService) - .to receive(:new).with(project, anything, anything) - .and_return(service) + expect(MergeRequests::MergeWhenPipelineSucceedsService). + to receive(:new).with(project, anything, anything). + and_return(service) expect(service).to receive(:execute).with(merge_request) merge_when_build_succeeds @@ -721,8 +721,8 @@ describe Projects::MergeRequestsController do describe 'GET conflicts' do context 'when the conflicts cannot be resolved in the UI' do before do - allow_any_instance_of(Gitlab::Conflict::Parser) - .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) + allow_any_instance_of(Gitlab::Conflict::Parser). + to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) get :conflicts, namespace_id: merge_request_with_conflicts.project.namespace.to_param, @@ -827,8 +827,8 @@ describe Projects::MergeRequestsController do context 'when the conflicts cannot be resolved in the UI' do before do - allow_any_instance_of(Gitlab::Conflict::Parser) - .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) + allow_any_instance_of(Gitlab::Conflict::Parser). + to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile) conflict_for_path('files/ruby/regex.rb') end @@ -1044,9 +1044,9 @@ describe Projects::MergeRequestsController do end it 'calls MergeRequests::AssignIssuesService' do - expect(MergeRequests::AssignIssuesService).to receive(:new) - .with(project, user, merge_request: merge_request) - .and_return(double(execute: { count: 1 })) + expect(MergeRequests::AssignIssuesService).to receive(:new). + with(project, user, merge_request: merge_request). + and_return(double(execute: { count: 1 })) post_assign_issues end diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb index 68fe29ce2d5..b23d6e257ba 100644 --- a/spec/controllers/projects/raw_controller_spec.rb +++ b/spec/controllers/projects/raw_controller_spec.rb @@ -15,8 +15,8 @@ describe Projects::RawController do expect(response).to have_http_status(200) expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8') - expect(response.header['Content-Disposition']) - .to eq("inline") + expect(response.header['Content-Disposition']). + to eq("inline") expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with("git-blob:") end end diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index 65e554aee49..8bab094a79e 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -89,21 +89,21 @@ describe Projects::SnippetsController do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) } - .to change { Snippet.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } - .not_to change { Snippet.count } + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } expect(response).to render_template(:new) end it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end it 'renders :new with recaptcha disabled' do @@ -169,8 +169,8 @@ describe Projects::SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'updates the snippet' do - expect { update_snippet(title: 'Foo') } - .to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') end end @@ -178,13 +178,13 @@ describe Projects::SnippetsController do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo') } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do @@ -223,13 +223,13 @@ describe Projects::SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb index 71193feaaaa..b81645a3d2d 100644 --- a/spec/controllers/projects/tree_controller_spec.rb +++ b/spec/controllers/projects/tree_controller_spec.rb @@ -82,8 +82,8 @@ describe Projects::TreeController do let(:id) { 'master/README.md' } it 'redirects' do redirect_url = "/#{project.path_with_namespace}/blob/master/README.md" - expect(subject) - .to redirect_to(redirect_url) + expect(subject). + to redirect_to(redirect_url) end end end @@ -106,8 +106,8 @@ describe Projects::TreeController do let(:target_branch) { 'master-test'} it 'redirects to the new directory' do - expect(subject) - .to redirect_to("/#{project.path_with_namespace}/tree/#{target_branch}/#{path}") + expect(subject). + to redirect_to("/#{project.path_with_namespace}/tree/#{target_branch}/#{path}") expect(flash[:notice]).to eq('The directory has been successfully created.') end end @@ -117,8 +117,8 @@ describe Projects::TreeController do let(:target_branch) { 'master'} it 'does not allow overwriting of existing files' do - expect(subject) - .to redirect_to("/#{project.path_with_namespace}/tree/master") + expect(subject). + to redirect_to("/#{project.path_with_namespace}/tree/master") expect(flash[:alert]).to eq('Directory already exists as a file') end end diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb index 6a437350248..954fc2eaf21 100644 --- a/spec/controllers/sent_notifications_controller_spec.rb +++ b/spec/controllers/sent_notifications_controller_spec.rb @@ -77,8 +77,8 @@ describe SentNotificationsController, type: :controller do end it 'redirects to the issue page' do - expect(response) - .to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + expect(response). + to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) end end @@ -100,8 +100,8 @@ describe SentNotificationsController, type: :controller do end it 'redirects to the merge request page' do - expect(response) - .to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request)) + expect(response). + to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request)) end end end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 42fd37f81d4..d951325f765 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -11,8 +11,8 @@ describe SessionsController do it 'does not authenticate user' do post(:create, user: { login: 'invalid', password: 'invalid' }) - expect(response) - .to set_flash.now[:alert].to /Invalid Login or password/ + expect(response). + to set_flash.now[:alert].to /Invalid Login or password/ end end @@ -42,8 +42,8 @@ describe SessionsController do context 'remember_me field' do it 'sets a remember_user_token cookie when enabled' do allow(controller).to receive(:find_user).and_return(user) - expect(controller) - .to receive(:remember_me).with(user).and_call_original + expect(controller). + to receive(:remember_me).with(user).and_call_original authenticate_2fa(remember_me: '1', otp_attempt: user.current_otp) @@ -102,8 +102,8 @@ describe SessionsController do end it 'warns about invalid OTP code' do - expect(response).to set_flash.now[:alert] - .to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert]. + to /Invalid two-factor code/ end end end @@ -129,8 +129,8 @@ describe SessionsController do end it 'warns about invalid login' do - expect(response).to set_flash.now[:alert] - .to /Invalid Login or password/ + expect(response).to set_flash.now[:alert]. + to /Invalid Login or password/ end it 'locks the user' do @@ -140,8 +140,8 @@ describe SessionsController do it 'keeps the user locked on future login attempts' do post(:create, user: { login: user.username, password: user.password }) - expect(response) - .to set_flash.now[:alert].to /Invalid Login or password/ + expect(response). + to set_flash.now[:alert].to /Invalid Login or password/ end end end @@ -153,8 +153,8 @@ describe SessionsController do authenticate_2fa(login: another_user.username, otp_attempt: 'invalid') - expect(response).to set_flash.now[:alert] - .to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert]. + to /Invalid two-factor code/ end end end @@ -177,8 +177,8 @@ describe SessionsController do it 'sets a remember_user_token cookie when enabled' do allow(U2fRegistration).to receive(:authenticate).and_return(true) allow(controller).to receive(:find_user).and_return(user) - expect(controller) - .to receive(:remember_me).with(user).and_call_original + expect(controller). + to receive(:remember_me).with(user).and_call_original authenticate_2fa_u2f(remember_me: '1', login: user.username, device_response: "{}") diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 6b52839fe2c..5de3b9890ef 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -156,20 +156,20 @@ describe SnippetsController do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(visibility_level: Snippet::PRIVATE) } - .to change { Snippet.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) } - .not_to change { Snippet.count } + expect { create_snippet(visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } end it 'creates a spam log' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end it 'renders :new with recaptcha disabled' do @@ -230,8 +230,8 @@ describe SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'updates the snippet' do - expect { update_snippet(title: 'Foo') } - .to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') end end @@ -239,13 +239,13 @@ describe SnippetsController do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do @@ -284,13 +284,13 @@ describe SnippetsController do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo') } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) end it 'renders :edit with recaptcha disabled' do diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 8df86435501..c80b09e9b9d 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -90,8 +90,8 @@ FactoryGirl.define do builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min - project.project_feature - .update_attributes!( + project.project_feature. + update_attributes!( wiki_access_level: evaluator.wiki_access_level, builds_access_level: builds_access_level, snippets_access_level: evaluator.snippets_access_level, diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index 7b82c3ae3d1..87a8f62687a 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -57,8 +57,8 @@ describe "Admin::Projects", feature: true do before do create(:group, name: 'Web') - allow_any_instance_of(Projects::TransferService) - .to receive(:move_uploads_to_new_namespace).and_return(true) + allow_any_instance_of(Projects::TransferService). + to receive(:move_uploads_to_new_namespace).and_return(true) end it 'transfers project to group web', js: true do diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 332abb121fc..c0807b8c507 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -77,10 +77,10 @@ describe "Admin::Users", feature: true do it "applies defaults to user" do click_button "Create user" user = User.find_by(username: 'bang') - expect(user.projects_limit) - .to eq(Gitlab.config.gitlab.default_projects_limit) - expect(user.can_create_group) - .to eq(Gitlab.config.gitlab.default_can_create_group) + expect(user.projects_limit). + to eq(Gitlab.config.gitlab.default_projects_limit) + expect(user.can_create_group). + to eq(Gitlab.config.gitlab.default_can_create_group) end it "creates user with valid data" do diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index 4ed06bb3a32..746df36bb25 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -28,8 +28,8 @@ describe "Dashboard Feed", feature: true do end it "has issue comment event" do - expect(body) - .to have_content("#{user.name} commented on issue ##{issue.iid}") + expect(body). + to have_content("#{user.name} commented on issue ##{issue.iid}") end end end diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index 6caaa703ae0..a01a050a013 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -17,8 +17,8 @@ describe 'Issues Feed', feature: true do login_with user visit namespace_project_issues_path(project.namespace, project, :atom) - expect(response_headers['Content-Type']) - .to have_content('application/atom+xml') + expect(response_headers['Content-Type']). + to have_content('application/atom+xml') expect(body).to have_selector('title', text: "#{project.name} issues") expect(body).to have_selector('author email', text: issue.author_email) expect(body).to have_selector('entry summary', text: issue.title) @@ -30,8 +30,8 @@ describe 'Issues Feed', feature: true do visit namespace_project_issues_path(project.namespace, project, :atom, private_token: user.private_token) - expect(response_headers['Content-Type']) - .to have_content('application/atom+xml') + expect(response_headers['Content-Type']). + to have_content('application/atom+xml') expect(body).to have_selector('title', text: "#{project.name} issues") expect(body).to have_selector('author email', text: issue.author_email) expect(body).to have_selector('entry summary', text: issue.title) diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index 9b569e83257..f8c3ccb416b 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -48,8 +48,8 @@ describe "User Feed", feature: true do end it 'has issue comment event' do - expect(body) - .to have_content("#{safe_name} commented on issue ##{issue.iid}") + expect(body). + to have_content("#{safe_name} commented on issue ##{issue.iid}") end it 'has XHTML summaries in issue descriptions' do diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index 78be7d36f47..513de297fdf 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -111,8 +111,8 @@ feature 'Environments page', :feature, :js do find('.js-dropdown-play-icon-container').click expect(page).to have_content(manual.name.humanize) - expect { click_link(manual.name.humanize) } - .not_to change { Ci::Pipeline.count } + expect { click_link(manual.name.humanize) }. + not_to change { Ci::Pipeline.count } expect(manual.reload).to be_pending end diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb index 45d21817824..84d73d693bc 100644 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ b/spec/features/gitlab_flavored_markdown_spec.rb @@ -11,8 +11,8 @@ describe "GitLab Flavored Markdown", feature: true do end before do - allow_any_instance_of(Commit).to receive(:title) - .and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details") + allow_any_instance_of(Commit).to receive(:title). + and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details") end let(:commit) { project.commit } diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb index d545d38424c..ae609160e18 100644 --- a/spec/features/login_spec.rb +++ b/spec/features/login_spec.rb @@ -110,8 +110,8 @@ feature 'Login', feature: true do end it 'invalidates the used code' do - expect { enter_code(codes.sample) } - .to change { user.reload.otp_backup_codes.size }.by(-1) + expect { enter_code(codes.sample) }. + to change { user.reload.otp_backup_codes.size }.by(-1) end end diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 75ade80012c..32159559c37 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -58,8 +58,8 @@ describe 'GitLab Markdown', feature: true do end it 'allows Markdown in tables' do - expect(doc.at_css('td:contains("Baz")').children.to_html) - .to eq 'Baz' + expect(doc.at_css('td:contains("Baz")').children.to_html). + to eq 'Baz' end it 'parses fenced code blocks' do @@ -150,14 +150,14 @@ describe 'GitLab Markdown', feature: true do describe 'Edge Cases' do it 'allows markup inside link elements' do aggregate_failures do - expect(doc.at_css('a[href="#link-emphasis"]').to_html) - .to eq %{text} + expect(doc.at_css('a[href="#link-emphasis"]').to_html). + to eq %{text} - expect(doc.at_css('a[href="#link-strong"]').to_html) - .to eq %{text} + expect(doc.at_css('a[href="#link-strong"]').to_html). + to eq %{text} - expect(doc.at_css('a[href="#link-code"]').to_html) - .to eq %{text} + expect(doc.at_css('a[href="#link-code"]').to_html). + to eq %{text} end end end diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index 73c5ef31edc..9fc5339308c 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -61,8 +61,8 @@ feature 'Merge request created from fork' do expect(page).to have_content pipeline.id end - expect(page.find('a.btn-remove')[:href]) - .to include fork_project.path_with_namespace + expect(page.find('a.btn-remove')[:href]). + to include fork_project.path_with_namespace end end diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb index bfb28e1de15..fab2d532e06 100644 --- a/spec/features/notes_on_merge_requests_spec.rb +++ b/spec/features/notes_on_merge_requests_spec.rb @@ -25,8 +25,8 @@ describe 'Comments', feature: true do describe 'the note form' do it 'is valid' do is_expected.to have_css('.js-main-target-form', visible: true, count: 1) - expect(find('.js-main-target-form input[type=submit]').value) - .to eq('Comment') + expect(find('.js-main-target-form input[type=submit]').value). + to eq('Comment') page.within('.js-main-target-form') do expect(page).not_to have_link('Cancel') end @@ -121,8 +121,8 @@ describe 'Comments', feature: true do page.within("#note_#{note.id}") do is_expected.to have_css('.note_edited_ago') - expect(find('.note_edited_ago').text) - .to match(/less than a minute ago/) + expect(find('.note_edited_ago').text). + to match(/less than a minute ago/) end end end @@ -201,8 +201,8 @@ describe 'Comments', feature: true do it "does not add a second form for same row" do click_diff_line - is_expected - .to have_css("form[data-line-code='#{line_code}']", + is_expected. + to have_css("form[data-line-code='#{line_code}']", count: 1) end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 592dc4483d2..81f5ebf6339 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -366,8 +366,8 @@ describe 'Pipelines', :feature, :js do before { stub_ci_pipeline_to_return_yaml_file } it 'creates a new pipeline' do - expect { click_on 'Create pipeline' } - .to change { Ci::Pipeline.count }.by(1) + expect { click_on 'Create pipeline' }. + to change { Ci::Pipeline.count }.by(1) end end diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb index 0c063f6d5ee..ed60a95deba 100644 --- a/spec/finders/environments_finder_spec.rb +++ b/spec/finders/environments_finder_spec.rb @@ -16,18 +16,18 @@ describe EnvironmentsFinder do end it 'returns environment when with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute). + to contain_exactly(environment) end it 'does not return environment when no with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). + to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). + to be_empty end end @@ -37,23 +37,23 @@ describe EnvironmentsFinder do end it 'returns environment when ref is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). + to contain_exactly(environment) end it 'does not environment when ref is different' do - expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute). + to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). + to be_empty end it 'returns environment when commit constraint is not set' do - expect(described_class.new(project, user, ref: 'master').execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master').execute). + to contain_exactly(environment) end end @@ -63,8 +63,8 @@ describe EnvironmentsFinder do end it 'returns environment' do - expect(described_class.new(project, user, commit: project.commit).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, commit: project.commit).execute). + to contain_exactly(environment) end end @@ -75,8 +75,8 @@ describe EnvironmentsFinder do end it 'finds recently updated environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) - .to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). + to contain_exactly(environment) end end @@ -87,8 +87,8 @@ describe EnvironmentsFinder do end it 'does not find environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) - .to be_empty + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). + to be_empty end end @@ -101,8 +101,8 @@ describe EnvironmentsFinder do end it 'finds both environments' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) - .to contain_exactly(environment, second_environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). + to contain_exactly(environment, second_environment) end end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index e96576b5d45..fd40fe99941 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -58,8 +58,8 @@ describe ApplicationHelper do project = create(:empty_project, avatar: File.open(uploaded_image_temp_path)) avatar_url = "http://#{Gitlab.config.gitlab.host}/uploads/project/avatar/#{project.id}/banana_sample.gif" - expect(helper.project_icon("#{project.namespace.to_param}/#{project.to_param}").to_s) - .to eq "\"Banana" + expect(helper.project_icon("#{project.namespace.to_param}/#{project.to_param}").to_s). + to eq "\"Banana" end it 'gives uploaded icon when present' do @@ -77,8 +77,8 @@ describe ApplicationHelper do it 'returns an url for the avatar' do user = create(:user, avatar: File.open(uploaded_image_temp_path)) - expect(helper.avatar_icon(user.email).to_s) - .to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") + expect(helper.avatar_icon(user.email).to_s). + to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") end it 'returns an url for the avatar with relative url' do @@ -88,8 +88,8 @@ describe ApplicationHelper do user = create(:user, avatar: File.open(uploaded_image_temp_path)) - expect(helper.avatar_icon(user.email).to_s) - .to match("/gitlab/uploads/user/avatar/#{user.id}/banana_sample.gif") + expect(helper.avatar_icon(user.email).to_s). + to match("/gitlab/uploads/user/avatar/#{user.id}/banana_sample.gif") end it 'calls gravatar_icon when no User exists with the given email' do @@ -102,8 +102,8 @@ describe ApplicationHelper do it 'returns an URL for the avatar' do user = create(:user, avatar: File.open(uploaded_image_temp_path)) - expect(helper.avatar_icon(user).to_s) - .to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") + expect(helper.avatar_icon(user).to_s). + to match("/uploads/user/avatar/#{user.id}/banana_sample.gif") end end end @@ -133,22 +133,22 @@ describe ApplicationHelper do it 'returns a valid Gravatar URL' do stub_config_setting(https: false) - expect(helper.gravatar_icon(user_email)) - .to match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118') + expect(helper.gravatar_icon(user_email)). + to match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118') end it 'uses HTTPs when configured' do stub_config_setting(https: true) - expect(helper.gravatar_icon(user_email)) - .to match('https://secure.gravatar.com') + expect(helper.gravatar_icon(user_email)). + to match('https://secure.gravatar.com') end it 'returns custom gravatar path when gravatar_url is set' do stub_gravatar_setting(plain_url: 'http://example.local/?s=%{size}&hash=%{hash}') - expect(gravatar_icon(user_email, 20)) - .to eq('http://example.local/?s=40&hash=b58c6f14d292556214bd64909bcdb118') + expect(gravatar_icon(user_email, 20)). + to eq('http://example.local/?s=40&hash=b58c6f14d292556214bd64909bcdb118') end it 'accepts a custom size argument' do @@ -220,8 +220,8 @@ describe ApplicationHelper do end it 'accepts a custom html_class' do - expect(element(html_class: 'custom_class').attr('class')) - .to eq 'js-timeago custom_class' + expect(element(html_class: 'custom_class').attr('class')). + to eq 'js-timeago custom_class' end it 'accepts a custom tooltip placement' do diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb index 9bec0f9f432..c6e3c5c2368 100644 --- a/spec/helpers/broadcast_messages_helper_spec.rb +++ b/spec/helpers/broadcast_messages_helper_spec.rb @@ -33,8 +33,8 @@ describe BroadcastMessagesHelper do it 'allows custom style' do broadcast_message = double(color: '#f2dede', font: '#b94a48') - expect(helper.broadcast_message_style(broadcast_message)) - .to match('background-color: #f2dede; color: #b94a48') + expect(helper.broadcast_message_style(broadcast_message)). + to match('background-color: #f2dede; color: #b94a48') end end diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb index c245bb439db..a2c008790f9 100644 --- a/spec/helpers/commits_helper_spec.rb +++ b/spec/helpers/commits_helper_spec.rb @@ -9,8 +9,8 @@ describe CommitsHelper do author_email: 'my@email.com" onmouseover="alert(1)' ) - expect(helper.commit_author_link(commit)) - .not_to include('onmouseover="alert(1)"') + expect(helper.commit_author_link(commit)). + not_to include('onmouseover="alert(1)"') end end @@ -22,8 +22,8 @@ describe CommitsHelper do committer_email: 'my@email.com" onmouseover="alert(1)' ) - expect(helper.commit_committer_link(commit)) - .not_to include('onmouseover="alert(1)"') + expect(helper.commit_committer_link(commit)). + not_to include('onmouseover="alert(1)"') end end diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb index 18cf0031d5f..b20373a96fb 100644 --- a/spec/helpers/form_helper_spec.rb +++ b/spec/helpers/form_helper_spec.rb @@ -11,18 +11,18 @@ describe FormHelper do it 'renders an alert div' do model = double(errors: errors_stub('Error 1')) - expect(helper.form_errors(model)) - .to include('
    ') + expect(helper.form_errors(model)). + to include('
    ') end it 'contains a summary message' do single_error = double(errors: errors_stub('A')) multi_errors = double(errors: errors_stub('A', 'B', 'C')) - expect(helper.form_errors(single_error)) - .to include('

    The form contains the following error:') - expect(helper.form_errors(multi_errors)) - .to include('

    The form contains the following errors:') + expect(helper.form_errors(single_error)). + to include('

    The form contains the following error:') + expect(helper.form_errors(multi_errors)). + to include('

    The form contains the following errors:') end it 'renders each message' do diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 7daf03bcc54..b8ec3521edb 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -70,8 +70,8 @@ describe GitlabMarkdownHelper do expect(doc.css('a')[0].text).to eq 'This should finally fix ' # First issue link - expect(doc.css('a')[1].attr('href')) - .to eq namespace_project_issue_path(project.namespace, project, issues[0]) + expect(doc.css('a')[1].attr('href')). + to eq namespace_project_issue_path(project.namespace, project, issues[0]) expect(doc.css('a')[1].text).to eq issues[0].to_reference # Internal commit link @@ -79,8 +79,8 @@ describe GitlabMarkdownHelper do expect(doc.css('a')[2].text).to eq ' and ' # Second issue link - expect(doc.css('a')[3].attr('href')) - .to eq namespace_project_issue_path(project.namespace, project, issues[1]) + expect(doc.css('a')[3].attr('href')). + to eq namespace_project_issue_path(project.namespace, project, issues[1]) expect(doc.css('a')[3].text).to eq issues[1].to_reference # Trailing commit link @@ -100,8 +100,8 @@ describe GitlabMarkdownHelper do it "escapes HTML passed in as the body" do actual = "This is a

    test

    - see #{issues[0].to_reference}" - expect(helper.link_to_gfm(actual, link)) - .to match('<h1>test</h1>') + expect(helper.link_to_gfm(actual, link)). + to match('<h1>test</h1>') end it 'ignores reference links when they are the entire body' do @@ -112,8 +112,8 @@ describe GitlabMarkdownHelper do it 'replaces commit message with emoji to link' do actual = link_to_gfm(':book:Book', '/foo') - expect(actual) - .to eq %Q(:book:Book) + expect(actual). + to eq %Q(:book:Book) end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index 531a54a9b8d..c8b0d86425f 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -8,8 +8,8 @@ describe GroupsHelper do group = create(:group) group.avatar = fixture_file_upload(avatar_file_path) group.save! - expect(group_icon(group.path).to_s) - .to match("/uploads/group/avatar/#{group.id}/banana_sample.gif") + expect(group_icon(group.path).to_s). + to match("/uploads/group/avatar/#{group.id}/banana_sample.gif") end it 'gives default avatar_icon when no avatar is present' do diff --git a/spec/helpers/import_helper_spec.rb b/spec/helpers/import_helper_spec.rb index 9afff47f4e9..10f293cddf5 100644 --- a/spec/helpers/import_helper_spec.rb +++ b/spec/helpers/import_helper_spec.rb @@ -29,21 +29,21 @@ describe ImportHelper do context 'when provider is "github"' do context 'when provider does not specify a custom URL' do it 'uses default GitHub URL' do - allow(Gitlab.config.omniauth).to receive(:providers) - .and_return([Settingslogic.new('name' => 'github')]) + allow(Gitlab.config.omniauth).to receive(:providers). + and_return([Settingslogic.new('name' => 'github')]) - expect(helper.provider_project_link('github', 'octocat/Hello-World')) - .to include('href="https://github.com/octocat/Hello-World"') + expect(helper.provider_project_link('github', 'octocat/Hello-World')). + to include('href="https://github.com/octocat/Hello-World"') end end context 'when provider specify a custom URL' do it 'uses custom URL' do - allow(Gitlab.config.omniauth).to receive(:providers) - .and_return([Settingslogic.new('name' => 'github', 'url' => 'https://github.company.com')]) + allow(Gitlab.config.omniauth).to receive(:providers). + and_return([Settingslogic.new('name' => 'github', 'url' => 'https://github.company.com')]) - expect(helper.provider_project_link('github', 'octocat/Hello-World')) - .to include('href="https://github.company.com/octocat/Hello-World"') + expect(helper.provider_project_link('github', 'octocat/Hello-World')). + to include('href="https://github.company.com/octocat/Hello-World"') end end end @@ -54,8 +54,8 @@ describe ImportHelper do end it 'uses given host' do - expect(helper.provider_project_link('gitea', 'octocat/Hello-World')) - .to include('href="https://try.gitea.io/octocat/Hello-World"') + expect(helper.provider_project_link('gitea', 'octocat/Hello-World')). + to include('href="https://try.gitea.io/octocat/Hello-World"') end end end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index f3bbb539d2b..93bb711f29a 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -23,23 +23,23 @@ describe IssuablesHelper do end it 'returns "Open" when state is :opened' do - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') end it 'returns "Closed" when state is :closed' do - expect(helper.issuables_state_counter_text(:issues, :closed)) - .to eq('Closed 42') + expect(helper.issuables_state_counter_text(:issues, :closed)). + to eq('Closed 42') end it 'returns "Merged" when state is :merged' do - expect(helper.issuables_state_counter_text(:merge_requests, :merged)) - .to eq('Merged 42') + expect(helper.issuables_state_counter_text(:merge_requests, :merged)). + to eq('Merged 42') end it 'returns "All" when state is :all' do - expect(helper.issuables_state_counter_text(:merge_requests, :all)) - .to eq('All 42') + expect(helper.issuables_state_counter_text(:merge_requests, :all)). + to eq('All 42') end end @@ -64,13 +64,13 @@ describe IssuablesHelper do expect(helper).to receive(:params).twice.and_return(params) expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42) - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') expect(helper).not_to receive(:issuables_count_for_state) - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') end it 'does not take some keys into account in the cache key' do @@ -83,8 +83,8 @@ describe IssuablesHelper do }.with_indifferent_access) expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42) - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') expect(helper).to receive(:params).and_return({ author_id: '11', @@ -95,22 +95,22 @@ describe IssuablesHelper do }.with_indifferent_access) expect(helper).not_to receive(:issuables_count_for_state) - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') end it 'does not take params order into account in the cache key' do expect(helper).to receive(:params).and_return('author_id' => '11', 'state' => 'opened') expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42) - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') expect(helper).to receive(:params).and_return('state' => 'opened', 'author_id' => '11') expect(helper).not_to receive(:issuables_count_for_state) - expect(helper.issuables_state_counter_text(:issues, :opened)) - .to eq('Open 42') + expect(helper.issuables_state_counter_text(:issues, :opened)). + to eq('Open 42') end end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index b61cebe6c8a..1204d5c9888 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -67,8 +67,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Joe') awards = Array.new(3, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)) - .to eq('Joe, Joe, and Joe') + expect(award_user_list(awards, nil, limit: 3)). + to eq('Joe, Joe, and Joe') end it "displays the current user's name as 'You'" do @@ -83,8 +83,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Jane') awards = Array.new(5, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)) - .to eq('Jane, Jane, Jane, and 2 more.') + expect(award_user_list(awards, nil, limit: 3)). + to eq('Jane, Jane, Jane, and 2 more.') end it "displays the current user in front of other users" do @@ -93,8 +93,8 @@ describe IssuesHelper do award = build_stubbed(:award_emoji, user: build_stubbed(:user, name: 'Jane')) awards = Array.new(5, award).push(my_award) - expect(award_user_list(awards, current_user, limit: 2)) - .to eq("You, Jane, and 4 more.") + expect(award_user_list(awards, current_user, limit: 2)). + to eq("You, Jane, and 4 more.") end end diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb index a8d6044fda7..7cf535fadae 100644 --- a/spec/helpers/labels_helper_spec.rb +++ b/spec/helpers/labels_helper_spec.rb @@ -55,8 +55,8 @@ describe LabelsHelper do context 'without block' do it 'uses render_colored_label as the link content' do - expect(self).to receive(:render_colored_label) - .with(label, tooltip: true).and_return('Foo') + expect(self).to receive(:render_colored_label). + with(label, tooltip: true).and_return('Foo') expect(link_to_label(label)).to match('Foo') end end diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index 67e839878c9..25f23826648 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -15,8 +15,8 @@ describe MergeRequestsHelper do end it 'does not include api credentials in a link' do - allow(ci_service) - .to receive(:build_page).and_return("http://secretuser:secretpass@jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c") + allow(ci_service). + to receive(:build_page).and_return("http://secretuser:secretpass@jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c") expect(helper.ci_build_details_path(merge_request)).not_to match("secret") end end diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index 9e18a1f88bf..9d7a39d3721 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -86,8 +86,8 @@ describe PageLayoutHelper do it 'raises ArgumentError when given more than two attributes' do map = { foo: 'foo', bar: 'bar', baz: 'baz' } - expect { helper.page_card_attributes(map) } - .to raise_error(ArgumentError, /more than two attributes/) + expect { helper.page_card_attributes(map) }. + to raise_error(ArgumentError, /more than two attributes/) end it 'rejects blank values' do @@ -111,8 +111,8 @@ describe PageLayoutHelper do end it 'escapes content' do - allow(helper).to receive(:page_card_attributes) - .and_return(foo: %q{foo" http-equiv="refresh}.html_safe) + allow(helper).to receive(:page_card_attributes). + and_return(foo: %q{foo" http-equiv="refresh}.html_safe) tags = helper.page_card_meta_tags diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb index 2575e8d8568..f3e79cc7290 100644 --- a/spec/helpers/preferences_helper_spec.rb +++ b/spec/helpers/preferences_helper_spec.rb @@ -29,15 +29,15 @@ describe PreferencesHelper do describe 'user_color_scheme' do context 'with a user' do it "returns user's scheme's css_class" do - allow(helper).to receive(:current_user) - .and_return(double(color_scheme_id: 3)) + allow(helper).to receive(:current_user). + and_return(double(color_scheme_id: 3)) expect(helper.user_color_scheme).to eq 'solarized-light' end it 'returns the default when id is invalid' do - allow(helper).to receive(:current_user) - .and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5)) + allow(helper).to receive(:current_user). + and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5)) end end @@ -45,8 +45,8 @@ describe PreferencesHelper do it 'returns the default theme' do stub_user - expect(helper.user_color_scheme) - .to eq Gitlab::ColorSchemes.default.css_class + expect(helper.user_color_scheme). + to eq Gitlab::ColorSchemes.default.css_class end end end @@ -55,8 +55,8 @@ describe PreferencesHelper do if messages.empty? allow(helper).to receive(:current_user).and_return(nil) else - allow(helper).to receive(:current_user) - .and_return(double('user', messages)) + allow(helper).to receive(:current_user). + and_return(double('user', messages)) end end diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index 8942b00b128..387279b2031 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -9,52 +9,52 @@ describe VisibilityLevelHelper do describe 'visibility_level_description' do context 'used with a Project' do it 'delegates projects to #project_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)) - .to match /project/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)). + to match /project/i end end context 'used with a Group' do it 'delegates groups to #group_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)) - .to match /group/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)). + to match /group/i end end context 'called with a Snippet' do it 'delegates snippets to #snippet_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)) - .to match /snippet/i + expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)). + to match /snippet/i end end end describe "#project_visibility_level_description" do it "describes private projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) - .to eq "Project access must be granted explicitly to each user." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). + to eq "Project access must be granted explicitly to each user." end it "describes public projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)) - .to eq "The project can be cloned without any authentication." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)). + to eq "The project can be cloned without any authentication." end end describe "#snippet_visibility_level_description" do it 'describes visibility only for me' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)) - .to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)). + to eq "The snippet is visible only to me." end it 'describes visibility for project members' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)) - .to eq "The snippet is visible only to project members." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)). + to eq "The snippet is visible only to project members." end it 'defaults to personal snippet' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) - .to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). + to eq "The snippet is visible only to me." end end diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb index 267318faed4..152c36a3ae6 100644 --- a/spec/lib/api/helpers/pagination_spec.rb +++ b/spec/lib/api/helpers/pagination_spec.rb @@ -37,8 +37,8 @@ describe API::Helpers::Pagination do describe 'first page' do before do - allow(subject).to receive(:params) - .and_return({ page: 1, per_page: 2 }) + allow(subject).to receive(:params). + and_return({ page: 1, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -60,8 +60,8 @@ describe API::Helpers::Pagination do describe 'second page' do before do - allow(subject).to receive(:params) - .and_return({ page: 2, per_page: 2 }) + allow(subject).to receive(:params). + and_return({ page: 2, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -87,8 +87,8 @@ describe API::Helpers::Pagination do end def expect_message(method) - expect(subject).to receive(method) - .at_least(:once).and_return(value) + expect(subject).to receive(method). + at_least(:once).and_return(value) end end end diff --git a/spec/lib/banzai/cross_project_reference_spec.rb b/spec/lib/banzai/cross_project_reference_spec.rb index 787212581e2..deaabceef1c 100644 --- a/spec/lib/banzai/cross_project_reference_spec.rb +++ b/spec/lib/banzai/cross_project_reference_spec.rb @@ -24,8 +24,8 @@ describe Banzai::CrossProjectReference, lib: true do it 'returns the referenced project' do project2 = double('referenced project') - expect(Project).to receive(:find_by_full_path) - .with('cross/reference').and_return(project2) + expect(Project).to receive(:find_by_full_path). + with('cross/reference').and_return(project2) expect(project_from_ref('cross/reference')).to eq project2 end diff --git a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb index fb614762a0d..27684882435 100644 --- a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb @@ -23,11 +23,11 @@ describe Banzai::Filter::AbstractReferenceFilter do doc = Nokogiri::HTML.fragment('') filter = described_class.new(doc, project: project) - expect(filter).to receive(:references_per_project) - .and_return({ project.path_with_namespace => Set.new(%w[1]) }) + expect(filter).to receive(:references_per_project). + and_return({ project.path_with_namespace => Set.new(%w[1]) }) - expect(filter.projects_per_reference) - .to eq({ project.path_with_namespace => project }) + expect(filter.projects_per_reference). + to eq({ project.path_with_namespace => project }) end end @@ -37,13 +37,13 @@ describe Banzai::Filter::AbstractReferenceFilter do context 'with RequestStore disabled' do it 'returns a list of Projects for a list of paths' do - expect(filter.find_projects_for_paths([project.path_with_namespace])) - .to eq([project]) + expect(filter.find_projects_for_paths([project.path_with_namespace])). + to eq([project]) end it "return an empty array for paths that don't exist" do - expect(filter.find_projects_for_paths(['nonexistent/project'])) - .to eq([]) + expect(filter.find_projects_for_paths(['nonexistent/project'])). + to eq([]) end end @@ -58,14 +58,14 @@ describe Banzai::Filter::AbstractReferenceFilter do end it 'returns a list of Projects for a list of paths' do - expect(filter.find_projects_for_paths([project.path_with_namespace])) - .to eq([project]) + expect(filter.find_projects_for_paths([project.path_with_namespace])). + to eq([project]) end context "when no project with that path exists" do it "returns no value" do - expect(filter.find_projects_for_paths(['nonexistent/project'])) - .to eq([]) + expect(filter.find_projects_for_paths(['nonexistent/project'])). + to eq([]) end it "adds the ref to the project refs cache" do @@ -84,8 +84,8 @@ describe Banzai::Filter::AbstractReferenceFilter do end it "return an empty array for paths that don't exist" do - expect(filter.find_projects_for_paths(['nonexistent/project'])) - .to eq([]) + expect(filter.find_projects_for_paths(['nonexistent/project'])). + to eq([]) end end end diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb index fc67c7ec3c4..deadc36524c 100644 --- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb @@ -28,15 +28,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid two-dot reference' do doc = reference_filter("See #{reference2}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param) end it 'links to a valid three-dot reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param) end it 'links to a valid short ID' do @@ -105,15 +105,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) end it 'link has valid text' do doc = reference_filter("Fixed (#{reference}.)") - expect(doc.css('a').first.text) - .to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}") + expect(doc.css('a').first.text). + to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}") end it 'has valid text' do @@ -140,15 +140,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) end it 'link has valid text' do doc = reference_filter("Fixed (#{reference}.)") - expect(doc.css('a').first.text) - .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") + expect(doc.css('a').first.text). + to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") end it 'has valid text' do @@ -175,15 +175,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) end it 'link has valid text' do doc = reference_filter("Fixed (#{reference}.)") - expect(doc.css('a').first.text) - .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") + expect(doc.css('a').first.text). + to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}") end it 'has valid text' do @@ -214,8 +214,8 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq reference + expect(doc.css('a').first.attr('href')). + to eq reference end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb index c4d8d3b6682..a19aac61229 100644 --- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb @@ -26,8 +26,8 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do doc = reference_filter("See #{reference[0...size]}") expect(doc.css('a').first.text).to eq commit.short_id - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_commit_url(project.namespace, project, reference) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_commit_url(project.namespace, project, reference) end end @@ -180,8 +180,8 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id) end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb index 5d625fe05bb..efd145e9452 100644 --- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb @@ -33,8 +33,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do doc = filter("Issue #{reference}") issue_id = doc.css('a').first.attr("data-external-issue") - expect(doc.css('a').first.attr('href')) - .to eq helper.url_for_issue(issue_id, project) + expect(doc.css('a').first.attr('href')). + to eq helper.url_for_issue(issue_id, project) end it 'links to the external tracker' do @@ -58,8 +58,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do end it 'escapes the title attribute' do - allow(project.external_issue_tracker).to receive(:title) - .and_return(%{">whateverwhatever project }) + expect(filter).to receive(:projects_per_reference). + and_return({ project.path_with_namespace => project }) - expect(filter).to receive(:references_per_project) - .and_return({ project.path_with_namespace => Set.new([issue.iid]) }) + expect(filter).to receive(:references_per_project). + and_return({ project.path_with_namespace => Set.new([issue.iid]) }) - expect(filter.issues_per_project) - .to eq({ project => { issue.iid => issue } }) + expect(filter.issues_per_project). + to eq({ project => { issue.iid => issue } }) end end @@ -335,14 +335,14 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do expect(project).to receive(:default_issues_tracker?).and_return(false) - expect(filter).to receive(:projects_per_reference) - .and_return({ project.path_with_namespace => project }) + expect(filter).to receive(:projects_per_reference). + and_return({ project.path_with_namespace => project }) - expect(filter).to receive(:references_per_project) - .and_return({ project.path_with_namespace => Set.new([1]) }) + expect(filter).to receive(:references_per_project). + and_return({ project.path_with_namespace => Set.new([1]) }) - expect(filter.issues_per_project[project][1]) - .to be_an_instance_of(ExternalIssue) + expect(filter.issues_per_project[project][1]). + to be_an_instance_of(ExternalIssue) end end end diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index cb3cf982351..5e16fd10ebe 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -72,8 +72,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) end it 'links with adjacent text' do @@ -95,8 +95,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See gfm' end @@ -119,8 +119,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See 2fa' end @@ -143,8 +143,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See ?g.fm&' end @@ -168,8 +168,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See gfm references' end @@ -192,8 +192,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See 2 factor authentication' end @@ -216,8 +216,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) expect(doc.text).to eq 'See g.fm & references?' end @@ -287,8 +287,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: label.name) end it 'links with adjacent text' do @@ -324,8 +324,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}", project: project) - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: group_label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: group_label.name) expect(doc.text).to eq 'See gfm references' end @@ -347,8 +347,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}", project: project) - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: group_label.name) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_issues_url(project.namespace, project, label_name: group_label.name) expect(doc.text).to eq "See gfm references" end @@ -372,8 +372,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -406,8 +406,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -440,15 +440,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')) - .to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')). + to match /background-color: #00ff00/ end it 'has valid link text' do @@ -476,25 +476,25 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(another_project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(another_project.namespace, another_project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')) - .to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')). + to match /background-color: #00ff00/ end it 'has valid link text' do - expect(result.css('a').first.text) - .to eq "#{group_label.name} in #{another_project.name_with_namespace}" + expect(result.css('a').first.text). + to eq "#{group_label.name} in #{another_project.name_with_namespace}" end it 'has valid text' do - expect(result.text) - .to eq "See #{group_label.name} in #{another_project.name_with_namespace}" + expect(result.text). + to eq "See #{group_label.name} in #{another_project.name_with_namespace}" end it 'ignores invalid IDs on the referenced label' do @@ -513,25 +513,25 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(another_project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(another_project.namespace, another_project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')) - .to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')). + to match /background-color: #00ff00/ end it 'has valid link text' do - expect(result.css('a').first.text) - .to eq "#{group_label.name} in #{another_project.name}" + expect(result.css('a').first.text). + to eq "#{group_label.name} in #{another_project.name}" end it 'has valid text' do - expect(result.text) - .to eq "See #{group_label.name} in #{another_project.name}" + expect(result.text). + to eq "See #{group_label.name} in #{another_project.name}" end it 'ignores invalid IDs on the referenced label' do @@ -549,15 +549,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')) - .to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')). + to match /background-color: #00ff00/ end it 'has valid link text' do @@ -583,15 +583,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')). + to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')) - .to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')). + to match /background-color: #00ff00/ end it 'has valid link text' do diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb index 0fc017788bd..3d3d36061f4 100644 --- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb @@ -23,8 +23,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_merge_request_url(project.namespace, project, merge) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_merge_request_url(project.namespace, project, merge) end it 'links with adjacent text' do @@ -94,8 +94,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_merge_request_url(project2.namespace, + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_merge_request_url(project2.namespace, project2, merge) end @@ -128,8 +128,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_merge_request_url(project2.namespace, + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_merge_request_url(project2.namespace, project2, merge) end @@ -162,8 +162,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_merge_request_url(project2.namespace, + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_merge_request_url(project2.namespace, project2, merge) end @@ -195,8 +195,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq reference + expect(doc.css('a').first.attr('href')). + to eq reference end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index fe88b9cb73e..a317c751d32 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -44,16 +44,16 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls - .namespace_project_milestone_path(project.namespace, project, milestone) + expect(link).to eq urls. + namespace_project_milestone_path(project.namespace, project, milestone) end context 'Integer-based references' do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(project.namespace, project, milestone) end it 'links with adjacent text' do @@ -75,8 +75,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(project.namespace, project, milestone) expect(doc.text).to eq 'See gfm' end @@ -99,8 +99,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(project.namespace, project, milestone) expect(doc.text).to eq 'See gfm references' end @@ -122,8 +122,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(project.namespace, project, milestone) end it 'links with adjacent text' do @@ -156,8 +156,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'points to referenced project milestone page' do - expect(result.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(another_project.namespace, + expect(result.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(another_project.namespace, another_project, milestone) end @@ -165,15 +165,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'link has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.css('a').first.text) - .to eq("#{milestone.name} in #{another_project.path_with_namespace}") + expect(doc.css('a').first.text). + to eq("#{milestone.name} in #{another_project.path_with_namespace}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.text) - .to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)") + expect(doc.text). + to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)") end it 'escapes the name attribute' do @@ -181,8 +181,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text) - .to eq "#{milestone.name} in #{another_project.path_with_namespace}" + expect(doc.css('a').first.text). + to eq "#{milestone.name} in #{another_project.path_with_namespace}" end end @@ -195,8 +195,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'points to referenced project milestone page' do - expect(result.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(another_project.namespace, + expect(result.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(another_project.namespace, another_project, milestone) end @@ -204,15 +204,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'link has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.css('a').first.text) - .to eq("#{milestone.name} in #{another_project.path}") + expect(doc.css('a').first.text). + to eq("#{milestone.name} in #{another_project.path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.text) - .to eq("See (#{milestone.name} in #{another_project.path}.)") + expect(doc.text). + to eq("See (#{milestone.name} in #{another_project.path}.)") end it 'escapes the name attribute' do @@ -220,8 +220,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text) - .to eq "#{milestone.name} in #{another_project.path}" + expect(doc.css('a').first.text). + to eq "#{milestone.name} in #{another_project.path}" end end @@ -234,8 +234,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'points to referenced project milestone page' do - expect(result.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(another_project.namespace, + expect(result.css('a').first.attr('href')).to eq urls. + namespace_project_milestone_url(another_project.namespace, another_project, milestone) end @@ -243,15 +243,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'link has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.css('a').first.text) - .to eq("#{milestone.name} in #{another_project.path}") + expect(doc.css('a').first.text). + to eq("#{milestone.name} in #{another_project.path}") end it 'has valid text' do doc = reference_filter("See (#{reference}.)") - expect(doc.text) - .to eq("See (#{milestone.name} in #{another_project.path}.)") + expect(doc.text). + to eq("See (#{milestone.name} in #{another_project.path}.)") end it 'escapes the name attribute' do @@ -259,8 +259,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.text) - .to eq "#{milestone.name} in #{another_project.path}" + expect(doc.css('a').first.text). + to eq "#{milestone.name} in #{another_project.path}" end end end diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb index 84bddda723a..0140a91c7ba 100644 --- a/spec/lib/banzai/filter/redactor_filter_spec.rb +++ b/spec/lib/banzai/filter/redactor_filter_spec.rb @@ -23,9 +23,9 @@ describe Banzai::Filter::RedactorFilter, lib: true do end before do - allow(Banzai::ReferenceParser).to receive(:[]) - .with('test') - .and_return(parser_class) + allow(Banzai::ReferenceParser).to receive(:[]). + with('test'). + and_return(parser_class) end context 'valid projects' do diff --git a/spec/lib/banzai/filter/reference_filter_spec.rb b/spec/lib/banzai/filter/reference_filter_spec.rb index ba0fa4a609a..55e681f6faf 100644 --- a/spec/lib/banzai/filter/reference_filter_spec.rb +++ b/spec/lib/banzai/filter/reference_filter_spec.rb @@ -8,8 +8,8 @@ describe Banzai::Filter::ReferenceFilter, lib: true do document = Nokogiri::HTML.fragment('foo') filter = described_class.new(document, project: project) - expect { |b| filter.each_node(&b) } - .to yield_with_args(an_instance_of(Nokogiri::XML::Element)) + expect { |b| filter.each_node(&b) }. + to yield_with_args(an_instance_of(Nokogiri::XML::Element)) end it 'returns an Enumerator when no block is given' do diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb index 1ce7bd7706e..1957ba739e2 100644 --- a/spec/lib/banzai/filter/relative_link_filter_spec.rb +++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb @@ -72,15 +72,15 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do it 'ignores ref if commit is passed' do doc = filter(link('non/existent.file'), commit: project.commit('empty-branch') ) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree end shared_examples :valid_repository do it 'rebuilds absolute URL for a file in the repo' do doc = filter(link('/doc/api/README.md')) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'ignores absolute URLs with two leading slashes' do @@ -90,71 +90,71 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do it 'rebuilds relative URL for a file in the repo' do doc = filter(link('doc/api/README.md')) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repo with leading ./' do doc = filter(link('./doc/api/README.md')) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repo up one directory' do relative_link = link('../api/README.md') doc = filter(relative_link, requested_path: 'doc/update/7.14-to-8.0.md') - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repo up multiple directories' do relative_link = link('../../../api/README.md') doc = filter(relative_link, requested_path: 'doc/foo/bar/baz/README.md') - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/doc/api/README.md" end it 'rebuilds relative URL for a file in the repository root' do relative_link = link('../README.md') doc = filter(relative_link, requested_path: 'doc/some-file.md') - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/README.md" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/README.md" end it 'rebuilds relative URL for a file in the repo with an anchor' do doc = filter(link('README.md#section')) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/blob/#{ref}/README.md#section" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/blob/#{ref}/README.md#section" end it 'rebuilds relative URL for a directory in the repo' do doc = filter(link('doc/api/')) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/tree/#{ref}/doc/api" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/tree/#{ref}/doc/api" end it 'rebuilds relative URL for an image in the repo' do doc = filter(image('files/images/logo-black.png')) - expect(doc.at_css('img')['src']) - .to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" + expect(doc.at_css('img')['src']). + to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" end it 'rebuilds relative URL for link to an image in the repo' do doc = filter(link('files/images/logo-black.png')) - expect(doc.at_css('a')['href']) - .to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" + expect(doc.at_css('a')['href']). + to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png" end it 'rebuilds relative URL for a video in the repo' do doc = filter(video('files/videos/intro.mp4'), commit: project.commit('video'), ref: 'video') - expect(doc.at_css('video')['src']) - .to eq "/#{project_path}/raw/video/files/videos/intro.mp4" + expect(doc.at_css('video')['src']). + to eq "/#{project_path}/raw/video/files/videos/intro.mp4" end it 'does not modify relative URL with an anchor only' do diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb index f2cff6861bc..b38e3b17e64 100644 --- a/spec/lib/banzai/filter/sanitization_filter_spec.rb +++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb @@ -194,8 +194,8 @@ describe Banzai::Filter::SanitizationFilter, lib: true do end it 'disallows invalid URIs' do - expect(Addressable::URI).to receive(:parse).with('foo://example.com') - .and_raise(Addressable::URI::InvalidURIError) + expect(Addressable::URI).to receive(:parse).with('foo://example.com'). + and_raise(Addressable::URI::InvalidURIError) input = 'Foo' output = filter(input) diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb index e851120bc3a..e036514d283 100644 --- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb @@ -22,8 +22,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_snippet_url(project.namespace, project, snippet) + expect(doc.css('a').first.attr('href')).to eq urls. + namespace_project_snippet_url(project.namespace, project, snippet) end it 'links with adjacent text' do @@ -88,8 +88,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'link has valid text' do @@ -121,8 +121,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'link has valid text' do @@ -154,8 +154,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'link has valid text' do @@ -186,8 +186,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do it 'links to a valid reference' do doc = reference_filter("See #{reference}") - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/upload_link_filter_spec.rb b/spec/lib/banzai/filter/upload_link_filter_spec.rb index 6327ca8bbfd..639cac6406a 100644 --- a/spec/lib/banzai/filter/upload_link_filter_spec.rb +++ b/spec/lib/banzai/filter/upload_link_filter_spec.rb @@ -51,22 +51,22 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do context 'with a valid repository' do it 'rebuilds relative URL for a link' do doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('a')['href']) - .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('a')['href']). + to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" doc = filter(nested_link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('a')['href']) - .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('a')['href']). + to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" end it 'rebuilds relative URL for an image' do doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('img')['src']) - .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('img')['src']). + to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" doc = filter(nested_image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) - expect(doc.at_css('img')['src']) - .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" + expect(doc.at_css('img')['src']). + to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" end it 'does not modify absolute URL' do @@ -79,10 +79,10 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do escaped = Addressable::URI.escape(path) # Stub these methods so the file doesn't actually need to be in the repo - allow_any_instance_of(described_class) - .to receive(:file_exists?).and_return(true) - allow_any_instance_of(described_class) - .to receive(:image?).with(path).and_return(true) + allow_any_instance_of(described_class). + to receive(:file_exists?).and_return(true) + allow_any_instance_of(described_class). + to receive(:image?).with(path).and_return(true) doc = filter(image(escaped)) expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png" diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index d5d128c1907..e9b7b566806 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -37,8 +37,8 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do doc = reference_filter("Hey #{reference}", author: user) expect(doc.css('a').length).to eq 1 - expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_url(project.namespace, project) + expect(doc.css('a').first.attr('href')). + to eq urls.namespace_project_url(project.namespace, project) end it 'includes a data-author attribute when there is an author' do diff --git a/spec/lib/banzai/note_renderer_spec.rb b/spec/lib/banzai/note_renderer_spec.rb index 32764bee5eb..49556074278 100644 --- a/spec/lib/banzai/note_renderer_spec.rb +++ b/spec/lib/banzai/note_renderer_spec.rb @@ -8,15 +8,15 @@ describe Banzai::NoteRenderer do wiki = double(:wiki) user = double(:user) - expect(Banzai::ObjectRenderer).to receive(:new) - .with(project, user, + expect(Banzai::ObjectRenderer).to receive(:new). + with(project, user, requested_path: 'foo', project_wiki: wiki, - ref: 'bar') - .and_call_original + ref: 'bar'). + and_call_original - expect_any_instance_of(Banzai::ObjectRenderer) - .to receive(:render).with([note], :note) + expect_any_instance_of(Banzai::ObjectRenderer). + to receive(:render).with([note], :note) described_class.render([note], project, user, 'foo', wiki, 'bar') end diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb index 2ce72a4c92e..6bcda87c999 100644 --- a/spec/lib/banzai/object_renderer_spec.rb +++ b/spec/lib/banzai/object_renderer_spec.rb @@ -17,12 +17,12 @@ describe Banzai::ObjectRenderer do renderer = described_class.new(project, user) object = fake_object(note: 'hello', note_html: nil) - expect(renderer).to receive(:render_objects).with([object], :note) - .and_call_original + expect(renderer).to receive(:render_objects).with([object], :note). + and_call_original - expect(renderer).to receive(:redact_documents) - .with(an_instance_of(Array)) - .and_call_original + expect(renderer).to receive(:redact_documents). + with(an_instance_of(Array)). + and_call_original expect(object).to receive(:redacted_note_html=).with('

    hello

    ') expect(object).to receive(:user_visible_reference_count=).with(0) @@ -37,8 +37,8 @@ describe Banzai::ObjectRenderer do renderer = described_class.new(project, user) - expect(renderer).to receive(:render_attributes).with([object], :note) - .and_call_original + expect(renderer).to receive(:render_attributes).with([object], :note). + and_call_original rendered = renderer.render_objects([object], :note) @@ -52,9 +52,9 @@ describe Banzai::ObjectRenderer do doc = Nokogiri::HTML.fragment('

    hello

    ') renderer = described_class.new(project, user) - expect_any_instance_of(Banzai::Redactor).to receive(:redact) - .with([doc]) - .and_call_original + expect_any_instance_of(Banzai::Redactor).to receive(:redact). + with([doc]). + and_call_original redacted = renderer.redact_documents([doc]) diff --git a/spec/lib/banzai/redactor_spec.rb b/spec/lib/banzai/redactor_spec.rb index a14a1405ca6..6d2c141e18b 100644 --- a/spec/lib/banzai/redactor_spec.rb +++ b/spec/lib/banzai/redactor_spec.rb @@ -12,11 +12,11 @@ describe Banzai::Redactor do end it 'redacts an array of documents' do - doc1 = Nokogiri::HTML - .fragment('foo') + doc1 = Nokogiri::HTML. + fragment('foo') - doc2 = Nokogiri::HTML - .fragment('bar') + doc2 = Nokogiri::HTML. + fragment('bar') redacted_data = redactor.redact([doc1, doc2]) @@ -68,9 +68,9 @@ describe Banzai::Redactor do doc = Nokogiri::HTML.fragment('foo') node = doc.children[0] - expect(redactor).to receive(:nodes_visible_to_user) - .with([node]) - .and_return(Set.new) + expect(redactor).to receive(:nodes_visible_to_user). + with([node]). + and_return(Set.new) redactor.redact_document_nodes([{ document: doc, nodes: [node] }]) @@ -83,10 +83,10 @@ describe Banzai::Redactor do doc = Nokogiri::HTML.fragment('') node = doc.children[0] - expect_any_instance_of(Banzai::ReferenceParser::IssueParser) - .to receive(:nodes_visible_to_user) - .with(user, [node]) - .and_return([node]) + expect_any_instance_of(Banzai::ReferenceParser::IssueParser). + to receive(:nodes_visible_to_user). + with(user, [node]). + and_return([node]) expect(redactor.nodes_visible_to_user([node])).to eq(Set.new([node])) end diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb index 9126afb0693..aa127f0179d 100644 --- a/spec/lib/banzai/reference_parser/base_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb @@ -54,8 +54,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do describe '#referenced_by' do context 'when references_relation is implemented' do it 'returns a collection of objects' do - links = Nokogiri::HTML.fragment("") - .children + links = Nokogiri::HTML.fragment(""). + children expect(subject).to receive(:references_relation).and_return(User) expect(subject.referenced_by(links)).to eq([user]) @@ -66,8 +66,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'raises NotImplementedError' do links = Nokogiri::HTML.fragment('').children - expect { subject.referenced_by(links) } - .to raise_error(NotImplementedError) + expect { subject.referenced_by(links) }. + to raise_error(NotImplementedError) end end end @@ -80,8 +80,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do describe '#gather_attributes_per_project' do it 'returns a Hash containing attribute values per project' do - link = Nokogiri::HTML.fragment('') - .children[0] + link = Nokogiri::HTML.fragment(''). + children[0] hash = subject.gather_attributes_per_project([link], 'data-foo') @@ -95,9 +95,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'returns a Hash grouping objects per ID' do nodes = [double(:node)] - expect(subject).to receive(:unique_attribute_values) - .with(nodes, 'data-user') - .and_return([user.id]) + expect(subject).to receive(:unique_attribute_values). + with(nodes, 'data-user'). + and_return([user.id]) hash = subject.grouped_objects_for_nodes(nodes, User, 'data-user') @@ -113,15 +113,15 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'returns an Array of unique values' do link = double(:link) - expect(link).to receive(:has_attribute?) - .with('data-foo') - .twice - .and_return(true) + expect(link).to receive(:has_attribute?). + with('data-foo'). + twice. + and_return(true) - expect(link).to receive(:attr) - .with('data-foo') - .twice - .and_return('1') + expect(link).to receive(:attr). + with('data-foo'). + twice. + and_return('1') nodes = [link, link] @@ -138,9 +138,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do instance = dummy.new(project, user) document = Nokogiri::HTML.fragment('') - expect(instance).to receive(:gather_references) - .with([document.children[1]]) - .and_return([user]) + expect(instance).to receive(:gather_references). + with([document.children[1]]). + and_return([user]) expect(instance.process([document])).to eq([user]) end @@ -150,9 +150,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do let(:link) { double(:link) } it 'does not process links a user can not reference' do - expect(subject).to receive(:nodes_user_can_reference) - .with(user, [link]) - .and_return([]) + expect(subject).to receive(:nodes_user_can_reference). + with(user, [link]). + and_return([]) expect(subject).to receive(:referenced_by).with([]) @@ -160,13 +160,13 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do end it 'does not process links a user can not see' do - expect(subject).to receive(:nodes_user_can_reference) - .with(user, [link]) - .and_return([link]) + expect(subject).to receive(:nodes_user_can_reference). + with(user, [link]). + and_return([link]) - expect(subject).to receive(:nodes_visible_to_user) - .with(user, [link]) - .and_return([]) + expect(subject).to receive(:nodes_visible_to_user). + with(user, [link]). + and_return([]) expect(subject).to receive(:referenced_by).with([]) @@ -174,13 +174,13 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do end it 'returns the references if a user can reference and see a link' do - expect(subject).to receive(:nodes_user_can_reference) - .with(user, [link]) - .and_return([link]) + expect(subject).to receive(:nodes_user_can_reference). + with(user, [link]). + and_return([link]) - expect(subject).to receive(:nodes_visible_to_user) - .with(user, [link]) - .and_return([link]) + expect(subject).to receive(:nodes_visible_to_user). + with(user, [link]). + and_return([link]) expect(subject).to receive(:referenced_by).with([link]) @@ -192,8 +192,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do it 'delegates the permissions check to the Ability class' do user = double(:user) - expect(Ability).to receive(:allowed?) - .with(user, :read_project, project) + expect(Ability).to receive(:allowed?). + with(user, :read_project, project) subject.can?(user, :read_project, project) end @@ -201,8 +201,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do describe '#find_projects_for_hash_keys' do it 'returns a list of Projects' do - expect(subject.find_projects_for_hash_keys(project.id => project)) - .to eq([project]) + expect(subject.find_projects_for_hash_keys(project.id => project)). + to eq([project]) end end @@ -214,8 +214,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do expect(collection).to receive(:where).twice.and_call_original 2.times do - expect(subject.collection_objects_for_ids(collection, [user.id])) - .to eq([user]) + expect(subject.collection_objects_for_ids(collection, [user.id])). + to eq([user]) end end end @@ -229,8 +229,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do end it 'queries the collection on the first call' do - expect(subject.collection_objects_for_ids(User, [user.id])) - .to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id])). + to eq([user]) end it 'does not query previously queried objects' do @@ -239,34 +239,34 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do expect(collection).to receive(:where).once.and_call_original 2.times do - expect(subject.collection_objects_for_ids(collection, [user.id])) - .to eq([user]) + expect(subject.collection_objects_for_ids(collection, [user.id])). + to eq([user]) end end it 'casts String based IDs to Fixnums before querying objects' do 2.times do - expect(subject.collection_objects_for_ids(User, [user.id.to_s])) - .to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id.to_s])). + to eq([user]) end end it 'queries any additional objects after the first call' do other_user = create(:user) - expect(subject.collection_objects_for_ids(User, [user.id])) - .to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id])). + to eq([user]) - expect(subject.collection_objects_for_ids(User, [user.id, other_user.id])) - .to eq([user, other_user]) + expect(subject.collection_objects_for_ids(User, [user.id, other_user.id])). + to eq([user, other_user]) end it 'caches objects on a per collection class basis' do - expect(subject.collection_objects_for_ids(User, [user.id])) - .to eq([user]) + expect(subject.collection_objects_for_ids(User, [user.id])). + to eq([user]) - expect(subject.collection_objects_for_ids(Project, [project.id])) - .to eq([project]) + expect(subject.collection_objects_for_ids(Project, [project.id])). + to eq([project]) end end end diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb index 9c2b2c0a1a9..412ffa77c36 100644 --- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb @@ -30,30 +30,30 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do it 'returns an Array of commits' do commit = double(:commit) - allow_any_instance_of(Project).to receive(:valid_repo?) - .and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?). + and_return(true) - expect(subject).to receive(:find_commits) - .with(project, ['123']) - .and_return([commit]) + expect(subject).to receive(:find_commits). + with(project, ['123']). + and_return([commit]) expect(subject.referenced_by([link])).to eq([commit]) end it 'returns an empty Array when the commit could not be found' do - allow_any_instance_of(Project).to receive(:valid_repo?) - .and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?). + and_return(true) - expect(subject).to receive(:find_commits) - .with(project, ['123']) - .and_return([]) + expect(subject).to receive(:find_commits). + with(project, ['123']). + and_return([]) expect(subject.referenced_by([link])).to eq([]) end it 'skips projects without valid repositories' do - allow_any_instance_of(Project).to receive(:valid_repo?) - .and_return(false) + allow_any_instance_of(Project).to receive(:valid_repo?). + and_return(false) expect(subject.referenced_by([link])).to eq([]) end @@ -61,8 +61,8 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do context 'when the link does not have a data-commit attribute' do it 'returns an empty Array' do - allow_any_instance_of(Project).to receive(:valid_repo?) - .and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?). + and_return(true) expect(subject.referenced_by([link])).to eq([]) end @@ -71,8 +71,8 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do context 'when the link does not have a data-project attribute' do it 'returns an empty Array' do - allow_any_instance_of(Project).to receive(:valid_repo?) - .and_return(true) + allow_any_instance_of(Project).to receive(:valid_repo?). + and_return(true) expect(subject.referenced_by([link])).to eq([]) end diff --git a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb index 5aec04e8d5b..96e55b0997a 100644 --- a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb @@ -30,17 +30,17 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do it 'returns an Array of commit ranges' do range = double(:range) - expect(subject).to receive(:find_object) - .with(project, '123..456') - .and_return(range) + expect(subject).to receive(:find_object). + with(project, '123..456'). + and_return(range) expect(subject.referenced_by([link])).to eq([range]) end it 'returns an empty Array when the commit range could not be found' do - expect(subject).to receive(:find_object) - .with(project, '123..456') - .and_return(nil) + expect(subject).to receive(:find_object). + with(project, '123..456'). + and_return(nil) expect(subject.referenced_by([link])).to eq([]) end @@ -86,17 +86,17 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do it 'returns an Array of range objects' do range = double(:commit) - expect(subject).to receive(:find_object) - .with(project, '123..456') - .and_return(range) + expect(subject).to receive(:find_object). + with(project, '123..456'). + and_return(range) expect(subject.find_ranges(project, ['123..456'])).to eq([range]) end it 'skips ranges that could not be found' do - expect(subject).to receive(:find_object) - .with(project, '123..456') - .and_return(nil) + expect(subject).to receive(:find_object). + with(project, '123..456'). + and_return(nil) expect(subject.find_ranges(project, ['123..456'])).to eq([]) end diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb index bc81d2808b5..6873b7b85f9 100644 --- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb @@ -18,17 +18,17 @@ describe Banzai::ReferenceParser::IssueParser, lib: true do it_behaves_like "referenced feature visibility", "issues" it 'returns the nodes when the user can read the issue' do - expect(Ability).to receive(:issues_readable_by_user) - .with([issue], user) - .and_return([issue]) + expect(Ability).to receive(:issues_readable_by_user). + with([issue], user). + and_return([issue]) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end it 'returns an empty Array when the user can not read the issue' do - expect(Ability).to receive(:issues_readable_by_user) - .with([issue], user) - .and_return([]) + expect(Ability).to receive(:issues_readable_by_user). + with([issue], user). + and_return([]) expect(subject.nodes_visible_to_user(user, [link])).to eq([]) end diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb index f2f11cd5088..31ca9d27b0b 100644 --- a/spec/lib/banzai/reference_parser/user_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb @@ -82,17 +82,17 @@ describe Banzai::ReferenceParser::UserParser, lib: true do end it 'returns the nodes if the user can read the group' do - expect(Ability).to receive(:allowed?) - .with(user, :read_group, group) - .and_return(true) + expect(Ability).to receive(:allowed?). + with(user, :read_group, group). + and_return(true) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end it 'returns an empty Array if the user can not read the group' do - expect(Ability).to receive(:allowed?) - .with(user, :read_group, group) - .and_return(false) + expect(Ability).to receive(:allowed?). + with(user, :read_group, group). + and_return(false) expect(subject.nodes_visible_to_user(user, [link])).to eq([]) end @@ -115,9 +115,9 @@ describe Banzai::ReferenceParser::UserParser, lib: true do link['data-project'] = other_project.id.to_s - expect(Ability).to receive(:allowed?) - .with(user, :read_project, other_project) - .and_return(true) + expect(Ability).to receive(:allowed?). + with(user, :read_project, other_project). + and_return(true) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end @@ -127,9 +127,9 @@ describe Banzai::ReferenceParser::UserParser, lib: true do link['data-project'] = other_project.id.to_s - expect(Ability).to receive(:allowed?) - .with(user, :read_project, other_project) - .and_return(false) + expect(Ability).to receive(:allowed?). + with(user, :read_project, other_project). + and_return(false) expect(subject.nodes_visible_to_user(user, [link])).to eq([]) end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 7145f0da1d3..ae3253777c3 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -25,8 +25,8 @@ module Ci end it 'includes coverage regexp in build attributes' do - expect(subject) - .to include(coverage_regex: 'Code coverage: \d+\.\d+') + expect(subject). + to include(coverage_regex: 'Code coverage: \d+\.\d+') end end end @@ -584,8 +584,8 @@ module Ci end it 'raises error' do - expect { subject } - .to raise_error(GitlabCiYamlProcessor::ValidationError, + expect { subject }. + to raise_error(GitlabCiYamlProcessor::ValidationError, /jobs:rspec:variables config should be a hash of key value pairs/) end end @@ -1365,8 +1365,8 @@ EOT it "returns an error about invalid configutaion" do content = YAML.dump("invalid: yaml: test") - expect(GitlabCiYamlProcessor.validation_message(content)) - .to eq "Invalid configuration format" + expect(GitlabCiYamlProcessor.validation_message(content)). + to eq "Invalid configuration format" end end @@ -1374,15 +1374,15 @@ EOT it "returns an error about invalid tags" do content = YAML.dump({ rspec: { script: "test", tags: "mysql" } }) - expect(GitlabCiYamlProcessor.validation_message(content)) - .to eq "jobs:rspec tags should be an array of strings" + expect(GitlabCiYamlProcessor.validation_message(content)). + to eq "jobs:rspec tags should be an array of strings" end end context "when YAML content is empty" do it "returns an error about missing content" do - expect(GitlabCiYamlProcessor.validation_message('')) - .to eq "Please provide content of .gitlab-ci.yml" + expect(GitlabCiYamlProcessor.validation_message('')). + to eq "Please provide content of .gitlab-ci.yml" end end diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb index 7fd2321d18a..bbacdc67ebd 100644 --- a/spec/lib/container_registry/blob_spec.rb +++ b/spec/lib/container_registry/blob_spec.rb @@ -51,8 +51,8 @@ describe ContainerRegistry::Blob do context '#delete' do before do - stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345') - .to_return(status: 200) + stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). + to_return(status: 200) end subject { blob.delete } @@ -67,8 +67,8 @@ describe ContainerRegistry::Blob do context 'when locally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345') - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). + to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: data) @@ -79,9 +79,9 @@ describe ContainerRegistry::Blob do context 'when externally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345') - .with(headers: { 'Authorization' => "bearer #{token}" }) - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). + with(headers: { 'Authorization' => "bearer #{token}" }). + to_return( status: 307, headers: { 'Location' => location }) end @@ -90,9 +90,9 @@ describe ContainerRegistry::Blob do let(:location) { 'http://external.com/blob/file' } before do - stub_request(:get, location) - .with(headers: { 'Authorization' => nil }) - .to_return( + stub_request(:get, location). + with(headers: { 'Authorization' => nil }). + to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: data) diff --git a/spec/lib/container_registry/repository_spec.rb b/spec/lib/container_registry/repository_spec.rb index eeb924ebe48..c364e759108 100644 --- a/spec/lib/container_registry/repository_spec.rb +++ b/spec/lib/container_registry/repository_spec.rb @@ -16,9 +16,9 @@ describe ContainerRegistry::Repository do context 'manifest processing' do before do - stub_request(:get, 'http://example.com/v2/group/test/tags/list') - .with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }) - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/tags/list'). + with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }). + to_return( status: 200, body: JSON.dump(tags: ['test']), headers: { 'Content-Type' => 'application/json' }) diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb index 2d7e355a737..c5e31ae82b6 100644 --- a/spec/lib/container_registry/tag_spec.rb +++ b/spec/lib/container_registry/tag_spec.rb @@ -19,9 +19,9 @@ describe ContainerRegistry::Tag do context 'manifest processing' do context 'schema v1' do before do - stub_request(:get, 'http://example.com/v2/group/test/manifests/tag') - .with(headers: headers) - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/manifests/tag'). + with(headers: headers). + to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest_1.json'), headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v1+prettyjws' }) @@ -56,9 +56,9 @@ describe ContainerRegistry::Tag do context 'schema v2' do before do - stub_request(:get, 'http://example.com/v2/group/test/manifests/tag') - .with(headers: headers) - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/manifests/tag'). + with(headers: headers). + to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest.json'), headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json' }) @@ -93,9 +93,9 @@ describe ContainerRegistry::Tag do context 'when locally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac') - .with(headers: { 'Accept' => 'application/octet-stream' }) - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac'). + with(headers: { 'Accept' => 'application/octet-stream' }). + to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json')) end @@ -105,14 +105,14 @@ describe ContainerRegistry::Tag do context 'when externally stored' do before do - stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac') - .with(headers: { 'Accept' => 'application/octet-stream' }) - .to_return( + stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac'). + with(headers: { 'Accept' => 'application/octet-stream' }). + to_return( status: 307, headers: { 'Location' => 'http://external.com/blob/file' }) - stub_request(:get, 'http://external.com/blob/file') - .to_return( + stub_request(:get, 'http://external.com/blob/file'). + to_return( status: 200, body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json')) end @@ -125,9 +125,9 @@ describe ContainerRegistry::Tag do context 'manifest digest' do before do - stub_request(:head, 'http://example.com/v2/group/test/manifests/tag') - .with(headers: headers) - .to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' }) + stub_request(:head, 'http://example.com/v2/group/test/manifests/tag'). + with(headers: headers). + to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' }) end context '#digest' do @@ -138,9 +138,9 @@ describe ContainerRegistry::Tag do context '#delete' do before do - stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest') - .with(headers: headers) - .to_return(status: 200) + stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest'). + with(headers: headers). + to_return(status: 200) end subject { tag.delete } diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb index 27f4a968321..33ab005667a 100644 --- a/spec/lib/extracts_path_spec.rb +++ b/spec/lib/extracts_path_spec.rb @@ -14,8 +14,8 @@ describe ExtractsPath, lib: true do repo = double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0', 'release/app', 'release/app/v1.0.0']) allow(project).to receive(:repository).and_return(repo) - allow(project).to receive(:path_with_namespace) - .and_return('gitlab/gitlab-ci') + allow(project).to receive(:path_with_namespace). + and_return('gitlab/gitlab-ci') allow(request).to receive(:format=) end diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index bca57105d1d..e193a3b79a6 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -19,8 +19,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS } - expect(Asciidoctor).to receive(:convert) - .with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert). + with(input, expected_asciidoc_opts).and_return(html) expect( render(input, context) ).to eql html end @@ -35,8 +35,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS + ['foo'] } - expect(Asciidoctor).to receive(:convert) - .with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert). + with(input, expected_asciidoc_opts).and_return(html) render(input, context, asciidoc_opts) end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index b234de4c772..57c416fb35a 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -140,8 +140,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) - .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). + to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end it 'falls through oauth authentication when the username is oauth2' do @@ -151,8 +151,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) - .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). + to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end end diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index f84782ab440..e9c69183d00 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -141,8 +141,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('No backups found')) + expect(progress).to have_received(:puts). + with(a_string_matching('No backups found')) end end @@ -158,8 +158,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('Found more than one backup')) + expect(progress).to have_received(:puts). + with(a_string_matching('Found more than one backup')) end end @@ -178,8 +178,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts) - .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress).to have_received(:puts). + with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) end end @@ -200,8 +200,8 @@ describe Backup::Manager, lib: true do it 'unpacks the file' do subject.unpack - expect(Kernel).to have_received(:system) - .with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") + expect(Kernel).to have_received(:system). + with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") expect(progress).to have_received(:puts).with(a_string_matching('done')) end end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb index 3c5414701a7..8a4bf4dc89b 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -20,8 +20,8 @@ describe Gitlab::Badge::Build::Status do describe '#metadata' do it 'returns badge metadata' do - expect(badge.metadata.image_url) - .to include 'badges/master/build.svg' + expect(badge.metadata.image_url). + to include 'badges/master/build.svg' end end diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb index aceb6bf871c..1da145e7b68 100644 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -86,11 +86,11 @@ describe Gitlab::BitbucketImport::Importer, lib: true do headers: { "Content-Type" => "application/json" }, body: issues_statuses_sample_data.to_json) - stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on") - .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }) - .to_return(status: 200, - body: "", - headers: {}) + stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on"). + with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }). + to_return(status: 200, + body: "", + headers: {}) sample_issues_statuses.each_with_index do |issue, index| stub_request( diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb index 6a52ae01b2f..eea01f91879 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb @@ -33,8 +33,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/').find_entries! } it 'matches correct paths' do - expect(subject.keys) - .to contain_exactly 'other_artifacts_0.1.2/', + expect(subject.keys). + to contain_exactly 'other_artifacts_0.1.2/', 'other_artifacts_0.1.2/doc_sample.txt', 'other_artifacts_0.1.2/another-subdirectory/' end @@ -44,8 +44,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/another-subdirectory/').find_entries! } it 'matches correct paths' do - expect(subject.keys) - .to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/', + expect(subject.keys). + to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/', 'other_artifacts_0.1.2/another-subdirectory/empty_directory/', 'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif' end @@ -55,8 +55,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do subject { metadata('other_artifacts_0.1.2/', recursive: true).find_entries! } it 'matches correct paths' do - expect(subject.keys) - .to contain_exactly 'other_artifacts_0.1.2/', + expect(subject.keys). + to contain_exactly 'other_artifacts_0.1.2/', 'other_artifacts_0.1.2/doc_sample.txt', 'other_artifacts_0.1.2/another-subdirectory/', 'other_artifacts_0.1.2/another-subdirectory/empty_directory/', diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb index 5c31423fdee..987a0b1f67f 100644 --- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb @@ -26,8 +26,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { name: 10 } } it 'reports error' do - expect(entry.errors) - .to include 'artifacts name should be a string' + expect(entry.errors). + to include 'artifacts name should be a string' end end @@ -35,8 +35,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { test: 100 } } it 'reports error' do - expect(entry.errors) - .to include 'artifacts config contains unknown keys: test' + expect(entry.errors). + to include 'artifacts config contains unknown keys: test' end end end diff --git a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb index fde03c51e2c..efb8c5adab1 100644 --- a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb @@ -14,9 +14,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is a hash' do before do - allow(instance) - .to receive(:config) - .and_return({ name: 'some name', test: 'some test' }) + allow(instance). + to receive(:config). + and_return({ name: 'some name', test: 'some test' }) end it 'returns the value of config' do @@ -31,9 +31,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is not a hash' do before do - allow(instance) - .to receive(:config) - .and_return('some test') + allow(instance). + to receive(:config). + and_return('some test') end it 'returns nil' do diff --git a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb index 5f067cad93c..8987c0549c5 100644 --- a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Boolean do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'boolean config should be a boolean value' + expect(entry.errors). + to include 'boolean config should be a boolean value' end end end diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index 70a327c5183..e91f049ee72 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -32,8 +32,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { 'ls' } it 'reports errors with config value' do - expect(entry.errors) - .to include 'cache config should be a hash' + expect(entry.errors). + to include 'cache config should be a hash' end end @@ -41,8 +41,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { key: 1 } } it 'reports error with descendants' do - expect(entry.errors) - .to include 'key config should be a string or symbol' + expect(entry.errors). + to include 'key config should be a string or symbol' end end @@ -50,8 +50,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { invalid: true } } it 'reports error with descendants' do - expect(entry.errors) - .to include 'cache config contains unknown keys: invalid' + expect(entry.errors). + to include 'cache config contains unknown keys: invalid' end end end diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb index afa4a089418..8fe82bc2ebd 100644 --- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb @@ -40,8 +40,8 @@ describe Gitlab::Ci::Config::Entry::Commands do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'commands config should be a ' \ + expect(entry.errors). + to include 'commands config should be a ' \ 'string or an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb index ae7e628b5b5..490ba9b7df1 100644 --- a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb @@ -52,8 +52,8 @@ describe Gitlab::Ci::Config::Entry::Configurable do end it 'creates a node factory' do - expect(entry.nodes[:object]) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Factory + expect(entry.nodes[:object]). + to be_an_instance_of Gitlab::Ci::Config::Entry::Factory end it 'returns a duplicated factory object' do diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb index 2adbed2154f..fab2825fbb0 100644 --- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb @@ -112,8 +112,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors) - .to include 'environment action should be start or stop' + expect(entry.errors). + to include 'environment action should be start or stop' end end end @@ -143,8 +143,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors) - .to include 'environment on stop should be a string' + expect(entry.errors). + to include 'environment on stop should be a string' end end end @@ -174,8 +174,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid type' do - expect(entry.errors) - .to include 'environment config should be a hash or a string' + expect(entry.errors). + to include 'environment config should be a hash or a string' end end end @@ -191,8 +191,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors?' do it 'contains error about missing environment name' do - expect(entry.errors) - .to include "environment name can't be blank" + expect(entry.errors). + to include "environment name can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/factory_spec.rb b/spec/lib/gitlab/ci/config/entry/factory_spec.rb index 3395b3c645b..5c5ce2d6f39 100644 --- a/spec/lib/gitlab/ci/config/entry/factory_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/factory_spec.rb @@ -7,19 +7,19 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting a concrete value' do it 'creates entry with valid value' do - entry = factory - .value(%w(ls pwd)) - .create! + entry = factory. + value(%w(ls pwd)). + create! expect(entry.value).to eq %w(ls pwd) end context 'when setting description' do it 'creates entry with description' do - entry = factory - .value(%w(ls pwd)) - .with(description: 'test description') - .create! + entry = factory. + value(%w(ls pwd)). + with(description: 'test description'). + create! expect(entry.value).to eq %w(ls pwd) expect(entry.description).to eq 'test description' @@ -28,10 +28,10 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting key' do it 'creates entry with custom key' do - entry = factory - .value(%w(ls pwd)) - .with(key: 'test key') - .create! + entry = factory. + value(%w(ls pwd)). + with(key: 'test key'). + create! expect(entry.key).to eq 'test key' end @@ -41,10 +41,10 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:object) { Object.new } it 'creates entry with valid parent' do - entry = factory - .value('ls') - .with(parent: object) - .create! + entry = factory. + value('ls'). + with(parent: object). + create! expect(entry.parent).to eq object end @@ -61,12 +61,12 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when creating entry with nil value' do it 'creates an undefined entry' do - entry = factory - .value(nil) - .create! + entry = factory. + value(nil). + create! - expect(entry) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(entry). + to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -74,13 +74,13 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:entry) { spy('entry') } it 'passes metadata as a parameter' do - factory - .value('some value') - .metadata(some: 'hash') - .create! + factory. + value('some value'). + metadata(some: 'hash'). + create! - expect(entry).to have_received(:new) - .with('some value', { some: 'hash' }) + expect(entry).to have_received(:new). + with('some value', { some: 'hash' }) end end end diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index ebd80ac5e1d..67a6b3cc98d 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -10,10 +10,10 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when filtering all the entry/node names' do it 'contains the expected node names' do - expect(described_class.nodes.keys) - .to match_array(%i[before_script image services - after_script variables stages - types cache]) + expect(described_class.nodes.keys). + to match_array(%i[before_script image services + after_script variables stages + types cache]) end end end @@ -44,17 +44,17 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'creates node object using valid class' do - expect(global.descendants.first) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Script - expect(global.descendants.second) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Image + expect(global.descendants.first). + to be_an_instance_of Gitlab::Ci::Config::Entry::Script + expect(global.descendants.second). + to be_an_instance_of Gitlab::Ci::Config::Entry::Image end it 'sets correct description for nodes' do - expect(global.descendants.first.description) - .to eq 'Script that will be executed before each job.' - expect(global.descendants.second.description) - .to eq 'Docker image that will be used to execute jobs.' + expect(global.descendants.first.description). + to eq 'Script that will be executed before each job.' + expect(global.descendants.second.description). + to eq 'Docker image that will be used to execute jobs.' end describe '#leaf?' do @@ -138,8 +138,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#cache_value' do it 'returns cache configuration' do - expect(global.cache_value) - .to eq(key: 'k', untracked: true, paths: ['public/']) + expect(global.cache_value). + to eq(key: 'k', untracked: true, paths: ['public/']) end end @@ -185,8 +185,8 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'contains unspecified nodes' do - expect(global.descendants.first) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(global.descendants.first). + to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -246,8 +246,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors from child nodes' do - expect(global.errors) - .to include 'before_script config should be an array of strings' + expect(global.errors). + to include 'before_script config should be an array of strings' end end @@ -265,8 +265,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors about missing script' do - expect(global.errors) - .to include "jobs:rspec script can't be blank" + expect(global.errors). + to include "jobs:rspec script can't be blank" end end end @@ -303,16 +303,16 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when entry exists' do it 'returns correct entry' do - expect(global[:cache]) - .to be_an_instance_of Gitlab::Ci::Config::Entry::Cache + expect(global[:cache]). + to be_an_instance_of Gitlab::Ci::Config::Entry::Cache expect(global[:jobs][:rspec][:script].value).to eq ['ls'] end end context 'when entry does not exist' do it 'always return unspecified node' do - expect(global[:some][:unknown][:node]) - .not_to be_specified + expect(global[:some][:unknown][:node]). + not_to be_specified end end end diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb index 3c99cb0a1ee..062817e07fd 100644 --- a/spec/lib/gitlab/ci/config/entry/image_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Image do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'image config should be a string' + expect(entry.errors). + to include 'image config should be a string' end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index d20f4ec207d..82feff0af1c 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -44,8 +44,8 @@ describe Gitlab::Ci::Config::Entry::Job do describe '#errors' do it 'reports error about a config type' do - expect(entry.errors) - .to include 'job config should be a hash' + expect(entry.errors). + to include 'job config should be a hash' end end end @@ -138,13 +138,13 @@ describe Gitlab::Ci::Config::Entry::Job do end it 'returns correct value' do - expect(entry.value) - .to eq(name: :rspec, - before_script: %w[ls pwd], - script: %w[rspec], - commands: "ls\npwd\nrspec", - stage: 'test', - after_script: %w[cleanup]) + expect(entry.value). + to eq(name: :rspec, + before_script: %w[ls pwd], + script: %w[rspec], + commands: "ls\npwd\nrspec", + stage: 'test', + after_script: %w[cleanup]) end end end diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index aaebf783962..c332b70dc71 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -22,8 +22,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { ['incorrect'] } it 'returns error about incorrect type' do - expect(entry.errors) - .to include 'jobs config should be a hash' + expect(entry.errors). + to include 'jobs config should be a hash' end end @@ -39,8 +39,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { { '.hidden'.to_sym => { script: [] } } } it 'returns error about no visible jobs defined' do - expect(entry.errors) - .to include 'jobs config should contain at least one visible job' + expect(entry.errors). + to include 'jobs config should contain at least one visible job' end end end @@ -73,10 +73,10 @@ describe Gitlab::Ci::Config::Entry::Jobs do describe '#descendants' do it 'creates valid descendant nodes' do expect(entry.descendants.count).to eq 3 - expect(entry.descendants.first(2)) - .to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) - expect(entry.descendants.last) - .to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) + expect(entry.descendants.first(2)). + to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) + expect(entry.descendants.last). + to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) end end diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb index 0dd36fe1f44..cd7b03ffb11 100644 --- a/spec/lib/gitlab/ci/config/entry/key_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Key do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'key config should be a string or symbol' + expect(entry.errors). + to include 'key config should be a string or symbol' end end end diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb index 1d9c5ddee9b..b0ac90f1d94 100644 --- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Paths do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'paths config should be an array of strings' + expect(entry.errors). + to include 'paths config should be an array of strings' end end end diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb index 069eaa26422..49cca49509c 100644 --- a/spec/lib/gitlab/ci/config/entry/script_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Script do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'script config should be an array of strings' + expect(entry.errors). + to include 'script config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb index 66fad3b6b16..c31a7c0ec3e 100644 --- a/spec/lib/gitlab/ci/config/entry/services_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Services do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'services config should be an array of strings' + expect(entry.errors). + to include 'services config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/stage_spec.rb b/spec/lib/gitlab/ci/config/entry/stage_spec.rb index 70c8a0a355a..cefef7a805a 100644 --- a/spec/lib/gitlab/ci/config/entry/stage_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stage_spec.rb @@ -24,8 +24,8 @@ describe Gitlab::Ci::Config::Entry::Stage do let(:config) { { test: true } } it 'reports errors about wrong type' do - expect(stage.errors) - .to include 'stage config should be a string' + expect(stage.errors). + to include 'stage config should be a string' end end end diff --git a/spec/lib/gitlab/ci/config/entry/stages_spec.rb b/spec/lib/gitlab/ci/config/entry/stages_spec.rb index 182c8d867c7..bdcd6c98a85 100644 --- a/spec/lib/gitlab/ci/config/entry/stages_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stages_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Stages do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'stages config should be an array of strings' + expect(entry.errors). + to include 'stages config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb index e4ee44f1274..13b00a98b6a 100644 --- a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Trigger do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include 'trigger config should be an array of strings or regexps' + expect(entry.errors). + to include 'trigger config should be an array of strings or regexps' end end end diff --git a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb index d1856801827..e31e85538b9 100644 --- a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb @@ -19,8 +19,8 @@ describe Gitlab::Ci::Config::Entry::Validatable do end it 'returns validator' do - expect(entry.validator.superclass) - .to be Gitlab::Ci::Config::Entry::Validator + expect(entry.validator.superclass). + to be Gitlab::Ci::Config::Entry::Validator end it 'returns only one validator to mitigate leaks' do diff --git a/spec/lib/gitlab/ci/config/entry/validator_spec.rb b/spec/lib/gitlab/ci/config/entry/validator_spec.rb index ad7e6f07d3c..c6e21cd67b0 100644 --- a/spec/lib/gitlab/ci/config/entry/validator_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validator_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Validator do it 'returns errors' do validator_instance.validate - expect(validator_instance.messages) - .to include "node test attribute can't be blank" + expect(validator_instance.messages). + to include "node test attribute can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index f15f02f403e..c117f35c906 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -33,8 +33,8 @@ describe Gitlab::Ci::Config::Entry::Variables do describe '#errors' do it 'saves errors' do - expect(entry.errors) - .to include /should be a hash of key value pairs/ + expect(entry.errors). + to include /should be a hash of key value pairs/ end end diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index 40b96b1807b..cd893a09748 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Build::Common do let(:project) { build.project } subject do - Gitlab::Ci::Status::Core - .new(build, user) - .extend(described_class) + Gitlab::Ci::Status::Core. + new(build, user). + extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index 0c40fca0c1a..aa026a66460 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -16,8 +16,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -42,8 +42,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -67,9 +67,9 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable, - Gitlab::Ci::Status::Build::FailedAllowed] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable, + Gitlab::Ci::Status::Build::FailedAllowed] end it 'fabricates a failed but allowed build status' do @@ -96,8 +96,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -121,8 +121,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a canceable build status' do @@ -146,8 +146,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a cancelable build status' do @@ -196,8 +196,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Play] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Play] end it 'fabricates a core skipped status' do @@ -222,8 +222,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::Build::Stop] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::Build::Stop] end it 'fabricates a core skipped status' do diff --git a/spec/lib/gitlab/ci/status/extended_spec.rb b/spec/lib/gitlab/ci/status/extended_spec.rb index c2d74ca5cde..459044eb968 100644 --- a/spec/lib/gitlab/ci/status/extended_spec.rb +++ b/spec/lib/gitlab/ci/status/extended_spec.rb @@ -6,7 +6,7 @@ describe Gitlab::Ci::Status::Extended do end it 'requires subclass to implement matcher' do - expect { subject.matches?(double, double) } - .to raise_error(NotImplementedError) + expect { subject.matches?(double, double) }. + to raise_error(NotImplementedError) end end diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index 5a97d98b55f..6a564eeb8b7 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -10,9 +10,9 @@ describe Gitlab::Ci::Status::External::Common do end subject do - Gitlab::Ci::Status::Core - .new(external_status, user) - .extend(described_class) + Gitlab::Ci::Status::Core. + new(external_status, user). + extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/factory_spec.rb b/spec/lib/gitlab/ci/status/factory_spec.rb index bbf9c7c83a3..45fd49b91ea 100644 --- a/spec/lib/gitlab/ci/status/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/factory_spec.rb @@ -84,15 +84,15 @@ describe Gitlab::Ci::Status::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [first_extended_status, second_extended_status] + expect(factory.extended_statuses). + to eq [first_extended_status, second_extended_status] end end context 'when exclusive statuses are matches' do before do - allow(described_class).to receive(:extended_statuses) - .and_return([[first_extended_status, second_extended_status]]) + allow(described_class).to receive(:extended_statuses). + and_return([[first_extended_status, second_extended_status]]) end it 'does not fabricate compound decorator' do @@ -116,8 +116,8 @@ describe Gitlab::Ci::Status::Factory do context 'when exclusive statuses are not matched' do before do - allow(described_class).to receive(:extended_statuses) - .and_return([[first_extended_status], [second_extended_status]]) + allow(described_class).to receive(:extended_statuses). + and_return([[first_extended_status], [second_extended_status]]) end it_behaves_like 'compound decorator factory' @@ -125,8 +125,8 @@ describe Gitlab::Ci::Status::Factory do context 'when using simplified status grouping' do before do - allow(described_class).to receive(:extended_statuses) - .and_return([first_extended_status, second_extended_status]) + allow(described_class).to receive(:extended_statuses). + and_return([first_extended_status, second_extended_status]) end it_behaves_like 'compound decorator factory' diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index d665674bf70..35dad60febf 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Pipeline::Common do let(:pipeline) { create(:ci_pipeline, project: project) } subject do - Gitlab::Ci::Status::Core - .new(pipeline, user) - .extend(described_class) + Gitlab::Ci::Status::Core. + new(pipeline, user). + extend(described_class) end describe '#has_action?' do @@ -29,8 +29,8 @@ describe Gitlab::Ci::Status::Pipeline::Common do describe '#details_path' do it 'links to the pipeline details page' do - expect(subject.details_path) - .to include "pipelines/#{pipeline.id}" + expect(subject.details_path). + to include "pipelines/#{pipeline.id}" end end end diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index b10a447c27a..7cee4435931 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do it 'extends core status with common pipeline methods' do expect(status).to have_details expect(status).not_to have_action - expect(status.details_path) - .to include "pipelines/#{pipeline.id}" + expect(status.details_path). + to include "pipelines/#{pipeline.id}" end end end @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses) - .to eq [Gitlab::Ci::Status::SuccessWarning] + expect(factory.extended_statuses). + to eq [Gitlab::Ci::Status::SuccessWarning] end it 'fabricates extended "success with warnings" status' do diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb index 8814a7614a0..3b25893d8c7 100644 --- a/spec/lib/gitlab/ci/status/stage/common_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Status::Stage::Common do end subject do - Class.new(Gitlab::Ci::Status::Core) - .new(stage, user).extend(described_class) + Class.new(Gitlab::Ci::Status::Core). + new(stage, user).extend(described_class) end it 'does not have action' do @@ -19,10 +19,10 @@ describe Gitlab::Ci::Status::Stage::Common do end it 'links to the pipeline details page' do - expect(subject.details_path) - .to include "pipelines/#{pipeline.id}" - expect(subject.details_path) - .to include "##{stage.name}" + expect(subject.details_path). + to include "pipelines/#{pipeline.id}" + expect(subject.details_path). + to include "##{stage.name}" end context 'when user has permission to read pipeline' do diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index bbb40e2c1ab..c8503392b34 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Stage::Factory do end it 'fabricates extended "success with warnings" status' do - expect(status) - .to be_a Gitlab::Ci::Status::SuccessWarning + expect(status). + to be_a Gitlab::Ci::Status::SuccessWarning end it 'extends core status with common stage method' do diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb index ca68010cb89..97af1c2523d 100644 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb @@ -306,58 +306,58 @@ describe Gitlab::ClosingIssueExtractor, lib: true do it 'fetches issues in single line message' do message = "Closes #{reference} and fix #{reference2}" - expect(subject.closed_by_message(message)) - .to match_array([issue, other_issue]) + expect(subject.closed_by_message(message)). + to match_array([issue, other_issue]) end it 'fetches comma-separated issues references in single line message' do message = "Closes #{reference}, closes #{reference2}" - expect(subject.closed_by_message(message)) - .to match_array([issue, other_issue]) + expect(subject.closed_by_message(message)). + to match_array([issue, other_issue]) end it 'fetches comma-separated issues numbers in single line message' do message = "Closes #{reference}, #{reference2} and #{reference3}" - expect(subject.closed_by_message(message)) - .to match_array([issue, other_issue, third_issue]) + expect(subject.closed_by_message(message)). + to match_array([issue, other_issue, third_issue]) end it 'fetches issues in multi-line message' do message = "Awesome commit (closes #{reference})\nAlso fixes #{reference2}" - expect(subject.closed_by_message(message)) - .to match_array([issue, other_issue]) + expect(subject.closed_by_message(message)). + to match_array([issue, other_issue]) end it 'fetches issues in hybrid message' do message = "Awesome commit (closes #{reference})\n"\ "Also fixing issues #{reference2}, #{reference3} and #4" - expect(subject.closed_by_message(message)) - .to match_array([issue, other_issue, third_issue]) + expect(subject.closed_by_message(message)). + to match_array([issue, other_issue, third_issue]) end it "fetches cross-project references" do message = "Closes #{reference} and #{cross_reference}" - expect(subject.closed_by_message(message)) - .to match_array([issue, issue2]) + expect(subject.closed_by_message(message)). + to match_array([issue, issue2]) end it "fetches cross-project URL references" do message = "Closes #{urls.namespace_project_issue_url(issue2.project.namespace, issue2.project, issue2)} and #{reference}" - expect(subject.closed_by_message(message)) - .to match_array([issue, issue2]) + expect(subject.closed_by_message(message)). + to match_array([issue, issue2]) end it "ignores invalid cross-project URL references" do message = "Closes https://google.com#{urls.namespace_project_issue_path(issue2.project.namespace, issue2.project, issue2)} and #{reference}" - expect(subject.closed_by_message(message)) - .to match_array([issue]) + expect(subject.closed_by_message(message)). + to match_array([issue]) end end end diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb index b3e107dca72..7e5531d92dc 100644 --- a/spec/lib/gitlab/conflict/file_spec.rb +++ b/spec/lib/gitlab/conflict/file_spec.rb @@ -43,8 +43,8 @@ describe Gitlab::Conflict::File, lib: true do end it 'returns a file containing only the chosen parts of the resolved sections' do - expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first)) - .to eq(%w(both new both old both new both)) + expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first)). + to eq(%w(both new both old both new both)) end end @@ -52,14 +52,14 @@ describe Gitlab::Conflict::File, lib: true do empty_hash = section_keys.map { |key| [key, nil] }.to_h invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h - expect { conflict_file.resolve_lines({}) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { conflict_file.resolve_lines({}) }. + to raise_error(Gitlab::Conflict::File::MissingResolution) - expect { conflict_file.resolve_lines(empty_hash) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { conflict_file.resolve_lines(empty_hash) }. + to raise_error(Gitlab::Conflict::File::MissingResolution) - expect { conflict_file.resolve_lines(invalid_hash) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { conflict_file.resolve_lines(invalid_hash) }. + to raise_error(Gitlab::Conflict::File::MissingResolution) end end @@ -250,8 +250,8 @@ FILE describe '#as_json' do it 'includes the blob path for the file' do - expect(conflict_file.as_json[:blob_path]) - .to eq("/#{project.namespace.to_param}/#{merge_request.project.to_param}/blob/#{our_commit.oid}/files/ruby/regex.rb") + expect(conflict_file.as_json[:blob_path]). + to eq("/#{project.namespace.to_param}/#{merge_request.project.to_param}/blob/#{our_commit.oid}/files/ruby/regex.rb") end it 'includes the blob icon for the file' do @@ -264,8 +264,8 @@ FILE end it 'includes the detected language of the conflict file' do - expect(conflict_file.as_json(full_content: true)[:blob_ace_mode]) - .to eq('ruby') + expect(conflict_file.as_json(full_content: true)[:blob_ace_mode]). + to eq('ruby') end end end diff --git a/spec/lib/gitlab/conflict/parser_spec.rb b/spec/lib/gitlab/conflict/parser_spec.rb index ca4bdcc3672..16eb3766356 100644 --- a/spec/lib/gitlab/conflict/parser_spec.rb +++ b/spec/lib/gitlab/conflict/parser_spec.rb @@ -121,72 +121,72 @@ CONFLICT context 'when the file contents include conflict delimiters' do it 'raises UnexpectedDelimiter when there is a non-start delimiter first' do - expect { parse_text('=======') } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text('=======') }. + to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text('>>>>>>> README.md') } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text('>>>>>>> README.md') }. + to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text('>>>>>>> some-other-path.md') } - .not_to raise_error + expect { parse_text('>>>>>>> some-other-path.md') }. + not_to raise_error end it 'raises UnexpectedDelimiter when a start delimiter is followed by a non-middle delimiter' do start_text = "<<<<<<< README.md\n" end_text = "\n=======\n>>>>>>> README.md" - expect { parse_text(start_text + '>>>>>>> README.md' + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }. + to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + start_text + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + start_text + end_text) }. + to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) } - .not_to raise_error + expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }. + not_to raise_error end it 'raises UnexpectedDelimiter when a middle delimiter is followed by a non-end delimiter' do start_text = "<<<<<<< README.md\n=======\n" end_text = "\n>>>>>>> README.md" - expect { parse_text(start_text + '=======' + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + '=======' + end_text) }. + to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + start_text + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) + expect { parse_text(start_text + start_text + end_text) }. + to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) } - .not_to raise_error + expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }. + not_to raise_error end it 'raises MissingEndDelimiter when there is no end delimiter at the end' do start_text = "<<<<<<< README.md\n=======\n" - expect { parse_text(start_text) } - .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) + expect { parse_text(start_text) }. + to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) - expect { parse_text(start_text + '>>>>>>> some-other-path.md') } - .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) + expect { parse_text(start_text + '>>>>>>> some-other-path.md') }. + to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) end end context 'other file types' do it 'raises UnmergeableFile when lines is blank, indicating a binary file' do - expect { parse_text('') } - .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) + expect { parse_text('') }. + to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) - expect { parse_text(nil) } - .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) + expect { parse_text(nil) }. + to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) end it 'raises UnmergeableFile when the file is over 200 KB' do - expect { parse_text('a' * 204801) } - .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) + expect { parse_text('a' * 204801) }. + to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) end it 'raises UnsupportedEncoding when the file contains non-UTF-8 characters' do - expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) } - .to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding) + expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }. + to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding) end end end diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb index 04ec34492e1..7658153df0b 100644 --- a/spec/lib/gitlab/data_builder/note_spec.rb +++ b/spec/lib/gitlab/data_builder/note_spec.rb @@ -9,8 +9,8 @@ describe Gitlab::DataBuilder::Note, lib: true do before(:each) do expect(data).to have_key(:object_attributes) expect(data[:object_attributes]).to have_key(:url) - expect(data[:object_attributes][:url]) - .to eq(Gitlab::UrlBuilder.build(note)) + expect(data[:object_attributes][:url]). + to eq(Gitlab::UrlBuilder.build(note)) expect(data[:object_kind]).to eq('note') expect(data[:user]).to eq(user.hook_attrs) end @@ -49,10 +49,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and issue-specific data' do expect(data).to have_key(:issue) - expect(data[:issue].except('updated_at')) - .to eq(issue.reload.hook_attrs.except('updated_at')) - expect(data[:issue]['updated_at']) - .to be > issue.hook_attrs['updated_at'] + expect(data[:issue].except('updated_at')). + to eq(issue.reload.hook_attrs.except('updated_at')) + expect(data[:issue]['updated_at']). + to be > issue.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -73,10 +73,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')) - .to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']) - .to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')). + to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']). + to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -96,10 +96,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request diff data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')) - .to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']) - .to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')). + to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']). + to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -119,10 +119,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and project snippet data' do expect(data).to have_key(:snippet) - expect(data[:snippet].except('updated_at')) - .to eq(snippet.reload.hook_attrs.except('updated_at')) - expect(data[:snippet]['updated_at']) - .to be > snippet.hook_attrs['updated_at'] + expect(data[:snippet].except('updated_at')). + to eq(snippet.reload.hook_attrs.except('updated_at')) + expect(data[:snippet]['updated_at']). + to be > snippet.hook_attrs['updated_at'] end include_examples 'project hook data' diff --git a/spec/lib/gitlab/data_builder/push_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb index 019d7d75814..dbcfb9b7400 100644 --- a/spec/lib/gitlab/data_builder/push_spec.rb +++ b/spec/lib/gitlab/data_builder/push_spec.rb @@ -46,8 +46,8 @@ describe Gitlab::DataBuilder::Push, lib: true do include_examples 'deprecated repository hook data' it 'does not raise an error when given nil commits' do - expect { described_class.build(spy, spy, spy, spy, spy, nil) } - .not_to raise_error + expect { described_class.build(spy, spy, spy, spy, spy, nil) }. + not_to raise_error end end end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 511b4a988aa..e007044868c 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -22,15 +22,15 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end it 'creates the index concurrently' do - expect(model).to receive(:add_index) - .with(:users, :foo, algorithm: :concurrently) + expect(model).to receive(:add_index). + with(:users, :foo, algorithm: :concurrently) model.add_concurrent_index(:users, :foo) end it 'creates unique index concurrently' do - expect(model).to receive(:add_index) - .with(:users, :foo, { algorithm: :concurrently, unique: true }) + expect(model).to receive(:add_index). + with(:users, :foo, { algorithm: :concurrently, unique: true }) model.add_concurrent_index(:users, :foo, unique: true) end @@ -40,8 +40,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do it 'creates a regular index' do expect(Gitlab::Database).to receive(:postgresql?).and_return(false) - expect(model).to receive(:add_index) - .with(:users, :foo, {}) + expect(model).to receive(:add_index). + with(:users, :foo, {}) model.add_concurrent_index(:users, :foo) end @@ -52,8 +52,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do it 'raises RuntimeError' do expect(model).to receive(:transaction_open?).and_return(true) - expect { model.add_concurrent_index(:users, :foo) } - .to raise_error(RuntimeError) + expect { model.add_concurrent_index(:users, :foo) }. + to raise_error(RuntimeError) end end end @@ -78,8 +78,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do it 'creates a regular foreign key' do allow(Gitlab::Database).to receive(:mysql?).and_return(true) - expect(model).to receive(:add_foreign_key) - .with(:projects, :users, column: :user_id, on_delete: :cascade) + expect(model).to receive(:add_foreign_key). + with(:projects, :users, column: :user_id, on_delete: :cascade) model.add_concurrent_foreign_key(:projects, :users, column: :user_id) end @@ -171,16 +171,16 @@ describe Gitlab::Database::MigrationHelpers, lib: true do expect(model).to receive(:transaction).and_yield - expect(model).to receive(:add_column) - .with(:projects, :foo, :integer, default: nil) + expect(model).to receive(:add_column). + with(:projects, :foo, :integer, default: nil) - expect(model).to receive(:change_column_default) - .with(:projects, :foo, 10) + expect(model).to receive(:change_column_default). + with(:projects, :foo, 10) end it 'adds the column while allowing NULL values' do - expect(model).to receive(:update_column_in_batches) - .with(:projects, :foo, 10) + expect(model).to receive(:update_column_in_batches). + with(:projects, :foo, 10) expect(model).not_to receive(:change_column_null) @@ -190,22 +190,22 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end it 'adds the column while not allowing NULL values' do - expect(model).to receive(:update_column_in_batches) - .with(:projects, :foo, 10) + expect(model).to receive(:update_column_in_batches). + with(:projects, :foo, 10) - expect(model).to receive(:change_column_null) - .with(:projects, :foo, false) + expect(model).to receive(:change_column_null). + with(:projects, :foo, false) model.add_column_with_default(:projects, :foo, :integer, default: 10) end it 'removes the added column whenever updating the rows fails' do - expect(model).to receive(:update_column_in_batches) - .with(:projects, :foo, 10) - .and_raise(RuntimeError) + expect(model).to receive(:update_column_in_batches). + with(:projects, :foo, 10). + and_raise(RuntimeError) - expect(model).to receive(:remove_column) - .with(:projects, :foo) + expect(model).to receive(:remove_column). + with(:projects, :foo) expect do model.add_column_with_default(:projects, :foo, :integer, default: 10) @@ -213,12 +213,12 @@ describe Gitlab::Database::MigrationHelpers, lib: true do end it 'removes the added column whenever changing a column NULL constraint fails' do - expect(model).to receive(:change_column_null) - .with(:projects, :foo, false) - .and_raise(RuntimeError) + expect(model).to receive(:change_column_null). + with(:projects, :foo, false). + and_raise(RuntimeError) - expect(model).to receive(:remove_column) - .with(:projects, :foo) + expect(model).to receive(:remove_column). + with(:projects, :foo) expect do model.add_column_with_default(:projects, :foo, :integer, default: 10) @@ -234,8 +234,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do allow(model).to receive(:change_column_null).with(:projects, :foo, false) allow(model).to receive(:change_column_default).with(:projects, :foo, 10) - expect(model).to receive(:add_column) - .with(:projects, :foo, :integer, default: nil, limit: 8) + expect(model).to receive(:add_column). + with(:projects, :foo, :integer, default: nil, limit: 8) model.add_column_with_default(:projects, :foo, :integer, default: 10, limit: 8) end diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 053ce1d9e68..5eff7e8425b 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -28,8 +28,8 @@ describe Gitlab::Database, lib: true do describe '.version' do context "on mysql" do it "extracts the version number" do - allow(described_class).to receive(:database_version) - .and_return("5.7.12-standard") + allow(described_class).to receive(:database_version). + and_return("5.7.12-standard") expect(described_class.version).to eq '5.7.12-standard' end @@ -37,8 +37,8 @@ describe Gitlab::Database, lib: true do context "on postgresql" do it "extracts the version number" do - allow(described_class).to receive(:database_version) - .and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0") + allow(described_class).to receive(:database_version). + and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0") expect(described_class.version).to eq '9.4.4' end @@ -120,8 +120,8 @@ describe Gitlab::Database, lib: true do pool = described_class.create_connection_pool(5) begin - expect(pool) - .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) + expect(pool). + to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) expect(pool.spec.config[:pool]).to eq(5) ensure diff --git a/spec/lib/gitlab/downtime_check_spec.rb b/spec/lib/gitlab/downtime_check_spec.rb index 1f1e4e0216c..42d895e548e 100644 --- a/spec/lib/gitlab/downtime_check_spec.rb +++ b/spec/lib/gitlab/downtime_check_spec.rb @@ -11,12 +11,12 @@ describe Gitlab::DowntimeCheck do context 'when a migration does not specify if downtime is required' do it 'raises RuntimeError' do - expect(subject).to receive(:class_for_migration_file) - .with(path) - .and_return(Class.new) + expect(subject).to receive(:class_for_migration_file). + with(path). + and_return(Class.new) - expect { subject.check([path]) } - .to raise_error(RuntimeError, /it requires downtime/) + expect { subject.check([path]) }. + to raise_error(RuntimeError, /it requires downtime/) end end @@ -25,12 +25,12 @@ describe Gitlab::DowntimeCheck do it 'raises RuntimeError' do stub_const('TestMigration::DOWNTIME', true) - expect(subject).to receive(:class_for_migration_file) - .with(path) - .and_return(TestMigration) + expect(subject).to receive(:class_for_migration_file). + with(path). + and_return(TestMigration) - expect { subject.check([path]) } - .to raise_error(RuntimeError, /no reason was given/) + expect { subject.check([path]) }. + to raise_error(RuntimeError, /no reason was given/) end end @@ -39,9 +39,9 @@ describe Gitlab::DowntimeCheck do stub_const('TestMigration::DOWNTIME', true) stub_const('TestMigration::DOWNTIME_REASON', 'foo') - expect(subject).to receive(:class_for_migration_file) - .with(path) - .and_return(TestMigration) + expect(subject).to receive(:class_for_migration_file). + with(path). + and_return(TestMigration) messages = subject.check([path]) @@ -65,9 +65,9 @@ describe Gitlab::DowntimeCheck do expect(subject).to receive(:require).with(path) - expect(subject).to receive(:class_for_migration_file) - .with(path) - .and_return(TestMigration) + expect(subject).to receive(:class_for_migration_file). + with(path). + and_return(TestMigration) expect(subject).to receive(:puts).with(an_instance_of(String)) diff --git a/spec/lib/gitlab/email/reply_parser_spec.rb b/spec/lib/gitlab/email/reply_parser_spec.rb index 02ff2a46c48..28698e89c33 100644 --- a/spec/lib/gitlab/email/reply_parser_spec.rb +++ b/spec/lib/gitlab/email/reply_parser_spec.rb @@ -20,8 +20,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders plaintext-only email" do - expect(test_parse_body(fixture_file("emails/plaintext_only.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/plaintext_only.eml"))). + to eq( <<-BODY.strip_heredoc.chomp ### reply from default mail client in Windows 8.1 Metro @@ -46,8 +46,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles multiple paragraphs" do - expect(test_parse_body(fixture_file("emails/paragraphs.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/paragraphs.eml"))). + to eq( <<-BODY.strip_heredoc.chomp Is there any reason the *old* candy can't be be kept in silos while the new candy is imported into *new* silos? @@ -61,8 +61,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles multiple paragraphs when parsing html" do - expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))). + to eq( <<-BODY.strip_heredoc.chomp Awesome! @@ -74,8 +74,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles newlines" do - expect(test_parse_body(fixture_file("emails/newlines.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/newlines.eml"))). + to eq( <<-BODY.strip_heredoc.chomp This is my reply. It is my best reply. @@ -85,8 +85,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "handles inline reply" do - expect(test_parse_body(fixture_file("emails/inline_reply.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/inline_reply.eml"))). + to eq( <<-BODY.strip_heredoc.chomp > techAPJ > November 28 @@ -132,8 +132,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from gmail web client" do - expect(test_parse_body(fixture_file("emails/gmail_web.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/gmail_web.eml"))). + to eq( <<-BODY.strip_heredoc.chomp ### This is a reply from standard GMail in Google Chrome. @@ -151,8 +151,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from iOS default mail client" do - expect(test_parse_body(fixture_file("emails/ios_default.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/ios_default.eml"))). + to eq( <<-BODY.strip_heredoc.chomp ### this is a reply from iOS default mail @@ -166,8 +166,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from Android 5 gmail client" do - expect(test_parse_body(fixture_file("emails/android_gmail.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/android_gmail.eml"))). + to eq( <<-BODY.strip_heredoc.chomp ### this is a reply from Android 5 gmail @@ -184,8 +184,8 @@ describe Gitlab::Email::ReplyParser, lib: true do end it "properly renders email reply from Windows 8.1 Metro default mail client" do - expect(test_parse_body(fixture_file("emails/windows_8_metro.eml"))) - .to eq( + expect(test_parse_body(fixture_file("emails/windows_8_metro.eml"))). + to eq( <<-BODY.strip_heredoc.chomp ### reply from default mail client in Windows 8.1 Metro diff --git a/spec/lib/gitlab/file_detector_spec.rb b/spec/lib/gitlab/file_detector_spec.rb index 695fd6f8573..e5ba13bbaf8 100644 --- a/spec/lib/gitlab/file_detector_spec.rb +++ b/spec/lib/gitlab/file_detector_spec.rb @@ -3,13 +3,13 @@ require 'spec_helper' describe Gitlab::FileDetector do describe '.types_in_paths' do it 'returns the file types for the given paths' do - expect(described_class.types_in_paths(%w(README.md CHANGELOG VERSION VERSION))) - .to eq(%i{readme changelog version}) + expect(described_class.types_in_paths(%w(README.md CHANGELOG VERSION VERSION))). + to eq(%i{readme changelog version}) end it 'does not include unrecognized file paths' do - expect(described_class.types_in_paths(%w(README.md foo.txt))) - .to eq(%i{readme}) + expect(described_class.types_in_paths(%w(README.md foo.txt))). + to eq(%i{readme}) end end diff --git a/spec/lib/gitlab/git/attributes_spec.rb b/spec/lib/gitlab/git/attributes_spec.rb index b29107eece4..9c011e34c11 100644 --- a/spec/lib/gitlab/git/attributes_spec.rb +++ b/spec/lib/gitlab/git/attributes_spec.rb @@ -14,13 +14,13 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'returns a Hash containing multiple attributes' do - expect(subject.attributes('test.sh')) - .to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' }) + expect(subject.attributes('test.sh')). + to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' }) end it 'returns a Hash containing attributes for a file with multiple extensions' do - expect(subject.attributes('test.haml.html')) - .to eq({ 'gitlab-language' => 'haml' }) + expect(subject.attributes('test.haml.html')). + to eq({ 'gitlab-language' => 'haml' }) end it 'returns a Hash containing attributes for a file in a directory' do @@ -28,8 +28,8 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'returns a Hash containing attributes with query string parameters' do - expect(subject.attributes('foo.cgi')) - .to eq({ 'key' => 'value?p1=v1&p2=v2' }) + expect(subject.attributes('foo.cgi')). + to eq({ 'key' => 'value?p1=v1&p2=v2' }) end it 'returns a Hash containing the attributes for an absolute path' do @@ -39,11 +39,11 @@ describe Gitlab::Git::Attributes, seed_helper: true do it 'returns a Hash containing the attributes when a pattern is defined using an absolute path' do # When a path is given without a leading slash it should still match # patterns defined with a leading slash. - expect(subject.attributes('foo.png')) - .to eq({ 'gitlab-language' => 'png' }) + expect(subject.attributes('foo.png')). + to eq({ 'gitlab-language' => 'png' }) - expect(subject.attributes('/foo.png')) - .to eq({ 'gitlab-language' => 'png' }) + expect(subject.attributes('/foo.png')). + to eq({ 'gitlab-language' => 'png' }) end it 'returns an empty Hash for a defined path without attributes' do @@ -74,8 +74,8 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'parses an entry that uses a tab to separate the pattern and attributes' do - expect(subject.patterns[File.join(path, '*.md')]) - .to eq({ 'gitlab-language' => 'markdown' }) + expect(subject.patterns[File.join(path, '*.md')]). + to eq({ 'gitlab-language' => 'markdown' }) end it 'stores patterns in reverse order' do @@ -91,9 +91,9 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'does not parse anything when the attributes file does not exist' do - expect(File).to receive(:exist?) - .with(File.join(path, 'info/attributes')) - .and_return(false) + expect(File).to receive(:exist?). + with(File.join(path, 'info/attributes')). + and_return(false) expect(subject.patterns).to eq({}) end @@ -115,13 +115,13 @@ describe Gitlab::Git::Attributes, seed_helper: true do it 'parses multiple attributes' do input = 'boolean key=value -negated' - expect(subject.parse_attributes(input)) - .to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false }) + expect(subject.parse_attributes(input)). + to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false }) end it 'parses attributes with query string parameters' do - expect(subject.parse_attributes('foo=bar?baz=1')) - .to eq({ 'foo' => 'bar?baz=1' }) + expect(subject.parse_attributes('foo=bar?baz=1')). + to eq({ 'foo' => 'bar?baz=1' }) end end @@ -133,9 +133,9 @@ describe Gitlab::Git::Attributes, seed_helper: true do end it 'does not yield when the attributes file does not exist' do - expect(File).to receive(:exist?) - .with(File.join(path, 'info/attributes')) - .and_return(false) + expect(File).to receive(:exist?). + with(File.join(path, 'info/attributes')). + and_return(false) expect { |b| subject.each_line(&b) }.not_to yield_control end diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb index 327aba9cae7..0c321f0343c 100644 --- a/spec/lib/gitlab/git/blob_spec.rb +++ b/spec/lib/gitlab/git/blob_spec.rb @@ -92,9 +92,9 @@ describe Gitlab::Git::Blob, seed_helper: true do end it 'marks the blob as binary' do - expect(Gitlab::Git::Blob).to receive(:new) - .with(hash_including(binary: true)) - .and_call_original + expect(Gitlab::Git::Blob).to receive(:new). + with(hash_including(binary: true)). + and_call_original expect(blob).to be_binary end diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb index c6ff864268d..47bdd7310d5 100644 --- a/spec/lib/gitlab/git/diff_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_collection_spec.rb @@ -309,8 +309,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do end it 'yields Diff instances even when they are too large' do - expect { |b| collection.each(&b) } - .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| collection.each(&b) }. + to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'prunes diffs that are too large' do @@ -331,8 +331,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do let(:no_collapse) { true } it 'yields Diff instances even when they are quite big' do - expect { |b| subject.each(&b) } - .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| subject.each(&b) }. + to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'does not prune diffs' do @@ -350,8 +350,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do let(:no_collapse) { false } it 'yields Diff instances even when they are quite big' do - expect { |b| subject.each(&b) } - .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| subject.each(&b) }. + to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'prunes diffs that are quite big' do @@ -437,8 +437,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do let(:all_diffs) { true } it 'yields Diff instances even when they are quite big' do - expect { |b| subject.each(&b) } - .to yield_with_args(an_instance_of(Gitlab::Git::Diff)) + expect { |b| subject.each(&b) }. + to yield_with_args(an_instance_of(Gitlab::Git::Diff)) end it 'does not prune diffs' do diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb index 70d3b1a9f81..4c55532d165 100644 --- a/spec/lib/gitlab/git/diff_spec.rb +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -70,8 +70,8 @@ EOT context 'using a diff that is too large' do it 'prunes the diff' do - expect_any_instance_of(String).to receive(:bytesize) - .and_return(1024 * 1024 * 1024) + expect_any_instance_of(String).to receive(:bytesize). + and_return(1024 * 1024 * 1024) diff = described_class.new(@rugged_diff) @@ -100,8 +100,8 @@ EOT context 'using a large binary diff' do it 'does not prune the diff' do - expect_any_instance_of(Rugged::Diff::Delta).to receive(:binary?) - .and_return(true) + expect_any_instance_of(Rugged::Diff::Delta).to receive(:binary?). + and_return(true) diff = described_class.new(@rugged_diff) diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 5e0c3a530e9..2a915bf426f 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -315,8 +315,8 @@ describe Gitlab::Git::Repository, seed_helper: true do end it "should move the tip of the master branch to the correct commit" do - new_tip = @normal_repo.rugged.references["refs/heads/master"] - .target.oid + new_tip = @normal_repo.rugged.references["refs/heads/master"]. + target.oid expect(new_tip).to eq(reset_commit) end diff --git a/spec/lib/gitlab/gitlab_import/importer_spec.rb b/spec/lib/gitlab/gitlab_import/importer_spec.rb index 4f588da0a83..9b499b593d3 100644 --- a/spec/lib/gitlab/gitlab_import/importer_spec.rb +++ b/spec/lib/gitlab/gitlab_import/importer_spec.rb @@ -45,8 +45,8 @@ describe Gitlab::GitlabImport::Importer, lib: true do def stub_request(path, body) url = "https://gitlab.com/api/v3/projects/asd%2Fvim/#{path}?page=1&per_page=100" - WebMock.stub_request(:get, url) - .to_return( + WebMock.stub_request(:get, url). + to_return( headers: { 'Content-Type' => 'application/json' }, body: body ) diff --git a/spec/lib/gitlab/identifier_spec.rb b/spec/lib/gitlab/identifier_spec.rb index 29912da2e25..bb758a8a202 100644 --- a/spec/lib/gitlab/identifier_spec.rb +++ b/spec/lib/gitlab/identifier_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::Identifier do describe '#identify' do context 'without an identifier' do it 'identifies the user using a commit' do - expect(identifier).to receive(:identify_using_commit) - .with(project, '123') + expect(identifier).to receive(:identify_using_commit). + with(project, '123') identifier.identify('', project, '123') end @@ -21,8 +21,8 @@ describe Gitlab::Identifier do context 'with a user identifier' do it 'identifies the user using a user ID' do - expect(identifier).to receive(:identify_using_user) - .with("user-#{user.id}") + expect(identifier).to receive(:identify_using_user). + with("user-#{user.id}") identifier.identify("user-#{user.id}", project, '123') end @@ -30,8 +30,8 @@ describe Gitlab::Identifier do context 'with an SSH key identifier' do it 'identifies the user using an SSH key ID' do - expect(identifier).to receive(:identify_using_ssh_key) - .with("key-#{key.id}") + expect(identifier).to receive(:identify_using_ssh_key). + with("key-#{key.id}") identifier.identify("key-#{key.id}", project, '123') end diff --git a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb index 08a42fd27a2..c141762421f 100644 --- a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb @@ -7,8 +7,8 @@ describe Gitlab::ImportExport::AvatarRestorer, lib: true do let(:project) { create(:empty_project) } before do - allow_any_instance_of(described_class).to receive(:avatar_export_file) - .and_return(uploaded_image_temp_path) + allow_any_instance_of(described_class).to receive(:avatar_export_file). + and_return(uploaded_image_temp_path) end after do diff --git a/spec/lib/gitlab/incoming_email_spec.rb b/spec/lib/gitlab/incoming_email_spec.rb index 698bd72d0f8..d54753ccf90 100644 --- a/spec/lib/gitlab/incoming_email_spec.rb +++ b/spec/lib/gitlab/incoming_email_spec.rb @@ -99,10 +99,10 @@ describe Gitlab::IncomingEmail, lib: true do end it 'returns reply key' do - expect(described_class.scan_fallback_references(references)) - .to eq(%w[issue_1@localhost - reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost - exchange@microsoft.com]) + expect(described_class.scan_fallback_references(references)). + to eq(%w[issue_1@localhost + reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost + exchange@microsoft.com]) end end end diff --git a/spec/lib/gitlab/job_waiter_spec.rb b/spec/lib/gitlab/job_waiter_spec.rb index 6186cec2689..780f5b1f8d7 100644 --- a/spec/lib/gitlab/job_waiter_spec.rb +++ b/spec/lib/gitlab/job_waiter_spec.rb @@ -4,8 +4,8 @@ describe Gitlab::JobWaiter do describe '#wait' do let(:waiter) { described_class.new(%w(a)) } it 'returns when all jobs have been completed' do - expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a)) - .and_return(true) + expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a)). + and_return(true) expect(waiter).not_to receive(:sleep) @@ -13,9 +13,9 @@ describe Gitlab::JobWaiter do end it 'sleeps between checking the job statuses' do - expect(Gitlab::SidekiqStatus).to receive(:all_completed?) - .with(%w(a)) - .and_return(false, true) + expect(Gitlab::SidekiqStatus).to receive(:all_completed?). + with(%w(a)). + and_return(false, true) expect(waiter).to receive(:sleep).with(described_class::INTERVAL) diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb index 563c074017a..fe3709f30e1 100644 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/ldap/adapter_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::LDAP::Adapter, lib: true do end it 'searches with the proper options when searching with a limit' do - expect(adapter) - .to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) + expect(adapter). + to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) adapter.users('uid', 'johndoe', 100) end diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb index f689b47fec4..b8f3290e84c 100644 --- a/spec/lib/gitlab/ldap/authentication_spec.rb +++ b/spec/lib/gitlab/ldap/authentication_spec.rb @@ -16,8 +16,8 @@ describe Gitlab::LDAP::Authentication, lib: true do # try only to fake the LDAP call adapter = double('adapter', dn: dn).as_null_object - allow_any_instance_of(described_class) - .to receive(:adapter).and_return(adapter) + allow_any_instance_of(described_class). + to receive(:adapter).and_return(adapter) expect(described_class.login(login, password)).to be_truthy end @@ -25,8 +25,8 @@ describe Gitlab::LDAP::Authentication, lib: true do it "is false if the user does not exist" do # try only to fake the LDAP call adapter = double('adapter', dn: dn).as_null_object - allow_any_instance_of(described_class) - .to receive(:adapter).and_return(adapter) + allow_any_instance_of(described_class). + to receive(:adapter).and_return(adapter) expect(described_class.login(login, password)).to be_falsey end @@ -36,8 +36,8 @@ describe Gitlab::LDAP::Authentication, lib: true do # try only to fake the LDAP call adapter = double('adapter', bind_as: nil).as_null_object - allow_any_instance_of(described_class) - .to receive(:adapter).and_return(adapter) + allow_any_instance_of(described_class). + to receive(:adapter).and_return(adapter) expect(described_class.login(login, password)).to be_falsey end diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index 5c56c210123..89790c9e1af 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -138,8 +138,8 @@ describe Gitlab::LDAP::User, lib: true do describe 'blocking' do def configure_block(value) - allow_any_instance_of(Gitlab::LDAP::Config) - .to receive(:block_auto_created_users).and_return(value) + allow_any_instance_of(Gitlab::LDAP::Config). + to receive(:block_auto_created_users).and_return(value) end context 'signup' do diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb index 4b19ee19103..a986cb520fb 100644 --- a/spec/lib/gitlab/metrics/instrumentation_spec.rb +++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb @@ -78,11 +78,11 @@ describe Gitlab::Metrics::Instrumentation do end it 'tracks the call duration upon calling the method' do - allow(Gitlab::Metrics).to receive(:method_call_threshold) - .and_return(0) + allow(Gitlab::Metrics).to receive(:method_call_threshold). + and_return(0) - allow(described_class).to receive(:transaction) - .and_return(transaction) + allow(described_class).to receive(:transaction). + and_return(transaction) expect_any_instance_of(Gitlab::Metrics::MethodCall).to receive(:measure) @@ -90,8 +90,8 @@ describe Gitlab::Metrics::Instrumentation do end it 'does not track method calls below a given duration threshold' do - allow(Gitlab::Metrics).to receive(:method_call_threshold) - .and_return(100) + allow(Gitlab::Metrics).to receive(:method_call_threshold). + and_return(100) expect(transaction).not_to receive(:add_metric) @@ -137,8 +137,8 @@ describe Gitlab::Metrics::Instrumentation do before do allow(Gitlab::Metrics).to receive(:enabled?).and_return(true) - described_class - .instrument_instance_method(@dummy, :bar) + described_class. + instrument_instance_method(@dummy, :bar) end it 'instruments instances of the Class' do @@ -156,11 +156,11 @@ describe Gitlab::Metrics::Instrumentation do end it 'tracks the call duration upon calling the method' do - allow(Gitlab::Metrics).to receive(:method_call_threshold) - .and_return(0) + allow(Gitlab::Metrics).to receive(:method_call_threshold). + and_return(0) - allow(described_class).to receive(:transaction) - .and_return(transaction) + allow(described_class).to receive(:transaction). + and_return(transaction) expect_any_instance_of(Gitlab::Metrics::MethodCall).to receive(:measure) @@ -168,8 +168,8 @@ describe Gitlab::Metrics::Instrumentation do end it 'does not track method calls below a given duration threshold' do - allow(Gitlab::Metrics).to receive(:method_call_threshold) - .and_return(100) + allow(Gitlab::Metrics).to receive(:method_call_threshold). + and_return(100) expect(transaction).not_to receive(:add_metric) @@ -183,8 +183,8 @@ describe Gitlab::Metrics::Instrumentation do end it 'does not instrument the method' do - described_class - .instrument_instance_method(@dummy, :bar) + described_class. + instrument_instance_method(@dummy, :bar) expect(described_class.instrumented?(@dummy)).to eq(false) end diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb index ec415f2bd85..fb470ea7568 100644 --- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb @@ -26,8 +26,8 @@ describe Gitlab::Metrics::RackMiddleware do allow(app).to receive(:call).with(env) - expect(middleware).to receive(:tag_controller) - .with(an_instance_of(Gitlab::Metrics::Transaction), env) + expect(middleware).to receive(:tag_controller). + with(an_instance_of(Gitlab::Metrics::Transaction), env) middleware.call(env) end @@ -40,8 +40,8 @@ describe Gitlab::Metrics::RackMiddleware do allow(app).to receive(:call).with(env) - expect(middleware).to receive(:tag_endpoint) - .with(an_instance_of(Gitlab::Metrics::Transaction), env) + expect(middleware).to receive(:tag_endpoint). + with(an_instance_of(Gitlab::Metrics::Transaction), env) middleware.call(env) end @@ -49,8 +49,8 @@ describe Gitlab::Metrics::RackMiddleware do it 'tracks any raised exceptions' do expect(app).to receive(:call).with(env).and_raise(RuntimeError) - expect_any_instance_of(Gitlab::Metrics::Transaction) - .to receive(:add_event).with(:rails_exception) + expect_any_instance_of(Gitlab::Metrics::Transaction). + to receive(:add_event).with(:rails_exception) expect { middleware.call(env) }.to raise_error(RuntimeError) end diff --git a/spec/lib/gitlab/metrics/sampler_spec.rb b/spec/lib/gitlab/metrics/sampler_spec.rb index d07ce6f81af..1ab923b58cf 100644 --- a/spec/lib/gitlab/metrics/sampler_spec.rb +++ b/spec/lib/gitlab/metrics/sampler_spec.rb @@ -38,8 +38,8 @@ describe Gitlab::Metrics::Sampler do describe '#flush' do it 'schedules the metrics using Sidekiq' do - expect(Gitlab::Metrics).to receive(:submit_metrics) - .with([an_instance_of(Hash)]) + expect(Gitlab::Metrics).to receive(:submit_metrics). + with([an_instance_of(Hash)]) sampler.sample_memory_usage sampler.flush @@ -48,12 +48,12 @@ describe Gitlab::Metrics::Sampler do describe '#sample_memory_usage' do it 'adds a metric containing the memory usage' do - expect(Gitlab::Metrics::System).to receive(:memory_usage) - .and_return(9000) + expect(Gitlab::Metrics::System).to receive(:memory_usage). + and_return(9000) - expect(sampler).to receive(:add_metric) - .with(/memory_usage/, value: 9000) - .and_call_original + expect(sampler).to receive(:add_metric). + with(/memory_usage/, value: 9000). + and_call_original sampler.sample_memory_usage end @@ -61,12 +61,12 @@ describe Gitlab::Metrics::Sampler do describe '#sample_file_descriptors' do it 'adds a metric containing the amount of open file descriptors' do - expect(Gitlab::Metrics::System).to receive(:file_descriptor_count) - .and_return(4) + expect(Gitlab::Metrics::System).to receive(:file_descriptor_count). + and_return(4) - expect(sampler).to receive(:add_metric) - .with(/file_descriptors/, value: 4) - .and_call_original + expect(sampler).to receive(:add_metric). + with(/file_descriptors/, value: 4). + and_call_original sampler.sample_file_descriptors end @@ -75,10 +75,10 @@ describe Gitlab::Metrics::Sampler do if Gitlab::Metrics.mri? describe '#sample_objects' do it 'adds a metric containing the amount of allocated objects' do - expect(sampler).to receive(:add_metric) - .with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash)) - .at_least(:once) - .and_call_original + expect(sampler).to receive(:add_metric). + with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash)). + at_least(:once). + and_call_original sampler.sample_objects end @@ -86,8 +86,8 @@ describe Gitlab::Metrics::Sampler do it 'ignores classes without a name' do expect(Allocations).to receive(:to_hash).and_return({ Class.new => 4 }) - expect(sampler).not_to receive(:add_metric) - .with('object_counts', an_instance_of(Hash), type: nil) + expect(sampler).not_to receive(:add_metric). + with('object_counts', an_instance_of(Hash), type: nil) sampler.sample_objects end @@ -98,9 +98,9 @@ describe Gitlab::Metrics::Sampler do it 'adds a metric containing garbage collection statistics' do expect(GC::Profiler).to receive(:total_time).and_return(0.24) - expect(sampler).to receive(:add_metric) - .with(/gc_statistics/, an_instance_of(Hash)) - .and_call_original + expect(sampler).to receive(:add_metric). + with(/gc_statistics/, an_instance_of(Hash)). + and_call_original sampler.sample_gc end @@ -110,9 +110,9 @@ describe Gitlab::Metrics::Sampler do it 'prefixes the series name for a Rails process' do expect(sampler).to receive(:sidekiq?).and_return(false) - expect(Gitlab::Metrics::Metric).to receive(:new) - .with('rails_cats', { value: 10 }, {}) - .and_call_original + expect(Gitlab::Metrics::Metric).to receive(:new). + with('rails_cats', { value: 10 }, {}). + and_call_original sampler.add_metric('cats', value: 10) end @@ -120,9 +120,9 @@ describe Gitlab::Metrics::Sampler do it 'prefixes the series name for a Sidekiq process' do expect(sampler).to receive(:sidekiq?).and_return(true) - expect(Gitlab::Metrics::Metric).to receive(:new) - .with('sidekiq_cats', { value: 10 }, {}) - .and_call_original + expect(Gitlab::Metrics::Metric).to receive(:new). + with('sidekiq_cats', { value: 10 }, {}). + and_call_original sampler.add_metric('cats', value: 10) end diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb index b576d7173f5..acaba785606 100644 --- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb +++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb @@ -8,12 +8,12 @@ describe Gitlab::Metrics::SidekiqMiddleware do it 'tracks the transaction' do worker = double(:worker, class: double(:class, name: 'TestWorker')) - expect(Gitlab::Metrics::Transaction).to receive(:new) - .with('TestWorker#perform') - .and_call_original + expect(Gitlab::Metrics::Transaction).to receive(:new). + with('TestWorker#perform'). + and_call_original - expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set) - .with(:sidekiq_queue_duration, instance_of(Float)) + expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set). + with(:sidekiq_queue_duration, instance_of(Float)) expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish) @@ -23,12 +23,12 @@ describe Gitlab::Metrics::SidekiqMiddleware do it 'tracks the transaction (for messages without `enqueued_at`)' do worker = double(:worker, class: double(:class, name: 'TestWorker')) - expect(Gitlab::Metrics::Transaction).to receive(:new) - .with('TestWorker#perform') - .and_call_original + expect(Gitlab::Metrics::Transaction).to receive(:new). + with('TestWorker#perform'). + and_call_original - expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set) - .with(:sidekiq_queue_duration, instance_of(Float)) + expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set). + with(:sidekiq_queue_duration, instance_of(Float)) expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish) @@ -38,17 +38,17 @@ describe Gitlab::Metrics::SidekiqMiddleware do it 'tracks any raised exceptions' do worker = double(:worker, class: double(:class, name: 'TestWorker')) - expect_any_instance_of(Gitlab::Metrics::Transaction) - .to receive(:run).and_raise(RuntimeError) + expect_any_instance_of(Gitlab::Metrics::Transaction). + to receive(:run).and_raise(RuntimeError) - expect_any_instance_of(Gitlab::Metrics::Transaction) - .to receive(:add_event).with(:sidekiq_exception) + expect_any_instance_of(Gitlab::Metrics::Transaction). + to receive(:add_event).with(:sidekiq_exception) - expect_any_instance_of(Gitlab::Metrics::Transaction) - .to receive(:finish) + expect_any_instance_of(Gitlab::Metrics::Transaction). + to receive(:finish) - expect { middleware.call(worker, message, :test) } - .to raise_error(RuntimeError) + expect { middleware.call(worker, message, :test) }. + to raise_error(RuntimeError) end end end diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb index e7b595405a8..0695c5ce096 100644 --- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb @@ -21,11 +21,11 @@ describe Gitlab::Metrics::Subscribers::ActionView do values = { duration: 2.1 } tags = { view: 'app/views/x.html.haml' } - expect(transaction).to receive(:increment) - .with(:view_duration, 2.1) + expect(transaction).to receive(:increment). + with(:view_duration, 2.1) - expect(transaction).to receive(:add_metric) - .with(described_class::SERIES, values, tags) + expect(transaction).to receive(:add_metric). + with(described_class::SERIES, values, tags) subscriber.render_template(event) end diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb index ce6587e993f..49699ffe28f 100644 --- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb @@ -12,8 +12,8 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do describe '#sql' do describe 'without a current transaction' do it 'simply returns' do - expect_any_instance_of(Gitlab::Metrics::Transaction) - .not_to receive(:increment) + expect_any_instance_of(Gitlab::Metrics::Transaction). + not_to receive(:increment) subscriber.sql(event) end @@ -21,15 +21,15 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do describe 'with a current transaction' do it 'increments the :sql_duration value' do - expect(subscriber).to receive(:current_transaction) - .at_least(:once) - .and_return(transaction) + expect(subscriber).to receive(:current_transaction). + at_least(:once). + and_return(transaction) - expect(transaction).to receive(:increment) - .with(:sql_duration, 0.2) + expect(transaction).to receive(:increment). + with(:sql_duration, 0.2) - expect(transaction).to receive(:increment) - .with(:sql_count, 1) + expect(transaction).to receive(:increment). + with(:sql_count, 1) subscriber.sql(event) end diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb index f04dc8dcc02..d986c6fac43 100644 --- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb @@ -8,26 +8,26 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_read' do it 'increments the cache_read duration' do - expect(subscriber).to receive(:increment) - .with(:cache_read, event.duration) + expect(subscriber).to receive(:increment). + with(:cache_read, event.duration) subscriber.cache_read(event) end context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction) - .and_return(transaction) + allow(subscriber).to receive(:current_transaction). + and_return(transaction) end context 'with hit event' do let(:event) { double(:event, duration: 15.2, payload: { hit: true }) } it 'increments the cache_read_hit count' do - expect(transaction).to receive(:increment) - .with(:cache_read_hit_count, 1) - expect(transaction).to receive(:increment) - .with(any_args).at_least(1) # Other calls + expect(transaction).to receive(:increment). + with(:cache_read_hit_count, 1) + expect(transaction).to receive(:increment). + with(any_args).at_least(1) # Other calls subscriber.cache_read(event) end @@ -36,8 +36,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do let(:event) { double(:event, duration: 15.2, payload: { hit: true, super_operation: :fetch }) } it 'does not increment cache read miss' do - expect(transaction).not_to receive(:increment) - .with(:cache_read_hit_count, 1) + expect(transaction).not_to receive(:increment). + with(:cache_read_hit_count, 1) subscriber.cache_read(event) end @@ -48,10 +48,10 @@ describe Gitlab::Metrics::Subscribers::RailsCache do let(:event) { double(:event, duration: 15.2, payload: { hit: false }) } it 'increments the cache_read_miss count' do - expect(transaction).to receive(:increment) - .with(:cache_read_miss_count, 1) - expect(transaction).to receive(:increment) - .with(any_args).at_least(1) # Other calls + expect(transaction).to receive(:increment). + with(:cache_read_miss_count, 1) + expect(transaction).to receive(:increment). + with(any_args).at_least(1) # Other calls subscriber.cache_read(event) end @@ -60,8 +60,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do let(:event) { double(:event, duration: 15.2, payload: { hit: false, super_operation: :fetch }) } it 'does not increment cache read miss' do - expect(transaction).not_to receive(:increment) - .with(:cache_read_miss_count, 1) + expect(transaction).not_to receive(:increment). + with(:cache_read_miss_count, 1) subscriber.cache_read(event) end @@ -72,8 +72,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_write' do it 'increments the cache_write duration' do - expect(subscriber).to receive(:increment) - .with(:cache_write, event.duration) + expect(subscriber).to receive(:increment). + with(:cache_write, event.duration) subscriber.cache_write(event) end @@ -81,8 +81,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_delete' do it 'increments the cache_delete duration' do - expect(subscriber).to receive(:increment) - .with(:cache_delete, event.duration) + expect(subscriber).to receive(:increment). + with(:cache_delete, event.duration) subscriber.cache_delete(event) end @@ -90,8 +90,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do describe '#cache_exist?' do it 'increments the cache_exists duration' do - expect(subscriber).to receive(:increment) - .with(:cache_exists, event.duration) + expect(subscriber).to receive(:increment). + with(:cache_exists, event.duration) subscriber.cache_exist?(event) end @@ -108,13 +108,13 @@ describe Gitlab::Metrics::Subscribers::RailsCache do context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction) - .and_return(transaction) + allow(subscriber).to receive(:current_transaction). + and_return(transaction) end it 'increments the cache_read_hit count' do - expect(transaction).to receive(:increment) - .with(:cache_read_hit_count, 1) + expect(transaction).to receive(:increment). + with(:cache_read_hit_count, 1) subscriber.cache_fetch_hit(event) end @@ -132,13 +132,13 @@ describe Gitlab::Metrics::Subscribers::RailsCache do context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction) - .and_return(transaction) + allow(subscriber).to receive(:current_transaction). + and_return(transaction) end it 'increments the cache_fetch_miss count' do - expect(transaction).to receive(:increment) - .with(:cache_read_miss_count, 1) + expect(transaction).to receive(:increment). + with(:cache_read_miss_count, 1) subscriber.cache_generate(event) end @@ -156,22 +156,22 @@ describe Gitlab::Metrics::Subscribers::RailsCache do context 'with a transaction' do before do - allow(subscriber).to receive(:current_transaction) - .and_return(transaction) + allow(subscriber).to receive(:current_transaction). + and_return(transaction) end it 'increments the total and specific cache duration' do - expect(transaction).to receive(:increment) - .with(:cache_duration, event.duration) + expect(transaction).to receive(:increment). + with(:cache_duration, event.duration) - expect(transaction).to receive(:increment) - .with(:cache_count, 1) + expect(transaction).to receive(:increment). + with(:cache_count, 1) - expect(transaction).to receive(:increment) - .with(:cache_delete_duration, event.duration) + expect(transaction).to receive(:increment). + with(:cache_delete_duration, event.duration) - expect(transaction).to receive(:increment) - .with(:cache_delete_count, 1) + expect(transaction).to receive(:increment). + with(:cache_delete_count, 1) subscriber.increment(:cache_delete, event.duration) end diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb index 3779af81512..0c5a6246d85 100644 --- a/spec/lib/gitlab/metrics/transaction_spec.rb +++ b/spec/lib/gitlab/metrics/transaction_spec.rb @@ -39,8 +39,8 @@ describe Gitlab::Metrics::Transaction do describe '#add_metric' do it 'adds a metric to the transaction' do - expect(Gitlab::Metrics::Metric).to receive(:new) - .with('rails_foo', { number: 10 }, {}) + expect(Gitlab::Metrics::Metric).to receive(:new). + with('rails_foo', { number: 10 }, {}) transaction.add_metric('foo', number: 10) end @@ -61,8 +61,8 @@ describe Gitlab::Metrics::Transaction do values = { duration: 0.0, time: 3, allocated_memory: a_kind_of(Numeric) } - expect(transaction).to receive(:add_metric) - .with('transactions', values, {}) + expect(transaction).to receive(:add_metric). + with('transactions', values, {}) transaction.track_self end @@ -78,8 +78,8 @@ describe Gitlab::Metrics::Transaction do allocated_memory: a_kind_of(Numeric) } - expect(transaction).to receive(:add_metric) - .with('transactions', values, {}) + expect(transaction).to receive(:add_metric). + with('transactions', values, {}) transaction.track_self end @@ -109,8 +109,8 @@ describe Gitlab::Metrics::Transaction do allocated_memory: a_kind_of(Numeric) } - expect(transaction).to receive(:add_metric) - .with('transactions', values, {}) + expect(transaction).to receive(:add_metric). + with('transactions', values, {}) transaction.track_self end @@ -120,8 +120,8 @@ describe Gitlab::Metrics::Transaction do it 'submits the metrics to Sidekiq' do transaction.track_self - expect(Gitlab::Metrics).to receive(:submit_metrics) - .with([an_instance_of(Hash)]) + expect(Gitlab::Metrics).to receive(:submit_metrics). + with([an_instance_of(Hash)]) transaction.submit end @@ -137,8 +137,8 @@ describe Gitlab::Metrics::Transaction do timestamp: a_kind_of(Integer) } - expect(Gitlab::Metrics).to receive(:submit_metrics) - .with([hash]) + expect(Gitlab::Metrics).to receive(:submit_metrics). + with([hash]) transaction.submit end @@ -154,8 +154,8 @@ describe Gitlab::Metrics::Transaction do timestamp: a_kind_of(Integer) } - expect(Gitlab::Metrics).to receive(:submit_metrics) - .with([hash]) + expect(Gitlab::Metrics).to receive(:submit_metrics). + with([hash]) transaction.submit end diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb index c8d292f4566..ab6e311b1e8 100644 --- a/spec/lib/gitlab/metrics_spec.rb +++ b/spec/lib/gitlab/metrics_spec.rb @@ -28,8 +28,8 @@ describe Gitlab::Metrics do describe '.prepare_metrics' do it 'returns a Hash with the keys as Symbols' do - metrics = described_class - .prepare_metrics([{ 'values' => {}, 'tags' => {} }]) + metrics = described_class. + prepare_metrics([{ 'values' => {}, 'tags' => {} }]) expect(metrics).to eq([{ values: {}, tags: {} }]) end @@ -74,19 +74,19 @@ describe Gitlab::Metrics do let(:transaction) { Gitlab::Metrics::Transaction.new } before do - allow(Gitlab::Metrics).to receive(:current_transaction) - .and_return(transaction) + allow(Gitlab::Metrics).to receive(:current_transaction). + and_return(transaction) end it 'adds a metric to the current transaction' do - expect(transaction).to receive(:increment) - .with('foo_real_time', a_kind_of(Numeric)) + expect(transaction).to receive(:increment). + with('foo_real_time', a_kind_of(Numeric)) - expect(transaction).to receive(:increment) - .with('foo_cpu_time', a_kind_of(Numeric)) + expect(transaction).to receive(:increment). + with('foo_cpu_time', a_kind_of(Numeric)) - expect(transaction).to receive(:increment) - .with('foo_call_count', 1) + expect(transaction).to receive(:increment). + with('foo_call_count', 1) Gitlab::Metrics.measure(:foo) { 10 } end @@ -102,8 +102,8 @@ describe Gitlab::Metrics do describe '.tag_transaction' do context 'without a transaction' do it 'does nothing' do - expect_any_instance_of(Gitlab::Metrics::Transaction) - .not_to receive(:add_tag) + expect_any_instance_of(Gitlab::Metrics::Transaction). + not_to receive(:add_tag) Gitlab::Metrics.tag_transaction(:foo, 'bar') end @@ -113,11 +113,11 @@ describe Gitlab::Metrics do let(:transaction) { Gitlab::Metrics::Transaction.new } it 'adds the tag to the transaction' do - expect(Gitlab::Metrics).to receive(:current_transaction) - .and_return(transaction) + expect(Gitlab::Metrics).to receive(:current_transaction). + and_return(transaction) - expect(transaction).to receive(:add_tag) - .with(:foo, 'bar') + expect(transaction).to receive(:add_tag). + with(:foo, 'bar') Gitlab::Metrics.tag_transaction(:foo, 'bar') end @@ -127,8 +127,8 @@ describe Gitlab::Metrics do describe '.action=' do context 'without a transaction' do it 'does nothing' do - expect_any_instance_of(Gitlab::Metrics::Transaction) - .not_to receive(:action=) + expect_any_instance_of(Gitlab::Metrics::Transaction). + not_to receive(:action=) Gitlab::Metrics.action = 'foo' end @@ -138,8 +138,8 @@ describe Gitlab::Metrics do it 'sets the action of a transaction' do trans = Gitlab::Metrics::Transaction.new - expect(Gitlab::Metrics).to receive(:current_transaction) - .and_return(trans) + expect(Gitlab::Metrics).to receive(:current_transaction). + and_return(trans) expect(trans).to receive(:action=).with('foo') @@ -157,8 +157,8 @@ describe Gitlab::Metrics do describe '.add_event' do context 'without a transaction' do it 'does nothing' do - expect_any_instance_of(Gitlab::Metrics::Transaction) - .not_to receive(:add_event) + expect_any_instance_of(Gitlab::Metrics::Transaction). + not_to receive(:add_event) Gitlab::Metrics.add_event(:meow) end @@ -170,8 +170,8 @@ describe Gitlab::Metrics do expect(transaction).to receive(:add_event).with(:meow) - expect(Gitlab::Metrics).to receive(:current_transaction) - .and_return(transaction) + expect(Gitlab::Metrics).to receive(:current_transaction). + and_return(transaction) Gitlab::Metrics.add_event(:meow) end diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index c49d2b286ff..4de5991db37 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -188,8 +188,8 @@ describe Gitlab::OAuth::User, lib: true do oauth_user.save identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash) - .to match_array( + expect(identities_as_hash). + to match_array( [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'twitter', extern_uid: uid } diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb index 21c00c6e5b8..2370f56a613 100644 --- a/spec/lib/gitlab/route_map_spec.rb +++ b/spec/lib/gitlab/route_map_spec.rb @@ -4,43 +4,43 @@ describe Gitlab::RouteMap, lib: true do describe '#initialize' do context 'when the data is not YAML' do it 'raises an error' do - expect { described_class.new('"') } - .to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/) + expect { described_class.new('"') }. + to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/) end end context 'when the data is not a YAML array' do it 'raises an error' do - expect { described_class.new(YAML.dump('foo')) } - .to raise_error(Gitlab::RouteMap::FormatError, /an array/) + expect { described_class.new(YAML.dump('foo')) }. + to raise_error(Gitlab::RouteMap::FormatError, /an array/) end end context 'when an entry is not a hash' do it 'raises an error' do - expect { described_class.new(YAML.dump(['foo'])) } - .to raise_error(Gitlab::RouteMap::FormatError, /a hash/) + expect { described_class.new(YAML.dump(['foo'])) }. + to raise_error(Gitlab::RouteMap::FormatError, /a hash/) end end context 'when an entry does not have a source key' do it 'raises an error' do - expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) } - .to raise_error(Gitlab::RouteMap::FormatError, /source key/) + expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) }. + to raise_error(Gitlab::RouteMap::FormatError, /source key/) end end context 'when an entry does not have a public key' do it 'raises an error' do - expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) } - .to raise_error(Gitlab::RouteMap::FormatError, /public key/) + expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) }. + to raise_error(Gitlab::RouteMap::FormatError, /public key/) end end context 'when an entry source is not a valid regex' do it 'raises an error' do - expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) } - .to raise_error(Gitlab::RouteMap::FormatError, /regular expression/) + expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) }. + to raise_error(Gitlab::RouteMap::FormatError, /regular expression/) end end diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb index 519eb1b274f..e05160da7a6 100644 --- a/spec/lib/gitlab/serializer/pagination_spec.rb +++ b/spec/lib/gitlab/serializer/pagination_spec.rb @@ -6,11 +6,11 @@ describe Gitlab::Serializer::Pagination do let(:headers) { spy('headers') } before do - allow(request).to receive(:query_parameters) - .and_return(params) + allow(request).to receive(:query_parameters). + and_return(params) - allow(response).to receive(:headers) - .and_return(headers) + allow(response).to receive(:headers). + and_return(headers) end let(:pagination) { described_class.new(request, response) } diff --git a/spec/lib/gitlab/sherlock/file_sample_spec.rb b/spec/lib/gitlab/sherlock/file_sample_spec.rb index 4989d14def3..cadf8bbce78 100644 --- a/spec/lib/gitlab/sherlock/file_sample_spec.rb +++ b/spec/lib/gitlab/sherlock/file_sample_spec.rb @@ -35,8 +35,8 @@ describe Gitlab::Sherlock::FileSample, lib: true do describe '#relative_path' do it 'returns the relative path' do - expect(sample.relative_path) - .to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb') + expect(sample.relative_path). + to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb') end end diff --git a/spec/lib/gitlab/sherlock/line_profiler_spec.rb b/spec/lib/gitlab/sherlock/line_profiler_spec.rb index 39c6b2a4844..d57627bba2b 100644 --- a/spec/lib/gitlab/sherlock/line_profiler_spec.rb +++ b/spec/lib/gitlab/sherlock/line_profiler_spec.rb @@ -20,9 +20,9 @@ describe Gitlab::Sherlock::LineProfiler, lib: true do describe '#profile_mri' do it 'returns an Array containing the return value and profiling samples' do - allow(profiler).to receive(:lineprof) - .and_yield - .and_return({ __FILE__ => [[0, 0, 0, 0]] }) + allow(profiler).to receive(:lineprof). + and_yield. + and_return({ __FILE__ => [[0, 0, 0, 0]] }) retval, samples = profiler.profile_mri { 42 } diff --git a/spec/lib/gitlab/sherlock/middleware_spec.rb b/spec/lib/gitlab/sherlock/middleware_spec.rb index b98ab0b14a2..2bbeb25ce98 100644 --- a/spec/lib/gitlab/sherlock/middleware_spec.rb +++ b/spec/lib/gitlab/sherlock/middleware_spec.rb @@ -72,8 +72,8 @@ describe Gitlab::Sherlock::Middleware, lib: true do 'REQUEST_URI' => '/cats' } - expect(middleware.transaction_from_env(env)) - .to be_an_instance_of(Gitlab::Sherlock::Transaction) + expect(middleware.transaction_from_env(env)). + to be_an_instance_of(Gitlab::Sherlock::Transaction) end end end diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb index d97b5eef573..0a620428138 100644 --- a/spec/lib/gitlab/sherlock/query_spec.rb +++ b/spec/lib/gitlab/sherlock/query_spec.rb @@ -13,8 +13,8 @@ describe Gitlab::Sherlock::Query, lib: true do sql = 'SELECT COUNT(*) FROM users WHERE id = $1' bindings = [[double(:column), 10]] - query = described_class - .new_with_bindings(sql, bindings, started_at, finished_at) + query = described_class. + new_with_bindings(sql, bindings, started_at, finished_at) expect(query.query).to eq('SELECT COUNT(*) FROM users WHERE id = 10;') end diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb index 6ae1aa20ea7..9fe18f253f0 100644 --- a/spec/lib/gitlab/sherlock/transaction_spec.rb +++ b/spec/lib/gitlab/sherlock/transaction_spec.rb @@ -109,8 +109,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do query1 = Gitlab::Sherlock::Query.new('SELECT 1', start_time, start_time) - query2 = Gitlab::Sherlock::Query - .new('SELECT 2', start_time, start_time + 5) + query2 = Gitlab::Sherlock::Query. + new('SELECT 2', start_time, start_time + 5) transaction.queries << query1 transaction.queries << query2 @@ -162,11 +162,11 @@ describe Gitlab::Sherlock::Transaction, lib: true do describe '#profile_lines' do describe 'when line profiling is enabled' do it 'yields the block using the line profiler' do - allow(Gitlab::Sherlock).to receive(:enable_line_profiler?) - .and_return(true) + allow(Gitlab::Sherlock).to receive(:enable_line_profiler?). + and_return(true) - allow_any_instance_of(Gitlab::Sherlock::LineProfiler) - .to receive(:profile).and_return('cats are amazing', []) + allow_any_instance_of(Gitlab::Sherlock::LineProfiler). + to receive(:profile).and_return('cats are amazing', []) retval = transaction.profile_lines { 'cats are amazing' } @@ -176,8 +176,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do describe 'when line profiling is disabled' do it 'yields the block' do - allow(Gitlab::Sherlock).to receive(:enable_line_profiler?) - .and_return(false) + allow(Gitlab::Sherlock).to receive(:enable_line_profiler?). + and_return(false) retval = transaction.profile_lines { 'cats are amazing' } @@ -196,8 +196,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do end it 'tracks executed queries' do - expect(transaction).to receive(:track_query) - .with('SELECT 1', [], time, time) + expect(transaction).to receive(:track_query). + with('SELECT 1', [], time, time) subscription.publish('test', time, time, nil, query_data) end @@ -205,8 +205,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do it 'only tracks queries triggered from the transaction thread' do expect(transaction).not_to receive(:track_query) - Thread.new { subscription.publish('test', time, time, nil, query_data) } - .join + Thread.new { subscription.publish('test', time, time, nil, query_data) }. + join end end @@ -228,8 +228,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do it 'only tracks views rendered from the transaction thread' do expect(transaction).not_to receive(:track_view) - Thread.new { subscription.publish('test', time, time, nil, view_data) } - .join + Thread.new { subscription.publish('test', time, time, nil, view_data) }. + join end end end diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb index 5faa5597aa5..287bf62d9bd 100644 --- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb +++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb @@ -5,8 +5,8 @@ describe Gitlab::SidekiqStatus::ClientMiddleware do it 'tracks the job in Redis' do expect(Gitlab::SidekiqStatus).to receive(:set).with('123') - described_class.new - .call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil } + described_class.new. + call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil } end end end diff --git a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb index 04e09d3dec8..80728197b8c 100644 --- a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb +++ b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb @@ -5,8 +5,8 @@ describe Gitlab::SidekiqStatus::ServerMiddleware do it 'stops tracking of a job upon completion' do expect(Gitlab::SidekiqStatus).to receive(:unset).with('123') - ret = described_class.new - .call(double(:worker), { 'jid' => '123' }, double(:queue)) { 10 } + ret = described_class.new. + call(double(:worker), { 'jid' => '123' }, double(:queue)) { 10 } expect(ret).to eq(10) end diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb index 027d832308c..3fe8cf43934 100644 --- a/spec/lib/gitlab/url_builder_spec.rb +++ b/spec/lib/gitlab/url_builder_spec.rb @@ -101,8 +101,8 @@ describe Gitlab::UrlBuilder, lib: true do it 'returns a proper URL' do project = build_stubbed(:empty_project) - expect { described_class.build(project) } - .to raise_error(NotImplementedError, 'No URL builder defined for Project') + expect { described_class.build(project) }. + to raise_error(NotImplementedError, 'No URL builder defined for Project') end end end diff --git a/spec/lib/gitlab/view/presenter/delegated_spec.rb b/spec/lib/gitlab/view/presenter/delegated_spec.rb index 940a2ce6ebd..e9d4af54389 100644 --- a/spec/lib/gitlab/view/presenter/delegated_spec.rb +++ b/spec/lib/gitlab/view/presenter/delegated_spec.rb @@ -18,8 +18,8 @@ describe Gitlab::View::Presenter::Delegated do end it 'raise an error if the presentee already respond to method' do - expect { presenter_class.new(project, user: 'Jane Doe') } - .to raise_error Gitlab::View::Presenter::CannotOverrideMethodError + expect { presenter_class.new(project, user: 'Jane Doe') }. + to raise_error Gitlab::View::Presenter::CannotOverrideMethodError end end diff --git a/spec/lib/light_url_builder_spec.rb b/spec/lib/light_url_builder_spec.rb index 027d832308c..3fe8cf43934 100644 --- a/spec/lib/light_url_builder_spec.rb +++ b/spec/lib/light_url_builder_spec.rb @@ -101,8 +101,8 @@ describe Gitlab::UrlBuilder, lib: true do it 'returns a proper URL' do project = build_stubbed(:empty_project) - expect { described_class.build(project) } - .to raise_error(NotImplementedError, 'No URL builder defined for Project') + expect { described_class.build(project) }. + to raise_error(NotImplementedError, 'No URL builder defined for Project') end end end diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb index 369e7b181b9..4b5938edeb9 100644 --- a/spec/lib/mattermost/command_spec.rb +++ b/spec/lib/mattermost/command_spec.rb @@ -6,8 +6,8 @@ describe Mattermost::Command do before do Mattermost::Session.base_uri('http://mattermost.example.com') - allow_any_instance_of(Mattermost::Client).to receive(:with_session) - .and_yield(Mattermost::Session.new(nil)) + allow_any_instance_of(Mattermost::Client).to receive(:with_session). + and_yield(Mattermost::Session.new(nil)) end describe '#create' do @@ -20,12 +20,12 @@ describe Mattermost::Command do context 'for valid trigger word' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') - .with(body: { + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). + with(body: { team_id: 'abc', trigger: 'gitlab' - }.to_json) - .to_return( + }.to_json). + to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: { token: 'token' }.to_json @@ -39,8 +39,8 @@ describe Mattermost::Command do context 'for error message' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') - .to_return( + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). + to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb index be3908e8f6a..74d12e37181 100644 --- a/spec/lib/mattermost/session_spec.rb +++ b/spec/lib/mattermost/session_spec.rb @@ -21,8 +21,8 @@ describe Mattermost::Session, type: :request do describe '#with session' do let(:location) { 'http://location.tld' } let!(:stub) do - WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login") - .to_return(headers: { 'location' => location }, status: 307) + WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login"). + to_return(headers: { 'location' => location }, status: 307) end context 'without oauth uri' do @@ -60,9 +60,9 @@ describe Mattermost::Session, type: :request do end before do - WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete") - .with(query: hash_including({ 'state' => state })) - .to_return do |request| + WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete"). + with(query: hash_including({ 'state' => state })). + to_return do |request| post "/oauth/token", client_id: doorkeeper.uid, client_secret: doorkeeper.secret, @@ -75,8 +75,8 @@ describe Mattermost::Session, type: :request do end end - WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout") - .to_return(headers: { Authorization: 'token thisworksnow' }, status: 200) + WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout"). + to_return(headers: { Authorization: 'token thisworksnow' }, status: 200) end it 'can setup a session' do diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb index 339178954ea..6a9c7cebfff 100644 --- a/spec/lib/mattermost/team_spec.rb +++ b/spec/lib/mattermost/team_spec.rb @@ -4,8 +4,8 @@ describe Mattermost::Team do before do Mattermost::Session.base_uri('http://mattermost.example.com') - allow_any_instance_of(Mattermost::Client).to receive(:with_session) - .and_yield(Mattermost::Session.new(nil)) + allow_any_instance_of(Mattermost::Client).to receive(:with_session). + and_yield(Mattermost::Session.new(nil)) end describe '#all' do @@ -30,8 +30,8 @@ describe Mattermost::Team do end before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') - .to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). + to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: response.to_json @@ -45,8 +45,8 @@ describe Mattermost::Team do context 'for error message' do before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') - .to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). + to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { diff --git a/spec/mailers/abuse_report_mailer_spec.rb b/spec/mailers/abuse_report_mailer_spec.rb index bda892083b3..eb433c38873 100644 --- a/spec/mailers/abuse_report_mailer_spec.rb +++ b/spec/mailers/abuse_report_mailer_spec.rb @@ -30,8 +30,8 @@ describe AbuseReportMailer do it 'returns early' do stub_application_setting(admin_notification_email: nil) - expect { described_class.notify(spy).deliver_now } - .not_to change { ActionMailer::Base.deliveries.count } + expect { described_class.notify(spy).deliver_now }. + not_to change { ActionMailer::Base.deliveries.count } end end end diff --git a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb index 1cbaa90151f..b6d678bac18 100644 --- a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb +++ b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb @@ -11,33 +11,33 @@ describe MigrateProcessCommitWorkerJobs do describe 'Project' do describe 'find_including_path' do it 'returns Project instances' do - expect(described_class::Project.find_including_path(project.id)) - .to be_an_instance_of(described_class::Project) + expect(described_class::Project.find_including_path(project.id)). + to be_an_instance_of(described_class::Project) end it 'selects the full path for every Project' do - migration_project = described_class::Project - .find_including_path(project.id) + migration_project = described_class::Project. + find_including_path(project.id) - expect(migration_project[:path_with_namespace]) - .to eq(project.path_with_namespace) + expect(migration_project[:path_with_namespace]). + to eq(project.path_with_namespace) end end describe '#repository_storage_path' do it 'returns the storage path for the repository' do - migration_project = described_class::Project - .find_including_path(project.id) + migration_project = described_class::Project. + find_including_path(project.id) - expect(File.directory?(migration_project.repository_storage_path)) - .to eq(true) + expect(File.directory?(migration_project.repository_storage_path)). + to eq(true) end end describe '#repository_path' do it 'returns the path to the repository' do - migration_project = described_class::Project - .find_including_path(project.id) + migration_project = described_class::Project. + find_including_path(project.id) expect(File.directory?(migration_project.repository_path)).to eq(true) end @@ -45,11 +45,11 @@ describe MigrateProcessCommitWorkerJobs do describe '#repository' do it 'returns a Rugged::Repository' do - migration_project = described_class::Project - .find_including_path(project.id) + migration_project = described_class::Project. + find_including_path(project.id) - expect(migration_project.repository) - .to be_an_instance_of(Rugged::Repository) + expect(migration_project.repository). + to be_an_instance_of(Rugged::Repository) end end end @@ -73,9 +73,9 @@ describe MigrateProcessCommitWorkerJobs do end it 'skips jobs using a project that no longer exists' do - allow(described_class::Project).to receive(:find_including_path) - .with(project.id) - .and_return(nil) + allow(described_class::Project).to receive(:find_including_path). + with(project.id). + and_return(nil) migration.up @@ -83,9 +83,9 @@ describe MigrateProcessCommitWorkerJobs do end it 'skips jobs using commits that no longer exist' do - allow_any_instance_of(Rugged::Repository).to receive(:lookup) - .with(commit.oid) - .and_raise(Rugged::OdbError) + allow_any_instance_of(Rugged::Repository).to receive(:lookup). + with(commit.oid). + and_raise(Rugged::OdbError) migration.up @@ -99,12 +99,12 @@ describe MigrateProcessCommitWorkerJobs do end it 'encodes data to UTF-8' do - allow_any_instance_of(Rugged::Repository).to receive(:lookup) - .with(commit.oid) - .and_return(commit) + allow_any_instance_of(Rugged::Repository).to receive(:lookup). + with(commit.oid). + and_return(commit) - allow(commit).to receive(:message) - .and_return('김치'.force_encoding('BINARY')) + allow(commit).to receive(:message). + and_return('김치'.force_encoding('BINARY')) migration.up diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index c34e58afaaf..30f8fdf91b2 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -63,8 +63,8 @@ describe Ability, lib: true do project = create(:empty_project, :public) user = build(:user) - expect(described_class.users_that_can_read_project([user], project)) - .to eq([user]) + expect(described_class.users_that_can_read_project([user], project)). + to eq([user]) end end @@ -74,8 +74,8 @@ describe Ability, lib: true do it 'returns users that are administrators' do user = build(:user, admin: true) - expect(described_class.users_that_can_read_project([user], project)) - .to eq([user]) + expect(described_class.users_that_can_read_project([user], project)). + to eq([user]) end it 'returns internal users while skipping external users' do @@ -83,8 +83,8 @@ describe Ability, lib: true do user2 = build(:user, external: true) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)) - .to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([user1]) end it 'returns external users if they are the project owner' do @@ -94,8 +94,8 @@ describe Ability, lib: true do expect(project).to receive(:owner).twice.and_return(user1) - expect(described_class.users_that_can_read_project(users, project)) - .to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([user1]) end it 'returns external users if they are project members' do @@ -105,8 +105,8 @@ describe Ability, lib: true do expect(project.team).to receive(:members).twice.and_return([user1]) - expect(described_class.users_that_can_read_project(users, project)) - .to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([user1]) end it 'returns an empty Array if all users are external users without access' do @@ -114,8 +114,8 @@ describe Ability, lib: true do user2 = build(:user, external: true) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)) - .to eq([]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([]) end end @@ -125,8 +125,8 @@ describe Ability, lib: true do it 'returns users that are administrators' do user = build(:user, admin: true) - expect(described_class.users_that_can_read_project([user], project)) - .to eq([user]) + expect(described_class.users_that_can_read_project([user], project)). + to eq([user]) end it 'returns external users if they are the project owner' do @@ -136,8 +136,8 @@ describe Ability, lib: true do expect(project).to receive(:owner).twice.and_return(user1) - expect(described_class.users_that_can_read_project(users, project)) - .to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([user1]) end it 'returns external users if they are project members' do @@ -147,8 +147,8 @@ describe Ability, lib: true do expect(project.team).to receive(:members).twice.and_return([user1]) - expect(described_class.users_that_can_read_project(users, project)) - .to eq([user1]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([user1]) end it 'returns an empty Array if all users are internal users without access' do @@ -156,8 +156,8 @@ describe Ability, lib: true do user2 = build(:user) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)) - .to eq([]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([]) end it 'returns an empty Array if all users are external users without access' do @@ -165,8 +165,8 @@ describe Ability, lib: true do user2 = build(:user, external: true) users = [user1, user2] - expect(described_class.users_that_can_read_project(users, project)) - .to eq([]) + expect(described_class.users_that_can_read_project(users, project)). + to eq([]) end end end @@ -204,8 +204,8 @@ describe Ability, lib: true do user = build(:user, admin: true) issue = build(:issue) - expect(described_class.issues_readable_by_user([issue], user)) - .to eq([issue]) + expect(described_class.issues_readable_by_user([issue], user)). + to eq([issue]) end end @@ -216,8 +216,8 @@ describe Ability, lib: true do expect(issue).to receive(:readable_by?).with(user).and_return(true) - expect(described_class.issues_readable_by_user([issue], user)) - .to eq([issue]) + expect(described_class.issues_readable_by_user([issue], user)). + to eq([issue]) end it 'returns an empty Array when no issues are readable' do @@ -238,8 +238,8 @@ describe Ability, lib: true do expect(hidden_issue).to receive(:publicly_visible?).and_return(false) expect(visible_issue).to receive(:publicly_visible?).and_return(true) - issues = described_class - .issues_readable_by_user([hidden_issue, visible_issue]) + issues = described_class. + issues_readable_by_user([hidden_issue, visible_issue]) expect(issues).to eq([visible_issue]) end diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb index d26e491e548..c4486a32082 100644 --- a/spec/models/abuse_report_spec.rb +++ b/spec/models/abuse_report_spec.rb @@ -37,8 +37,8 @@ RSpec.describe AbuseReport, type: :model do describe '#notify' do it 'delivers' do - expect(AbuseReportMailer).to receive(:notify).with(subject.id) - .and_return(spy) + expect(AbuseReportMailer).to receive(:notify).with(subject.id). + and_return(spy) subject.notify end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 4086e00e363..8688639168b 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -32,9 +32,9 @@ describe ApplicationSetting, models: true do it { is_expected.to validate_presence_of(:max_attachment_size) } it do - is_expected.to validate_numericality_of(:max_attachment_size) - .only_integer - .is_greater_than(0) + is_expected.to validate_numericality_of(:max_attachment_size). + only_integer. + is_greater_than(0) end it_behaves_like 'an object with email-formated attributes', :admin_notification_email do diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 355b8bf3af8..a173e3aeff6 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -212,15 +212,15 @@ describe Ci::Build, :models do retried_rspec = Ci::Build.retry(rspec_test, user) - expect(staging.depends_on_builds.map(&:id)) - .to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) + expect(staging.depends_on_builds.map(&:id)). + to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) end end describe '#detailed_status' do it 'returns a detailed status' do - expect(build.detailed_status(user)) - .to be_a Gitlab::Ci::Status::Build::Cancelable + expect(build.detailed_status(user)). + to be_a Gitlab::Ci::Status::Build::Cancelable end end @@ -784,8 +784,8 @@ describe Ci::Build, :models do pipeline2 = create(:ci_pipeline, project: project) @build2 = create(:ci_build, pipeline: pipeline2) - allow(@merge_request).to receive(:commits_sha) - .and_return([pipeline.sha, pipeline2.sha]) + allow(@merge_request).to receive(:commits_sha). + and_return([pipeline.sha, pipeline2.sha]) allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request]) end @@ -1151,8 +1151,8 @@ describe Ci::Build, :models do let!(:build) { create(:ci_build, artifacts_size: 23) } it 'updates project statistics when the artifact size changes' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(build.project_id, [], [:build_artifacts_size]) build.artifacts_size = 42 build.save! @@ -1166,8 +1166,8 @@ describe Ci::Build, :models do end it 'updates project statistics when the build is destroyed' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(build.project_id, [], [:build_artifacts_size]) build.destroy end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 9eff58880e3..c2fc8c02bb3 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -455,8 +455,8 @@ describe Ci::Pipeline, models: true do it 'returns the latest pipeline for the same ref and different sha' do expect(pipelines.map(&:sha)).to contain_exactly('A', 'B', 'C') - expect(pipelines.map(&:status)) - .to contain_exactly('success', 'failed', 'skipped') + expect(pipelines.map(&:status)). + to contain_exactly('success', 'failed', 'skipped') end end @@ -465,8 +465,8 @@ describe Ci::Pipeline, models: true do it 'returns the latest pipeline for ref and different sha' do expect(pipelines.map(&:sha)).to contain_exactly('A', 'B') - expect(pipelines.map(&:status)) - .to contain_exactly('success', 'failed') + expect(pipelines.map(&:status)). + to contain_exactly('success', 'failed') end end end @@ -501,8 +501,8 @@ describe Ci::Pipeline, models: true do end it 'returns the latest successful pipeline' do - expect(described_class.latest_successful_for('ref')) - .to eq(latest_successful_pipeline) + expect(described_class.latest_successful_for('ref')). + to eq(latest_successful_pipeline) end end diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index 674c52eecb2..bee9f714849 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -32,8 +32,8 @@ describe Ci::Variable, models: true do it 'fails to decrypt if iv is incorrect' do subject.encrypted_value_iv = SecureRandom.hex subject.instance_variable_set(:@value, nil) - expect { subject.value } - .to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt') + expect { subject.value }. + to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt') end end end diff --git a/spec/models/commit_range_spec.rb b/spec/models/commit_range_spec.rb index ba9c3f66d21..e4bddf67096 100644 --- a/spec/models/commit_range_spec.rb +++ b/spec/models/commit_range_spec.rb @@ -147,9 +147,9 @@ describe CommitRange, models: true do note: commit1.revert_description(user), project: issue.project) - expect_any_instance_of(Commit).to receive(:reverts_commit?) - .with(commit1, user) - .and_return(true) + expect_any_instance_of(Commit).to receive(:reverts_commit?). + with(commit1, user). + and_return(true) expect(commit1.has_been_reverted?(user, issue)).to eq(true) end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 36533bdd11e..f770e6a9e34 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -253,8 +253,8 @@ describe CommitStatus, :models do let(:user) { create(:user) } it 'returns a detailed status' do - expect(commit_status.detailed_status(user)) - .to be_a Gitlab::Ci::Status::Success + expect(commit_status.detailed_status(user)). + to be_a Gitlab::Ci::Status::Success end end diff --git a/spec/models/concerns/case_sensitivity_spec.rb b/spec/models/concerns/case_sensitivity_spec.rb index a6fccb668e3..92fdc5cd65d 100644 --- a/spec/models/concerns/case_sensitivity_spec.rb +++ b/spec/models/concerns/case_sensitivity_spec.rb @@ -15,13 +15,13 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:foo) - .and_return('"foo"') + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('"foo"') - expect(model).to receive(:where) - .with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar') - .and_return(criteria) + expect(model).to receive(:where). + with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar'). + and_return(criteria) expect(model.iwhere(foo: 'bar')).to eq(criteria) end @@ -29,13 +29,13 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column with a table, and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:'foo.bar') - .and_return('"foo"."bar"') + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('"foo"."bar"') - expect(model).to receive(:where) - .with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar') - .and_return(criteria) + expect(model).to receive(:where). + with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar'). + and_return(criteria) expect(model.iwhere('foo.bar'.to_sym => 'bar')).to eq(criteria) end @@ -46,21 +46,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:foo) - .and_return('"foo"') + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('"foo"') - expect(connection).to receive(:quote_table_name) - .with(:bar) - .and_return('"bar"') + expect(connection).to receive(:quote_table_name). + with(:bar). + and_return('"bar"') - expect(model).to receive(:where) - .with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar') - .and_return(initial) + expect(model).to receive(:where). + with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar'). + and_return(initial) - expect(initial).to receive(:where) - .with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz') - .and_return(final) + expect(initial).to receive(:where). + with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz'). + and_return(final) got = model.iwhere(foo: 'bar', bar: 'baz') @@ -71,21 +71,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:'foo.bar') - .and_return('"foo"."bar"') + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('"foo"."bar"') - expect(connection).to receive(:quote_table_name) - .with(:'foo.baz') - .and_return('"foo"."baz"') + expect(connection).to receive(:quote_table_name). + with(:'foo.baz'). + and_return('"foo"."baz"') - expect(model).to receive(:where) - .with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar') - .and_return(initial) + expect(model).to receive(:where). + with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar'). + and_return(initial) - expect(initial).to receive(:where) - .with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz') - .and_return(final) + expect(initial).to receive(:where). + with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz'). + and_return(final) got = model.iwhere('foo.bar'.to_sym => 'bar', 'foo.baz'.to_sym => 'baz') @@ -105,13 +105,13 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:foo) - .and_return('`foo`') + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('`foo`') - expect(model).to receive(:where) - .with(%q{`foo` = :value}, value: 'bar') - .and_return(criteria) + expect(model).to receive(:where). + with(%q{`foo` = :value}, value: 'bar'). + and_return(criteria) expect(model.iwhere(foo: 'bar')).to eq(criteria) end @@ -119,16 +119,16 @@ describe CaseSensitivity, models: true do it 'returns the criteria for a column with a table, and a value' do criteria = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:'foo.bar') - .and_return('`foo`.`bar`') + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('`foo`.`bar`') - expect(model).to receive(:where) - .with(%q{`foo`.`bar` = :value}, value: 'bar') - .and_return(criteria) + expect(model).to receive(:where). + with(%q{`foo`.`bar` = :value}, value: 'bar'). + and_return(criteria) - expect(model.iwhere('foo.bar'.to_sym => 'bar')) - .to eq(criteria) + expect(model.iwhere('foo.bar'.to_sym => 'bar')). + to eq(criteria) end end @@ -137,21 +137,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:foo) - .and_return('`foo`') + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('`foo`') - expect(connection).to receive(:quote_table_name) - .with(:bar) - .and_return('`bar`') + expect(connection).to receive(:quote_table_name). + with(:bar). + and_return('`bar`') - expect(model).to receive(:where) - .with(%q{`foo` = :value}, value: 'bar') - .and_return(initial) + expect(model).to receive(:where). + with(%q{`foo` = :value}, value: 'bar'). + and_return(initial) - expect(initial).to receive(:where) - .with(%q{`bar` = :value}, value: 'baz') - .and_return(final) + expect(initial).to receive(:where). + with(%q{`bar` = :value}, value: 'baz'). + and_return(final) got = model.iwhere(foo: 'bar', bar: 'baz') @@ -162,21 +162,21 @@ describe CaseSensitivity, models: true do initial = double(:criteria) final = double(:criteria) - expect(connection).to receive(:quote_table_name) - .with(:'foo.bar') - .and_return('`foo`.`bar`') + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('`foo`.`bar`') - expect(connection).to receive(:quote_table_name) - .with(:'foo.baz') - .and_return('`foo`.`baz`') + expect(connection).to receive(:quote_table_name). + with(:'foo.baz'). + and_return('`foo`.`baz`') - expect(model).to receive(:where) - .with(%q{`foo`.`bar` = :value}, value: 'bar') - .and_return(initial) + expect(model).to receive(:where). + with(%q{`foo`.`bar` = :value}, value: 'bar'). + and_return(initial) - expect(initial).to receive(:where) - .with(%q{`foo`.`baz` = :value}, value: 'baz') - .and_return(final) + expect(initial).to receive(:where). + with(%q{`foo`.`baz` = :value}, value: 'baz'). + and_return(final) got = model.iwhere('foo.bar'.to_sym => 'bar', 'foo.baz'.to_sym => 'baz') diff --git a/spec/models/concerns/has_status_spec.rb b/spec/models/concerns/has_status_spec.rb index e6107197368..dbfe3cd2d36 100644 --- a/spec/models/concerns/has_status_spec.rb +++ b/spec/models/concerns/has_status_spec.rb @@ -132,8 +132,8 @@ describe HasStatus do describe ".#{status}" do it 'contains the job' do - expect(CommitStatus.public_send(status).all) - .to contain_exactly(job) + expect(CommitStatus.public_send(status).all). + to contain_exactly(job) end end diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index a372824b6e5..545a11912e3 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -87,8 +87,8 @@ describe Issue, "Issuable" do let!(:searchable_issue) { create(:issue, title: "Searchable issue") } it 'returns notes with a matching title' do - expect(described_class.search(searchable_issue.title)) - .to eq([searchable_issue]) + expect(described_class.search(searchable_issue.title)). + to eq([searchable_issue]) end it 'returns notes with a partially matching title' do @@ -96,8 +96,8 @@ describe Issue, "Issuable" do end it 'returns notes with a matching title regardless of the casing' do - expect(described_class.search(searchable_issue.title.upcase)) - .to eq([searchable_issue]) + expect(described_class.search(searchable_issue.title.upcase)). + to eq([searchable_issue]) end end @@ -107,8 +107,8 @@ describe Issue, "Issuable" do end it 'returns notes with a matching title' do - expect(described_class.full_search(searchable_issue.title)) - .to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.title)). + to eq([searchable_issue]) end it 'returns notes with a partially matching title' do @@ -116,23 +116,23 @@ describe Issue, "Issuable" do end it 'returns notes with a matching title regardless of the casing' do - expect(described_class.full_search(searchable_issue.title.upcase)) - .to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.title.upcase)). + to eq([searchable_issue]) end it 'returns notes with a matching description' do - expect(described_class.full_search(searchable_issue.description)) - .to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.description)). + to eq([searchable_issue]) end it 'returns notes with a partially matching description' do - expect(described_class.full_search(searchable_issue.description)) - .to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.description)). + to eq([searchable_issue]) end it 'returns notes with a matching description regardless of the casing' do - expect(described_class.full_search(searchable_issue.description.upcase)) - .to eq([searchable_issue]) + expect(described_class.full_search(searchable_issue.description.upcase)). + to eq([searchable_issue]) end end @@ -287,16 +287,16 @@ describe Issue, "Issuable" do allow(issue).to receive(:author).and_return(double(name: 'Robert')) allow(issue).to receive(:assignee).and_return(nil) - expect(issue.card_attributes) - .to eq({ 'Author' => 'Robert', 'Assignee' => nil }) + expect(issue.card_attributes). + to eq({ 'Author' => 'Robert', 'Assignee' => nil }) end it 'includes the assignee name' do allow(issue).to receive(:author).and_return(double(name: 'Robert')) allow(issue).to receive(:assignee).and_return(double(name: 'Douwe')) - expect(issue.card_attributes) - .to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' }) + expect(issue.card_attributes). + to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' }) end end diff --git a/spec/models/discussion_spec.rb b/spec/models/discussion_spec.rb index 47c22a03797..bc32fadd391 100644 --- a/spec/models/discussion_spec.rb +++ b/spec/models/discussion_spec.rb @@ -304,22 +304,22 @@ describe Discussion, model: true do it "doesn't change resolved_at on the resolved note" do expect(first_note.resolved_at).not_to be_nil - expect { subject.resolve!(current_user) } - .not_to change { first_note.reload.resolved_at } + expect { subject.resolve!(current_user) }. + not_to change { first_note.reload.resolved_at } end it "doesn't change resolved_by on the resolved note" do expect(first_note.resolved_by).to eq(user) - expect { subject.resolve!(current_user) } - .not_to change { first_note.reload && first_note.resolved_by } + expect { subject.resolve!(current_user) }. + not_to change { first_note.reload && first_note.resolved_by } end it "doesn't change the resolved state on the resolved note" do expect(first_note.resolved?).to be true - expect { subject.resolve!(current_user) } - .not_to change { first_note.reload && first_note.resolved? } + expect { subject.resolve!(current_user) }. + not_to change { first_note.reload && first_note.resolved? } end it "sets resolved_at on the unresolved note" do diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index fe4de1b2afb..4652af1cb97 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -8,7 +8,7 @@ describe Email, models: true do end it 'normalize email value' do - expect(described_class.new(email: ' inFO@exAMPLe.com ').email) - .to eq 'info@example.com' + expect(described_class.new(email: ' inFO@exAMPLe.com ').email). + to eq 'info@example.com' end end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 3198f67a041..dce18f008f8 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -284,9 +284,9 @@ describe Environment, models: true do before { allow(environment).to receive(:has_terminals?).and_return(true) } it 'returns the terminals from the deployment service' do - expect(project.deployment_service) - .to receive(:terminals).with(environment) - .and_return(:fake_terminals) + expect(project.deployment_service). + to receive(:terminals).with(environment). + and_return(:fake_terminals) is_expected.to eq(:fake_terminals) end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index c5acfceb853..8c90a538f57 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -240,8 +240,8 @@ describe Event, models: true do it 'does not update the project' do project.update(last_activity_at: Time.now) - expect(project).not_to receive(:update_column) - .with(:last_activity_at, a_kind_of(Time)) + expect(project).not_to receive(:update_column). + with(:last_activity_at, a_kind_of(Time)) create_event(project, project.owner) end diff --git a/spec/models/group_label_spec.rb b/spec/models/group_label_spec.rb index 555a876daeb..c8d88022ec7 100644 --- a/spec/models/group_label_spec.rb +++ b/spec/models/group_label_spec.rb @@ -49,8 +49,8 @@ describe GroupLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) } - .to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) }. + to raise_error StandardError, /Unknown format/ end end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 57975d6c70b..a4e6eb4e3a6 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -309,8 +309,8 @@ describe Group, models: true do group.add_user(master, GroupMember::MASTER) group.add_user(developer, GroupMember::DEVELOPER) - expect(group.user_ids_for_project_authorizations) - .to include(master.id, developer.id) + expect(group.user_ids_for_project_authorizations). + to include(master.id, developer.id) end end end diff --git a/spec/models/issue_collection_spec.rb b/spec/models/issue_collection_spec.rb index 79584f94a4c..d8aed25c041 100644 --- a/spec/models/issue_collection_spec.rb +++ b/spec/models/issue_collection_spec.rb @@ -50,8 +50,8 @@ describe IssueCollection do context 'using a user that is the owner of a project' do it 'returns the issues of the project' do - expect(collection.updatable_by_user(project.namespace.owner)) - .to eq([issue1, issue2]) + expect(collection.updatable_by_user(project.namespace.owner)). + to eq([issue1, issue2]) end end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 143e84dac96..bba9058f394 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -239,8 +239,8 @@ describe Issue, models: true do let(:user) { build(:admin) } before do - allow(subject.project.repository).to receive(:branch_names) - .and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"]) + allow(subject.project.repository).to receive(:branch_names). + and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"]) # Without this stub, the `create(:merge_request)` above fails because it can't find # the source branch. This seems like a reasonable compromise, in comparison with @@ -262,8 +262,8 @@ describe Issue, models: true do end it 'excludes stable branches from the related branches' do - allow(subject.project.repository).to receive(:branch_names) - .and_return(["#{subject.iid}-0-stable"]) + allow(subject.project.repository).to receive(:branch_names). + and_return(["#{subject.iid}-0-stable"]) expect(subject.related_branches(user)).to eq [] end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index f5f7e82480e..7c40cfd8253 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -34,8 +34,8 @@ describe Key, models: true do context 'when key was not updated during the last day' do before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) - .and_return('000000') + allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). + and_return('000000') end it 'enqueues a UseKeyWorker job' do @@ -46,8 +46,8 @@ describe Key, models: true do context 'when key was updated during the last day' do before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) - .and_return(false) + allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). + and_return(false) end it 'does not enqueue a UseKeyWorker job' do diff --git a/spec/models/lfs_objects_project_spec.rb b/spec/models/lfs_objects_project_spec.rb index 7bc278e350f..a2031beeab2 100644 --- a/spec/models/lfs_objects_project_spec.rb +++ b/spec/models/lfs_objects_project_spec.rb @@ -18,8 +18,8 @@ describe LfsObjectsProject, models: true do describe '#update_project_statistics' do it 'updates project statistics when the object is added' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(project.id, [], [:lfs_objects_size]) subject.save! end @@ -27,8 +27,8 @@ describe LfsObjectsProject, models: true do it 'updates project statistics when the object is removed' do subject.save! - expect(ProjectCacheWorker).to receive(:perform_async) - .with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async). + with(project.id, [], [:lfs_objects_size]) subject.destroy end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index ec17000d17a..c720cc9f2c2 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -83,8 +83,8 @@ describe Member, models: true do @accepted_invite_member = create(:project_member, :developer, project: project, invite_token: '1234', - invite_email: 'toto2@example.com') - .tap { |u| u.accept_invite!(accepted_invite_user) } + invite_email: 'toto2@example.com'). + tap { |u| u.accept_invite!(accepted_invite_user) } requested_user = create(:user).tap { |u| project.request_access(u) } @requested_member = project.requesters.find_by(user_id: requested_user.id) @@ -265,8 +265,8 @@ describe Member, models: true do expect(source.users).not_to include(user) expect(source.requesters.exists?(user_id: user)).to be_truthy - expect { described_class.add_user(source, user, :master) } - .to raise_error(Gitlab::Access::AccessDeniedError) + expect { described_class.add_user(source, user, :master) }. + to raise_error(Gitlab::Access::AccessDeniedError) expect(source.users.reload).not_to include(user) expect(source.requesters.reload.exists?(user_id: user)).to be_truthy diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index 4a8ea3b6893..370aeb9e0a9 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -33,8 +33,8 @@ describe GroupMember, models: true do it "sends email to user" do membership = build(:group_member) - allow(membership).to receive(:notification_service) - .and_return(double('NotificationService').as_null_object) + allow(membership).to receive(:notification_service). + and_return(double('NotificationService').as_null_object) expect(membership).to receive(:notification_service) membership.save @@ -44,8 +44,8 @@ describe GroupMember, models: true do describe "#after_update" do before do @group_member = create :group_member - allow(@group_member).to receive(:notification_service) - .and_return(double('NotificationService').as_null_object) + allow(@group_member).to receive(:notification_service). + and_return(double('NotificationService').as_null_object) end it "sends email to user" do diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index 0a10ee01506..e74e4ae0e96 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -84,8 +84,8 @@ describe MergeRequestDiff, models: true do end it 'saves overflow state' do - allow(Commit).to receive(:max_diff_options) - .and_return(max_lines: 0, max_files: 0) + allow(Commit).to receive(:max_diff_options). + and_return(max_lines: 0, max_files: 0) mr_diff = create(:merge_request).merge_request_diff @@ -93,8 +93,8 @@ describe MergeRequestDiff, models: true do end it 'saves empty state' do - allow_any_instance_of(MergeRequestDiff).to receive(:commits) - .and_return([]) + allow_any_instance_of(MergeRequestDiff).to receive(:commits). + and_return([]) mr_diff = create(:merge_request).merge_request_diff diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 6a1f6cee03f..810c08256dc 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -270,8 +270,8 @@ describe MergeRequest, models: true do end it 'accesses the set of issues that will be closed on acceptance' do - allow(subject.project).to receive(:default_branch) - .and_return(subject.target_branch) + allow(subject.project).to receive(:default_branch). + and_return(subject.target_branch) closed = subject.closes_issues @@ -297,8 +297,8 @@ describe MergeRequest, models: true do subject.description = "Is related to #{mentioned_issue.to_reference} and #{closing_issue.to_reference}" allow(subject).to receive(:commits).and_return([commit]) - allow(subject.project).to receive(:default_branch) - .and_return(subject.target_branch) + allow(subject.project).to receive(:default_branch). + and_return(subject.target_branch) expect(subject.issues_mentioned_but_not_closing(subject.author)).to match_array([mentioned_issue]) end @@ -412,15 +412,15 @@ describe MergeRequest, models: true do it 'includes merge information as the title' do request = build(:merge_request, source_branch: 'source', target_branch: 'target') - expect(request.merge_commit_message) - .to match("Merge branch 'source' into 'target'\n\n") + expect(request.merge_commit_message). + to match("Merge branch 'source' into 'target'\n\n") end it 'includes its title in the body' do request = build(:merge_request, title: 'Remove all technical debt') - expect(request.merge_commit_message) - .to match("Remove all technical debt\n\n") + expect(request.merge_commit_message). + to match("Remove all technical debt\n\n") end it 'includes its closed issues in the body' do @@ -429,18 +429,18 @@ describe MergeRequest, models: true do subject.project.team << [subject.author, :developer] subject.description = "This issue Closes #{issue.to_reference}" - allow(subject.project).to receive(:default_branch) - .and_return(subject.target_branch) + allow(subject.project).to receive(:default_branch). + and_return(subject.target_branch) - expect(subject.merge_commit_message) - .to match("Closes #{issue.to_reference}") + expect(subject.merge_commit_message). + to match("Closes #{issue.to_reference}") end it 'includes its reference in the body' do request = build_stubbed(:merge_request) - expect(request.merge_commit_message) - .to match("See merge request #{request.to_reference}") + expect(request.merge_commit_message). + to match("See merge request #{request.to_reference}") end it 'excludes multiple linebreak runs when description is blank' do @@ -452,15 +452,15 @@ describe MergeRequest, models: true do it 'includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message(include_description: true)) - .to match("By removing all code\n\n") + expect(request.merge_commit_message(include_description: true)). + to match("By removing all code\n\n") end it 'does not includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message) - .not_to match("By removing all code\n\n") + expect(request.merge_commit_message). + not_to match("By removing all code\n\n") end end @@ -551,18 +551,18 @@ describe MergeRequest, models: true do end it 'caches the output' do - expect(subject).to receive(:compute_diverged_commits_count) - .once - .and_return(2) + expect(subject).to receive(:compute_diverged_commits_count). + once. + and_return(2) subject.diverged_commits_count subject.diverged_commits_count end it 'invalidates the cache when the source sha changes' do - expect(subject).to receive(:compute_diverged_commits_count) - .twice - .and_return(2) + expect(subject).to receive(:compute_diverged_commits_count). + twice. + and_return(2) subject.diverged_commits_count allow(subject).to receive(:source_branch_sha).and_return('123abc') @@ -570,9 +570,9 @@ describe MergeRequest, models: true do end it 'invalidates the cache when the target sha changes' do - expect(subject).to receive(:compute_diverged_commits_count) - .twice - .and_return(2) + expect(subject).to receive(:compute_diverged_commits_count). + twice. + and_return(2) subject.diverged_commits_count allow(subject).to receive(:target_branch_sha).and_return('123abc') @@ -594,8 +594,8 @@ describe MergeRequest, models: true do describe '#commits_sha' do before do - allow(subject.merge_request_diff).to receive(:commits_sha) - .and_return(['sha1']) + allow(subject.merge_request_diff).to receive(:commits_sha). + and_return(['sha1']) end it 'delegates to merge request diff' do @@ -610,9 +610,9 @@ describe MergeRequest, models: true do allow(subject).to receive(:diff_head_sha).and_return('123abc') - expect(subject.source_project).to receive(:pipeline_for) - .with('master', '123abc') - .and_return(pipeline) + expect(subject.source_project).to receive(:pipeline_for). + with('master', '123abc'). + and_return(pipeline) expect(subject.head_pipeline).to eq(pipeline) end @@ -1632,8 +1632,8 @@ describe MergeRequest, models: true do describe '#has_commits?' do before do - allow(subject.merge_request_diff).to receive(:commits_count) - .and_return(2) + allow(subject.merge_request_diff).to receive(:commits_count). + and_return(2) end it 'returns true when merge request diff has commits' do @@ -1643,8 +1643,8 @@ describe MergeRequest, models: true do describe '#has_no_commits?' do before do - allow(subject.merge_request_diff).to receive(:commits_count) - .and_return(0) + allow(subject.merge_request_diff).to receive(:commits_count). + and_return(0) end it 'returns true when merge request diff has 0 commits' do diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 0ffcbf7e3f6..3cee2b7714f 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -205,13 +205,13 @@ describe Milestone, models: true do end it 'returns milestones with a partially matching description' do - expect(described_class.search(milestone.description[0..2])) - .to eq([milestone]) + expect(described_class.search(milestone.description[0..2])). + to eq([milestone]) end it 'returns milestones with a matching description regardless of the casing' do - expect(described_class.search(milestone.description.upcase)) - .to eq([milestone]) + expect(described_class.search(milestone.description.upcase)). + to eq([milestone]) end end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 74fbae07a6f..35d932f1c64 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -216,8 +216,8 @@ describe Namespace, models: true do describe '#user_ids_for_project_authorizations' do it 'returns the user IDs for which to refresh authorizations' do - expect(namespace.user_ids_for_project_authorizations) - .to eq([namespace.owner_id]) + expect(namespace.user_ids_for_project_authorizations). + to eq([namespace.owner_id]) end end end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index 973a0b9d592..1cde9e04951 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -148,8 +148,8 @@ describe Note, models: true do let!(:note2) { create(:note_on_issue) } it "reads the rendered note body from the cache" do - expect(Banzai::Renderer).to receive(:cache_collection_render) - .with([{ + expect(Banzai::Renderer).to receive(:cache_collection_render). + with([{ text: note1.note, context: { skip_project_check: false, @@ -160,8 +160,8 @@ describe Note, models: true do } }]).and_call_original - expect(Banzai::Renderer).to receive(:cache_collection_render) - .with([{ + expect(Banzai::Renderer).to receive(:cache_collection_render). + with([{ text: note2.note, context: { skip_project_check: false, @@ -361,8 +361,8 @@ describe Note, models: true do let(:note) { build(:note_on_project_snippet) } before do - expect(Banzai::Renderer).to receive(:cacheless_render_field) - .with(note, :note, { skip_project_check: false }).and_return(html) + expect(Banzai::Renderer).to receive(:cacheless_render_field). + with(note, :note, { skip_project_check: false }).and_return(html) note.save end @@ -376,8 +376,8 @@ describe Note, models: true do let(:note) { build(:note_on_personal_snippet) } before do - expect(Banzai::Renderer).to receive(:cacheless_render_field) - .with(note, :note, { skip_project_check: true }).and_return(html) + expect(Banzai::Renderer).to receive(:cacheless_render_field). + with(note, :note, { skip_project_check: true }).and_return(html) note.save end diff --git a/spec/models/project_authorization_spec.rb b/spec/models/project_authorization_spec.rb index 4001851b9ec..33ef67f97a7 100644 --- a/spec/models/project_authorization_spec.rb +++ b/spec/models/project_authorization_spec.rb @@ -7,8 +7,8 @@ describe ProjectAuthorization do describe '.insert_authorizations' do it 'inserts the authorizations' do - described_class - .insert_authorizations([[user.id, project1.id, Gitlab::Access::MASTER]]) + described_class. + insert_authorizations([[user.id, project1.id, Gitlab::Access::MASTER]]) expect(user.project_authorizations.count).to eq(1) end diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb index 9cdbfa44e5b..3e9dd3758ed 100644 --- a/spec/models/project_label_spec.rb +++ b/spec/models/project_label_spec.rb @@ -94,8 +94,8 @@ describe ProjectLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) } - .to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) }. + to raise_error StandardError, /Unknown format/ end end @@ -104,15 +104,15 @@ describe ProjectLabel, models: true do context 'using name' do it 'returns cross reference with label name' do - expect(label.to_reference(project, format: :name)) - .to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") + expect(label.to_reference(project, format: :name)). + to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") end end context 'using id' do it 'returns cross reference with label id' do - expect(label.to_reference(project, format: :id)) - .to eq %Q(#{label.project.path_with_namespace}~#{label.id}) + expect(label.to_reference(project, format: :id)). + to eq %Q(#{label.project.path_with_namespace}~#{label.id}) end end end diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb index 9082156788e..598ff232c82 100644 --- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb +++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb @@ -11,8 +11,8 @@ describe MattermostSlashCommandsService, :models do before do Mattermost::Session.base_uri("http://mattermost.example.com") - allow_any_instance_of(Mattermost::Client).to receive(:with_session) - .and_yield(Mattermost::Session.new(nil)) + allow_any_instance_of(Mattermost::Client).to receive(:with_session). + and_yield(Mattermost::Session.new(nil)) end describe '#configure' do @@ -24,8 +24,8 @@ describe MattermostSlashCommandsService, :models do context 'the requests succeeds' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') - .with(body: { + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). + with(body: { team_id: 'abc', trigger: 'gitlab', url: 'http://trigger.url', @@ -37,8 +37,8 @@ describe MattermostSlashCommandsService, :models do display_name: "GitLab / #{project.name_with_namespace}", method: 'P', username: 'GitLab' - }.to_json) - .to_return( + }.to_json). + to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: { token: 'token' }.to_json @@ -58,8 +58,8 @@ describe MattermostSlashCommandsService, :models do context 'an error is received' do before do - stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create') - .to_return( + stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create'). + to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { @@ -88,8 +88,8 @@ describe MattermostSlashCommandsService, :models do context 'the requests succeeds' do before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') - .to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). + to_return( status: 200, headers: { 'Content-Type' => 'application/json' }, body: ['list'].to_json @@ -103,8 +103,8 @@ describe MattermostSlashCommandsService, :models do context 'an error is received' do before do - stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all') - .to_return( + stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all'). + to_return( status: 500, headers: { 'Content-Type' => 'application/json' }, body: { diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 66e0ea6d9a5..b0087a9e15d 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1150,23 +1150,23 @@ describe Project, models: true do it 'renames a repository' do ns = project.namespace_dir - expect(gitlab_shell).to receive(:mv_repository) - .ordered - .with(project.repository_storage_path, "#{ns}/foo", "#{ns}/#{project.path}") - .and_return(true) + expect(gitlab_shell).to receive(:mv_repository). + ordered. + with(project.repository_storage_path, "#{ns}/foo", "#{ns}/#{project.path}"). + and_return(true) - expect(gitlab_shell).to receive(:mv_repository) - .ordered - .with(project.repository_storage_path, "#{ns}/foo.wiki", "#{ns}/#{project.path}.wiki") - .and_return(true) + expect(gitlab_shell).to receive(:mv_repository). + ordered. + with(project.repository_storage_path, "#{ns}/foo.wiki", "#{ns}/#{project.path}.wiki"). + and_return(true) - expect_any_instance_of(SystemHooksService) - .to receive(:execute_hooks_for) - .with(project, :rename) + expect_any_instance_of(SystemHooksService). + to receive(:execute_hooks_for). + with(project, :rename) - expect_any_instance_of(Gitlab::UploadsTransfer) - .to receive(:rename_project) - .with('foo', project.path, ns) + expect_any_instance_of(Gitlab::UploadsTransfer). + to receive(:rename_project). + with('foo', project.path, ns) expect(project).to receive(:expire_caches_before_rename) @@ -1191,13 +1191,13 @@ describe Project, models: true do let(:wiki) { double(:wiki, exists?: true) } it 'expires the caches of the repository and wiki' do - allow(Repository).to receive(:new) - .with('foo', project) - .and_return(repo) + allow(Repository).to receive(:new). + with('foo', project). + and_return(repo) - allow(Repository).to receive(:new) - .with('foo.wiki', project) - .and_return(wiki) + allow(Repository).to receive(:new). + with('foo.wiki', project). + and_return(wiki) expect(repo).to receive(:before_delete) expect(wiki).to receive(:before_delete) @@ -1248,9 +1248,9 @@ describe Project, models: true do context 'using a regular repository' do it 'creates the repository' do - expect(shell).to receive(:add_repository) - .with(project.repository_storage_path, project.path_with_namespace) - .and_return(true) + expect(shell).to receive(:add_repository). + with(project.repository_storage_path, project.path_with_namespace). + and_return(true) expect(project.repository).to receive(:after_create) @@ -1258,9 +1258,9 @@ describe Project, models: true do end it 'adds an error if the repository could not be created' do - expect(shell).to receive(:add_repository) - .with(project.repository_storage_path, project.path_with_namespace) - .and_return(false) + expect(shell).to receive(:add_repository). + with(project.repository_storage_path, project.path_with_namespace). + and_return(false) expect(project.repository).not_to receive(:after_create) @@ -1536,8 +1536,8 @@ describe Project, models: true do let(:project) { forked_project_link.forked_to_project } it 'schedules a RepositoryForkWorker job' do - expect(RepositoryForkWorker).to receive(:perform_async) - .with(project.id, forked_from_project.repository_storage_path, + expect(RepositoryForkWorker).to receive(:perform_async). + with(project.id, forked_from_project.repository_storage_path, forked_from_project.path_with_namespace, project.namespace.path) project.add_import_job diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index 8c43937c398..58b57bd4fef 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -143,15 +143,15 @@ describe ProjectWiki, models: true do describe '#find_file' do before do file = Gollum::File.new(subject.wiki) - allow_any_instance_of(Gollum::Wiki) - .to receive(:file).with('image.jpg', 'master', true) - .and_return(file) - allow_any_instance_of(Gollum::File) - .to receive(:mime_type) - .and_return('image/jpeg') - allow_any_instance_of(Gollum::Wiki) - .to receive(:file).with('non-existant', 'master', true) - .and_return(nil) + allow_any_instance_of(Gollum::Wiki). + to receive(:file).with('image.jpg', 'master', true). + and_return(file) + allow_any_instance_of(Gollum::File). + to receive(:mime_type). + and_return('image/jpeg') + allow_any_instance_of(Gollum::Wiki). + to receive(:file).with('non-existant', 'master', true). + and_return(nil) end after do @@ -253,9 +253,9 @@ describe ProjectWiki, models: true do describe '#create_repo!' do it 'creates a repository' do - expect(subject).to receive(:init_repo) - .with(subject.path_with_namespace) - .and_return(true) + expect(subject).to receive(:init_repo). + with(subject.path_with_namespace). + and_return(true) expect(subject.repository).to receive(:after_create) diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index dfa019d28b0..a3fe412b229 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -125,8 +125,8 @@ describe Repository, models: true do describe '#ref_name_for_sha' do context 'ref found' do it 'returns the ref' do - allow_any_instance_of(Gitlab::Popen).to receive(:popen) - .and_return(["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0]) + allow_any_instance_of(Gitlab::Popen).to receive(:popen). + and_return(["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0]) expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77' end @@ -134,8 +134,8 @@ describe Repository, models: true do context 'ref not found' do it 'returns nil' do - allow_any_instance_of(Gitlab::Popen).to receive(:popen) - .and_return(["", 0]) + allow_any_instance_of(Gitlab::Popen).to receive(:popen). + and_return(["", 0]) expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq nil end @@ -265,8 +265,8 @@ describe Repository, models: true do describe '#commit' do context 'when ref exists' do it 'returns commit object' do - expect(repository.commit('master')) - .to be_an_instance_of Commit + expect(repository.commit('master')). + to be_an_instance_of Commit end end @@ -596,8 +596,8 @@ describe Repository, models: true do user, 'LICENSE', 'Copyright!', message: 'Add LICENSE', branch_name: 'master', update: false) - allow(repository).to receive(:file_on_head) - .and_raise(Rugged::ReferenceError) + allow(repository).to receive(:file_on_head). + and_raise(Rugged::ReferenceError) expect(repository.license_blob).to be_nil end @@ -749,8 +749,8 @@ describe Repository, models: true do context 'when pre hooks were successful' do it 'runs without errors' do - expect_any_instance_of(GitHooksService).to receive(:execute) - .with(user, project.repository.path_to_repo, old_rev, blank_sha, 'refs/heads/feature') + expect_any_instance_of(GitHooksService).to receive(:execute). + with(user, project.repository.path_to_repo, old_rev, blank_sha, 'refs/heads/feature') expect { repository.rm_branch(user, 'feature') }.not_to raise_error end @@ -792,14 +792,14 @@ describe Repository, models: true do before do service = GitHooksService.new expect(GitHooksService).to receive(:new).and_return(service) - expect(service).to receive(:execute) - .with( + expect(service).to receive(:execute). + with( user, repository.path_to_repo, old_rev, new_rev, - 'refs/heads/feature') - .and_yield(service).and_return(true) + 'refs/heads/feature'). + and_yield(service).and_return(true) end it 'runs without errors' do @@ -893,8 +893,8 @@ describe Repository, models: true do expect(repository).not_to receive(:expire_emptiness_caches) expect(repository).to receive(:expire_branches_cache) - GitOperationService.new(user, repository) - .with_branch('new-feature') do + GitOperationService.new(user, repository). + with_branch('new-feature') do new_rev end end @@ -978,8 +978,8 @@ describe Repository, models: true do end it 'does nothing' do - expect(repository.raw_repository).not_to receive(:autocrlf=) - .with(:input) + expect(repository.raw_repository).not_to receive(:autocrlf=). + with(:input) GitOperationService.new(nil, repository).send(:update_autocrlf_option) end @@ -998,9 +998,9 @@ describe Repository, models: true do end it 'caches the output' do - expect(repository.raw_repository).to receive(:empty?) - .once - .and_return(false) + expect(repository.raw_repository).to receive(:empty?). + once. + and_return(false) repository.empty? repository.empty? @@ -1013,9 +1013,9 @@ describe Repository, models: true do end it 'caches the output' do - expect(repository.raw_repository).to receive(:root_ref) - .once - .and_return('master') + expect(repository.raw_repository).to receive(:root_ref). + once. + and_return('master') repository.root_ref repository.root_ref @@ -1026,9 +1026,9 @@ describe Repository, models: true do it 'expires the root reference cache' do repository.root_ref - expect(repository.raw_repository).to receive(:root_ref) - .once - .and_return('foo') + expect(repository.raw_repository).to receive(:root_ref). + once. + and_return('foo') repository.expire_root_ref_cache @@ -1042,17 +1042,17 @@ describe Repository, models: true do let(:cache) { repository.send(:cache) } it 'expires the cache for all branches' do - expect(cache).to receive(:expire) - .at_least(repository.branches.length) - .times + expect(cache).to receive(:expire). + at_least(repository.branches.length). + times repository.expire_branch_cache end it 'expires the cache for all branches when the root branch is given' do - expect(cache).to receive(:expire) - .at_least(repository.branches.length) - .times + expect(cache).to receive(:expire). + at_least(repository.branches.length). + times repository.expire_branch_cache(repository.root_ref) end @@ -1314,12 +1314,12 @@ describe Repository, models: true do describe '#after_push_commit' do it 'expires statistics caches' do - expect(repository).to receive(:expire_statistics_caches) - .and_call_original + expect(repository).to receive(:expire_statistics_caches). + and_call_original - expect(repository).to receive(:expire_branch_cache) - .with('master') - .and_call_original + expect(repository).to receive(:expire_branch_cache). + with('master'). + and_call_original repository.after_push_commit('master') end @@ -1394,9 +1394,9 @@ describe Repository, models: true do describe '#expire_branches_cache' do it 'expires the cache' do - expect(repository).to receive(:expire_method_caches) - .with(%i(branch_names branch_count)) - .and_call_original + expect(repository).to receive(:expire_method_caches). + with(%i(branch_names branch_count)). + and_call_original repository.expire_branches_cache end @@ -1404,9 +1404,9 @@ describe Repository, models: true do describe '#expire_tags_cache' do it 'expires the cache' do - expect(repository).to receive(:expire_method_caches) - .with(%i(tag_names tag_count)) - .and_call_original + expect(repository).to receive(:expire_method_caches). + with(%i(tag_names tag_count)). + and_call_original repository.expire_tags_cache end @@ -1417,11 +1417,11 @@ describe Repository, models: true do let(:user) { build_stubbed(:user) } it 'creates the tag using rugged' do - expect(repository.rugged.tags).to receive(:create) - .with('8.5', repository.commit('master').id, + expect(repository.rugged.tags).to receive(:create). + with('8.5', repository.commit('master').id, hash_including(message: 'foo', - tagger: hash_including(name: user.name, email: user.email))) - .and_call_original + tagger: hash_including(name: user.name, email: user.email))). + and_call_original repository.add_tag(user, '8.5', 'master', 'foo') end @@ -1438,8 +1438,8 @@ describe Repository, models: true do update_hook = Gitlab::Git::Hook.new('update', repository.path_to_repo) post_receive_hook = Gitlab::Git::Hook.new('post-receive', repository.path_to_repo) - allow(Gitlab::Git::Hook).to receive(:new) - .and_return(pre_receive_hook, update_hook, post_receive_hook) + allow(Gitlab::Git::Hook).to receive(:new). + and_return(pre_receive_hook, update_hook, post_receive_hook) allow(pre_receive_hook).to receive(:trigger).and_call_original allow(update_hook).to receive(:trigger).and_call_original @@ -1450,12 +1450,12 @@ describe Repository, models: true do commit_sha = repository.commit('master').id tag_sha = tag.target - expect(pre_receive_hook).to have_received(:trigger) - .with(anything, anything, commit_sha, anything) - expect(update_hook).to have_received(:trigger) - .with(anything, anything, commit_sha, anything) - expect(post_receive_hook).to have_received(:trigger) - .with(anything, anything, tag_sha, anything) + expect(pre_receive_hook).to have_received(:trigger). + with(anything, anything, commit_sha, anything) + expect(update_hook).to have_received(:trigger). + with(anything, anything, commit_sha, anything) + expect(post_receive_hook).to have_received(:trigger). + with(anything, anything, tag_sha, anything) end end @@ -1489,25 +1489,25 @@ describe Repository, models: true do describe '#avatar' do it 'returns nil if repo does not exist' do - expect(repository).to receive(:file_on_head) - .and_raise(Rugged::ReferenceError) + expect(repository).to receive(:file_on_head). + and_raise(Rugged::ReferenceError) expect(repository.avatar).to eq(nil) end it 'returns the first avatar file found in the repository' do - expect(repository).to receive(:file_on_head) - .with(:avatar) - .and_return(double(:tree, path: 'logo.png')) + expect(repository).to receive(:file_on_head). + with(:avatar). + and_return(double(:tree, path: 'logo.png')) expect(repository.avatar).to eq('logo.png') end it 'caches the output' do - expect(repository).to receive(:file_on_head) - .with(:avatar) - .once - .and_return(double(:tree, path: 'logo.png')) + expect(repository).to receive(:file_on_head). + with(:avatar). + once. + and_return(double(:tree, path: 'logo.png')) 2.times { expect(repository.avatar).to eq('logo.png') } end @@ -1567,24 +1567,24 @@ describe Repository, models: true do describe '#contribution_guide', caching: true do it 'returns and caches the output' do - expect(repository).to receive(:file_on_head) - .with(:contributing) - .and_return(Gitlab::Git::Tree.new(path: 'CONTRIBUTING.md')) - .once + expect(repository).to receive(:file_on_head). + with(:contributing). + and_return(Gitlab::Git::Tree.new(path: 'CONTRIBUTING.md')). + once 2.times do - expect(repository.contribution_guide) - .to be_an_instance_of(Gitlab::Git::Tree) + expect(repository.contribution_guide). + to be_an_instance_of(Gitlab::Git::Tree) end end end describe '#gitignore', caching: true do it 'returns and caches the output' do - expect(repository).to receive(:file_on_head) - .with(:gitignore) - .and_return(Gitlab::Git::Tree.new(path: '.gitignore')) - .once + expect(repository).to receive(:file_on_head). + with(:gitignore). + and_return(Gitlab::Git::Tree.new(path: '.gitignore')). + once 2.times do expect(repository.gitignore).to be_an_instance_of(Gitlab::Git::Tree) @@ -1594,10 +1594,10 @@ describe Repository, models: true do describe '#koding_yml', caching: true do it 'returns and caches the output' do - expect(repository).to receive(:file_on_head) - .with(:koding) - .and_return(Gitlab::Git::Tree.new(path: '.koding.yml')) - .once + expect(repository).to receive(:file_on_head). + with(:koding). + and_return(Gitlab::Git::Tree.new(path: '.koding.yml')). + once 2.times do expect(repository.koding_yml).to be_an_instance_of(Gitlab::Git::Tree) @@ -1623,8 +1623,8 @@ describe Repository, models: true do describe '#expire_statistics_caches' do it 'expires the caches' do - expect(repository).to receive(:expire_method_caches) - .with(%i(size commit_count)) + expect(repository).to receive(:expire_method_caches). + with(%i(size commit_count)) repository.expire_statistics_caches end @@ -1641,8 +1641,8 @@ describe Repository, models: true do describe '#expire_all_method_caches' do it 'expires the caches of all methods' do - expect(repository).to receive(:expire_method_caches) - .with(Repository::CACHED_METHODS) + expect(repository).to receive(:expire_method_caches). + with(Repository::CACHED_METHODS) repository.expire_all_method_caches end @@ -1667,8 +1667,8 @@ describe Repository, models: true do context 'with an existing repository' do it 'returns a Gitlab::Git::Tree' do - expect(repository.file_on_head(:readme)) - .to be_an_instance_of(Gitlab::Git::Tree) + expect(repository.file_on_head(:readme)). + to be_an_instance_of(Gitlab::Git::Tree) end end end @@ -1783,8 +1783,8 @@ describe Repository, models: true do describe '#refresh_method_caches' do it 'refreshes the caches of the given types' do - expect(repository).to receive(:expire_method_caches) - .with(%i(readme license_blob license_key)) + expect(repository).to receive(:expire_method_caches). + with(%i(readme license_blob license_key)) expect(repository).to receive(:readme) expect(repository).to receive(:license_blob) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 2c03a485823..d7aa7754834 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -808,8 +808,8 @@ describe User, models: true do describe '.find_by_username!' do it 'raises RecordNotFound' do - expect { described_class.find_by_username!('JohnDoe') } - .to raise_error(ActiveRecord::RecordNotFound) + expect { described_class.find_by_username!('JohnDoe') }. + to raise_error(ActiveRecord::RecordNotFound) end it 'is case-insensitive' do @@ -1146,8 +1146,8 @@ describe User, models: true do user = create(:user) project = create(:empty_project, :private, namespace: user.namespace) - expect(user.authorized_projects(Gitlab::Access::REPORTER)) - .to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)). + to contain_exactly(project) end it 'includes projects for which the user is a master' do @@ -1156,8 +1156,8 @@ describe User, models: true do project.team << [user, Gitlab::Access::MASTER] - expect(user.authorized_projects(Gitlab::Access::REPORTER)) - .to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)). + to contain_exactly(project) end end @@ -1385,8 +1385,8 @@ describe User, models: true do end it 'returns the projects when using an ActiveRecord relation' do - projects = user - .projects_with_reporter_access_limited_to(Project.select(:id)) + projects = user. + projects_with_reporter_access_limited_to(Project.select(:id)) expect(projects).to eq([project1]) end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 4a73552b8a6..753dc938c52 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -61,8 +61,8 @@ describe WikiPage, models: true do actual_order = grouped_entries.map do |page_or_dir| get_slugs(page_or_dir) - end - .flatten + end. + flatten expect(actual_order).to eq(expected_order) end end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 29315821ab7..0a5edf35f59 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -80,8 +80,8 @@ describe ProjectPolicy, models: true do expect(project.team.member?(issue.author)).to eq(false) - expect(BasePolicy.class_for(project).abilities(user, project).can_set) - .not_to include(:read_issue) + expect(BasePolicy.class_for(project).abilities(user, project).can_set). + not_to include(:read_issue) expect(Ability.allowed?(user, :read_issue, project)).to be_falsy end diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index 14290350c13..7a35da38b2b 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -47,8 +47,8 @@ describe Ci::BuildPresenter do context 'when build is erased' do before do expect(presenter).to receive(:erased_by_user?).and_return(true) - expect(build).to receive(:erased_by) - .and_return(double(:user, name: 'John Doe')) + expect(build).to receive(:erased_by). + and_return(double(:user, name: 'John Doe')) end it 'returns the name of the eraser' do diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb index 921d8714173..576eb80605b 100644 --- a/spec/requests/api/broadcast_messages_spec.rb +++ b/spec/requests/api/broadcast_messages_spec.rb @@ -27,8 +27,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_kind_of(Array) - expect(json_response.first.keys) - .to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.first.keys). + to match_array(%w(id message starts_at ends_at color font active)) end end @@ -52,8 +52,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(json_response['id']).to eq message.id - expect(json_response.keys) - .to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.keys). + to match_array(%w(id message starts_at ends_at color font active)) end end @@ -174,8 +174,8 @@ describe API::BroadcastMessages, api: true do end it 'deletes the broadcast message for admins' do - expect { delete api("/broadcast_messages/#{message.id}", admin) } - .to change { BroadcastMessage.count }.by(-1) + expect { delete api("/broadcast_messages/#{message.id}", admin) }. + to change { BroadcastMessage.count }.by(-1) end end end diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index 81a8856b8f1..eface28976e 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -207,8 +207,8 @@ describe API::CommitStatuses, api: true do it 'responds with bad request status and validation errors' do expect(response).to have_http_status(400) - expect(json_response['message']['target_url']) - .to include 'must be a valid URL' + expect(json_response['message']['target_url']). + to include 'must be a valid URL' end end end diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index b1380f660f9..a8ce0430401 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -127,8 +127,8 @@ describe API::Files, api: true do end it "returns a 400 if editor fails to create file" do - allow_any_instance_of(Repository).to receive(:commit_file) - .and_return(false) + allow_any_instance_of(Repository).to receive(:commit_file). + and_return(false) post api("/projects/#{project.id}/repository/files", user), valid_params diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index d13c67aa220..b82372b1b60 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -36,8 +36,8 @@ describe API::Groups, api: true do expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.length).to eq(1) - expect(json_response) - .to satisfy_one { |group| group['name'] == group1.name } + expect(json_response). + to satisfy_one { |group| group['name'] == group1.name } end it "does not include statistics" do @@ -84,8 +84,8 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response) - .to satisfy_one { |group| group['statistics'] == attributes } + expect(json_response). + to satisfy_one { |group| group['statistics'] == attributes } end end @@ -522,8 +522,8 @@ describe API::Groups, api: true do let(:project_path) { "#{project.namespace.path}%2F#{project.path}" } before(:each) do - allow_any_instance_of(Projects::TransferService) - .to receive(:execute).and_return(true) + allow_any_instance_of(Projects::TransferService). + to receive(:execute).and_return(true) end context "when authenticated as user" do diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index ffeacb15f17..d1e765d1fdd 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -74,8 +74,8 @@ describe API::Internal, api: true do context 'when two-factor is enabled' do it 'returns new recovery codes when the user exists' do allow_any_instance_of(User).to receive(:two_factor_enabled?).and_return(true) - allow_any_instance_of(User) - .to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) + allow_any_instance_of(User). + to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) post api('/internal/two_factor_recovery_codes'), secret_token: secret_token, diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 9f26560be78..b87d0cd7de9 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -426,8 +426,8 @@ describe API::MergeRequests, api: true do end it "returns 406 if branch can't be merged" do - allow_any_instance_of(MergeRequest) - .to receive(:can_be_merged?).and_return(false) + allow_any_instance_of(MergeRequest). + to receive(:can_be_merged?).and_return(false) put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user) diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb index 5d5e57aa1ca..3cca4468be7 100644 --- a/spec/requests/api/notes_spec.rb +++ b/spec/requests/api/notes_spec.rb @@ -14,8 +14,8 @@ describe API::Notes, api: true do # For testing the cross-reference of a private issue in a public issue let(:private_user) { create(:user) } let(:private_project) do - create(:empty_project, namespace: private_user.namespace) - .tap { |p| p.team << [private_user, :master] } + create(:empty_project, namespace: private_user.namespace). + tap { |p| p.team << [private_user, :master] } end let(:private_issue) { create(:issue, project: private_project) } diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index e79de9aacf2..da9df56401b 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -80,23 +80,23 @@ describe API::ProjectSnippets, api: true do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) } - .to change { Snippet.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } - .not_to change { Snippet.count } + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end @@ -142,8 +142,8 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'creates the snippet' do - expect { update_snippet(title: 'Foo') } - .to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') end end @@ -151,13 +151,13 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo') } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) end end @@ -165,16 +165,16 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 30247b3bcc8..8d139782fdf 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -263,15 +263,15 @@ describe API::Projects, api: true do context 'maximum number of projects reached' do it 'does not create new project and respond with 403' do allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0) - expect { post api('/projects', user2), name: 'foo' } - .to change {Project.count}.by(0) + expect { post api('/projects', user2), name: 'foo' }. + to change {Project.count}.by(0) expect(response).to have_http_status(403) end end it 'creates new project without path and return 201' do - expect { post api('/projects', user), name: 'foo' } - .to change { Project.count }.by(1) + expect { post api('/projects', user), name: 'foo' }. + to change { Project.count }.by(1) expect(response).to have_http_status(201) end @@ -406,8 +406,8 @@ describe API::Projects, api: true do end it 'responds with 400 on failure and not project' do - expect { post api("/projects/user/#{user.id}", admin) } - .not_to change { Project.count } + expect { post api("/projects/user/#{user.id}", admin) }. + not_to change { Project.count } expect(response).to have_http_status(400) expect(json_response['error']).to eq('name is missing') @@ -611,8 +611,8 @@ describe API::Projects, api: true do get api("/projects", user) expect(response).to have_http_status(200) - expect(json_response.first['permissions']['project_access']['access_level']) - .to eq(Gitlab::Access::MASTER) + expect(json_response.first['permissions']['project_access']['access_level']). + to eq(Gitlab::Access::MASTER) expect(json_response.first['permissions']['group_access']).to be_nil end end @@ -623,8 +623,8 @@ describe API::Projects, api: true do get api("/projects/#{project.id}", user) expect(response).to have_http_status(200) - expect(json_response['permissions']['project_access']['access_level']) - .to eq(Gitlab::Access::MASTER) + expect(json_response['permissions']['project_access']['access_level']). + to eq(Gitlab::Access::MASTER) expect(json_response['permissions']['group_access']).to be_nil end end @@ -639,8 +639,8 @@ describe API::Projects, api: true do expect(response).to have_http_status(200) expect(json_response['permissions']['project_access']).to be_nil - expect(json_response['permissions']['group_access']['access_level']) - .to eq(Gitlab::Access::OWNER) + expect(json_response['permissions']['group_access']['access_level']). + to eq(Gitlab::Access::OWNER) end end end diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 103d6755888..2e596f4197e 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -202,8 +202,8 @@ describe API::Runners, api: true do expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql') expect(shared_runner.run_untagged?).to be(false) expect(shared_runner.locked?).to be(true) - expect(shared_runner.ensure_runner_queue_value) - .not_to eq(runner_queue_value) + expect(shared_runner.ensure_runner_queue_value). + not_to eq(runner_queue_value) end end @@ -218,8 +218,8 @@ describe API::Runners, api: true do expect(response).to have_http_status(200) expect(specific_runner.description).to eq('test') expect(specific_runner.description).not_to eq(description) - expect(specific_runner.ensure_runner_queue_value) - .not_to eq(runner_queue_value) + expect(specific_runner.ensure_runner_queue_value). + not_to eq(runner_queue_value) end end diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index 25cb75d8685..41def7cd1d4 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -120,23 +120,23 @@ describe API::Snippets, api: true do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(visibility_level: Snippet::PRIVATE) } - .to change { Snippet.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) } - .not_to change { Snippet.count } + expect { create_snippet(visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { create_snippet(visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { create_snippet(visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end @@ -192,8 +192,8 @@ describe API::Snippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'updates the snippet' do - expect { update_snippet(title: 'Foo') } - .to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') end end @@ -201,16 +201,16 @@ describe API::Snippets, api: true do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the shippet' do - expect { update_snippet(title: 'Foo') } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) end end @@ -218,13 +218,13 @@ describe API::Snippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index b1bdf76d6b2..603da9f49fc 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -247,14 +247,14 @@ describe API::Users, api: true do bio: 'g' * 256, projects_limit: -1 expect(response).to have_http_status(400) - expect(json_response['message']['password']) - .to eq(['is too short (minimum is 8 characters)']) - expect(json_response['message']['bio']) - .to eq(['is too long (maximum is 255 characters)']) - expect(json_response['message']['projects_limit']) - .to eq(['must be greater than or equal to 0']) - expect(json_response['message']['username']) - .to eq([Gitlab::Regex.namespace_regex_message]) + expect(json_response['message']['password']). + to eq(['is too short (minimum is 8 characters)']) + expect(json_response['message']['bio']). + to eq(['is too long (maximum is 255 characters)']) + expect(json_response['message']['projects_limit']). + to eq(['must be greater than or equal to 0']) + expect(json_response['message']['username']). + to eq([Gitlab::Regex.namespace_regex_message]) end it "is not available for non admin users" do @@ -421,14 +421,14 @@ describe API::Users, api: true do bio: 'g' * 256, projects_limit: -1 expect(response).to have_http_status(400) - expect(json_response['message']['password']) - .to eq(['is too short (minimum is 8 characters)']) - expect(json_response['message']['bio']) - .to eq(['is too long (maximum is 255 characters)']) - expect(json_response['message']['projects_limit']) - .to eq(['must be greater than or equal to 0']) - expect(json_response['message']['username']) - .to eq([Gitlab::Regex.namespace_regex_message]) + expect(json_response['message']['password']). + to eq(['is too short (minimum is 8 characters)']) + expect(json_response['message']['bio']). + to eq(['is too long (maximum is 255 characters)']) + expect(json_response['message']['projects_limit']). + to eq(['must be greater than or equal to 0']) + expect(json_response['message']['username']). + to eq([Gitlab::Regex.namespace_regex_message]) end it 'returns 400 if provider is missing for identity update' do diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb index 2099e386c85..4af05605ec6 100644 --- a/spec/requests/api/v3/files_spec.rb +++ b/spec/requests/api/v3/files_spec.rb @@ -127,8 +127,8 @@ describe API::V3::Files, api: true do end it "returns a 400 if editor fails to create file" do - allow_any_instance_of(Repository).to receive(:commit_file) - .and_return(false) + allow_any_instance_of(Repository).to receive(:commit_file). + and_return(false) post v3_api("/projects/#{project.id}/repository/files", user), valid_params diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb index cb370418e9c..51764d1000e 100644 --- a/spec/requests/api/v3/merge_requests_spec.rb +++ b/spec/requests/api/v3/merge_requests_spec.rb @@ -413,8 +413,8 @@ describe API::MergeRequests, api: true do end it "returns 406 if branch can't be merged" do - allow_any_instance_of(MergeRequest) - .to receive(:can_be_merged?).and_return(false) + allow_any_instance_of(MergeRequest). + to receive(:can_be_merged?).and_return(false) put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user) diff --git a/spec/requests/api/v3/project_snippets_spec.rb b/spec/requests/api/v3/project_snippets_spec.rb index 0b3b39ddaba..957a3bf97ef 100644 --- a/spec/requests/api/v3/project_snippets_spec.rb +++ b/spec/requests/api/v3/project_snippets_spec.rb @@ -87,23 +87,23 @@ describe API::ProjectSnippets, api: true do context 'when the snippet is private' do it 'creates the snippet' do - expect { create_snippet(project, visibility_level: Snippet::PRIVATE) } - .to change { Snippet.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }. + to change { Snippet.count }.by(1) end end context 'when the snippet is public' do it 'rejects the shippet' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } - .not_to change { Snippet.count } + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + not_to change { Snippet.count } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { create_snippet(project, visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end @@ -149,8 +149,8 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'creates the snippet' do - expect { update_snippet(title: 'Foo') } - .to change { snippet.reload.title }.to('Foo') + expect { update_snippet(title: 'Foo') }. + to change { snippet.reload.title }.to('Foo') end end @@ -158,13 +158,13 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PUBLIC } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo') } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo') }. + not_to change { snippet.reload.title } end it 'creates a spam log' do - expect { update_snippet(title: 'Foo') } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo') }. + to change { SpamLog.count }.by(1) end end @@ -172,16 +172,16 @@ describe API::ProjectSnippets, api: true do let(:visibility_level) { Snippet::PRIVATE } it 'rejects the snippet' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .not_to change { snippet.reload.title } + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + not_to change { snippet.reload.title } expect(response).to have_http_status(400) expect(json_response['message']).to eq({ "error" => "Spam detected" }) end it 'creates a spam log' do - expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) } - .to change { SpamLog.count }.by(1) + expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }. + to change { SpamLog.count }.by(1) end end end diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb index 273a4a58224..662be3f3531 100644 --- a/spec/requests/api/v3/projects_spec.rb +++ b/spec/requests/api/v3/projects_spec.rb @@ -303,15 +303,15 @@ describe API::V3::Projects, api: true do context 'maximum number of projects reached' do it 'does not create new project and respond with 403' do allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0) - expect { post v3_api('/projects', user2), name: 'foo' } - .to change {Project.count}.by(0) + expect { post v3_api('/projects', user2), name: 'foo' }. + to change {Project.count}.by(0) expect(response).to have_http_status(403) end end it 'creates new project without path and return 201' do - expect { post v3_api('/projects', user), name: 'foo' } - .to change { Project.count }.by(1) + expect { post v3_api('/projects', user), name: 'foo' }. + to change { Project.count }.by(1) expect(response).to have_http_status(201) end @@ -465,8 +465,8 @@ describe API::V3::Projects, api: true do end it 'responds with 400 on failure and not project' do - expect { post v3_api("/projects/user/#{user.id}", admin) } - .not_to change { Project.count } + expect { post v3_api("/projects/user/#{user.id}", admin) }. + not_to change { Project.count } expect(response).to have_http_status(400) expect(json_response['error']).to eq('name is missing') @@ -694,8 +694,8 @@ describe API::V3::Projects, api: true do get v3_api("/projects", user) expect(response).to have_http_status(200) - expect(json_response.first['permissions']['project_access']['access_level']) - .to eq(Gitlab::Access::MASTER) + expect(json_response.first['permissions']['project_access']['access_level']). + to eq(Gitlab::Access::MASTER) expect(json_response.first['permissions']['group_access']).to be_nil end end @@ -706,8 +706,8 @@ describe API::V3::Projects, api: true do get v3_api("/projects/#{project.id}", user) expect(response).to have_http_status(200) - expect(json_response['permissions']['project_access']['access_level']) - .to eq(Gitlab::Access::MASTER) + expect(json_response['permissions']['project_access']['access_level']). + to eq(Gitlab::Access::MASTER) expect(json_response['permissions']['group_access']).to be_nil end end @@ -722,8 +722,8 @@ describe API::V3::Projects, api: true do expect(response).to have_http_status(200) expect(json_response['permissions']['project_access']).to be_nil - expect(json_response['permissions']['group_access']['access_level']) - .to eq(Gitlab::Access::OWNER) + expect(json_response['permissions']['group_access']['access_level']). + to eq(Gitlab::Access::OWNER) end end end diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index 5ba1209af5d..6d79f2e7b41 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -38,8 +38,8 @@ describe Ci::API::Builds do it 'gives 204 and set the same X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']) - .to eq(last_update) + expect(response.header['X-GitLab-Last-Update']). + to eq(last_update) end end @@ -49,8 +49,8 @@ describe Ci::API::Builds do it 'gives 204 and set a new X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']) - .to eq(new_update) + expect(response.header['X-GitLab-Last-Update']). + to eq(new_update) end end @@ -93,8 +93,8 @@ describe Ci::API::Builds do context 'when concurrently updating build' do before do - expect_any_instance_of(Ci::Build).to receive(:run!) - .and_raise(ActiveRecord::StaleObjectError.new(nil, nil)) + expect_any_instance_of(Ci::Build).to receive(:run!). + and_raise(ActiveRecord::StaleObjectError.new(nil, nil)) end it 'returns a conflict' do @@ -260,8 +260,8 @@ describe Ci::API::Builds do end it 'does not update runner info' do - expect { register_builds } - .not_to change { runner.reload.contacted_at } + expect { register_builds }. + not_to change { runner.reload.contacted_at } end end diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index 9adbcc3f814..87786e85621 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -389,8 +389,8 @@ describe 'Git HTTP requests', lib: true do shared_examples 'can download code only' do it 'downloads get status 200' do - allow_any_instance_of(Repository) - .to receive(:exists?).and_return(true) + allow_any_instance_of(Repository). + to receive(:exists?).and_return(true) clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token @@ -400,8 +400,8 @@ describe 'Git HTTP requests', lib: true do end it 'downloads from non-existing repository and gets 403' do - allow_any_instance_of(Repository) - .to receive(:exists?).and_return(false) + allow_any_instance_of(Repository). + to receive(:exists?).and_return(false) clone_get "#{project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token diff --git a/spec/serializers/analytics_build_serializer_spec.rb b/spec/serializers/analytics_build_serializer_spec.rb index e3b1dd93dc2..c8bad5ef105 100644 --- a/spec/serializers/analytics_build_serializer_spec.rb +++ b/spec/serializers/analytics_build_serializer_spec.rb @@ -7,8 +7,8 @@ describe AnalyticsBuildSerializer do context 'when there is a single object provided' do it 'contains important elements of analyticsBuild' do - expect(subject) - .to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) + expect(subject). + to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) end end end diff --git a/spec/serializers/analytics_issue_serializer_spec.rb b/spec/serializers/analytics_issue_serializer_spec.rb index 2f08958a783..fe26b001740 100644 --- a/spec/serializers/analytics_issue_serializer_spec.rb +++ b/spec/serializers/analytics_issue_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsIssueSerializer do subject do - described_class - .new(project: project, entity: :merge_request) - .represent(resource) + described_class. + new(project: project, entity: :merge_request). + represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_merge_request_serializer_spec.rb b/spec/serializers/analytics_merge_request_serializer_spec.rb index 62067cc0ef2..ee08762d237 100644 --- a/spec/serializers/analytics_merge_request_serializer_spec.rb +++ b/spec/serializers/analytics_merge_request_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsMergeRequestSerializer do subject do - described_class - .new(project: project, entity: :merge_request) - .represent(resource) + described_class. + new(project: project, entity: :merge_request). + represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb index 5d7a94c2d02..3106af0ded7 100644 --- a/spec/serializers/analytics_summary_serializer_spec.rb +++ b/spec/serializers/analytics_summary_serializer_spec.rb @@ -9,13 +9,13 @@ describe AnalyticsSummarySerializer do let(:user) { create(:user) } let(:resource) do - Gitlab::CycleAnalytics::Summary::Issue - .new(project: double, from: 1.day.ago, current_user: user) + Gitlab::CycleAnalytics::Summary::Issue. + new(project: double, from: 1.day.ago, current_user: user) end before do - allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue) - .to receive(:value).and_return(1.12) + allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue). + to receive(:value).and_return(1.12) end it 'it generates payload for single object' do diff --git a/spec/serializers/build_artifact_entity_spec.rb b/spec/serializers/build_artifact_entity_spec.rb index 2fc60aa9de6..6ccea199376 100644 --- a/spec/serializers/build_artifact_entity_spec.rb +++ b/spec/serializers/build_artifact_entity_spec.rb @@ -15,8 +15,8 @@ describe BuildArtifactEntity do end it 'contains path to the artifacts' do - expect(subject[:path]) - .to include "builds/#{build.id}/artifacts/download" + expect(subject[:path]). + to include "builds/#{build.id}/artifacts/download" end end end diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index 0333d73b5b5..895aeb30035 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -42,8 +42,8 @@ describe CommitEntity do end it 'needs to receive project in the request' do - expect(request).to receive(:project) - .and_return(project) + expect(request).to receive(:project). + and_return(project) subject end diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb index 6a6df377b35..61b2fce8e8a 100644 --- a/spec/serializers/environment_serializer_spec.rb +++ b/spec/serializers/environment_serializer_spec.rb @@ -5,9 +5,9 @@ describe EnvironmentSerializer do let(:project) { create(:project) } let(:json) do - described_class - .new(user: user, project: project) - .represent(resource) + described_class. + new(user: user, project: project). + represent(resource) end context 'when there is a single object provided' do @@ -27,15 +27,15 @@ describe EnvironmentSerializer do let(:resource) { deployment.environment } it 'contains important elements of environment' do - expect(json) - .to include(:name, :external_url, :environment_path, :last_deployment) + expect(json). + to include(:name, :external_url, :environment_path, :last_deployment) end it 'contains relevant information about last deployment' do last_deployment = json.fetch(:last_deployment) - expect(last_deployment) - .to include(:ref, :user, :commit, :deployable, :manual_actions) + expect(last_deployment). + to include(:ref, :user, :commit, :deployable, :manual_actions) end end @@ -44,8 +44,8 @@ describe EnvironmentSerializer do let(:resource) { create_list(:environment, 2) } it 'contains important elements of environment' do - expect(json.first) - .to include(:last_deployment, :name, :external_url) + expect(json.first). + to include(:last_deployment, :name, :external_url) end it 'generates payload for collection' do @@ -122,13 +122,13 @@ describe EnvironmentSerializer do let(:pagination) { { page: 1, per_page: 2 } } let(:serializer) do - described_class.new(project: project) - .with_pagination(request, response) + described_class.new(project: project). + with_pagination(request, response) end before do - allow(request).to receive(:query_parameters) - .and_return(pagination) + allow(request).to receive(:query_parameters). + and_return(pagination) end subject { serializer.represent(resource) } @@ -164,9 +164,9 @@ describe EnvironmentSerializer do context 'when grouping environments within folders' do let(:serializer) do - described_class.new(project: project) - .with_pagination(request, response) - .within_folders + described_class.new(project: project). + with_pagination(request, response). + within_folders end before do diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb index ccb72973f9c..96ef1d3c071 100644 --- a/spec/serializers/pipeline_entity_spec.rb +++ b/spec/serializers/pipeline_entity_spec.rb @@ -26,17 +26,17 @@ describe PipelineEntity do it 'contains details' do expect(subject).to include :details - expect(subject[:details]) - .to include :duration, :finished_at - expect(subject[:details]) - .to include :stages, :artifacts, :manual_actions + expect(subject[:details]). + to include :duration, :finished_at + expect(subject[:details]). + to include :stages, :artifacts, :manual_actions expect(subject[:details][:status]).to include :icon, :text, :label end it 'contains flags' do expect(subject).to include :flags - expect(subject[:flags]) - .to include :latest, :triggered, :stuck, + expect(subject[:flags]). + to include :latest, :triggered, :stuck, :yaml_errors, :retryable, :cancelable end end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 2aaef03cb93..5f84a98f06d 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -38,14 +38,14 @@ describe PipelineSerializer do let(:pagination) { {} } before do - allow(request) - .to receive(:query_parameters) - .and_return(pagination) + allow(request). + to receive(:query_parameters). + and_return(pagination) end let(:serializer) do - described_class.new(user: user) - .with_pagination(request, response) + described_class.new(user: user). + with_pagination(request, response) end it 'created a paginated serializer' do diff --git a/spec/serializers/request_aware_entity_spec.rb b/spec/serializers/request_aware_entity_spec.rb index aa666b961dc..94dbf02aee8 100644 --- a/spec/serializers/request_aware_entity_spec.rb +++ b/spec/serializers/request_aware_entity_spec.rb @@ -14,8 +14,8 @@ describe RequestAwareEntity do end it 'fetches request from options' do - expect(subject).to receive(:options) - .and_return({ request: 'some value' }) + expect(subject).to receive(:options). + and_return({ request: 'some value' }) expect(subject.request).to eq 'some value' end diff --git a/spec/serializers/stage_entity_spec.rb b/spec/serializers/stage_entity_spec.rb index 4ab40d08432..42f19935453 100644 --- a/spec/serializers/stage_entity_spec.rb +++ b/spec/serializers/stage_entity_spec.rb @@ -35,13 +35,13 @@ describe StageEntity do end it 'contains path to the stage' do - expect(subject[:path]) - .to include "pipelines/#{pipeline.id}##{stage.name}" + expect(subject[:path]). + to include "pipelines/#{pipeline.id}##{stage.name}" end it 'contains path to the stage dropdown' do - expect(subject[:dropdown_path]) - .to include "pipelines/#{pipeline.id}/stage.json?stage=test" + expect(subject[:dropdown_path]). + to include "pipelines/#{pipeline.id}/stage.json?stage=test" end it 'contains stage title' do diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index b818dfdd50c..65544c57431 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -284,14 +284,14 @@ describe Ci::ProcessPipelineService, :services do pipeline.builds.running_or_pending.each(&:success) - expect(builds.pluck(:name)) - .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)). + to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') pipeline.builds.find_by(name: 'test:1').success pipeline.builds.find_by(name: 'test:2').drop - expect(builds.pluck(:name)) - .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)). + to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') Ci::Build.retry(pipeline.builds.find_by(name: 'test:2'), user).success diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index d03f7505eac..6499c7ad63e 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -61,8 +61,8 @@ describe Ci::RetryBuildService, :services do end it 'resolves todos for old build that failed' do - expect(MergeRequests::AddTodoWhenBuildFailsService) - .to receive_message_chain(:new, :close) + expect(MergeRequests::AddTodoWhenBuildFailsService). + to receive_message_chain(:new, :close) service.execute(build) end @@ -82,8 +82,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.execute(build) } - .to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(build) }. + to raise_error Gitlab::Access::AccessDeniedError end end end @@ -109,8 +109,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.reprocess(build) } - .to raise_error Gitlab::Access::AccessDeniedError + expect { service.reprocess(build) }. + to raise_error Gitlab::Access::AccessDeniedError end end end diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index c0af8b8450a..84915b5f1aa 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -134,8 +134,8 @@ describe Ci::RetryPipelineService, '#execute', :services do end it 'closes all todos about failed jobs for pipeline' do - expect(MergeRequests::AddTodoWhenBuildFailsService) - .to receive_message_chain(:new, :close_all) + expect(MergeRequests::AddTodoWhenBuildFailsService). + to receive_message_chain(:new, :close_all) service.execute(pipeline) end @@ -149,8 +149,8 @@ describe Ci::RetryPipelineService, '#execute', :services do context 'when user is not allowed to retry pipeline' do it 'raises an error' do - expect { service.execute(pipeline) } - .to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(pipeline) }. + to raise_error Gitlab::Access::AccessDeniedError end end diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb index 560f83d94f7..23e0856fecd 100644 --- a/spec/services/ci/stop_environments_service_spec.rb +++ b/spec/services/ci/stop_environments_service_spec.rb @@ -44,8 +44,8 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment is not stopped' do before do - allow_any_instance_of(Environment) - .to receive(:state).and_return(:stopped) + allow_any_instance_of(Environment). + to receive(:state).and_return(:stopped) end it 'does not stop environment' do @@ -83,22 +83,22 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment does not exist' do it 'does not raise error' do - expect { service.execute('master') } - .not_to raise_error + expect { service.execute('master') }. + not_to raise_error end end end def expect_environment_stopped_on(branch) - expect_any_instance_of(Environment) - .to receive(:stop!) + expect_any_instance_of(Environment). + to receive(:stop!) service.execute(branch) end def expect_environment_not_stopped_on(branch) - expect_any_instance_of(Environment) - .not_to receive(:stop!) + expect_any_instance_of(Environment). + not_to receive(:stop!) service.execute(branch) end diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb index f01a388b895..14092d9dcca 100644 --- a/spec/services/ci/update_build_queue_service_spec.rb +++ b/spec/services/ci/update_build_queue_service_spec.rb @@ -12,15 +12,15 @@ describe Ci::UpdateBuildQueueService, :services do before { build.project.runners << runner } it 'ticks runner queue value' do - expect { subject.execute(build) } - .to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + to change { runner.ensure_runner_queue_value } end end context 'when there are no runners that can pick build' do it 'does not tick runner queue value' do - expect { subject.execute(build) } - .not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + not_to change { runner.ensure_runner_queue_value } end end end @@ -30,8 +30,8 @@ describe Ci::UpdateBuildQueueService, :services do context 'when there are runner that can pick build' do it 'ticks runner queue value' do - expect { subject.execute(build) } - .to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + to change { runner.ensure_runner_queue_value } end end @@ -39,8 +39,8 @@ describe Ci::UpdateBuildQueueService, :services do before { build.tag_list = [:docker] } it 'does not tick runner queue value' do - expect { subject.execute(build) } - .not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) }. + not_to change { runner.ensure_runner_queue_value } end end end diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb index 3e0a0e95870..35e6e139238 100644 --- a/spec/services/files/update_service_spec.rb +++ b/spec/services/files/update_service_spec.rb @@ -32,8 +32,8 @@ describe Files::UpdateService do let(:last_commit_sha) { "foo" } it "returns a hash with the correct error message and a :error status " do - expect { subject.execute } - .to raise_error(Files::UpdateService::FileChangedError, + expect { subject.execute }. + to raise_error(Files::UpdateService::FileChangedError, "You are attempting to update a file that has changed since you started editing it.") end end diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index d4fc4611bed..2a0f00ce937 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -145,8 +145,8 @@ describe GitPushService, services: true do context "Updates merge requests" do it "when pushing a new branch for the first time" do - expect(UpdateMergeRequestsWorker).to receive(:perform_async) - .with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master') + expect(UpdateMergeRequestsWorker).to receive(:perform_async). + with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master') execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' ) end end @@ -263,8 +263,8 @@ describe GitPushService, services: true do author_email: commit_author.email ) - allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) - .and_return(commit) + allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit). + and_return(commit) allow(project.repository).to receive(:commits_between).and_return([commit]) end @@ -321,8 +321,8 @@ describe GitPushService, services: true do committed_date: commit_time ) - allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) - .and_return(commit) + allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit). + and_return(commit) allow(project.repository).to receive(:commits_between).and_return([commit]) end @@ -357,11 +357,11 @@ describe GitPushService, services: true do author_email: commit_author.email ) - allow(project.repository).to receive(:commits_between) - .and_return([closing_commit]) + allow(project.repository).to receive(:commits_between). + and_return([closing_commit]) - allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) - .and_return(closing_commit) + allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit). + and_return(closing_commit) project.team << [commit_author, :master] end @@ -383,8 +383,8 @@ describe GitPushService, services: true do end it "doesn't close issues when external issue tracker is in use" do - allow_any_instance_of(Project).to receive(:default_issues_tracker?) - .and_return(false) + allow_any_instance_of(Project).to receive(:default_issues_tracker?). + and_return(false) external_issue_tracker = double(title: 'My Tracker', issue_path: issue.iid, reference_pattern: project.issue_reference_pattern) allow_any_instance_of(Project).to receive(:external_issue_tracker).and_return(external_issue_tracker) @@ -577,13 +577,13 @@ describe GitPushService, services: true do commit = double(:commit) diff = double(:diff, new_path: 'README.md') - expect(commit).to receive(:raw_diffs).with(deltas_only: true) - .and_return([diff]) + expect(commit).to receive(:raw_diffs).with(deltas_only: true). + and_return([diff]) service.push_commits = [commit] - expect(ProjectCacheWorker).to receive(:perform_async) - .with(project.id, %i(readme), %i(commit_count repository_size)) + expect(ProjectCacheWorker).to receive(:perform_async). + with(project.id, %i(readme), %i(commit_count repository_size)) service.update_caches end @@ -595,9 +595,9 @@ describe GitPushService, services: true do end it 'does not flush any conditional caches' do - expect(ProjectCacheWorker).to receive(:perform_async) - .with(project.id, [], %i(commit_count repository_size)) - .and_call_original + expect(ProjectCacheWorker).to receive(:perform_async). + with(project.id, [], %i(commit_count repository_size)). + and_call_original service.update_caches end @@ -614,8 +614,8 @@ describe GitPushService, services: true do end it 'only schedules a limited number of commits' do - allow(service).to receive(:push_commits) - .and_return(Array.new(1000, double(:commit, to_hash: {}))) + allow(service).to receive(:push_commits). + and_return(Array.new(1000, double(:commit, to_hash: {}))) expect(ProcessCommitWorker).to receive(:perform_async).exactly(100).times diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb index 0475f38fe5e..87da8581e68 100644 --- a/spec/services/issuable/bulk_update_service_spec.rb +++ b/spec/services/issuable/bulk_update_service_spec.rb @@ -5,8 +5,8 @@ describe Issuable::BulkUpdateService, services: true do let(:project) { create(:empty_project, namespace: user.namespace) } def bulk_update(issues, extra_params = {}) - bulk_update_params = extra_params - .reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) + bulk_update_params = extra_params. + reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) Issuable::BulkUpdateService.new(project, user, bulk_update_params).execute('issue') end @@ -65,22 +65,22 @@ describe Issuable::BulkUpdateService, services: true do assignee = create(:user) project.team << [assignee, :developer] - expect { bulk_update(issue, assignee_id: assignee.id) } - .to change { issue.reload.assignee }.from(user).to(assignee) + expect { bulk_update(issue, assignee_id: assignee.id) }. + to change { issue.reload.assignee }.from(user).to(assignee) end end context "when the new assignee ID is #{IssuableFinder::NONE}" do it "unassigns the issues" do - expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) } - .to change { issue.reload.assignee }.to(nil) + expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) }. + to change { issue.reload.assignee }.to(nil) end end context 'when the new assignee ID is not present' do it 'does not unassign' do - expect { bulk_update(issue, assignee_id: nil) } - .not_to change { issue.reload.assignee } + expect { bulk_update(issue, assignee_id: nil) }. + not_to change { issue.reload.assignee } end end end @@ -97,8 +97,8 @@ describe Issuable::BulkUpdateService, services: true do end it 'updates the issue milestone' do - expect { bulk_update(issue, milestone_id: milestone.id) } - .to change { issue.reload.milestone }.from(nil).to(milestone) + expect { bulk_update(issue, milestone_id: milestone.id) }. + to change { issue.reload.milestone }.from(nil).to(milestone) end end diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index 8f5bd4566ec..7a54373963e 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -18,26 +18,26 @@ describe Issues::CloseService, services: true do let(:service) { described_class.new(project, user) } it 'checks if the user is authorized to update the issue' do - expect(service).to receive(:can?).with(user, :update_issue, issue) - .and_call_original + expect(service).to receive(:can?).with(user, :update_issue, issue). + and_call_original service.execute(issue) end it 'does not close the issue when the user is not authorized to do so' do - allow(service).to receive(:can?).with(user, :update_issue, issue) - .and_return(false) + allow(service).to receive(:can?).with(user, :update_issue, issue). + and_return(false) expect(service).not_to receive(:close_issue) expect(service.execute(issue)).to eq(issue) end it 'closes the issue when the user is authorized to do so' do - allow(service).to receive(:can?).with(user, :update_issue, issue) - .and_return(true) + allow(service).to receive(:can?).with(user, :update_issue, issue). + and_return(true) - expect(service).to receive(:close_issue) - .with(issue, commit: nil, notifications: true, system_note: true) + expect(service).to receive(:close_issue). + with(issue, commit: nil, notifications: true, system_note: true) service.execute(issue) end diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index db196ed5751..59c0fa50994 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -188,8 +188,8 @@ describe Issues::MoveService, services: true do let(:new_note) { new_issue.notes.first } it 'rewrites references using a cross reference to old project' do - expect(new_note.note) - .to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" + expect(new_note.note). + to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" end end @@ -201,8 +201,8 @@ describe Issues::MoveService, services: true do it 'rewrites uploads in description' do expect(new_issue.description).not_to eq description - expect(new_issue.description) - .to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) + expect(new_issue.description). + to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) expect(new_issue.description).not_to include uploader.secret end end @@ -216,8 +216,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{another_issue.to_reference}" } it 'rewrites referenced issues creating cross project reference' do - expect(new_issue.description) - .to eq "Some description #{another_issue.to_reference(new_project)}" + expect(new_issue.description). + to eq "Some description #{another_issue.to_reference(new_project)}" end end @@ -226,8 +226,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{user.to_reference}" } it "doesn't throw any errors for issues containing user references" do - expect(new_issue.description) - .to eq "Some description #{user.to_reference}" + expect(new_issue.description). + to eq "Some description #{user.to_reference}" end end end @@ -236,8 +236,8 @@ describe Issues::MoveService, services: true do let(:new_project) { old_project } it 'raises error' do - expect { move_service.execute(old_issue, new_project) } - .to raise_error(StandardError, /Cannot move issue/) + expect { move_service.execute(old_issue, new_project) }. + to raise_error(StandardError, /Cannot move issue/) end end end diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb index 500afdfb916..4b90ad19640 100644 --- a/spec/services/labels/promote_service_spec.rb +++ b/spec/services/labels/promote_service_spec.rb @@ -66,9 +66,9 @@ describe Labels::PromoteService, services: true do end it 'recreates the label as a group label' do - expect { service.execute(project_label_1_1) } - .to change(project_1.labels, :count).by(-1) - .and change(group_1.labels, :count).by(1) + expect { service.execute(project_label_1_1) }. + to change(project_1.labels, :count).by(-1). + and change(group_1.labels, :count).by(1) expect(new_label).not_to be_nil end diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index e6160e0ad42..574df6e0f42 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -104,8 +104,8 @@ describe Members::DestroyService, services: true do let(:params) { { id: project.members.find_by!(user_id: user.id).id } } it 'destroys the member' do - expect { described_class.new(project, user, params).execute } - .to change { project.members.count }.by(-1) + expect { described_class.new(project, user, params).execute }. + to change { project.members.count }.by(-1) end end end diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb index d80fb8a1af1..881458c190f 100644 --- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb +++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb @@ -29,9 +29,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do end before do - allow_any_instance_of(MergeRequest) - .to receive(:head_pipeline) - .and_return(pipeline) + allow_any_instance_of(MergeRequest). + to receive(:head_pipeline). + and_return(pipeline) allow(service).to receive(:todo_service).and_return(todo_service) end @@ -113,9 +113,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'resolves todos about failed builds for pipeline' do service.close_all(pipeline) - expect(todo_service) - .to have_received(:merge_request_build_retried) - .with(merge_request) + expect(todo_service). + to have_received(:merge_request_build_retried). + with(merge_request) end end @@ -125,8 +125,8 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'does not resolve any todos about failed builds' do service.close_all(pipeline) - expect(todo_service) - .not_to have_received(:merge_request_build_retried) + expect(todo_service). + not_to have_received(:merge_request_build_retried) end end end diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb index abc266b3aa7..d55a7657c0e 100644 --- a/spec/services/merge_requests/close_service_spec.rb +++ b/spec/services/merge_requests/close_service_spec.rb @@ -30,8 +30,8 @@ describe MergeRequests::CloseService, services: true do it { expect(@merge_request).to be_closed } it 'executes hooks with close action' do - expect(service).to have_received(:execute_hooks) - .with(@merge_request, 'close') + expect(service).to have_received(:execute_hooks). + with(@merge_request, 'close') end it 'sends email to user2 about assign of new merge_request' do diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index 1dcb4f6b3ee..d96f819e66a 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -139,9 +139,9 @@ describe MergeRequests::MergeService, services: true do end it 'removes the source branch' do - expect(DeleteBranchService).to receive(:new) - .with(merge_request.source_project, merge_request.author) - .and_call_original + expect(DeleteBranchService).to receive(:new). + with(merge_request.source_project, merge_request.author). + and_call_original service.execute(merge_request) end end diff --git a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb index f92978a33a3..65c08ce15f7 100644 --- a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb @@ -27,9 +27,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do context 'first time enabling' do before do - allow(merge_request) - .to receive(:head_pipeline) - .and_return(pipeline) + allow(merge_request). + to receive(:head_pipeline). + and_return(pipeline) service.execute(merge_request) end @@ -52,11 +52,11 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) } before do - allow(mr_merge_if_green_enabled).to receive(:head_pipeline) - .and_return(pipeline) + allow(mr_merge_if_green_enabled).to receive(:head_pipeline). + and_return(pipeline) - allow(mr_merge_if_green_enabled).to receive(:mergeable?) - .and_return(true) + allow(mr_merge_if_green_enabled).to receive(:mergeable?). + and_return(true) allow(pipeline).to receive(:success?).and_return(true) end @@ -152,9 +152,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do before do # This behavior of MergeRequest: we instantiate a new object # - allow_any_instance_of(MergeRequest) - .to receive(:head_pipeline) - .and_wrap_original do + allow_any_instance_of(MergeRequest). + to receive(:head_pipeline). + and_wrap_original do Ci::Pipeline.find(pipeline.id) end end diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb index af951588fc6..983dac6efdb 100644 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -56,8 +56,8 @@ describe MergeRequests::RefreshService, services: true do end it 'executes hooks with update action' do - expect(refresh_service).to have_received(:execute_hooks) - .with(@merge_request, 'update', @oldrev) + expect(refresh_service).to have_received(:execute_hooks). + with(@merge_request, 'update', @oldrev) end it { expect(@merge_request.notes).not_to be_empty } @@ -115,8 +115,8 @@ describe MergeRequests::RefreshService, services: true do end it 'executes hooks with update action' do - expect(refresh_service).to have_received(:execute_hooks) - .with(@fork_merge_request, 'update', @oldrev) + expect(refresh_service).to have_received(:execute_hooks). + with(@fork_merge_request, 'update', @oldrev) end it { expect(@merge_request.notes).to be_empty } @@ -191,8 +191,8 @@ describe MergeRequests::RefreshService, services: true do let(:refresh_service) { service.new(@fork_project, @user) } it 'refreshes the merge request' do - expect(refresh_service).to receive(:execute_hooks) - .with(@fork_merge_request, 'update', Gitlab::Git::BLANK_SHA) + expect(refresh_service).to receive(:execute_hooks). + with(@fork_merge_request, 'update', Gitlab::Git::BLANK_SHA) allow_any_instance_of(Repository).to receive(:merge_base).and_return(@oldrev) refresh_service.execute(Gitlab::Git::BLANK_SHA, @newrev, 'refs/heads/master') diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb index 3fda94a8bc5..a99d4eac9bd 100644 --- a/spec/services/merge_requests/reopen_service_spec.rb +++ b/spec/services/merge_requests/reopen_service_spec.rb @@ -29,8 +29,8 @@ describe MergeRequests::ReopenService, services: true do it { expect(merge_request).to be_reopened } it 'executes hooks with reopen action' do - expect(service).to have_received(:execute_hooks) - .with(merge_request, 'reopen') + expect(service).to have_received(:execute_hooks). + with(merge_request, 'reopen') end it 'sends email to user2 about reopen of merge_request' do diff --git a/spec/services/merge_requests/resolve_service_spec.rb b/spec/services/merge_requests/resolve_service_spec.rb index b7f475597b4..57b1c088ce4 100644 --- a/spec/services/merge_requests/resolve_service_spec.rb +++ b/spec/services/merge_requests/resolve_service_spec.rb @@ -58,8 +58,8 @@ describe MergeRequests::ResolveService do end it 'creates a commit with the correct parents' do - expect(merge_request.source_branch_head.parents.map(&:id)) - .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 + expect(merge_request.source_branch_head.parents.map(&:id)). + to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 824be604a34828eb682305f0d963056cfac87b2d)) end end @@ -84,8 +84,8 @@ describe MergeRequests::ResolveService do end it 'creates a commit with the correct parents' do - expect(merge_request_from_fork.source_branch_head.parents.map(&:id)) - .to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', + expect(merge_request_from_fork.source_branch_head.parents.map(&:id)). + to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', target_head]) end end @@ -124,8 +124,8 @@ describe MergeRequests::ResolveService do end it 'creates a commit with the correct parents' do - expect(merge_request.source_branch_head.parents.map(&:id)) - .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 + expect(merge_request.source_branch_head.parents.map(&:id)). + to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 824be604a34828eb682305f0d963056cfac87b2d)) end @@ -158,8 +158,8 @@ describe MergeRequests::ResolveService do let(:service) { MergeRequests::ResolveService.new(project, user, invalid_params) } it 'raises a MissingResolution error' do - expect { service.execute(merge_request) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { service.execute(merge_request) }. + to raise_error(Gitlab::Conflict::File::MissingResolution) end end @@ -184,8 +184,8 @@ describe MergeRequests::ResolveService do let(:service) { MergeRequests::ResolveService.new(project, user, invalid_params) } it 'raises a MissingResolution error' do - expect { service.execute(merge_request) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + expect { service.execute(merge_request) }. + to raise_error(Gitlab::Conflict::File::MissingResolution) end end @@ -206,8 +206,8 @@ describe MergeRequests::ResolveService do let(:service) { MergeRequests::ResolveService.new(project, user, invalid_params) } it 'raises a MissingFiles error' do - expect { service.execute(merge_request) } - .to raise_error(MergeRequests::ResolveService::MissingFiles) + expect { service.execute(merge_request) }. + to raise_error(MergeRequests::ResolveService::MissingFiles) end end end diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index b67874ed4c3..7d73c0ea5d0 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -68,8 +68,8 @@ describe MergeRequests::UpdateService, services: true do it { expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') } it 'executes hooks with update action' do - expect(service).to have_received(:execute_hooks) - .with(@merge_request, 'update') + expect(service).to have_received(:execute_hooks). + with(@merge_request, 'update') end it 'sends email to user2 about assign of new merge request and email to user3 about merge request unassignment' do @@ -171,8 +171,8 @@ describe MergeRequests::UpdateService, services: true do ref: merge_request.source_branch, sha: merge_request.diff_head_sha) - expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user) - .and_return(service_mock) + expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user). + and_return(service_mock) expect(service_mock).to receive(:execute).with(merge_request) end diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb index 471ba78714b..57a5aa5cedc 100644 --- a/spec/services/projects/housekeeping_service_spec.rb +++ b/spec/services/projects/housekeeping_service_spec.rb @@ -66,14 +66,14 @@ describe Projects::HousekeepingService do allow(subject).to receive(:lease_key).and_return(:the_lease_key) # At push 200 - expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid) - .exactly(1).times + expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid). + exactly(1).times # At push 50, 100, 150 - expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid) - .exactly(3).times + expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid). + exactly(3).times # At push 10, 20, ... (except those above) - expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid) - .exactly(16).times + expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid). + exactly(16).times 201.times do subject.increment! diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb index 297837537a3..ab6e8f537ba 100644 --- a/spec/services/projects/import_service_spec.rb +++ b/spec/services/projects/import_service_spec.rb @@ -73,18 +73,18 @@ describe Projects::ImportService, services: true do end it 'flushes various caches' do - expect_any_instance_of(Gitlab::Shell).to receive(:import_repository) - .with(project.repository_storage_path, project.path_with_namespace, project.import_url) - .and_return(true) + expect_any_instance_of(Gitlab::Shell).to receive(:import_repository). + with(project.repository_storage_path, project.path_with_namespace, project.import_url). + and_return(true) - expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute) - .and_return(true) + expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute). + and_return(true) - expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) - .and_call_original + expect_any_instance_of(Repository).to receive(:expire_emptiness_caches). + and_call_original - expect_any_instance_of(Repository).to receive(:expire_exists_cache) - .and_call_original + expect_any_instance_of(Repository).to receive(:expire_exists_cache). + and_call_original subject.execute end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index b6b7f94061e..5c6fbea8d0e 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -7,10 +7,10 @@ describe Projects::TransferService, services: true do context 'namespace -> namespace' do before do - allow_any_instance_of(Gitlab::UploadsTransfer) - .to receive(:move_project).and_return(true) - allow_any_instance_of(Gitlab::PagesTransfer) - .to receive(:move_project).and_return(true) + allow_any_instance_of(Gitlab::UploadsTransfer). + to receive(:move_project).and_return(true) + allow_any_instance_of(Gitlab::PagesTransfer). + to receive(:move_project).and_return(true) group.add_owner(user) @result = transfer_project(project, user, group) end @@ -102,9 +102,9 @@ describe Projects::TransferService, services: true do end it 'only schedules a single job for every user' do - expect(UserProjectAccessChangedService).to receive(:new) - .with([owner.id, group_member.id]) - .and_call_original + expect(UserProjectAccessChangedService).to receive(:new). + with([owner.id, group_member.id]). + and_call_original transfer_project(project, owner, group) end diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb index d34652bd7ac..23f5555d3e0 100644 --- a/spec/services/projects/unlink_fork_service_spec.rb +++ b/spec/services/projects/unlink_fork_service_spec.rb @@ -12,9 +12,9 @@ describe Projects::UnlinkForkService, services: true do let(:mr_close_service) { MergeRequests::CloseService.new(fork_project, user) } before do - allow(MergeRequests::CloseService).to receive(:new) - .with(fork_project, user) - .and_return(mr_close_service) + allow(MergeRequests::CloseService).to receive(:new). + with(fork_project, user). + and_return(mr_close_service) end it 'close all pending merge requests' do diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index dfa5175b7d8..eca5a418f2a 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -253,8 +253,8 @@ describe SystemNoteService, services: true do it_behaves_like 'a system note' it 'sets the note text' do - expect(subject.note) - .to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**" + expect(subject.note). + to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**" end end end @@ -388,8 +388,8 @@ describe SystemNoteService, services: true do context 'when mentioner is not a MergeRequest' do it 'is falsey' do mentioner = noteable.dup - expect(described_class.cross_reference_disallowed?(noteable, mentioner)) - .to be_falsey + expect(described_class.cross_reference_disallowed?(noteable, mentioner)). + to be_falsey end end @@ -399,14 +399,14 @@ describe SystemNoteService, services: true do it 'is truthy when noteable is in commits' do expect(mentioner).to receive(:commits).and_return([noteable]) - expect(described_class.cross_reference_disallowed?(noteable, mentioner)) - .to be_truthy + expect(described_class.cross_reference_disallowed?(noteable, mentioner)). + to be_truthy end it 'is falsey when noteable is not in commits' do expect(mentioner).to receive(:commits).and_return([]) - expect(described_class.cross_reference_disallowed?(noteable, mentioner)) - .to be_falsey + expect(described_class.cross_reference_disallowed?(noteable, mentioner)). + to be_falsey end end @@ -414,8 +414,8 @@ describe SystemNoteService, services: true do let(:noteable) { ExternalIssue.new('EXT-1234', project) } it 'is truthy' do mentioner = noteable.dup - expect(described_class.cross_reference_disallowed?(noteable, mentioner)) - .to be_truthy + expect(described_class.cross_reference_disallowed?(noteable, mentioner)). + to be_truthy end end @@ -425,13 +425,13 @@ describe SystemNoteService, services: true do it 'is truthy when issue is closed' do issue.close - expect(described_class.cross_reference_disallowed?(issue, project.commit)) - .to be_truthy + expect(described_class.cross_reference_disallowed?(issue, project.commit)). + to be_truthy end it 'is falsey when issue is open' do - expect(described_class.cross_reference_disallowed?(issue, project.commit)) - .to be_falsy + expect(described_class.cross_reference_disallowed?(issue, project.commit)). + to be_falsy end end @@ -441,20 +441,20 @@ describe SystemNoteService, services: true do it 'is truthy when merge request is closed' do allow(merge_request).to receive(:closed?).and_return(:true) - expect(described_class.cross_reference_disallowed?(merge_request, project.commit)) - .to be_truthy + expect(described_class.cross_reference_disallowed?(merge_request, project.commit)). + to be_truthy end it 'is truthy when merge request is merged' do allow(merge_request).to receive(:closed?).and_return(:true) - expect(described_class.cross_reference_disallowed?(merge_request, project.commit)) - .to be_truthy + expect(described_class.cross_reference_disallowed?(merge_request, project.commit)). + to be_truthy end it 'is falsey when merge request is open' do - expect(described_class.cross_reference_disallowed?(merge_request, project.commit)) - .to be_falsy + expect(described_class.cross_reference_disallowed?(merge_request, project.commit)). + to be_falsy end end end @@ -470,13 +470,13 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(noteable, commit0)) - .to be_truthy + expect(described_class.cross_reference_exists?(noteable, commit0)). + to be_truthy end it 'is falsey when not already mentioned' do - expect(described_class.cross_reference_exists?(noteable, commit1)) - .to be_falsey + expect(described_class.cross_reference_exists?(noteable, commit1)). + to be_falsey end context 'legacy capitalized cross reference' do @@ -487,8 +487,8 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(noteable, commit0)) - .to be_truthy + expect(described_class.cross_reference_exists?(noteable, commit0)). + to be_truthy end end end @@ -500,13 +500,13 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(commit0, commit1)) - .to be_truthy + expect(described_class.cross_reference_exists?(commit0, commit1)). + to be_truthy end it 'is falsey when not already mentioned' do - expect(described_class.cross_reference_exists?(commit1, commit0)) - .to be_falsey + expect(described_class.cross_reference_exists?(commit1, commit0)). + to be_falsey end context 'legacy capitalized cross reference' do @@ -517,8 +517,8 @@ describe SystemNoteService, services: true do end it 'is truthy when already mentioned' do - expect(described_class.cross_reference_exists?(commit0, commit1)) - .to be_truthy + expect(described_class.cross_reference_exists?(commit0, commit1)). + to be_truthy end end end @@ -533,8 +533,8 @@ describe SystemNoteService, services: true do end it 'is true when a fork mentions an external issue' do - expect(described_class.cross_reference_exists?(noteable, commit2)) - .to be true + expect(described_class.cross_reference_exists?(noteable, commit2)). + to be true end context 'legacy capitalized cross reference' do @@ -544,8 +544,8 @@ describe SystemNoteService, services: true do end it 'is true when a fork mentions an external issue' do - expect(described_class.cross_reference_exists?(noteable, commit2)) - .to be true + expect(described_class.cross_reference_exists?(noteable, commit2)). + to be true end end end @@ -771,8 +771,8 @@ describe SystemNoteService, services: true do it 'creates a new note in the discussion' do # we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded. - expect { SystemNoteService.discussion_continued_in_issue(discussion, project, user, issue) } - .to change { reloaded_merge_request.discussions.first.notes.size }.by(1) + expect { SystemNoteService.discussion_continued_in_issue(discussion, project, user, issue) }. + to change { reloaded_merge_request.discussions.first.notes.size }.by(1) end it 'mentions the created issue in the system note' do diff --git a/spec/services/tags/create_service_spec.rb b/spec/services/tags/create_service_spec.rb index 4bb8a0ec290..5478b8c9ec0 100644 --- a/spec/services/tags/create_service_spec.rb +++ b/spec/services/tags/create_service_spec.rb @@ -26,9 +26,9 @@ describe Tags::CreateService, services: true do context 'when tag already exists' do it 'returns an error' do - expect(repository).to receive(:add_tag) - .with(user, 'v1.1.0', 'master', 'Foo') - .and_raise(Rugged::TagError) + expect(repository).to receive(:add_tag). + with(user, 'v1.1.0', 'master', 'Foo'). + and_raise(Rugged::TagError) response = service.execute('v1.1.0', 'master', 'Foo') @@ -39,9 +39,9 @@ describe Tags::CreateService, services: true do context 'when pre-receive hook fails' do it 'returns an error' do - expect(repository).to receive(:add_tag) - .with(user, 'v1.1.0', 'master', 'Foo') - .and_raise(GitHooksService::PreReceiveError, 'something went wrong') + expect(repository).to receive(:add_tag). + with(user, 'v1.1.0', 'master', 'Foo'). + and_raise(GitHooksService::PreReceiveError, 'something went wrong') response = service.execute('v1.1.0', 'master', 'Foo') diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 9f24cc0f3f2..6dfcb702510 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -768,15 +768,15 @@ describe TodoService, services: true do create(:todo, :mentioned, user: john_doe, target: issue, project: project) todos = TodosFinder.new(john_doe, {}).execute - expect { TodoService.new.mark_todos_as_done(todos, john_doe) } - .to change { john_doe.todos.done.count }.from(0).to(1) + expect { TodoService.new.mark_todos_as_done(todos, john_doe) }. + to change { john_doe.todos.done.count }.from(0).to(1) end it 'marks an array of todos as done' do todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project) - expect { TodoService.new.mark_todos_as_done([todo], john_doe) } - .to change { todo.reload.state }.from('pending').to('done') + expect { TodoService.new.mark_todos_as_done([todo], john_doe) }. + to change { todo.reload.state }.from('pending').to('done') end it 'returns the number of updated todos' do # Needed on API diff --git a/spec/services/user_project_access_changed_service_spec.rb b/spec/services/user_project_access_changed_service_spec.rb index 14a5e40350a..b4efe7de431 100644 --- a/spec/services/user_project_access_changed_service_spec.rb +++ b/spec/services/user_project_access_changed_service_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe UserProjectAccessChangedService do describe '#execute' do it 'schedules the user IDs' do - expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait) - .with([[1], [2]]) + expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait). + with([[1], [2]]) described_class.new([1, 2]).execute end diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb index 0a527c7c5d1..690fe979492 100644 --- a/spec/services/users/refresh_authorized_projects_service_spec.rb +++ b/spec/services/users/refresh_authorized_projects_service_spec.rb @@ -6,17 +6,17 @@ describe Users::RefreshAuthorizedProjectsService do let(:service) { described_class.new(user) } def create_authorization(project, user, access_level = Gitlab::Access::MASTER) - ProjectAuthorization - .create!(project: project, user: user, access_level: access_level) + ProjectAuthorization. + create!(project: project, user: user, access_level: access_level) end describe '#execute', :redis do it 'refreshes the authorizations using a lease' do - expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) - .and_return('foo') + expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). + and_return('foo') - expect(Gitlab::ExclusiveLease).to receive(:cancel) - .with(an_instance_of(String), 'foo') + expect(Gitlab::ExclusiveLease).to receive(:cancel). + with(an_instance_of(String), 'foo') expect(service).to receive(:execute_without_lease) @@ -33,8 +33,8 @@ describe Users::RefreshAuthorizedProjectsService do project2 = create(:empty_project) to_remove = create_authorization(project2, user) - expect(service).to receive(:update_authorizations) - .with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) + expect(service).to receive(:update_authorizations). + with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) service.execute_without_lease end @@ -42,8 +42,8 @@ describe Users::RefreshAuthorizedProjectsService do it 'sets the access level of a project to the highest available level' do to_remove = create_authorization(project, user, Gitlab::Access::DEVELOPER) - expect(service).to receive(:update_authorizations) - .with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) + expect(service).to receive(:update_authorizations). + with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]]) service.execute_without_lease end diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb index c8f8d2d57b4..d0fd2d52004 100644 --- a/spec/support/controllers/githubish_import_controller_shared_examples.rb +++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb @@ -14,8 +14,8 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do it "updates access token" do token = 'asdfasdf9876' - allow_any_instance_of(Gitlab::GithubImport::Client) - .to receive(:user).and_return(true) + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:user).and_return(true) post :personal_access_token, personal_access_token: token @@ -79,8 +79,8 @@ shared_examples 'a GitHub-ish import controller: GET status' do end it "handles an invalid access token" do - allow_any_instance_of(Gitlab::GithubImport::Client) - .to receive(:repos).and_raise(Octokit::Unauthorized) + allow_any_instance_of(Gitlab::GithubImport::Client). + to receive(:repos).and_raise(Octokit::Unauthorized) get :status @@ -110,9 +110,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do context "when the repository owner is the provider user" do context "when the provider user and GitLab user's usernames match" do it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, format: :js end @@ -122,9 +122,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do let(:provider_username) { "someone_else" } it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, format: :js end @@ -144,9 +144,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do context "when the namespace is owned by the GitLab user" do it "takes the existing namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, format: :js end @@ -159,9 +159,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do end it "creates a project using user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, format: :js end @@ -171,16 +171,16 @@ shared_examples 'a GitHub-ish import controller: POST create' do context "when a namespace with the provider user's username doesn't exist" do context "when current user can create namespaces" do it "creates the namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1) end it "takes the new namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider). + and_return(double(execute: true)) post :create, target_namespace: provider_repo.name, format: :js end @@ -192,16 +192,16 @@ shared_examples 'a GitHub-ish import controller: POST create' do end it "doesn't create the namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).and_return(double(execute: true)) expect { post :create, format: :js }.not_to change(Namespace, :count) end it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, format: :js end @@ -213,17 +213,17 @@ shared_examples 'a GitHub-ish import controller: POST create' do let(:test_name) { 'test_name' } it 'takes the selected namespace and name' do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js } end it 'takes the selected name and default namespace' do - expect(Gitlab::GithubImport::ProjectCreator) - .to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider) - .and_return(double(execute: true)) + expect(Gitlab::GithubImport::ProjectCreator). + to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider). + and_return(double(execute: true)) post :create, { new_name: test_name, format: :js } end diff --git a/spec/support/ldap_helpers.rb b/spec/support/ldap_helpers.rb index 079f244475c..ab635711cf7 100644 --- a/spec/support/ldap_helpers.rb +++ b/spec/support/ldap_helpers.rb @@ -16,8 +16,8 @@ module LdapHelpers # ) def stub_ldap_config(messages) messages.each do |config, value| - allow_any_instance_of(::Gitlab::LDAP::Config) - .to receive(config.to_sym).and_return(value) + allow_any_instance_of(::Gitlab::LDAP::Config). + to receive(config.to_sym).and_return(value) end end @@ -32,8 +32,8 @@ module LdapHelpers def stub_ldap_person_find_by_uid(uid, entry, provider = 'ldapmain') return_value = ::Gitlab::LDAP::Person.new(entry, provider) if entry.present? - allow(::Gitlab::LDAP::Person) - .to receive(:find_by_uid).with(uid, any_args).and_return(return_value) + allow(::Gitlab::LDAP::Person). + to receive(:find_by_uid).with(uid, any_args).and_return(return_value) end # Create a simple LDAP user entry. diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb index 3ac201f1fb1..87936bb4859 100644 --- a/spec/support/mentionable_shared_examples.rb +++ b/spec/support/mentionable_shared_examples.rb @@ -81,8 +81,8 @@ shared_examples 'a mentionable' do ext_issue, ext_mr, ext_commit] mentioned_objects.each do |referenced| - expect(SystemNoteService).to receive(:cross_reference) - .with(referenced, subject.local_reference, author) + expect(SystemNoteService).to receive(:cross_reference). + with(referenced, subject.local_reference, author) end subject.create_cross_references! @@ -127,15 +127,15 @@ shared_examples 'an editable mentionable' do # These three objects were already referenced, and should not receive new # notes [mentioned_issue, mentioned_commit, ext_issue].each do |oldref| - expect(SystemNoteService).not_to receive(:cross_reference) - .with(oldref, any_args) + expect(SystemNoteService).not_to receive(:cross_reference). + with(oldref, any_args) end # These two issues are new and should receive reference notes # In the case of MergeRequests remember that cannot mention commits included in the MergeRequest new_issues.each do |newref| - expect(SystemNoteService).to receive(:cross_reference) - .with(newref, subject.local_reference, author) + expect(SystemNoteService).to receive(:cross_reference). + with(newref, subject.local_reference, author) end set_mentionable_text.call(new_text) diff --git a/spec/support/reactive_caching_helpers.rb b/spec/support/reactive_caching_helpers.rb index 34124f02133..98eb57f8b54 100644 --- a/spec/support/reactive_caching_helpers.rb +++ b/spec/support/reactive_caching_helpers.rb @@ -35,8 +35,8 @@ module ReactiveCachingHelpers end def expect_reactive_cache_update_queued(subject) - expect(ReactiveCachingWorker) - .to receive(:perform_in) - .with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) + expect(ReactiveCachingWorker). + to receive(:perform_in). + with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id) end end diff --git a/spec/support/services_shared_context.rb b/spec/support/services_shared_context.rb index 7457484a932..66c93890e31 100644 --- a/spec/support/services_shared_context.rb +++ b/spec/support/services_shared_context.rb @@ -6,9 +6,9 @@ Service.available_services_names.each do |service| let(:service_fields) { service_klass.new.fields } let(:service_attrs_list) { service_fields.inject([]) {|arr, hash| arr << hash[:name].to_sym } } let(:service_attrs_list_without_passwords) do - service_fields - .select { |field| field[:type] != 'password' } - .map { |field| field[:name].to_sym} + service_fields. + select { |field| field[:type] != 'password' }. + map { |field| field[:name].to_sym} end let(:service_attrs) do service_attrs_list.inject({}) do |hash, k| diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb index e18b79c89d1..704922b6cf4 100644 --- a/spec/support/slack_mattermost_notifications_shared_examples.rb +++ b/spec/support/slack_mattermost_notifications_shared_examples.rb @@ -104,9 +104,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it 'uses the username as an option for slack when configured' do allow(chat_service).to receive(:username).and_return(username) - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, username: username) - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, username: username). + and_return( double(:slack_service).as_null_object ) @@ -115,9 +115,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it 'uses the channel as an option when it is configured' do allow(chat_service).to receive(:channel).and_return(channel) - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, channel: channel) - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: channel). + and_return( double(:slack_service).as_null_object ) chat_service.execute(push_sample_data) @@ -127,9 +127,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for push event" do chat_service.update_attributes(push_channel: "random") - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, channel: "random") - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( double(:slack_service).as_null_object ) @@ -139,9 +139,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for merge request event" do chat_service.update_attributes(merge_request_channel: "random") - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, channel: "random") - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( double(:slack_service).as_null_object ) @@ -151,9 +151,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for issue event" do chat_service.update_attributes(issue_channel: "random") - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, channel: "random") - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( double(:slack_service).as_null_object ) @@ -163,9 +163,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do it "uses the right channel for wiki event" do chat_service.update_attributes(wiki_page_channel: "random") - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, channel: "random") - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( double(:slack_service).as_null_object ) @@ -182,9 +182,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do note_data = Gitlab::DataBuilder::Note.build(issue_note, user) - expect(Slack::Notifier).to receive(:new) - .with(webhook_url, channel: "random") - .and_return( + expect(Slack::Notifier).to receive(:new). + with(webhook_url, channel: "random"). + and_return( double(:slack_service).as_null_object ) diff --git a/spec/support/stub_configuration.rb b/spec/support/stub_configuration.rb index a04714622fc..f40ee862df8 100644 --- a/spec/support/stub_configuration.rb +++ b/spec/support/stub_configuration.rb @@ -5,8 +5,8 @@ module StubConfiguration # Stubbing both of these because we're not yet consistent with how we access # current application settings allow_any_instance_of(ApplicationSetting).to receive_messages(messages) - allow(Gitlab::CurrentSettings.current_application_settings) - .to receive_messages(messages) + allow(Gitlab::CurrentSettings.current_application_settings). + to receive_messages(messages) end def stub_config_setting(messages) diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 69e1ad18b15..07602c0cb40 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -51,22 +51,22 @@ module StubGitlabCalls def stub_session f = File.read(Rails.root.join('spec/support/gitlab_stubs/session.json')) - stub_request(:post, "#{gitlab_url}api/v3/session.json") - .with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}", - headers: { 'Content-Type' => 'application/json' }) - .to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:post, "#{gitlab_url}api/v3/session.json"). + with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}", + headers: { 'Content-Type' => 'application/json' }). + to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' }) end def stub_user f = File.read(Rails.root.join('spec/support/gitlab_stubs/user.json')) - stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz") - .with(headers: { 'Content-Type' => 'application/json' }) - .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz"). + with(headers: { 'Content-Type' => 'application/json' }). + to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) - stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token") - .with(headers: { 'Content-Type' => 'application/json' }) - .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token"). + with(headers: { 'Content-Type' => 'application/json' }). + to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) end def stub_project_8 @@ -82,21 +82,21 @@ module StubGitlabCalls def stub_projects f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json')) - stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz") - .with(headers: { 'Content-Type' => 'application/json' }) - .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) + stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz"). + with(headers: { 'Content-Type' => 'application/json' }). + to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' }) end def stub_projects_owned - stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz") - .with(headers: { 'Content-Type' => 'application/json' }) - .to_return(status: 200, body: "", headers: {}) + stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz"). + with(headers: { 'Content-Type' => 'application/json' }). + to_return(status: 200, body: "", headers: {}) end def stub_ci_enable - stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz") - .with(headers: { 'Content-Type' => 'application/json' }) - .to_return(status: 200, body: "", headers: {}) + stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz"). + with(headers: { 'Content-Type' => 'application/json' }). + to_return(status: 200, body: "", headers: {}) end def project_hash_array diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index 21ff688f6dd..4e63a4cd537 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -74,13 +74,13 @@ module TestEnv end def disable_mailer - allow_any_instance_of(NotificationService).to receive(:mailer) - .and_return(double.as_null_object) + allow_any_instance_of(NotificationService).to receive(:mailer). + and_return(double.as_null_object) end def enable_mailer - allow_any_instance_of(NotificationService).to receive(:mailer) - .and_call_original + allow_any_instance_of(NotificationService).to receive(:mailer). + and_call_original end def disable_pre_receive diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index 85c34a00b11..df8a47893f9 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -47,24 +47,24 @@ describe 'gitlab:app namespace rake task' do allow(Kernel).to receive(:system).and_return(true) allow(FileUtils).to receive(:cp_r).and_return(true) allow(FileUtils).to receive(:mv).and_return(true) - allow(Rake::Task["gitlab:shell:setup"]) - .to receive(:invoke).and_return(true) + allow(Rake::Task["gitlab:shell:setup"]). + to receive(:invoke).and_return(true) ENV['force'] = 'yes' end let(:gitlab_version) { Gitlab::VERSION } it 'fails on mismatch' do - allow(YAML).to receive(:load_file) - .and_return({ gitlab_version: "not #{gitlab_version}" }) + allow(YAML).to receive(:load_file). + and_return({ gitlab_version: "not #{gitlab_version}" }) - expect { run_rake_task('gitlab:backup:restore') } - .to raise_error(SystemExit) + expect { run_rake_task('gitlab:backup:restore') }. + to raise_error(SystemExit) end it 'invokes restoration on match' do - allow(YAML).to receive(:load_file) - .and_return({ gitlab_version: gitlab_version }) + allow(YAML).to receive(:load_file). + and_return({ gitlab_version: gitlab_version }) expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke) expect(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke) expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke) @@ -320,8 +320,8 @@ describe 'gitlab:app namespace rake task' do end it 'does not invoke repositories restore' do - allow(Rake::Task['gitlab:shell:setup']) - .to receive(:invoke).and_return(true) + allow(Rake::Task['gitlab:shell:setup']). + to receive(:invoke).and_return(true) allow($stdout).to receive :write expect(Rake::Task['gitlab:db:drop_tables']).to receive :invoke diff --git a/spec/tasks/gitlab/check_rake_spec.rb b/spec/tasks/gitlab/check_rake_spec.rb index 538ff952bf4..a808ef7dcc0 100644 --- a/spec/tasks/gitlab/check_rake_spec.rb +++ b/spec/tasks/gitlab/check_rake_spec.rb @@ -23,8 +23,8 @@ describe 'gitlab:ldap:check rake task' do let(:adapter) { ldap_adapter('ldapmain', ldap) } before do - allow(Gitlab::LDAP::Config) - .to receive_messages( + allow(Gitlab::LDAP::Config). + to receive_messages( enabled?: true, providers: ['ldapmain'] ) diff --git a/spec/tasks/gitlab/shell_rake_spec.rb b/spec/tasks/gitlab/shell_rake_spec.rb index 226d34fe2c9..0787894ad2c 100644 --- a/spec/tasks/gitlab/shell_rake_spec.rb +++ b/spec/tasks/gitlab/shell_rake_spec.rb @@ -17,8 +17,8 @@ describe 'gitlab:shell rake tasks' do describe 'create_hooks task' do it 'calls gitlab-shell bin/create_hooks' do - expect_any_instance_of(Object).to receive(:system) - .with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) + expect_any_instance_of(Object).to receive(:system). + with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) run_rake_task('gitlab:shell:create_hooks') end diff --git a/spec/tasks/gitlab/task_helpers_spec.rb b/spec/tasks/gitlab/task_helpers_spec.rb index 528fdbaaa74..86e42d845ce 100644 --- a/spec/tasks/gitlab/task_helpers_spec.rb +++ b/spec/tasks/gitlab/task_helpers_spec.rb @@ -41,8 +41,8 @@ describe Gitlab::TaskHelpers do describe '#clone_repo' do it 'clones the repo in the target dir' do - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{clone_path}]) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{clone_path}]) subject.clone_repo(repo, clone_path) end @@ -50,10 +50,10 @@ describe Gitlab::TaskHelpers do describe '#checkout_tag' do it 'clones the repo in the target dir' do - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --tags --quiet]) - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}]) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --tags --quiet]) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}]) subject.checkout_tag(tag, clone_path) end @@ -62,21 +62,21 @@ describe Gitlab::TaskHelpers do describe '#reset_to_tag' do let(:tag) { 'v1.1.0' } before do - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}]) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}]) end context 'when the tag is not checked out locally' do before do - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_raise(Gitlab::TaskFailedError) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_raise(Gitlab::TaskFailedError) end it 'fetch origin, ensure the tag exists, and resets --hard to the given tag' do - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch origin]) - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- origin/#{tag}]).and_return(tag) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch origin]) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- origin/#{tag}]).and_return(tag) subject.reset_to_tag(tag, clone_path) end @@ -84,8 +84,8 @@ describe Gitlab::TaskHelpers do context 'when the tag is checked out locally' do before do - expect(subject) - .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_return(tag) + expect(subject). + to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_return(tag) end it 'resets --hard to the given tag' do diff --git a/spec/tasks/gitlab/workhorse_rake_spec.rb b/spec/tasks/gitlab/workhorse_rake_spec.rb index da4b408023c..6de66c3cf07 100644 --- a/spec/tasks/gitlab/workhorse_rake_spec.rb +++ b/spec/tasks/gitlab/workhorse_rake_spec.rb @@ -23,8 +23,8 @@ describe 'gitlab:workhorse namespace rake task' do context 'when an underlying Git command fail' do it 'aborts and display a help message' do - expect_any_instance_of(Object) - .to receive(:checkout_or_clone_tag).and_raise 'Git error' + expect_any_instance_of(Object). + to receive(:checkout_or_clone_tag).and_raise 'Git error' expect { run_rake_task('gitlab:workhorse:install', clone_path) }.to raise_error 'Git error' end @@ -36,8 +36,8 @@ describe 'gitlab:workhorse namespace rake task' do end it 'calls checkout_or_clone_tag with the right arguments' do - expect_any_instance_of(Object) - .to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path) + expect_any_instance_of(Object). + to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path) run_rake_task('gitlab:workhorse:install', clone_path) end diff --git a/spec/views/devise/shared/_signin_box.html.haml_spec.rb b/spec/views/devise/shared/_signin_box.html.haml_spec.rb index 9adbb0476be..1397bfa5864 100644 --- a/spec/views/devise/shared/_signin_box.html.haml_spec.rb +++ b/spec/views/devise/shared/_signin_box.html.haml_spec.rb @@ -31,7 +31,7 @@ describe 'devise/shared/_signin_box' do def enable_crowd allow(view).to receive(:form_based_providers).and_return([:crowd]) allow(view).to receive(:crowd_enabled?).and_return(true) - allow(view).to receive(:omniauth_authorize_path).with(:user, :crowd) - .and_return('/crowd') + allow(view).to receive(:omniauth_authorize_path).with(:user, :crowd). + and_return('/crowd') end end diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb index 8020faa1f9c..254672a5612 100644 --- a/spec/views/layouts/_head.html.haml_spec.rb +++ b/spec/views/layouts/_head.html.haml_spec.rb @@ -26,7 +26,7 @@ describe 'layouts/_head' do end def stub_helper_with_safe_string(method) - allow_any_instance_of(PageLayoutHelper).to receive(method) - .and_return(%q{foo" http-equiv="refresh}.html_safe) + allow_any_instance_of(PageLayoutHelper).to receive(method). + and_return(%q{foo" http-equiv="refresh}.html_safe) end end diff --git a/spec/views/projects/merge_requests/edit.html.haml_spec.rb b/spec/views/projects/merge_requests/edit.html.haml_spec.rb index 3650b22c389..2e4390d6797 100644 --- a/spec/views/projects/merge_requests/edit.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/edit.html.haml_spec.rb @@ -23,8 +23,8 @@ describe 'projects/merge_requests/edit.html.haml' do assign(:merge_request, closed_merge_request) allow(view).to receive(:can?).and_return(true) - allow(view).to receive(:current_user) - .and_return(User.find(closed_merge_request.author_id)) + allow(view).to receive(:current_user). + and_return(User.find(closed_merge_request.author_id)) end context 'when a merge request without fork' do diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index ba20488f663..8ebf00374a1 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildCoverageWorker do let!(:build) { create(:ci_build) } it 'updates code coverage' do - expect_any_instance_of(Ci::Build) - .to receive(:update_coverage) + expect_any_instance_of(Ci::Build). + to receive(:update_coverage) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildCoverageWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index 2868167c7d4..f8119913116 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -6,15 +6,15 @@ describe BuildFinishedWorker do let(:build) { create(:ci_build) } it 'calculates coverage and calls hooks' do - expect(BuildCoverageWorker) - .to receive(:new).ordered.and_call_original - expect(BuildHooksWorker) - .to receive(:new).ordered.and_call_original + expect(BuildCoverageWorker). + to receive(:new).ordered.and_call_original + expect(BuildHooksWorker). + to receive(:new).ordered.and_call_original - expect_any_instance_of(BuildCoverageWorker) - .to receive(:perform) - expect_any_instance_of(BuildHooksWorker) - .to receive(:perform) + expect_any_instance_of(BuildCoverageWorker). + to receive(:perform) + expect_any_instance_of(BuildHooksWorker). + to receive(:perform) described_class.new.perform(build.id) end @@ -22,8 +22,8 @@ describe BuildFinishedWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index 97654a93f5c..51abc1d89a1 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildHooksWorker do let!(:build) { create(:ci_build) } it 'calls build hooks' do - expect_any_instance_of(Ci::Build) - .to receive(:execute_hooks) + expect_any_instance_of(Ci::Build). + to receive(:execute_hooks) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildHooksWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb index dba70883130..d016ecbb738 100644 --- a/spec/workers/build_success_worker_spec.rb +++ b/spec/workers/build_success_worker_spec.rb @@ -7,8 +7,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, environment: 'production') } it 'executes deployment service' do - expect_any_instance_of(CreateDeploymentService) - .to receive(:execute) + expect_any_instance_of(CreateDeploymentService). + to receive(:execute) described_class.new.perform(build.id) end @@ -18,8 +18,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, project: nil) } it 'does not create deployment' do - expect_any_instance_of(CreateDeploymentService) - .not_to receive(:execute) + expect_any_instance_of(CreateDeploymentService). + not_to receive(:execute) described_class.new.perform(build.id) end @@ -28,8 +28,8 @@ describe BuildSuccessWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/delete_user_worker_spec.rb b/spec/workers/delete_user_worker_spec.rb index 06b470f68f2..0765573408c 100644 --- a/spec/workers/delete_user_worker_spec.rb +++ b/spec/workers/delete_user_worker_spec.rb @@ -5,15 +5,15 @@ describe DeleteUserWorker do let!(:current_user) { create(:user) } it "calls the DeleteUserWorker with the params it was given" do - expect_any_instance_of(Users::DestroyService).to receive(:execute) - .with(user, {}) + expect_any_instance_of(Users::DestroyService).to receive(:execute). + with(user, {}) DeleteUserWorker.new.perform(current_user.id, user.id) end it "uses symbolized keys" do - expect_any_instance_of(Users::DestroyService).to receive(:execute) - .with(user, test: "test") + expect_any_instance_of(Users::DestroyService).to receive(:execute). + with(user, test: "test") DeleteUserWorker.new.perform(current_user.id, user.id, "test" => "test") end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index 30908534eb3..fc9adf47c1e 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -5,8 +5,8 @@ describe 'Every Sidekiq worker' do root = Rails.root.join('app', 'workers') concerns = root.join('concerns').to_s - workers = Dir[root.join('**', '*.rb')] - .reject { |path| path.start_with?(concerns) } + workers = Dir[root.join('**', '*.rb')]. + reject { |path| path.start_with?(concerns) } workers.map do |path| ns = Pathname.new(path).relative_path_from(root).to_s.gsub('.rb', '') @@ -22,9 +22,9 @@ describe 'Every Sidekiq worker' do end it 'uses the cronjob queue when the worker runs as a cronjob' do - cron_workers = Settings.cron_jobs - .map { |job_name, options| options['job_class'].constantize } - .to_set + cron_workers = Settings.cron_jobs. + map { |job_name, options| options['job_class'].constantize }. + to_set workers.each do |worker| next unless cron_workers.include?(worker) diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb index e4c4a9ac17a..a60af574a08 100644 --- a/spec/workers/git_garbage_collect_worker_spec.rb +++ b/spec/workers/git_garbage_collect_worker_spec.rb @@ -11,8 +11,8 @@ describe GitGarbageCollectWorker do describe "#perform" do it "flushes ref caches when the task is 'gc'" do expect(subject).to receive(:command).with(:gc).and_return([:the, :command]) - expect(Gitlab::Popen).to receive(:popen) - .with([:the, :command], project.repository.path_to_repo).and_return(["", 0]) + expect(Gitlab::Popen).to receive(:popen). + with([:the, :command], project.repository.path_to_repo).and_return(["", 0]) expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original expect_any_instance_of(Repository).to receive(:branch_names).and_call_original diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb index 575361c93d4..8fdbb35afd0 100644 --- a/spec/workers/new_note_worker_spec.rb +++ b/spec/workers/new_note_worker_spec.rb @@ -24,8 +24,8 @@ describe NewNoteWorker do let(:unexistent_note_id) { 999 } it 'logs NewNoteWorker process skipping' do - expect(Rails.logger).to receive(:error) - .with("NewNoteWorker: couldn't find note with ID=999, skipping job") + expect(Rails.logger).to receive(:error). + with("NewNoteWorker: couldn't find note with ID=999, skipping job") described_class.new.perform(unexistent_note_id) end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index 035e329839f..061f4bda36c 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe PipelineHooksWorker do let(:pipeline) { create(:ci_pipeline) } it 'executes hooks for the pipeline' do - expect_any_instance_of(Ci::Pipeline) - .to receive(:execute_hooks) + expect_any_instance_of(Ci::Pipeline). + to receive(:execute_hooks) described_class.new.perform(pipeline.id) end @@ -15,8 +15,8 @@ describe PipelineHooksWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index b9bd234d168..603ae52ed1e 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -56,8 +56,8 @@ describe PipelineNotificationWorker do context 'with success pipeline notification on' do before do - watcher.global_notification_setting - .update(level: 'custom', success_pipeline: true) + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: true) end it_behaves_like 'sending emails' @@ -67,8 +67,8 @@ describe PipelineNotificationWorker do let(:receivers) { [pusher] } before do - watcher.global_notification_setting - .update(level: 'custom', success_pipeline: false) + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: false) end it_behaves_like 'sending emails' @@ -87,8 +87,8 @@ describe PipelineNotificationWorker do context 'with failed pipeline notification on' do before do - watcher.global_notification_setting - .update(level: 'custom', failed_pipeline: true) + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) end it_behaves_like 'sending emails' @@ -98,8 +98,8 @@ describe PipelineNotificationWorker do let(:receivers) { [pusher] } before do - watcher.global_notification_setting - .update(level: 'custom', failed_pipeline: false) + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: false) end it_behaves_like 'sending emails' @@ -117,8 +117,8 @@ describe PipelineNotificationWorker do before do pipeline.project.team << [watcher, Gitlab::Access::GUEST] - watcher.global_notification_setting - .update(level: 'custom', failed_pipeline: true) + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) perform_enqueued_jobs do subject.perform(pipeline.id) diff --git a/spec/workers/pipeline_proccess_worker_spec.rb b/spec/workers/pipeline_proccess_worker_spec.rb index 86e9d7f6684..fd6ee0714ea 100644 --- a/spec/workers/pipeline_proccess_worker_spec.rb +++ b/spec/workers/pipeline_proccess_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineProcessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_success_worker_spec.rb b/spec/workers/pipeline_success_worker_spec.rb index d1c84adda6f..f6c56465feb 100644 --- a/spec/workers/pipeline_success_worker_spec.rb +++ b/spec/workers/pipeline_success_worker_spec.rb @@ -16,8 +16,8 @@ describe PipelineSuccessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index 0b456cfd0da..24d78aae112 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineUpdateWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) } - .not_to raise_error + expect { described_class.new.perform(123) }. + not_to raise_error end end end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index e0bdbab3f15..5919b99a6ed 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -79,9 +79,9 @@ describe PostReceive do end it "does not run if the author is not in the project" do - allow_any_instance_of(Gitlab::GitPostReceive) - .to receive(:identify_using_ssh_key) - .and_return(nil) + allow_any_instance_of(Gitlab::GitPostReceive). + to receive(:identify_using_ssh_key). + and_return(nil) expect(project).not_to receive(:execute_hooks) diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb index dfa0ffb1314..75c7fc1efd2 100644 --- a/spec/workers/process_commit_worker_spec.rb +++ b/spec/workers/process_commit_worker_spec.rb @@ -36,11 +36,11 @@ describe ProcessCommitWorker do describe '#process_commit_message' do context 'when pushing to the default branch' do it 'closes issues that should be closed per the commit message' do - allow(commit).to receive(:safe_message) - .and_return("Closes #{issue.to_reference}") + allow(commit).to receive(:safe_message). + and_return("Closes #{issue.to_reference}") - expect(worker).to receive(:close_issues) - .with(project, user, user, commit, [issue]) + expect(worker).to receive(:close_issues). + with(project, user, user, commit, [issue]) worker.process_commit_message(project, commit, user, user, true) end @@ -48,8 +48,8 @@ describe ProcessCommitWorker do context 'when pushing to a non-default branch' do it 'does not close any issues' do - allow(commit).to receive(:safe_message) - .and_return("Closes #{issue.to_reference}") + allow(commit).to receive(:safe_message). + and_return("Closes #{issue.to_reference}") expect(worker).not_to receive(:close_issues) @@ -90,8 +90,8 @@ describe ProcessCommitWorker do describe '#update_issue_metrics' do it 'updates any existing issue metrics' do - allow(commit).to receive(:safe_message) - .and_return("Closes #{issue.to_reference}") + allow(commit).to receive(:safe_message). + and_return("Closes #{issue.to_reference}") worker.update_issue_metrics(commit, user) @@ -109,8 +109,8 @@ describe ProcessCommitWorker do end it 'parses date strings into Time instances' do - commit = worker - .build_commit(project, id: '123', authored_date: Time.now.to_s) + commit = worker. + build_commit(project, id: '123', authored_date: Time.now.to_s) expect(commit.authored_date).to be_an_instance_of(Time) end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index da9136282e4..0fc274f1a01 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -7,8 +7,8 @@ describe ProjectCacheWorker do describe '#perform' do before do - allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) - .and_return(true) + allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain). + and_return(true) end context 'with a non-existing project' do @@ -31,17 +31,17 @@ describe ProjectCacheWorker do context 'with an existing project' do it 'updates the project statistics' do - expect(worker).to receive(:update_statistics) - .with(kind_of(Project), %i(repository_size)) - .and_call_original + expect(worker).to receive(:update_statistics). + with(kind_of(Project), %i(repository_size)). + and_call_original worker.perform(project.id, [], %w(repository_size)) end it 'refreshes the method caches' do - expect_any_instance_of(Repository).to receive(:refresh_method_caches) - .with(%i(readme)) - .and_call_original + expect_any_instance_of(Repository).to receive(:refresh_method_caches). + with(%i(readme)). + and_call_original worker.perform(project.id, %w(readme)) end @@ -51,9 +51,9 @@ describe ProjectCacheWorker do describe '#update_statistics' do context 'when a lease could not be obtained' do it 'does not update the repository size' do - allow(worker).to receive(:try_obtain_lease_for) - .with(project.id, :update_statistics) - .and_return(false) + allow(worker).to receive(:try_obtain_lease_for). + with(project.id, :update_statistics). + and_return(false) expect(statistics).not_to receive(:refresh!) @@ -63,13 +63,13 @@ describe ProjectCacheWorker do context 'when a lease could be obtained' do it 'updates the project statistics' do - allow(worker).to receive(:try_obtain_lease_for) - .with(project.id, :update_statistics) - .and_return(true) + allow(worker).to receive(:try_obtain_lease_for). + with(project.id, :update_statistics). + and_return(true) - expect(statistics).to receive(:refresh!) - .with(only: %i(repository_size)) - .and_call_original + expect(statistics).to receive(:refresh!). + with(only: %i(repository_size)). + and_call_original worker.update_statistics(project, %i(repository_size)) end diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb index b9d8af4d8b0..60605460adb 100644 --- a/spec/workers/repository_fork_worker_spec.rb +++ b/spec/workers/repository_fork_worker_spec.rb @@ -35,11 +35,11 @@ describe RepositoryForkWorker do fork_project.namespace.path ).and_return(true) - expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) - .and_call_original + expect_any_instance_of(Repository).to receive(:expire_emptiness_caches). + and_call_original - expect_any_instance_of(Repository).to receive(:expire_exists_cache) - .and_call_original + expect_any_instance_of(Repository).to receive(:expire_exists_cache). + and_call_original subject.perform(project.id, '/test/path', project.path_with_namespace, fork_project.namespace.path) diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb index 0faf9bff9c3..c42f3147b7a 100644 --- a/spec/workers/repository_import_worker_spec.rb +++ b/spec/workers/repository_import_worker_spec.rb @@ -8,8 +8,8 @@ describe RepositoryImportWorker do describe '#perform' do context 'when the import was successful' do it 'imports a project' do - expect_any_instance_of(Projects::ImportService).to receive(:execute) - .and_return({ status: :ok }) + expect_any_instance_of(Projects::ImportService).to receive(:execute). + and_return({ status: :ok }) expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) expect_any_instance_of(Project).to receive(:import_finish) @@ -21,8 +21,8 @@ describe RepositoryImportWorker do context 'when the import has failed' do it 'hide the credentials that were used in the import URL' do error = %q{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found } - expect_any_instance_of(Projects::ImportService).to receive(:execute) - .and_return({ status: :error, message: error }) + expect_any_instance_of(Projects::ImportService).to receive(:execute). + and_return({ status: :error, message: error }) subject.perform(project.id) diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb index e50c788b82a..f8752c42a49 100644 --- a/spec/workers/use_key_worker_spec.rb +++ b/spec/workers/use_key_worker_spec.rb @@ -8,8 +8,8 @@ describe UseKeyWorker do current_time = Time.zone.now Timecop.freeze(current_time) do - expect { worker.perform(key.id) } - .to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) + expect { worker.perform(key.id) }. + to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) end end From 56de781a2cef437b6e1af748dc0c231af74e044d Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 16:54:59 -0600 Subject: [PATCH 243/247] Revert "Enable Style/DotPosition" This reverts commit e00fb2bdc2090e9cabeb1eb35a2672a882cc96e9. # Conflicts: # .rubocop.yml # .rubocop_todo.yml # lib/gitlab/ci/config/entry/global.rb # lib/gitlab/ci/config/entry/jobs.rb # spec/lib/gitlab/ci/config/entry/factory_spec.rb # spec/lib/gitlab/ci/config/entry/global_spec.rb # spec/lib/gitlab/ci/config/entry/job_spec.rb # spec/lib/gitlab/ci/status/build/factory_spec.rb # spec/lib/gitlab/incoming_email_spec.rb --- .rubocop.yml | 5 -- .rubocop_todo.yml | 9 +++- .../admin/application_settings_controller.rb | 6 +-- app/controllers/concerns/issues_action.rb | 6 +-- .../concerns/merge_requests_action.rb | 4 +- .../import/bitbucket_controller.rb | 6 +-- app/controllers/projects/badges_controller.rb | 8 +-- .../projects/boards/issues_controller.rb | 8 +-- app/controllers/projects/commit_controller.rb | 6 +-- .../projects/compare_controller.rb | 4 +- .../projects/environments_controller.rb | 22 ++++---- .../projects/merge_requests_controller.rb | 28 +++++----- .../projects/pipelines_controller.rb | 24 ++++----- app/controllers/projects_controller.rb | 4 +- app/controllers/users_controller.rb | 4 +- app/finders/environments_finder.rb | 10 ++-- app/models/ci/build.rb | 18 +++---- app/models/ci/pipeline.rb | 34 ++++++------ app/models/ci/runner.rb | 4 +- app/models/ci/stage.rb | 6 +-- app/models/commit_status.rb | 10 ++-- app/models/concerns/milestoneish.rb | 4 +- app/models/concerns/presentable.rb | 6 +-- app/models/concerns/subscribable.rb | 8 +-- app/models/generic_commit_status.rb | 6 +-- app/models/global_milestone.rb | 4 +- app/models/group.rb | 6 +-- app/models/label.rb | 6 +-- app/models/lfs_object.rb | 6 +-- app/models/member.rb | 6 +-- app/models/merge_request.rb | 6 +-- app/models/merge_request_diff.rb | 4 +- app/models/namespace.rb | 6 +-- app/models/network/commit.rb | 4 +- app/models/network/graph.rb | 12 ++--- app/serializers/base_serializer.rb | 6 +-- app/serializers/environment_serializer.rb | 6 +-- app/services/after_branch_delete_service.rb | 6 +-- app/services/boards/issues/list_service.rb | 8 +-- app/services/boards/lists/destroy_service.rb | 4 +- app/services/boards/lists/move_service.rb | 12 ++--- app/services/ci/create_pipeline_service.rb | 6 +-- app/services/ci/process_pipeline_service.rb | 6 +-- app/services/ci/retry_build_service.rb | 10 ++-- app/services/ci/retry_pipeline_service.rb | 10 ++-- app/services/commits/change_service.rb | 4 +- app/services/create_branch_service.rb | 4 +- app/services/git_push_service.rb | 10 ++-- app/services/issues/move_service.rb | 4 +- app/services/merge_requests/base_service.rb | 10 ++-- .../merge_requests/refresh_service.rb | 6 +-- app/workers/build_coverage_worker.rb | 4 +- app/workers/build_hooks_worker.rb | 4 +- app/workers/emails_on_push_worker.rb | 8 +-- .../expire_build_instance_artifacts_worker.rb | 8 +-- app/workers/pipeline_hooks_worker.rb | 4 +- app/workers/pipeline_process_worker.rb | 4 +- app/workers/pipeline_success_worker.rb | 6 +-- app/workers/pipeline_update_worker.rb | 4 +- lib/api/merge_requests.rb | 18 +++---- lib/api/pipelines.rb | 4 +- lib/api/v3/merge_requests.rb | 18 +++---- lib/banzai/pipeline/wiki_pipeline.rb | 4 +- lib/banzai/reference_extractor.rb | 4 +- lib/ci/gitlab_ci_yaml_processor.rb | 4 +- lib/gitlab/badge/build/status.rb | 6 +-- lib/gitlab/badge/coverage/report.rb | 6 +-- lib/gitlab/bitbucket_import/importer.rb | 8 +-- lib/gitlab/checks/matching_merge_request.rb | 8 +-- lib/gitlab/ci/config/entry/configurable.rb | 10 ++-- lib/gitlab/ci/config/entry/global.rb | 8 +-- lib/gitlab/ci/config/entry/jobs.rb | 10 ++-- lib/gitlab/ci/status/factory.rb | 8 +-- lib/gitlab/ci/trace_reader.rb | 4 +- lib/gitlab/git/encoding_helper.rb | 6 +-- lib/gitlab/github_import/importer.rb | 6 +-- lib/gitlab/github_import/user_formatter.rb | 14 ++--- rubocop/cop/gem_fetcher.rb | 12 ++--- .../ci/projects_controller_spec.rb | 4 +- .../merge_requests_controller_spec.rb | 6 +-- spec/controllers/sessions_controller_spec.rb | 20 +++---- spec/features/environments_spec.rb | 4 +- .../merge_requests/created_from_fork_spec.rb | 4 +- .../projects/pipelines/pipelines_spec.rb | 4 +- spec/finders/environments_finder_spec.rb | 44 ++++++++-------- spec/helpers/issues_helper_spec.rb | 8 +-- spec/helpers/page_layout_helper_spec.rb | 4 +- spec/helpers/visibility_level_helper_spec.rb | 32 ++++++------ spec/lib/api/helpers/pagination_spec.rb | 12 ++--- .../external_issue_reference_filter_spec.rb | 4 +- .../filter/label_reference_filter_spec.rb | 28 +++++----- .../filter/user_reference_filter_spec.rb | 4 +- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 20 +++---- spec/lib/gitlab/asciidoc_spec.rb | 8 +-- spec/lib/gitlab/auth_spec.rb | 8 +-- spec/lib/gitlab/backup/manager_spec.rb | 16 +++--- spec/lib/gitlab/badge/build/status_spec.rb | 4 +- .../gitlab/bitbucket_import/importer_spec.rb | 4 +- .../gitlab/ci/config/entry/artifacts_spec.rb | 8 +-- .../ci/config/entry/attributable_spec.rb | 12 ++--- .../gitlab/ci/config/entry/boolean_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/cache_spec.rb | 12 ++--- .../gitlab/ci/config/entry/commands_spec.rb | 4 +- .../ci/config/entry/configurable_spec.rb | 4 +- .../ci/config/entry/environment_spec.rb | 16 +++--- .../gitlab/ci/config/entry/factory_spec.rb | 52 +++++++++---------- .../lib/gitlab/ci/config/entry/global_spec.rb | 48 ++++++++--------- spec/lib/gitlab/ci/config/entry/image_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/job_spec.rb | 18 +++---- spec/lib/gitlab/ci/config/entry/jobs_spec.rb | 16 +++--- spec/lib/gitlab/ci/config/entry/key_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/paths_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/script_spec.rb | 4 +- .../gitlab/ci/config/entry/services_spec.rb | 4 +- spec/lib/gitlab/ci/config/entry/stage_spec.rb | 4 +- .../lib/gitlab/ci/config/entry/stages_spec.rb | 4 +- .../gitlab/ci/config/entry/trigger_spec.rb | 4 +- .../ci/config/entry/validatable_spec.rb | 4 +- .../gitlab/ci/config/entry/validator_spec.rb | 4 +- .../gitlab/ci/config/entry/variables_spec.rb | 4 +- .../lib/gitlab/ci/status/build/common_spec.rb | 6 +-- .../gitlab/ci/status/build/factory_spec.rb | 34 ++++++------ spec/lib/gitlab/ci/status/extended_spec.rb | 4 +- .../gitlab/ci/status/external/common_spec.rb | 6 +-- spec/lib/gitlab/ci/status/factory_spec.rb | 16 +++--- .../gitlab/ci/status/pipeline/common_spec.rb | 10 ++-- .../gitlab/ci/status/pipeline/factory_spec.rb | 8 +-- .../lib/gitlab/ci/status/stage/common_spec.rb | 12 ++--- .../gitlab/ci/status/stage/factory_spec.rb | 4 +- spec/lib/gitlab/data_builder/note_spec.rb | 36 ++++++------- spec/lib/gitlab/database_spec.rb | 4 +- .../import_export/avatar_restorer_spec.rb | 4 +- spec/lib/gitlab/incoming_email_spec.rb | 8 +-- spec/lib/gitlab/ldap/adapter_spec.rb | 4 +- spec/lib/gitlab/o_auth/user_spec.rb | 4 +- spec/lib/gitlab/serializer/pagination_spec.rb | 8 +-- spec/models/application_setting_spec.rb | 6 +-- spec/models/ci/build_spec.rb | 16 +++--- spec/models/commit_status_spec.rb | 4 +- spec/models/email_spec.rb | 4 +- spec/models/group_label_spec.rb | 4 +- spec/models/lfs_objects_project_spec.rb | 8 +-- spec/models/merge_request_diff_spec.rb | 8 +-- spec/models/merge_request_spec.rb | 24 ++++----- spec/models/project_label_spec.rb | 12 ++--- spec/models/repository_spec.rb | 4 +- spec/models/user_spec.rb | 8 +-- spec/requests/api/broadcast_messages_spec.rb | 12 ++--- spec/requests/api/commit_statuses_spec.rb | 4 +- spec/requests/api/groups_spec.rb | 8 +-- spec/requests/api/internal_spec.rb | 4 +- spec/requests/api/runners_spec.rb | 8 +-- spec/requests/ci/api/builds_spec.rb | 12 ++--- .../analytics_build_serializer_spec.rb | 4 +- .../analytics_issue_serializer_spec.rb | 6 +-- ...analytics_merge_request_serializer_spec.rb | 6 +-- .../analytics_summary_serializer_spec.rb | 8 +-- .../serializers/build_artifact_entity_spec.rb | 4 +- spec/serializers/commit_entity_spec.rb | 4 +- .../environment_serializer_spec.rb | 32 ++++++------ spec/serializers/pipeline_entity_spec.rb | 12 ++--- spec/serializers/pipeline_serializer_spec.rb | 10 ++-- spec/serializers/request_aware_entity_spec.rb | 4 +- spec/serializers/stage_entity_spec.rb | 8 +-- .../ci/process_pipeline_service_spec.rb | 8 +-- spec/services/ci/retry_build_service_spec.rb | 12 ++--- .../ci/retry_pipeline_service_spec.rb | 8 +-- .../ci/stop_environments_service_spec.rb | 16 +++--- .../ci/update_build_queue_service_spec.rb | 16 +++--- .../issuable/bulk_update_service_spec.rb | 20 +++---- spec/services/issues/move_service_spec.rb | 20 +++---- .../add_todo_when_build_fails_service_spec.rb | 16 +++--- ...rge_when_pipeline_succeeds_service_spec.rb | 20 +++---- .../merge_requests/resolve_service_spec.rb | 6 +-- spec/services/todo_service_spec.rb | 8 +-- spec/support/ldap_helpers.rb | 8 +-- spec/support/stub_gitlab_calls.rb | 2 +- spec/tasks/gitlab/check_rake_spec.rb | 4 +- spec/tasks/gitlab/shell_rake_spec.rb | 4 +- spec/views/layouts/_head.html.haml_spec.rb | 4 +- .../merge_requests/edit.html.haml_spec.rb | 4 +- spec/workers/build_coverage_worker_spec.rb | 8 +-- spec/workers/build_finished_worker_spec.rb | 20 +++---- spec/workers/build_hooks_worker_spec.rb | 8 +-- spec/workers/build_success_worker_spec.rb | 12 ++--- spec/workers/pipeline_hooks_worker_spec.rb | 8 +-- spec/workers/pipeline_proccess_worker_spec.rb | 4 +- spec/workers/pipeline_success_worker_spec.rb | 4 +- spec/workers/pipeline_update_worker_spec.rb | 4 +- spec/workers/project_cache_worker_spec.rb | 12 ++--- spec/workers/use_key_worker_spec.rb | 4 +- 191 files changed, 886 insertions(+), 884 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 2eebe73313b..b72bcf8a34a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -163,11 +163,6 @@ Style/DefWithParentheses: Style/Documentation: Enabled: false -# This cop checks the . position in multi-line method calls. -Style/DotPosition: - Enabled: true - EnforcedStyle: trailing - # This cop checks for uses of double negation (!!) to convert something # to a boolean value. As this is both cryptic and usually redundant, it # should be avoided. diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 8bc7d568c10..c24142c0a11 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -63,7 +63,7 @@ Rails/SkipsModelValidations: # Cop supports --auto-correct. Security/YAMLLoad: Enabled: false - + # Offense count: 55 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. @@ -71,6 +71,13 @@ Security/YAMLLoad: Style/BarePercentLiterals: Enabled: false +# Offense count: 1304 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: leading, trailing +Style/DotPosition: + Enabled: false + # Offense count: 6 # Cop supports --auto-correct. Style/EachWithObject: diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index f801fac1839..b0f5d4a9933 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -5,9 +5,9 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController end def update - successful = ApplicationSettings::UpdateService. - new(@application_setting, current_user, application_setting_params). - execute + successful = ApplicationSettings::UpdateService + .new(@application_setting, current_user, application_setting_params) + .execute if successful redirect_to admin_application_settings_path, diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index 8b985b6d003..b17c138d5c7 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -5,9 +5,9 @@ module IssuesAction def issues @label = issues_finder.labels.first - @issues = issues_collection. - non_archived. - page(params[:page]) + @issues = issues_collection + .non_archived + .page(params[:page]) @collection_type = "Issue" @issuable_meta_data = issuable_meta_data(@issues, @collection_type) diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index 28e34cffc24..d3c8e4888bc 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -5,8 +5,8 @@ module MergeRequestsAction def merge_requests @label = merge_requests_finder.labels.first - @merge_requests = merge_requests_collection. - page(params[:page]) + @merge_requests = merge_requests_collection + .page(params[:page]) @collection_type = "MergeRequest" @issuable_meta_data = issuable_meta_data(@merge_requests, @collection_type) diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index cd5cef2c20f..8e42cdf415f 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -29,9 +29,9 @@ class Import::BitbucketController < Import::BaseController end def jobs - render json: current_user.created_projects. - where(import_type: 'bitbucket'). - to_json(only: [:id, :import_status]) + render json: current_user.created_projects + .where(import_type: 'bitbucket') + .to_json(only: [:id, :import_status]) end def create diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index c1727d9fa28..6c25cd83a24 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -4,15 +4,15 @@ class Projects::BadgesController < Projects::ApplicationController before_action :no_cache_headers, except: [:index] def build - build_status = Gitlab::Badge::Build::Status. - new(project, params[:ref]) + build_status = Gitlab::Badge::Build::Status + .new(project, params[:ref]) render_badge build_status end def coverage - coverage_report = Gitlab::Badge::Coverage::Report. - new(project, params[:ref], params[:job]) + coverage_report = Gitlab::Badge::Coverage::Report + .new(project, params[:ref], params[:job]) render_badge coverage_report end diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb index 8bcf18642cf..61fef4dc133 100644 --- a/app/controllers/projects/boards/issues_controller.rb +++ b/app/controllers/projects/boards/issues_controller.rb @@ -40,10 +40,10 @@ module Projects def issue @issue ||= - IssuesFinder.new(current_user, project_id: project.id). - execute. - where(iid: params[:id]). - first! + IssuesFinder.new(current_user, project_id: project.id) + .execute + .where(iid: params[:id]) + .first! end def authorize_read_issue! diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 23466dda981..e10d7992db7 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -35,9 +35,9 @@ class Projects::CommitController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: PipelineSerializer. - new(project: @project, user: @current_user). - represent(@pipelines) + render json: PipelineSerializer + .new(project: @project, user: @current_user) + .represent(@pipelines) end end end diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 99204c82784..c6651254d70 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -46,8 +46,8 @@ class Projects::CompareController < Projects::ApplicationController end def define_diff_vars - @compare = CompareService.new(@project, @head_ref). - execute(@project, @start_ref) + @compare = CompareService.new(@project, @head_ref) + .execute(@project, @start_ref) if @compare @commits = @compare.commits diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 2bbd8c6d046..fed75396d6e 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -9,18 +9,18 @@ class Projects::EnvironmentsController < Projects::ApplicationController before_action :verify_api_request!, only: :terminal_websocket_authorize def index - @environments = project.environments. - with_state(params[:scope] || :available) + @environments = project.environments + .with_state(params[:scope] || :available) respond_to do |format| format.html format.json do render json: { - environments: EnvironmentSerializer. - new(project: @project, user: @current_user). - with_pagination(request, response). - within_folders. - represent(@environments), + environments: EnvironmentSerializer + .new(project: @project, user: @current_user) + .with_pagination(request, response) + .within_folders + .represent(@environments), available_count: project.environments.available.count, stopped_count: project.environments.stopped.count } @@ -36,10 +36,10 @@ class Projects::EnvironmentsController < Projects::ApplicationController format.html format.json do render json: { - environments: EnvironmentSerializer. - new(project: @project, user: @current_user). - with_pagination(request, response). - represent(@environments), + environments: EnvironmentSerializer + .new(project: @project, user: @current_user) + .with_pagination(request, response) + .represent(@environments), available_count: folder_environments.available.count, stopped_count: folder_environments.stopped.count } diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 5ee7972e29e..d122c7fdcb2 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -232,9 +232,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end format.json do - render json: PipelineSerializer. - new(project: @project, user: @current_user). - represent(@pipelines) + render json: PipelineSerializer + .new(project: @project, user: @current_user) + .represent(@pipelines) end end end @@ -245,9 +245,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController format.json do define_pipelines_vars - render json: PipelineSerializer. - new(project: @project, user: @current_user). - represent(@pipelines) + render json: PipelineSerializer + .new(project: @project, user: @current_user) + .represent(@pipelines) end end end @@ -332,9 +332,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController return access_denied! end - MergeRequests::MergeWhenPipelineSucceedsService. - new(@project, current_user). - cancel(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService + .new(@project, current_user) + .cancel(@merge_request) end def merge @@ -361,9 +361,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController end if @merge_request.head_pipeline.active? - MergeRequests::MergeWhenPipelineSucceedsService. - new(@project, current_user, merge_params). - execute(@merge_request) + MergeRequests::MergeWhenPipelineSucceedsService + .new(@project, current_user, merge_params) + .execute(@merge_request) @status = :merge_when_build_succeeds elsif @merge_request.head_pipeline.success? @@ -640,8 +640,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_request_params - params.require(:merge_request). - permit(merge_request_params_ce) + params.require(:merge_request) + .permit(merge_request_params_ce) end def merge_request_params_ce diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 0f2b7b2a4c8..e436c6666c3 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -7,11 +7,11 @@ class Projects::PipelinesController < Projects::ApplicationController def index @scope = params[:scope] - @pipelines = PipelinesFinder. - new(project). - execute(scope: @scope). - page(params[:page]). - per(30) + @pipelines = PipelinesFinder + .new(project) + .execute(scope: @scope) + .page(params[:page]) + .per(30) @running_count = PipelinesFinder. .new(project).execute(scope: 'running').count @@ -29,10 +29,10 @@ class Projects::PipelinesController < Projects::ApplicationController format.html format.json do render json: { - pipelines: PipelineSerializer. - new(project: @project, user: @current_user). - with_pagination(request, response). - represent(@pipelines), + pipelines: PipelineSerializer + .new(project: @project, user: @current_user) + .with_pagination(request, response) + .represent(@pipelines), count: { all: @pipelines_count, running: @running_count, @@ -49,9 +49,9 @@ class Projects::PipelinesController < Projects::ApplicationController end def create - @pipeline = Ci::CreatePipelineService. - new(project, current_user, create_params). - execute(ignore_skip_ci: true, save_on_errors: false) + @pipeline = Ci::CreatePipelineService + .new(project, current_user, create_params) + .execute(ignore_skip_ci: true, save_on_errors: false) unless @pipeline.persisted? render 'new' return diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 9ffb8152e32..acca821782c 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -293,8 +293,8 @@ class ProjectsController < Projects::ApplicationController end def project_params - params.require(:project). - permit(project_params_ce) + params.require(:project) + .permit(project_params_ce) end def project_params_ce diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c92594d4097..6e29f1e8a65 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -118,8 +118,8 @@ class UsersController < ApplicationController def load_projects @projects = - PersonalProjectsFinder.new(user).execute(current_user). - page(params[:page]) + PersonalProjectsFinder.new(user).execute(current_user) + .page(params[:page]) end def load_contributed_projects diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb index 52c73abc31d..a59f8c1efa3 100644 --- a/app/finders/environments_finder.rb +++ b/app/finders/environments_finder.rb @@ -17,12 +17,12 @@ class EnvironmentsFinder deployments.none end - environment_ids = deployments. - group(:environment_id). - select(:environment_id) + environment_ids = deployments + .group(:environment_id) + .select(:environment_id) - environments = project.environments.available. - where(id: environment_ids).order_by_last_deployed_at.to_a + environments = project.environments.available + .where(id: environment_ids).order_by_last_deployed_at.to_a environments.select! do |environment| Ability.allowed?(current_user, :read_environment, environment) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 2689078c771..16d4f3b4f1b 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -65,9 +65,9 @@ module Ci end def retry(build, current_user) - Ci::RetryBuildService. - new(build.project, current_user). - execute(build) + Ci::RetryBuildService + .new(build.project, current_user) + .execute(build) end end @@ -98,9 +98,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Build::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Build::Factory + .new(self, current_user) + .fabricate! end def manual? @@ -222,9 +222,9 @@ module Ci end def merge_request - merge_requests = MergeRequest.includes(:merge_request_diff). - where(source_branch: ref, source_project_id: pipeline.gl_project_id). - reorder(iid: :asc) + merge_requests = MergeRequest.includes(:merge_request_diff) + .where(source_branch: ref, source_project_id: pipeline.gl_project_id) + .reorder(iid: :asc) merge_requests.find do |merge_request| merge_request.commits_sha.include?(pipeline.sha) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 04d43ca3c5c..80e11a5b58f 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -91,9 +91,9 @@ module Ci # ref can't be HEAD or SHA, can only be branch/tag name scope :latest, ->(ref = nil) do - max_id = unscope(:select). - select("max(#{quoted_table_name}.id)"). - group(:ref, :sha) + max_id = unscope(:select) + .select("max(#{quoted_table_name}.id)") + .group(:ref, :sha) if ref where(ref: ref, id: max_id.where(ref: ref)) @@ -135,16 +135,16 @@ module Ci def stages # TODO, this needs refactoring, see gitlab-ce#26481. - stages_query = statuses. - group('stage').select(:stage).order('max(stage_idx)') + stages_query = statuses + .group('stage').select(:stage).order('max(stage_idx)') status_sql = statuses.latest.where('stage=sg.stage').status_sql - warnings_sql = statuses.latest.select('COUNT(*) > 0'). - where('stage=sg.stage').failed_but_allowed.to_sql + warnings_sql = statuses.latest.select('COUNT(*) > 0') + .where('stage=sg.stage').failed_but_allowed.to_sql - stages_with_statuses = CommitStatus.from(stages_query, :sg). - pluck('sg.stage', status_sql, "(#{warnings_sql})") + stages_with_statuses = CommitStatus.from(stages_query, :sg) + .pluck('sg.stage', status_sql, "(#{warnings_sql})") stages_with_statuses.map do |stage| Ci::Stage.new(self, Hash[%i[name status warnings].zip(stage)]) @@ -220,8 +220,8 @@ module Ci end def retry_failed(current_user) - Ci::RetryPipelineService.new(project, current_user). - execute(self) + Ci::RetryPipelineService.new(project, current_user) + .execute(self) end def mark_as_processable_after_stage(stage_idx) @@ -353,15 +353,15 @@ module Ci # Merge requests for which the current pipeline is running against # the merge request's latest commit. def merge_requests - @merge_requests ||= project.merge_requests. - where(source_branch: self.ref). - select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } + @merge_requests ||= project.merge_requests + .where(source_branch: self.ref) + .select { |merge_request| merge_request.head_pipeline.try(:id) == self.id } end def detailed_status(current_user) - Gitlab::Ci::Status::Pipeline::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Pipeline::Factory + .new(self, current_user) + .fabricate! end private diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index a120112e882..4863c34a6a6 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -23,8 +23,8 @@ module Ci scope :ordered, ->() { order(id: :desc) } scope :owned_or_shared, ->(project_id) do - joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id'). - where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) + joins('LEFT JOIN ci_runner_projects ON ci_runner_projects.runner_id = ci_runners.id') + .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end scope :assignable_for, ->(project) do diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb index 0751ab1b7d8..ca74c91b062 100644 --- a/app/models/ci/stage.rb +++ b/app/models/ci/stage.rb @@ -28,9 +28,9 @@ module Ci end def detailed_status(current_user) - Gitlab::Ci::Status::Stage::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Stage::Factory + .new(self, current_user) + .fabricate! end def statuses diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 1349beafb76..fc750a3e5e9 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -97,8 +97,8 @@ class CommitStatus < ActiveRecord::Base after_transition any => :failed do |commit_status| commit_status.run_after_commit do - MergeRequests::AddTodoWhenBuildFailsService. - new(pipeline.project, nil).execute(self) + MergeRequests::AddTodoWhenBuildFailsService + .new(pipeline.project, nil).execute(self) end end end @@ -132,9 +132,9 @@ class CommitStatus < ActiveRecord::Base end def detailed_status(current_user) - Gitlab::Ci::Status::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::Factory + .new(self, current_user) + .fabricate! end def sortable_name diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index 870a6fbaa90..f449229864d 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -39,8 +39,8 @@ module Milestoneish def issues_visible_to_user(user) memoize_per_user(user, :issues_visible_to_user) do - IssuesFinder.new(user, issues_finder_params). - execute.where(milestone_id: milestoneish_ids) + IssuesFinder.new(user, issues_finder_params) + .execute.where(milestone_id: milestoneish_ids) end end diff --git a/app/models/concerns/presentable.rb b/app/models/concerns/presentable.rb index d0f84831d71..7b33b837004 100644 --- a/app/models/concerns/presentable.rb +++ b/app/models/concerns/presentable.rb @@ -1,7 +1,7 @@ module Presentable def present(**attributes) - Gitlab::View::Presenter::Factory. - new(self, attributes). - fabricate! + Gitlab::View::Presenter::Factory + .new(self, attributes) + .fabricate! end end diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index e4f5818d0e3..83daa9b1a64 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -42,15 +42,15 @@ module Subscribable def subscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project). - update(subscribed: true) + find_or_initialize_subscription(user, project) + .update(subscribed: true) end def unsubscribe(user, project = nil) unsubscribe_from_other_levels(user, project) - find_or_initialize_subscription(user, project). - update(subscribed: false) + find_or_initialize_subscription(user, project) + .update(subscribed: false) end private diff --git a/app/models/generic_commit_status.rb b/app/models/generic_commit_status.rb index 36b8568871b..8867ba0d2ff 100644 --- a/app/models/generic_commit_status.rb +++ b/app/models/generic_commit_status.rb @@ -18,8 +18,8 @@ class GenericCommitStatus < CommitStatus end def detailed_status(current_user) - Gitlab::Ci::Status::External::Factory. - new(self, current_user). - fabricate! + Gitlab::Ci::Status::External::Factory + .new(self, current_user) + .fabricate! end end diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb index 84deb67ba9b..b991d78e27f 100644 --- a/app/models/global_milestone.rb +++ b/app/models/global_milestone.rb @@ -76,8 +76,8 @@ class GlobalMilestone end def labels - @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten). - sort_by!(&:title) + @labels ||= GlobalLabel.build_collection(milestones.includes(:labels).map(&:labels).flatten) + .sort_by!(&:title) end def due_date diff --git a/app/models/group.rb b/app/models/group.rb index 1835ce118a1..240a17f1dc1 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -71,9 +71,9 @@ class Group < Namespace def select_for_project_authorization if current_scope.joins_values.include?(:shared_projects) - joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id'). - where('project_namespace.share_with_group_lock = ?', false). - select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") + joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id') + .where('project_namespace.share_with_group_lock = ?', false) + .select("members.user_id, projects.id AS project_id, LEAST(project_group_links.group_access, members.access_level) AS access_level") else super end diff --git a/app/models/label.rb b/app/models/label.rb index 27429e60e4a..f68a8c9cff2 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -34,9 +34,9 @@ class Label < ActiveRecord::Base scope :with_title, ->(title) { where(title: title) } def self.prioritized(project) - joins(:priorities). - where(label_priorities: { project_id: project }). - reorder('label_priorities.priority ASC, labels.title ASC') + joins(:priorities) + .where(label_priorities: { project_id: project }) + .reorder('label_priorities.priority ASC, labels.title ASC') end def self.unprioritized(project) diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index ee9ac282e39..7712d5783e0 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -19,8 +19,8 @@ class LfsObject < ActiveRecord::Base end def self.destroy_unreferenced - joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id"). - where(lfs_objects_projects: { id: nil }). - destroy_all + joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id") + .where(lfs_objects_projects: { id: nil }) + .destroy_all end end diff --git a/app/models/member.rb b/app/models/member.rb index abe9aee3edf..0545bd4eedf 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -41,9 +41,9 @@ class Member < ActiveRecord::Base is_external_invite = arel_table[:user_id].eq(nil).and(arel_table[:invite_token].not_eq(nil)) user_is_active = User.arel_table[:state].eq(:active) - includes(:user).references(:users). - where(is_external_invite.or(user_is_active)). - where(requested_at: nil) + includes(:user).references(:users) + .where(is_external_invite.or(user_is_active)) + .where(requested_at: nil) end scope :invite, -> { where.not(invite_token: nil) } diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index ea784f77015..d5eb44aeeb8 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -813,9 +813,9 @@ class MergeRequest < ActiveRecord::Base def all_pipelines return Ci::Pipeline.none unless source_project - @all_pipelines ||= source_project.pipelines. - where(sha: all_commits_sha, ref: source_branch). - order(id: :desc) + @all_pipelines ||= source_project.pipelines + .where(sha: all_commits_sha, ref: source_branch) + .order(id: :desc) end # Note that this could also return SHA from now dangling commits diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 53d08488788..baee00b8fcd 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -169,8 +169,8 @@ class MergeRequestDiff < ActiveRecord::Base # When compare merge request versions we want diff A..B instead of A...B # so we handle cases when user does squash and rebase of the commits between versions. # For this reason we set straight to true by default. - CompareService.new(project, head_commit_sha). - execute(project, sha, straight: straight) + CompareService.new(project, head_commit_sha) + .execute(project, sha, straight: straight) end def commits_count diff --git a/app/models/namespace.rb b/app/models/namespace.rb index e207ac3db4e..bd0336c984a 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -48,9 +48,9 @@ class Namespace < ActiveRecord::Base scope :root, -> { where('type IS NULL') } scope :with_statistics, -> do - joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id'). - group('namespaces.id'). - select( + joins('LEFT JOIN project_statistics ps ON ps.namespace_id = namespaces.id') + .group('namespaces.id') + .select( 'namespaces.*', 'COALESCE(SUM(ps.storage_size), 0) AS storage_size', 'COALESCE(SUM(ps.repository_size), 0) AS repository_size', diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb index a48e872ad84..8417f200e36 100644 --- a/app/models/network/commit.rb +++ b/app/models/network/commit.rb @@ -28,8 +28,8 @@ module Network if map.include?(p.id) map[p.id] end - end. - compact + end + .compact end end end diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index 2a7fa7d0607..0bbc9451ffd 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -23,12 +23,12 @@ module Network def collect_notes h = Hash.new(0) - @project. - notes. - where('noteable_type = ?', 'Commit'). - group('notes.commit_id'). - select('notes.commit_id, count(notes.id) as note_count'). - each do |item| + @project + .notes + .where('noteable_type = ?', 'Commit') + .group('notes.commit_id') + .select('notes.commit_id, count(notes.id) as note_count') + .each do |item| h[item.commit_id] = item.note_count.to_i end diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb index 032c44274ef..311ee9c96be 100644 --- a/app/serializers/base_serializer.rb +++ b/app/serializers/base_serializer.rb @@ -4,9 +4,9 @@ class BaseSerializer end def represent(resource, opts = {}) - self.class.entity_class. - represent(resource, opts.merge(request: @request)). - as_json + self.class.entity_class + .represent(resource, opts.merge(request: @request)) + .as_json end def self.entity(entity_class) diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb index ffc4fd34c75..d0a60f134da 100644 --- a/app/serializers/environment_serializer.rb +++ b/app/serializers/environment_serializer.rb @@ -36,9 +36,9 @@ class EnvironmentSerializer < BaseSerializer private def itemize(resource) - items = resource.order('folder_name ASC'). - group('COALESCE(environment_type, name)'). - select('COALESCE(environment_type, name) AS folder_name', + items = resource.order('folder_name ASC') + .group('COALESCE(environment_type, name)') + .select('COALESCE(environment_type, name) AS folder_name', 'COUNT(*) AS size', 'MAX(id) AS last_id') # It makes a difference when you call `paginate` method, because diff --git a/app/services/after_branch_delete_service.rb b/app/services/after_branch_delete_service.rb index 95492f709bb..227e9ea9c6d 100644 --- a/app/services/after_branch_delete_service.rb +++ b/app/services/after_branch_delete_service.rb @@ -14,8 +14,8 @@ class AfterBranchDeleteService < BaseService private def stop_environments - Ci::StopEnvironmentsService. - new(project, current_user). - execute(branch_name) + Ci::StopEnvironmentsService + .new(project, current_user) + .execute(branch_name) end end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 2d664f3f0c8..8a94c54b6ab 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -57,15 +57,15 @@ module Boards return issues unless board_label_ids.any? issues.where.not( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). - where(label_id: board_label_ids).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") + .where(label_id: board_label_ids).limit(1).arel.exists ) end def with_list_label(issues) issues.where( - LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id"). - where("label_links.label_id = ?", list.label_id).limit(1).arel.exists + LabelLink.where("label_links.target_type = 'Issue' AND label_links.target_id = issues.id") + .where("label_links.label_id = ?", list.label_id).limit(1).arel.exists ) end end diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index 6c80dd61873..f986e05944c 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -17,8 +17,8 @@ module Boards attr_reader :board def decrement_higher_lists(list) - board.lists.movable.where('position > ?', list.position). - update_all('position = position - 1') + board.lists.movable.where('position > ?', list.position) + .update_all('position = position - 1') end def remove_list(list) diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index 2f109934ea9..f2a68865f7b 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -33,15 +33,15 @@ module Boards end def decrement_intermediate_lists - board.lists.movable.where('position > ?', old_position). - where('position <= ?', new_position). - update_all('position = position - 1') + board.lists.movable.where('position > ?', old_position) + .where('position <= ?', new_position) + .update_all('position = position - 1') end def increment_intermediate_lists - board.lists.movable.where('position >= ?', new_position). - where('position < ?', old_position). - update_all('position = position + 1') + board.lists.movable.where('position >= ?', new_position) + .where('position < ?', old_position) + .update_all('position = position + 1') end def update_list_position(list) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index b53a467655f..38a85e9fc42 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -48,9 +48,9 @@ module Ci Ci::Pipeline.transaction do pipeline.save - Ci::CreatePipelineBuildsService. - new(project, current_user). - execute(pipeline) + Ci::CreatePipelineBuildsService + .new(project, current_user) + .execute(pipeline) end pipeline.tap(&:process!) diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 442230abe29..79eb97b7b55 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -78,9 +78,9 @@ module Ci def ensure_created_builds! return if created_builds.any? - Ci::CreatePipelineBuildsService. - new(project, current_user). - execute(pipeline) + Ci::CreatePipelineBuildsService + .new(project, current_user) + .execute(pipeline) end end end diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb index c1fa9278f0f..38ef323f6e5 100644 --- a/app/services/ci/retry_build_service.rb +++ b/app/services/ci/retry_build_service.rb @@ -2,8 +2,8 @@ module Ci class RetryBuildService < ::BaseService CLONE_ATTRIBUTES = %i[pipeline project ref tag options commands name allow_failure stage stage_idx trigger_request - yaml_variables when environment coverage_regex]. - freeze + yaml_variables when environment coverage_regex] + .freeze REJECT_ATTRIBUTES = %i[id status user token coverage trace runner artifacts_expire_at artifacts_file @@ -20,9 +20,9 @@ module Ci new_build.enqueue! - MergeRequests::AddTodoWhenBuildFailsService. - new(project, current_user). - close(new_build) + MergeRequests::AddTodoWhenBuildFailsService + .new(project, current_user) + .close(new_build) end end diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb index 6e9781ca8cf..2c5e130e5aa 100644 --- a/app/services/ci/retry_pipeline_service.rb +++ b/app/services/ci/retry_pipeline_service.rb @@ -8,13 +8,13 @@ module Ci pipeline.builds.failed_or_canceled.find_each do |build| next unless build.retryable? - Ci::RetryBuildService.new(project, current_user). - reprocess(build) + Ci::RetryBuildService.new(project, current_user) + .reprocess(build) end - MergeRequests::AddTodoWhenBuildFailsService. - new(project, current_user). - close_all(pipeline) + MergeRequests::AddTodoWhenBuildFailsService + .new(project, current_user) + .close_all(pipeline) pipeline.process! end diff --git a/app/services/commits/change_service.rb b/app/services/commits/change_service.rb index 75281837b09..25e22f14e60 100644 --- a/app/services/commits/change_service.rb +++ b/app/services/commits/change_service.rb @@ -70,8 +70,8 @@ module Commits # Temporary branch exists and contains the change commit return if repository.find_branch(new_branch) - result = ValidateNewBranchService.new(@project, current_user). - execute(new_branch) + result = ValidateNewBranchService.new(@project, current_user) + .execute(new_branch) if result[:status] == :error raise ChangeError, "There was an error creating the source branch: #{result[:message]}" diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb index 1b5e504573a..77459d8779d 100644 --- a/app/services/create_branch_service.rb +++ b/app/services/create_branch_service.rb @@ -1,7 +1,7 @@ class CreateBranchService < BaseService def execute(branch_name, ref) - result = ValidateNewBranchService.new(project, current_user). - execute(branch_name) + result = ValidateNewBranchService.new(project, current_user) + .execute(branch_name) return result if result[:status] == :error diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index f681f831cbd..dbe2fda27b5 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -96,8 +96,8 @@ class GitPushService < BaseService # Update merge requests that may be affected by this push. A new branch # could cause the last commit of a merge request to change. # - UpdateMergeRequestsWorker. - perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) + UpdateMergeRequestsWorker + .perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref]) EventCreateService.new.push(@project, current_user, build_push_data) @project.execute_hooks(build_push_data.dup, :push_hooks) @@ -105,9 +105,9 @@ class GitPushService < BaseService Ci::CreatePipelineService.new(@project, current_user, build_push_data).execute if push_remove_branch? - AfterBranchDeleteService. - new(project, current_user). - execute(branch_name) + AfterBranchDeleteService + .new(project, current_user) + .execute(branch_name) end end diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb index 17b65947468..a2a5f57d069 100644 --- a/app/services/issues/move_service.rb +++ b/app/services/issues/move_service.rb @@ -61,8 +61,8 @@ module Issues end def cloneable_milestone_id - @new_project.milestones. - find_by(title: @old_issue.milestone.try(:title)).try(:id) + @new_project.milestones + .find_by(title: @old_issue.milestone.try(:title)).try(:id) end def rewrite_notes diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index fd9d7de35f4..5a53b973059 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -40,11 +40,11 @@ module MergeRequests # Returns all origin and fork merge requests from `@project` satisfying passed arguments. def merge_requests_for(source_branch, mr_states: [:opened]) - MergeRequest. - with_state(mr_states). - where(source_branch: source_branch, source_project_id: @project.id). - preload(:source_project). # we don't need a #includes since we're just preloading for the #select - select(&:source_project) + MergeRequest + .with_state(mr_states) + .where(source_branch: source_branch, source_project_id: @project.id) + .preload(:source_project) # we don't need a #includes since we're just preloading for the #select + .select(&:source_project) end def pipeline_merge_requests(pipeline) diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index edee3032683..581d18032e6 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -60,9 +60,9 @@ module MergeRequests by_source_or_target_branch(@branch_name).to_a # Fork merge requests - merge_requests += MergeRequest.opened. - where(source_branch: @branch_name, source_project: @project). - where.not(target_project: @project).to_a + merge_requests += MergeRequest.opened + .where(source_branch: @branch_name, source_project: @project) + .where.not(target_project: @project).to_a filter_merge_requests(merge_requests).each do |merge_request| if merge_request.source_branch == @branch_name || force_push? diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index 31e2dc448da..def0ab1dde1 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -3,7 +3,7 @@ class BuildCoverageWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id). - try(:update_coverage) + Ci::Build.find_by(id: build_id) + .try(:update_coverage) end end diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index ff22313c491..9965af935d4 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -3,7 +3,7 @@ class BuildHooksWorker include BuildQueue def perform(build_id) - Ci::Build.find_by(id: build_id). - try(:execute_hooks) + Ci::Build.find_by(id: build_id) + .try(:execute_hooks) end end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index d4c3f14ec06..f5ccc84c160 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -33,15 +33,15 @@ class EmailsOnPushWorker reverse_compare = false if action == :push - compare = CompareService.new(project, after_sha). - execute(project, before_sha) + compare = CompareService.new(project, after_sha) + .execute(project, before_sha) diff_refs = compare.diff_refs return false if compare.same if compare.commits.empty? - compare = CompareService.new(project, before_sha). - execute(project, after_sha) + compare = CompareService.new(project, before_sha) + .execute(project, after_sha) diff_refs = compare.diff_refs reverse_compare = true diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index 2c29a9a58e1..eb403c134d1 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -3,10 +3,10 @@ class ExpireBuildInstanceArtifactsWorker include DedicatedSidekiqQueue def perform(build_id) - build = Ci::Build. - with_expired_artifacts. - reorder(nil). - find_by(id: build_id) + build = Ci::Build + .with_expired_artifacts + .reorder(nil) + .find_by(id: build_id) return unless build.try(:project) diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index 7480a055e6a..7e36eacebf8 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -3,7 +3,7 @@ class PipelineHooksWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id). - try(:execute_hooks) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:execute_hooks) end end diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 5dcb09f553e..357e4a9a1c3 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -3,7 +3,7 @@ class PipelineProcessWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id). - try(:process!) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:process!) end end diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb index ef710f374ca..cc0eb708cf9 100644 --- a/app/workers/pipeline_success_worker.rb +++ b/app/workers/pipeline_success_worker.rb @@ -4,9 +4,9 @@ class PipelineSuccessWorker def perform(pipeline_id) Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| - MergeRequests::MergeWhenPipelineSucceedsService. - new(pipeline.project, nil). - trigger(pipeline) + MergeRequests::MergeWhenPipelineSucceedsService + .new(pipeline.project, nil) + .trigger(pipeline) end end end diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index e6d06d0577d..96c4152c674 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -3,7 +3,7 @@ class PipelineUpdateWorker include PipelineQueue def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id). - try(:update_status) + Ci::Pipeline.find_by(id: pipeline_id) + .try(:update_status) end end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 6a2476424a7..bdd764abfeb 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -193,13 +193,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) else - ::MergeRequests::MergeService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) end present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project @@ -213,9 +213,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user). - cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user) + .cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb index 02e397a681c..3afc1e385fe 100644 --- a/lib/api/pipelines.rb +++ b/lib/api/pipelines.rb @@ -36,8 +36,8 @@ module API new_pipeline = Ci::CreatePipelineService.new(user_project, current_user, - declared_params(include_missing: false)). - execute(ignore_skip_ci: true, save_on_errors: false) + declared_params(include_missing: false)) + .execute(ignore_skip_ci: true, save_on_errors: false) if new_pipeline.persisted? present new_pipeline, with: Entities::Pipeline else diff --git a/lib/api/v3/merge_requests.rb b/lib/api/v3/merge_requests.rb index 5a8dacc9c44..129f9d850e9 100644 --- a/lib/api/v3/merge_requests.rb +++ b/lib/api/v3/merge_requests.rb @@ -200,13 +200,13 @@ module API } if params[:merge_when_build_succeeds] && merge_request.head_pipeline && merge_request.head_pipeline.active? - ::MergeRequests::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) else - ::MergeRequests::MergeService. - new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeService + .new(merge_request.target_project, current_user, merge_params) + .execute(merge_request) end present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project @@ -220,9 +220,9 @@ module API unauthorized! unless merge_request.can_cancel_merge_when_build_succeeds?(current_user) - ::MergeRequest::MergeWhenPipelineSucceedsService. - new(merge_request.target_project, current_user). - cancel(merge_request) + ::MergeRequest::MergeWhenPipelineSucceedsService + .new(merge_request.target_project, current_user) + .cancel(merge_request) end desc 'Get the comments of a merge request' do diff --git a/lib/banzai/pipeline/wiki_pipeline.rb b/lib/banzai/pipeline/wiki_pipeline.rb index 17b460608d7..c37b8e71cb0 100644 --- a/lib/banzai/pipeline/wiki_pipeline.rb +++ b/lib/banzai/pipeline/wiki_pipeline.rb @@ -3,8 +3,8 @@ module Banzai class WikiPipeline < FullPipeline def self.filters @filters ||= begin - super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter). - insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) + super.insert_after(Filter::TableOfContentsFilter, Filter::GollumTagsFilter) + .insert_before(Filter::TaskListFilter, Filter::WikiLinkFilter) end end end diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index c6426210a92..8e3b0c4db79 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -28,8 +28,8 @@ module Banzai # text blobs to parse. return [] if @texts_and_contexts.empty? - @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts). - map { |html| Nokogiri::HTML.fragment(html) } + @html_documents ||= Renderer.cache_collection_render(@texts_and_contexts) + .map { |html| Nokogiri::HTML.fragment(html) } end end end diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 04d9756657a..649ee4d018b 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -115,8 +115,8 @@ module Ci end def yaml_variables(name) - variables = (@variables || {}). - merge(job_variables(name)) + variables = (@variables || {}) + .merge(job_variables(name)) variables.map do |key, value| { key: key.to_s, value: value, public: true } diff --git a/lib/gitlab/badge/build/status.rb b/lib/gitlab/badge/build/status.rb index 3c65fd02e4c..b762d85b6e5 100644 --- a/lib/gitlab/badge/build/status.rb +++ b/lib/gitlab/badge/build/status.rb @@ -19,9 +19,9 @@ module Gitlab end def status - @project.pipelines. - where(sha: @sha). - latest_status(@ref) || 'unknown' + @project.pipelines + .where(sha: @sha) + .latest_status(@ref) || 'unknown' end def metadata diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb index 8a6564755ab..9a0482306b7 100644 --- a/lib/gitlab/badge/coverage/report.rb +++ b/lib/gitlab/badge/coverage/report.rb @@ -42,9 +42,9 @@ module Gitlab if @job.blank? @pipeline.coverage else - @pipeline.builds. - find_by(name: @job). - try(:coverage) + @pipeline.builds + .find_by(name: @job) + .try(:coverage) end end end diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb index 03a7981b1db..44323b47dca 100644 --- a/lib/gitlab/bitbucket_import/importer.rb +++ b/lib/gitlab/bitbucket_import/importer.rb @@ -48,10 +48,10 @@ module Gitlab return users[username] if users.key?(username) - users[username] = User.select(:id). - joins(:identities). - find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username). - try(:id) + users[username] = User.select(:id) + .joins(:identities) + .find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", username) + .try(:id) end def repo diff --git a/lib/gitlab/checks/matching_merge_request.rb b/lib/gitlab/checks/matching_merge_request.rb index bd295c25194..849848515da 100644 --- a/lib/gitlab/checks/matching_merge_request.rb +++ b/lib/gitlab/checks/matching_merge_request.rb @@ -8,10 +8,10 @@ module Gitlab end def match? - @project.merge_requests. - with_state(:locked). - where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name). - exists? + @project.merge_requests + .with_state(:locked) + .where(in_progress_merge_commit_sha: @newrev, target_branch: @branch_name) + .exists? end end end diff --git a/lib/gitlab/ci/config/entry/configurable.rb b/lib/gitlab/ci/config/entry/configurable.rb index deaaf06bbd7..e05aca9881b 100644 --- a/lib/gitlab/ci/config/entry/configurable.rb +++ b/lib/gitlab/ci/config/entry/configurable.rb @@ -27,9 +27,9 @@ module Gitlab return unless valid? self.class.nodes.each do |key, factory| - factory. - value(@config[key]). - with(key: key, parent: self) + factory + .value(@config[key]) + .with(key: key, parent: self) @entries[key] = factory.create! end @@ -49,8 +49,8 @@ module Gitlab private # rubocop:disable Lint/UselessAccessModifier def entry(key, entry, metadata) - factory = Entry::Factory.new(entry). - with(description: metadata[:description]) + factory = Entry::Factory.new(entry) + .with(description: metadata[:description]) (@nodes ||= {}).merge!(key.to_sym => factory) end diff --git a/lib/gitlab/ci/config/entry/global.rb b/lib/gitlab/ci/config/entry/global.rb index 0a404331225..a4ec8f0ff2f 100644 --- a/lib/gitlab/ci/config/entry/global.rb +++ b/lib/gitlab/ci/config/entry/global.rb @@ -46,10 +46,10 @@ module Gitlab private def compose_jobs! - factory = Entry::Factory.new(Entry::Jobs). - value(@config.except(*self.class.nodes.keys)). - with(key: :jobs, parent: self, - description: 'Jobs definition for this pipeline') + factory = Entry::Factory.new(Entry::Jobs) + .value(@config.except(*self.class.nodes.keys)) + .with(key: :jobs, parent: self, + description: 'Jobs definition for this pipeline') @entries[:jobs] = factory.create! end diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb index 7b83f0f1b69..5671a09480b 100644 --- a/lib/gitlab/ci/config/entry/jobs.rb +++ b/lib/gitlab/ci/config/entry/jobs.rb @@ -31,11 +31,11 @@ module Gitlab @config.each do |name, config| node = hidden?(name) ? Entry::Hidden : Entry::Job - factory = Entry::Factory.new(node). - value(config || {}). - metadata(name: name). - with(key: name, parent: self, - description: "#{name} job definition.") + factory = Entry::Factory.new(node) + .value(config || {}) + .metadata(name: name) + .with(key: name, parent: self, + description: "#{name} job definition.") @entries[name] = factory.create! end diff --git a/lib/gitlab/ci/status/factory.rb b/lib/gitlab/ci/status/factory.rb index efe756cc585..15836c699c7 100644 --- a/lib/gitlab/ci/status/factory.rb +++ b/lib/gitlab/ci/status/factory.rb @@ -17,10 +17,10 @@ module Gitlab end def core_status - Gitlab::Ci::Status. - const_get(@status.capitalize). - new(@subject, @user). - extend(self.class.common_helpers) + Gitlab::Ci::Status + .const_get(@status.capitalize) + .new(@subject, @user) + .extend(self.class.common_helpers) end def compound_extended_status diff --git a/lib/gitlab/ci/trace_reader.rb b/lib/gitlab/ci/trace_reader.rb index dd6a84d7d1c..1d7ddeb3e0f 100644 --- a/lib/gitlab/ci/trace_reader.rb +++ b/lib/gitlab/ci/trace_reader.rb @@ -41,8 +41,8 @@ module Gitlab chunks.unshift(buf) end - chunks.join.lines.last(max_lines).join. - force_encoding(Encoding.default_external) + chunks.join.lines.last(max_lines).join + .force_encoding(Encoding.default_external) end end end diff --git a/lib/gitlab/git/encoding_helper.rb b/lib/gitlab/git/encoding_helper.rb index 874fd8fe6e2..e57d228e688 100644 --- a/lib/gitlab/git/encoding_helper.rb +++ b/lib/gitlab/git/encoding_helper.rb @@ -49,9 +49,9 @@ module Gitlab private def clean(message) - message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: ""). - encode("UTF-8"). - gsub("\0".encode("UTF-8"), "") + message.encode("UTF-16BE", undef: :replace, invalid: :replace, replace: "") + .encode("UTF-8") + .gsub("\0".encode("UTF-8"), "") end end end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index a160869541a..dc73cad93a5 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -178,9 +178,9 @@ module Gitlab def apply_labels(issuable, raw) return unless raw.labels.count > 0 - label_ids = raw.labels. - map { |attrs| @labels[attrs.name] }. - compact + label_ids = raw.labels + .map { |attrs| @labels[attrs.name] } + .compact issuable.update_attribute(:label_ids, label_ids) end diff --git a/lib/gitlab/github_import/user_formatter.rb b/lib/gitlab/github_import/user_formatter.rb index 7f3bf0052a7..04c2964da20 100644 --- a/lib/gitlab/github_import/user_formatter.rb +++ b/lib/gitlab/github_import/user_formatter.rb @@ -25,8 +25,8 @@ module Gitlab def find_by_email return nil unless email - User.find_by_any_email(email). - try(:id) + User.find_by_any_email(email) + .try(:id) end def find_by_external_uid @@ -34,11 +34,11 @@ module Gitlab identities = ::Identity.arel_table - User.select(:id). - joins(:identities).where(identities[:provider].eq(:github). - and(identities[:extern_uid].eq(id))). - first. - try(:id) + User.select(:id) + .joins(:identities).where(identities[:provider].eq(:github) + .and(identities[:extern_uid].eq(id))) + .first + .try(:id) end end end diff --git a/rubocop/cop/gem_fetcher.rb b/rubocop/cop/gem_fetcher.rb index 6a951f5f91a..e157d8e0791 100644 --- a/rubocop/cop/gem_fetcher.rb +++ b/rubocop/cop/gem_fetcher.rb @@ -25,12 +25,12 @@ module RuboCop private def gemfile?(node) - node. - location. - expression. - source_buffer. - name. - end_with?("Gemfile") + node + .location + .expression + .source_buffer + .name + .end_with?("Gemfile") end end end diff --git a/spec/controllers/ci/projects_controller_spec.rb b/spec/controllers/ci/projects_controller_spec.rb index 3cd955dc9d4..86f01f437a2 100644 --- a/spec/controllers/ci/projects_controller_spec.rb +++ b/spec/controllers/ci/projects_controller_spec.rb @@ -33,8 +33,8 @@ describe Ci::ProjectsController do shared_examples 'badge provider' do it 'shows badge' do expect(response.status).to eq 200 - expect(response.headers). - to include('Content-Type' => 'image/svg+xml') + expect(response.headers) + .to include('Content-Type' => 'image/svg+xml') end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index e631e5fa5e7..af13649eec5 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -335,9 +335,9 @@ describe Projects::MergeRequestsController do it 'sets the MR to merge when the build succeeds' do service = double(:merge_when_build_succeeds_service) - expect(MergeRequests::MergeWhenPipelineSucceedsService). - to receive(:new).with(project, anything, anything). - and_return(service) + expect(MergeRequests::MergeWhenPipelineSucceedsService) + .to receive(:new).with(project, anything, anything) + .and_return(service) expect(service).to receive(:execute).with(merge_request) merge_when_build_succeeds diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index d951325f765..b56c7880b64 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -11,8 +11,8 @@ describe SessionsController do it 'does not authenticate user' do post(:create, user: { login: 'invalid', password: 'invalid' }) - expect(response). - to set_flash.now[:alert].to /Invalid Login or password/ + expect(response) + .to set_flash.now[:alert].to /Invalid Login or password/ end end @@ -102,8 +102,8 @@ describe SessionsController do end it 'warns about invalid OTP code' do - expect(response).to set_flash.now[:alert]. - to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert] + .to /Invalid two-factor code/ end end end @@ -129,8 +129,8 @@ describe SessionsController do end it 'warns about invalid login' do - expect(response).to set_flash.now[:alert]. - to /Invalid Login or password/ + expect(response).to set_flash.now[:alert] + .to /Invalid Login or password/ end it 'locks the user' do @@ -140,8 +140,8 @@ describe SessionsController do it 'keeps the user locked on future login attempts' do post(:create, user: { login: user.username, password: user.password }) - expect(response). - to set_flash.now[:alert].to /Invalid Login or password/ + expect(response) + .to set_flash.now[:alert].to /Invalid Login or password/ end end end @@ -153,8 +153,8 @@ describe SessionsController do authenticate_2fa(login: another_user.username, otp_attempt: 'invalid') - expect(response).to set_flash.now[:alert]. - to /Invalid two-factor code/ + expect(response).to set_flash.now[:alert] + .to /Invalid two-factor code/ end end end diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index 513de297fdf..78be7d36f47 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -111,8 +111,8 @@ feature 'Environments page', :feature, :js do find('.js-dropdown-play-icon-container').click expect(page).to have_content(manual.name.humanize) - expect { click_link(manual.name.humanize) }. - not_to change { Ci::Pipeline.count } + expect { click_link(manual.name.humanize) } + .not_to change { Ci::Pipeline.count } expect(manual.reload).to be_pending end diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index 9fc5339308c..73c5ef31edc 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -61,8 +61,8 @@ feature 'Merge request created from fork' do expect(page).to have_content pipeline.id end - expect(page.find('a.btn-remove')[:href]). - to include fork_project.path_with_namespace + expect(page.find('a.btn-remove')[:href]) + .to include fork_project.path_with_namespace end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 81f5ebf6339..592dc4483d2 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -366,8 +366,8 @@ describe 'Pipelines', :feature, :js do before { stub_ci_pipeline_to_return_yaml_file } it 'creates a new pipeline' do - expect { click_on 'Create pipeline' }. - to change { Ci::Pipeline.count }.by(1) + expect { click_on 'Create pipeline' } + .to change { Ci::Pipeline.count }.by(1) end end diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb index ed60a95deba..0c063f6d5ee 100644 --- a/spec/finders/environments_finder_spec.rb +++ b/spec/finders/environments_finder_spec.rb @@ -16,18 +16,18 @@ describe EnvironmentsFinder do end it 'returns environment when with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit, with_tags: true).execute) + .to contain_exactly(environment) end it 'does not return environment when no with_tags is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). - to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) + .to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). - to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) + .to be_empty end end @@ -37,23 +37,23 @@ describe EnvironmentsFinder do end it 'returns environment when ref is set' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master', commit: project.commit).execute) + .to contain_exactly(environment) end it 'does not environment when ref is different' do - expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute). - to be_empty + expect(described_class.new(project, user, ref: 'feature', commit: project.commit).execute) + .to be_empty end it 'does not return environment when commit is not part of deployment' do - expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute). - to be_empty + expect(described_class.new(project, user, ref: 'master', commit: project.commit('feature')).execute) + .to be_empty end it 'returns environment when commit constraint is not set' do - expect(described_class.new(project, user, ref: 'master').execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'master').execute) + .to contain_exactly(environment) end end @@ -63,8 +63,8 @@ describe EnvironmentsFinder do end it 'returns environment' do - expect(described_class.new(project, user, commit: project.commit).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, commit: project.commit).execute) + .to contain_exactly(environment) end end @@ -75,8 +75,8 @@ describe EnvironmentsFinder do end it 'finds recently updated environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). - to contain_exactly(environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) + .to contain_exactly(environment) end end @@ -87,8 +87,8 @@ describe EnvironmentsFinder do end it 'does not find environment' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). - to be_empty + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) + .to be_empty end end @@ -101,8 +101,8 @@ describe EnvironmentsFinder do end it 'finds both environments' do - expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute). - to contain_exactly(environment, second_environment) + expect(described_class.new(project, user, ref: 'feature', recently_updated: true).execute) + .to contain_exactly(environment, second_environment) end end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 1204d5c9888..88d853935c7 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -67,8 +67,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Joe') awards = Array.new(3, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)). - to eq('Joe, Joe, and Joe') + expect(award_user_list(awards, nil, limit: 3)) + .to eq('Joe, Joe, and Joe') end it "displays the current user's name as 'You'" do @@ -83,8 +83,8 @@ describe IssuesHelper do user = build_stubbed(:user, name: 'Jane') awards = Array.new(5, build_stubbed(:award_emoji, user: user)) - expect(award_user_list(awards, nil, limit: 3)). - to eq('Jane, Jane, Jane, and 2 more.') + expect(award_user_list(awards, nil, limit: 3)) + .to eq('Jane, Jane, Jane, and 2 more.') end it "displays the current user in front of other users" do diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index 9d7a39d3721..2cc0b40b2d0 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -111,8 +111,8 @@ describe PageLayoutHelper do end it 'escapes content' do - allow(helper).to receive(:page_card_attributes). - and_return(foo: %q{foo" http-equiv="refresh}.html_safe) + allow(helper).to receive(:page_card_attributes) + .and_return(foo: %q{foo" http-equiv="refresh}.html_safe) tags = helper.page_card_meta_tags diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index 387279b2031..8942b00b128 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -9,52 +9,52 @@ describe VisibilityLevelHelper do describe 'visibility_level_description' do context 'used with a Project' do it 'delegates projects to #project_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)). - to match /project/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project)) + .to match /project/i end end context 'used with a Group' do it 'delegates groups to #group_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)). - to match /group/i + expect(visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group)) + .to match /group/i end end context 'called with a Snippet' do it 'delegates snippets to #snippet_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)). - to match /snippet/i + expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)) + .to match /snippet/i end end end describe "#project_visibility_level_description" do it "describes private projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). - to eq "Project access must be granted explicitly to each user." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) + .to eq "Project access must be granted explicitly to each user." end it "describes public projects" do - expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)). - to eq "The project can be cloned without any authentication." + expect(project_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC)) + .to eq "The project can be cloned without any authentication." end end describe "#snippet_visibility_level_description" do it 'describes visibility only for me' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)). - to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)) + .to eq "The snippet is visible only to me." end it 'describes visibility for project members' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)). - to eq "The snippet is visible only to project members." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)) + .to eq "The snippet is visible only to project members." end it 'defaults to personal snippet' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)). - to eq "The snippet is visible only to me." + expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) + .to eq "The snippet is visible only to me." end end diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb index 152c36a3ae6..267318faed4 100644 --- a/spec/lib/api/helpers/pagination_spec.rb +++ b/spec/lib/api/helpers/pagination_spec.rb @@ -37,8 +37,8 @@ describe API::Helpers::Pagination do describe 'first page' do before do - allow(subject).to receive(:params). - and_return({ page: 1, per_page: 2 }) + allow(subject).to receive(:params) + .and_return({ page: 1, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -60,8 +60,8 @@ describe API::Helpers::Pagination do describe 'second page' do before do - allow(subject).to receive(:params). - and_return({ page: 2, per_page: 2 }) + allow(subject).to receive(:params) + .and_return({ page: 2, per_page: 2 }) end it 'returns appropriate amount of resources' do @@ -87,8 +87,8 @@ describe API::Helpers::Pagination do end def expect_message(method) - expect(subject).to receive(method). - at_least(:once).and_return(value) + expect(subject).to receive(method) + .at_least(:once).and_return(value) end end end diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb index efd145e9452..fbf7a461fa5 100644 --- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb @@ -33,8 +33,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do doc = filter("Issue #{reference}") issue_id = doc.css('a').first.attr("data-external-issue") - expect(doc.css('a').first.attr('href')). - to eq helper.url_for_issue(issue_id, project) + expect(doc.css('a').first.attr('href')) + .to eq helper.url_for_issue(issue_id, project) end it 'links to the external tracker' do diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index 5e16fd10ebe..284641fb20a 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -372,8 +372,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -406,8 +406,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -440,8 +440,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}") } it 'links to a valid reference' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project2.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project2.namespace, project2, label_name: label.name) end @@ -476,8 +476,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(another_project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(another_project.namespace, another_project, label_name: group_label.name) end @@ -549,15 +549,15 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end it 'has valid color' do - expect(result.css('a span').first.attr('style')). - to match /background-color: #00ff00/ + expect(result.css('a span').first.attr('style')) + .to match /background-color: #00ff00/ end it 'has valid link text' do @@ -583,8 +583,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do let!(:result) { reference_filter("See #{reference}", project: project) } it 'points to referenced project issues page' do - expect(result.css('a').first.attr('href')). - to eq urls.namespace_project_issues_url(project.namespace, + expect(result.css('a').first.attr('href')) + .to eq urls.namespace_project_issues_url(project.namespace, project, label_name: group_label.name) end diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index e9b7b566806..d5d128c1907 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -37,8 +37,8 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do doc = reference_filter("Hey #{reference}", author: user) expect(doc.css('a').length).to eq 1 - expect(doc.css('a').first.attr('href')). - to eq urls.namespace_project_url(project.namespace, project) + expect(doc.css('a').first.attr('href')) + .to eq urls.namespace_project_url(project.namespace, project) end it 'includes a data-author attribute when there is an author' do diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index ae3253777c3..7145f0da1d3 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -25,8 +25,8 @@ module Ci end it 'includes coverage regexp in build attributes' do - expect(subject). - to include(coverage_regex: 'Code coverage: \d+\.\d+') + expect(subject) + .to include(coverage_regex: 'Code coverage: \d+\.\d+') end end end @@ -584,8 +584,8 @@ module Ci end it 'raises error' do - expect { subject }. - to raise_error(GitlabCiYamlProcessor::ValidationError, + expect { subject } + .to raise_error(GitlabCiYamlProcessor::ValidationError, /jobs:rspec:variables config should be a hash of key value pairs/) end end @@ -1365,8 +1365,8 @@ EOT it "returns an error about invalid configutaion" do content = YAML.dump("invalid: yaml: test") - expect(GitlabCiYamlProcessor.validation_message(content)). - to eq "Invalid configuration format" + expect(GitlabCiYamlProcessor.validation_message(content)) + .to eq "Invalid configuration format" end end @@ -1374,15 +1374,15 @@ EOT it "returns an error about invalid tags" do content = YAML.dump({ rspec: { script: "test", tags: "mysql" } }) - expect(GitlabCiYamlProcessor.validation_message(content)). - to eq "jobs:rspec tags should be an array of strings" + expect(GitlabCiYamlProcessor.validation_message(content)) + .to eq "jobs:rspec tags should be an array of strings" end end context "when YAML content is empty" do it "returns an error about missing content" do - expect(GitlabCiYamlProcessor.validation_message('')). - to eq "Please provide content of .gitlab-ci.yml" + expect(GitlabCiYamlProcessor.validation_message('')) + .to eq "Please provide content of .gitlab-ci.yml" end end diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index e193a3b79a6..bca57105d1d 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -19,8 +19,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS } - expect(Asciidoctor).to receive(:convert). - with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert) + .with(input, expected_asciidoc_opts).and_return(html) expect( render(input, context) ).to eql html end @@ -35,8 +35,8 @@ module Gitlab attributes: described_class::DEFAULT_ADOC_ATTRS + ['foo'] } - expect(Asciidoctor).to receive(:convert). - with(input, expected_asciidoc_opts).and_return(html) + expect(Asciidoctor).to receive(:convert) + .with(input, expected_asciidoc_opts).and_return(html) render(input, context, asciidoc_opts) end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 57c416fb35a..b234de4c772 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -140,8 +140,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). - to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) + .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end it 'falls through oauth authentication when the username is oauth2' do @@ -151,8 +151,8 @@ describe Gitlab::Auth, lib: true do password: 'my-secret', ) - expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')). - to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) + expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip')) + .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities)) end end diff --git a/spec/lib/gitlab/backup/manager_spec.rb b/spec/lib/gitlab/backup/manager_spec.rb index e9c69183d00..f84782ab440 100644 --- a/spec/lib/gitlab/backup/manager_spec.rb +++ b/spec/lib/gitlab/backup/manager_spec.rb @@ -141,8 +141,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts). - with(a_string_matching('No backups found')) + expect(progress).to have_received(:puts) + .with(a_string_matching('No backups found')) end end @@ -158,8 +158,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit - expect(progress).to have_received(:puts). - with(a_string_matching('Found more than one backup')) + expect(progress).to have_received(:puts) + .with(a_string_matching('Found more than one backup')) end end @@ -178,8 +178,8 @@ describe Backup::Manager, lib: true do it 'fails the operation and prints an error' do expect { subject.unpack }.to raise_error SystemExit expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts). - with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress).to have_received(:puts) + .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) end end @@ -200,8 +200,8 @@ describe Backup::Manager, lib: true do it 'unpacks the file' do subject.unpack - expect(Kernel).to have_received(:system). - with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") + expect(Kernel).to have_received(:system) + .with("tar", "-xf", "1451606400_2016_01_01_gitlab_backup.tar") expect(progress).to have_received(:puts).with(a_string_matching('done')) end end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb index 8a4bf4dc89b..3c5414701a7 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -20,8 +20,8 @@ describe Gitlab::Badge::Build::Status do describe '#metadata' do it 'returns badge metadata' do - expect(badge.metadata.image_url). - to include 'badges/master/build.svg' + expect(badge.metadata.image_url) + .to include 'badges/master/build.svg' end end diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb index 1da145e7b68..a7ee7f53a6b 100644 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -89,8 +89,8 @@ describe Gitlab::BitbucketImport::Importer, lib: true do stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on"). with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }). to_return(status: 200, - body: "", - headers: {}) + body: "", + headers: {}) sample_issues_statuses.each_with_index do |issue, index| stub_request( diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb index 987a0b1f67f..5c31423fdee 100644 --- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb @@ -26,8 +26,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { name: 10 } } it 'reports error' do - expect(entry.errors). - to include 'artifacts name should be a string' + expect(entry.errors) + .to include 'artifacts name should be a string' end end @@ -35,8 +35,8 @@ describe Gitlab::Ci::Config::Entry::Artifacts do let(:config) { { test: 100 } } it 'reports error' do - expect(entry.errors). - to include 'artifacts config contains unknown keys: test' + expect(entry.errors) + .to include 'artifacts config contains unknown keys: test' end end end diff --git a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb index efb8c5adab1..fde03c51e2c 100644 --- a/spec/lib/gitlab/ci/config/entry/attributable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/attributable_spec.rb @@ -14,9 +14,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is a hash' do before do - allow(instance). - to receive(:config). - and_return({ name: 'some name', test: 'some test' }) + allow(instance) + .to receive(:config) + .and_return({ name: 'some name', test: 'some test' }) end it 'returns the value of config' do @@ -31,9 +31,9 @@ describe Gitlab::Ci::Config::Entry::Attributable do context 'config is not a hash' do before do - allow(instance). - to receive(:config). - and_return('some test') + allow(instance) + .to receive(:config) + .and_return('some test') end it 'returns nil' do diff --git a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb index 8987c0549c5..5f067cad93c 100644 --- a/spec/lib/gitlab/ci/config/entry/boolean_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/boolean_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Boolean do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'boolean config should be a boolean value' + expect(entry.errors) + .to include 'boolean config should be a boolean value' end end end diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index e91f049ee72..70a327c5183 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -32,8 +32,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { 'ls' } it 'reports errors with config value' do - expect(entry.errors). - to include 'cache config should be a hash' + expect(entry.errors) + .to include 'cache config should be a hash' end end @@ -41,8 +41,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { key: 1 } } it 'reports error with descendants' do - expect(entry.errors). - to include 'key config should be a string or symbol' + expect(entry.errors) + .to include 'key config should be a string or symbol' end end @@ -50,8 +50,8 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { invalid: true } } it 'reports error with descendants' do - expect(entry.errors). - to include 'cache config contains unknown keys: invalid' + expect(entry.errors) + .to include 'cache config contains unknown keys: invalid' end end end diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb index 8fe82bc2ebd..afa4a089418 100644 --- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb @@ -40,8 +40,8 @@ describe Gitlab::Ci::Config::Entry::Commands do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'commands config should be a ' \ + expect(entry.errors) + .to include 'commands config should be a ' \ 'string or an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb index 490ba9b7df1..ae7e628b5b5 100644 --- a/spec/lib/gitlab/ci/config/entry/configurable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/configurable_spec.rb @@ -52,8 +52,8 @@ describe Gitlab::Ci::Config::Entry::Configurable do end it 'creates a node factory' do - expect(entry.nodes[:object]). - to be_an_instance_of Gitlab::Ci::Config::Entry::Factory + expect(entry.nodes[:object]) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Factory end it 'returns a duplicated factory object' do diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb index fab2825fbb0..2adbed2154f 100644 --- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb @@ -112,8 +112,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors). - to include 'environment action should be start or stop' + expect(entry.errors) + .to include 'environment action should be start or stop' end end end @@ -143,8 +143,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid action' do - expect(entry.errors). - to include 'environment on stop should be a string' + expect(entry.errors) + .to include 'environment on stop should be a string' end end end @@ -174,8 +174,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors' do it 'contains error about invalid type' do - expect(entry.errors). - to include 'environment config should be a hash or a string' + expect(entry.errors) + .to include 'environment config should be a hash or a string' end end end @@ -191,8 +191,8 @@ describe Gitlab::Ci::Config::Entry::Environment do describe '#errors?' do it 'contains error about missing environment name' do - expect(entry.errors). - to include "environment name can't be blank" + expect(entry.errors) + .to include "environment name can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/factory_spec.rb b/spec/lib/gitlab/ci/config/entry/factory_spec.rb index 5c5ce2d6f39..3395b3c645b 100644 --- a/spec/lib/gitlab/ci/config/entry/factory_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/factory_spec.rb @@ -7,19 +7,19 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting a concrete value' do it 'creates entry with valid value' do - entry = factory. - value(%w(ls pwd)). - create! + entry = factory + .value(%w(ls pwd)) + .create! expect(entry.value).to eq %w(ls pwd) end context 'when setting description' do it 'creates entry with description' do - entry = factory. - value(%w(ls pwd)). - with(description: 'test description'). - create! + entry = factory + .value(%w(ls pwd)) + .with(description: 'test description') + .create! expect(entry.value).to eq %w(ls pwd) expect(entry.description).to eq 'test description' @@ -28,10 +28,10 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when setting key' do it 'creates entry with custom key' do - entry = factory. - value(%w(ls pwd)). - with(key: 'test key'). - create! + entry = factory + .value(%w(ls pwd)) + .with(key: 'test key') + .create! expect(entry.key).to eq 'test key' end @@ -41,10 +41,10 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:object) { Object.new } it 'creates entry with valid parent' do - entry = factory. - value('ls'). - with(parent: object). - create! + entry = factory + .value('ls') + .with(parent: object) + .create! expect(entry.parent).to eq object end @@ -61,12 +61,12 @@ describe Gitlab::Ci::Config::Entry::Factory do context 'when creating entry with nil value' do it 'creates an undefined entry' do - entry = factory. - value(nil). - create! + entry = factory + .value(nil) + .create! - expect(entry). - to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(entry) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -74,13 +74,13 @@ describe Gitlab::Ci::Config::Entry::Factory do let(:entry) { spy('entry') } it 'passes metadata as a parameter' do - factory. - value('some value'). - metadata(some: 'hash'). - create! + factory + .value('some value') + .metadata(some: 'hash') + .create! - expect(entry).to have_received(:new). - with('some value', { some: 'hash' }) + expect(entry).to have_received(:new) + .with('some value', { some: 'hash' }) end end end diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 67a6b3cc98d..ebd80ac5e1d 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -10,10 +10,10 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when filtering all the entry/node names' do it 'contains the expected node names' do - expect(described_class.nodes.keys). - to match_array(%i[before_script image services - after_script variables stages - types cache]) + expect(described_class.nodes.keys) + .to match_array(%i[before_script image services + after_script variables stages + types cache]) end end end @@ -44,17 +44,17 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'creates node object using valid class' do - expect(global.descendants.first). - to be_an_instance_of Gitlab::Ci::Config::Entry::Script - expect(global.descendants.second). - to be_an_instance_of Gitlab::Ci::Config::Entry::Image + expect(global.descendants.first) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Script + expect(global.descendants.second) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Image end it 'sets correct description for nodes' do - expect(global.descendants.first.description). - to eq 'Script that will be executed before each job.' - expect(global.descendants.second.description). - to eq 'Docker image that will be used to execute jobs.' + expect(global.descendants.first.description) + .to eq 'Script that will be executed before each job.' + expect(global.descendants.second.description) + .to eq 'Docker image that will be used to execute jobs.' end describe '#leaf?' do @@ -138,8 +138,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#cache_value' do it 'returns cache configuration' do - expect(global.cache_value). - to eq(key: 'k', untracked: true, paths: ['public/']) + expect(global.cache_value) + .to eq(key: 'k', untracked: true, paths: ['public/']) end end @@ -185,8 +185,8 @@ describe Gitlab::Ci::Config::Entry::Global do end it 'contains unspecified nodes' do - expect(global.descendants.first). - to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified + expect(global.descendants.first) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Unspecified end end @@ -246,8 +246,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors from child nodes' do - expect(global.errors). - to include 'before_script config should be an array of strings' + expect(global.errors) + .to include 'before_script config should be an array of strings' end end @@ -265,8 +265,8 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#errors' do it 'reports errors about missing script' do - expect(global.errors). - to include "jobs:rspec script can't be blank" + expect(global.errors) + .to include "jobs:rspec script can't be blank" end end end @@ -303,16 +303,16 @@ describe Gitlab::Ci::Config::Entry::Global do context 'when entry exists' do it 'returns correct entry' do - expect(global[:cache]). - to be_an_instance_of Gitlab::Ci::Config::Entry::Cache + expect(global[:cache]) + .to be_an_instance_of Gitlab::Ci::Config::Entry::Cache expect(global[:jobs][:rspec][:script].value).to eq ['ls'] end end context 'when entry does not exist' do it 'always return unspecified node' do - expect(global[:some][:unknown][:node]). - not_to be_specified + expect(global[:some][:unknown][:node]) + .not_to be_specified end end end diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb index 062817e07fd..3c99cb0a1ee 100644 --- a/spec/lib/gitlab/ci/config/entry/image_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Image do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'image config should be a string' + expect(entry.errors) + .to include 'image config should be a string' end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 82feff0af1c..d20f4ec207d 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -44,8 +44,8 @@ describe Gitlab::Ci::Config::Entry::Job do describe '#errors' do it 'reports error about a config type' do - expect(entry.errors). - to include 'job config should be a hash' + expect(entry.errors) + .to include 'job config should be a hash' end end end @@ -138,13 +138,13 @@ describe Gitlab::Ci::Config::Entry::Job do end it 'returns correct value' do - expect(entry.value). - to eq(name: :rspec, - before_script: %w[ls pwd], - script: %w[rspec], - commands: "ls\npwd\nrspec", - stage: 'test', - after_script: %w[cleanup]) + expect(entry.value) + .to eq(name: :rspec, + before_script: %w[ls pwd], + script: %w[rspec], + commands: "ls\npwd\nrspec", + stage: 'test', + after_script: %w[cleanup]) end end end diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index c332b70dc71..aaebf783962 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -22,8 +22,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { ['incorrect'] } it 'returns error about incorrect type' do - expect(entry.errors). - to include 'jobs config should be a hash' + expect(entry.errors) + .to include 'jobs config should be a hash' end end @@ -39,8 +39,8 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:config) { { '.hidden'.to_sym => { script: [] } } } it 'returns error about no visible jobs defined' do - expect(entry.errors). - to include 'jobs config should contain at least one visible job' + expect(entry.errors) + .to include 'jobs config should contain at least one visible job' end end end @@ -73,10 +73,10 @@ describe Gitlab::Ci::Config::Entry::Jobs do describe '#descendants' do it 'creates valid descendant nodes' do expect(entry.descendants.count).to eq 3 - expect(entry.descendants.first(2)). - to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) - expect(entry.descendants.last). - to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) + expect(entry.descendants.first(2)) + .to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job)) + expect(entry.descendants.last) + .to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden) end end diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb index cd7b03ffb11..0dd36fe1f44 100644 --- a/spec/lib/gitlab/ci/config/entry/key_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Key do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'key config should be a string or symbol' + expect(entry.errors) + .to include 'key config should be a string or symbol' end end end diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb index b0ac90f1d94..1d9c5ddee9b 100644 --- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Paths do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'paths config should be an array of strings' + expect(entry.errors) + .to include 'paths config should be an array of strings' end end end diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb index 49cca49509c..069eaa26422 100644 --- a/spec/lib/gitlab/ci/config/entry/script_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb @@ -31,8 +31,8 @@ describe Gitlab::Ci::Config::Entry::Script do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'script config should be an array of strings' + expect(entry.errors) + .to include 'script config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb index c31a7c0ec3e..66fad3b6b16 100644 --- a/spec/lib/gitlab/ci/config/entry/services_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Services do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'services config should be an array of strings' + expect(entry.errors) + .to include 'services config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/stage_spec.rb b/spec/lib/gitlab/ci/config/entry/stage_spec.rb index cefef7a805a..70c8a0a355a 100644 --- a/spec/lib/gitlab/ci/config/entry/stage_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stage_spec.rb @@ -24,8 +24,8 @@ describe Gitlab::Ci::Config::Entry::Stage do let(:config) { { test: true } } it 'reports errors about wrong type' do - expect(stage.errors). - to include 'stage config should be a string' + expect(stage.errors) + .to include 'stage config should be a string' end end end diff --git a/spec/lib/gitlab/ci/config/entry/stages_spec.rb b/spec/lib/gitlab/ci/config/entry/stages_spec.rb index bdcd6c98a85..182c8d867c7 100644 --- a/spec/lib/gitlab/ci/config/entry/stages_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stages_spec.rb @@ -25,8 +25,8 @@ describe Gitlab::Ci::Config::Entry::Stages do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'stages config should be an array of strings' + expect(entry.errors) + .to include 'stages config should be an array of strings' end end diff --git a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb index 13b00a98b6a..e4ee44f1274 100644 --- a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Trigger do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include 'trigger config should be an array of strings or regexps' + expect(entry.errors) + .to include 'trigger config should be an array of strings or regexps' end end end diff --git a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb index e31e85538b9..d1856801827 100644 --- a/spec/lib/gitlab/ci/config/entry/validatable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validatable_spec.rb @@ -19,8 +19,8 @@ describe Gitlab::Ci::Config::Entry::Validatable do end it 'returns validator' do - expect(entry.validator.superclass). - to be Gitlab::Ci::Config::Entry::Validator + expect(entry.validator.superclass) + .to be Gitlab::Ci::Config::Entry::Validator end it 'returns only one validator to mitigate leaks' do diff --git a/spec/lib/gitlab/ci/config/entry/validator_spec.rb b/spec/lib/gitlab/ci/config/entry/validator_spec.rb index c6e21cd67b0..ad7e6f07d3c 100644 --- a/spec/lib/gitlab/ci/config/entry/validator_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/validator_spec.rb @@ -47,8 +47,8 @@ describe Gitlab::Ci::Config::Entry::Validator do it 'returns errors' do validator_instance.validate - expect(validator_instance.messages). - to include "node test attribute can't be blank" + expect(validator_instance.messages) + .to include "node test attribute can't be blank" end end end diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index c117f35c906..f15f02f403e 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -33,8 +33,8 @@ describe Gitlab::Ci::Config::Entry::Variables do describe '#errors' do it 'saves errors' do - expect(entry.errors). - to include /should be a hash of key value pairs/ + expect(entry.errors) + .to include /should be a hash of key value pairs/ end end diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index cd893a09748..40b96b1807b 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Build::Common do let(:project) { build.project } subject do - Gitlab::Ci::Status::Core. - new(build, user). - extend(described_class) + Gitlab::Ci::Status::Core + .new(build, user) + .extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index aa026a66460..0c40fca0c1a 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -16,8 +16,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -42,8 +42,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -67,9 +67,9 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable, - Gitlab::Ci::Status::Build::FailedAllowed] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable, + Gitlab::Ci::Status::Build::FailedAllowed] end it 'fabricates a failed but allowed build status' do @@ -96,8 +96,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Retryable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Retryable] end it 'fabricates a retryable build status' do @@ -121,8 +121,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a canceable build status' do @@ -146,8 +146,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Cancelable] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Cancelable] end it 'fabricates a cancelable build status' do @@ -196,8 +196,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Play] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Play] end it 'fabricates a core skipped status' do @@ -222,8 +222,8 @@ describe Gitlab::Ci::Status::Build::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::Build::Stop] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Build::Stop] end it 'fabricates a core skipped status' do diff --git a/spec/lib/gitlab/ci/status/extended_spec.rb b/spec/lib/gitlab/ci/status/extended_spec.rb index 459044eb968..c2d74ca5cde 100644 --- a/spec/lib/gitlab/ci/status/extended_spec.rb +++ b/spec/lib/gitlab/ci/status/extended_spec.rb @@ -6,7 +6,7 @@ describe Gitlab::Ci::Status::Extended do end it 'requires subclass to implement matcher' do - expect { subject.matches?(double, double) }. - to raise_error(NotImplementedError) + expect { subject.matches?(double, double) } + .to raise_error(NotImplementedError) end end diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index 6a564eeb8b7..5a97d98b55f 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -10,9 +10,9 @@ describe Gitlab::Ci::Status::External::Common do end subject do - Gitlab::Ci::Status::Core. - new(external_status, user). - extend(described_class) + Gitlab::Ci::Status::Core + .new(external_status, user) + .extend(described_class) end describe '#has_action?' do diff --git a/spec/lib/gitlab/ci/status/factory_spec.rb b/spec/lib/gitlab/ci/status/factory_spec.rb index 45fd49b91ea..bbf9c7c83a3 100644 --- a/spec/lib/gitlab/ci/status/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/factory_spec.rb @@ -84,15 +84,15 @@ describe Gitlab::Ci::Status::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [first_extended_status, second_extended_status] + expect(factory.extended_statuses) + .to eq [first_extended_status, second_extended_status] end end context 'when exclusive statuses are matches' do before do - allow(described_class).to receive(:extended_statuses). - and_return([[first_extended_status, second_extended_status]]) + allow(described_class).to receive(:extended_statuses) + .and_return([[first_extended_status, second_extended_status]]) end it 'does not fabricate compound decorator' do @@ -116,8 +116,8 @@ describe Gitlab::Ci::Status::Factory do context 'when exclusive statuses are not matched' do before do - allow(described_class).to receive(:extended_statuses). - and_return([[first_extended_status], [second_extended_status]]) + allow(described_class).to receive(:extended_statuses) + .and_return([[first_extended_status], [second_extended_status]]) end it_behaves_like 'compound decorator factory' @@ -125,8 +125,8 @@ describe Gitlab::Ci::Status::Factory do context 'when using simplified status grouping' do before do - allow(described_class).to receive(:extended_statuses). - and_return([first_extended_status, second_extended_status]) + allow(described_class).to receive(:extended_statuses) + .and_return([first_extended_status, second_extended_status]) end it_behaves_like 'compound decorator factory' diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index 35dad60febf..d665674bf70 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -6,9 +6,9 @@ describe Gitlab::Ci::Status::Pipeline::Common do let(:pipeline) { create(:ci_pipeline, project: project) } subject do - Gitlab::Ci::Status::Core. - new(pipeline, user). - extend(described_class) + Gitlab::Ci::Status::Core + .new(pipeline, user) + .extend(described_class) end describe '#has_action?' do @@ -29,8 +29,8 @@ describe Gitlab::Ci::Status::Pipeline::Common do describe '#details_path' do it 'links to the pipeline details page' do - expect(subject.details_path). - to include "pipelines/#{pipeline.id}" + expect(subject.details_path) + .to include "pipelines/#{pipeline.id}" end end end diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index 7cee4435931..b10a447c27a 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do it 'extends core status with common pipeline methods' do expect(status).to have_details expect(status).not_to have_action - expect(status.details_path). - to include "pipelines/#{pipeline.id}" + expect(status.details_path) + .to include "pipelines/#{pipeline.id}" end end end @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do end it 'matches correct extended statuses' do - expect(factory.extended_statuses). - to eq [Gitlab::Ci::Status::SuccessWarning] + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::SuccessWarning] end it 'fabricates extended "success with warnings" status' do diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb index 3b25893d8c7..8814a7614a0 100644 --- a/spec/lib/gitlab/ci/status/stage/common_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb @@ -10,8 +10,8 @@ describe Gitlab::Ci::Status::Stage::Common do end subject do - Class.new(Gitlab::Ci::Status::Core). - new(stage, user).extend(described_class) + Class.new(Gitlab::Ci::Status::Core) + .new(stage, user).extend(described_class) end it 'does not have action' do @@ -19,10 +19,10 @@ describe Gitlab::Ci::Status::Stage::Common do end it 'links to the pipeline details page' do - expect(subject.details_path). - to include "pipelines/#{pipeline.id}" - expect(subject.details_path). - to include "##{stage.name}" + expect(subject.details_path) + .to include "pipelines/#{pipeline.id}" + expect(subject.details_path) + .to include "##{stage.name}" end context 'when user has permission to read pipeline' do diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index c8503392b34..bbb40e2c1ab 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -55,8 +55,8 @@ describe Gitlab::Ci::Status::Stage::Factory do end it 'fabricates extended "success with warnings" status' do - expect(status). - to be_a Gitlab::Ci::Status::SuccessWarning + expect(status) + .to be_a Gitlab::Ci::Status::SuccessWarning end it 'extends core status with common stage method' do diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb index 7658153df0b..04ec34492e1 100644 --- a/spec/lib/gitlab/data_builder/note_spec.rb +++ b/spec/lib/gitlab/data_builder/note_spec.rb @@ -9,8 +9,8 @@ describe Gitlab::DataBuilder::Note, lib: true do before(:each) do expect(data).to have_key(:object_attributes) expect(data[:object_attributes]).to have_key(:url) - expect(data[:object_attributes][:url]). - to eq(Gitlab::UrlBuilder.build(note)) + expect(data[:object_attributes][:url]) + .to eq(Gitlab::UrlBuilder.build(note)) expect(data[:object_kind]).to eq('note') expect(data[:user]).to eq(user.hook_attrs) end @@ -49,10 +49,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and issue-specific data' do expect(data).to have_key(:issue) - expect(data[:issue].except('updated_at')). - to eq(issue.reload.hook_attrs.except('updated_at')) - expect(data[:issue]['updated_at']). - to be > issue.hook_attrs['updated_at'] + expect(data[:issue].except('updated_at')) + .to eq(issue.reload.hook_attrs.except('updated_at')) + expect(data[:issue]['updated_at']) + .to be > issue.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -73,10 +73,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')). - to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']). - to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')) + .to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']) + .to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -96,10 +96,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and merge request diff data' do expect(data).to have_key(:merge_request) - expect(data[:merge_request].except('updated_at')). - to eq(merge_request.reload.hook_attrs.except('updated_at')) - expect(data[:merge_request]['updated_at']). - to be > merge_request.hook_attrs['updated_at'] + expect(data[:merge_request].except('updated_at')) + .to eq(merge_request.reload.hook_attrs.except('updated_at')) + expect(data[:merge_request]['updated_at']) + .to be > merge_request.hook_attrs['updated_at'] end include_examples 'project hook data' @@ -119,10 +119,10 @@ describe Gitlab::DataBuilder::Note, lib: true do it 'returns the note and project snippet data' do expect(data).to have_key(:snippet) - expect(data[:snippet].except('updated_at')). - to eq(snippet.reload.hook_attrs.except('updated_at')) - expect(data[:snippet]['updated_at']). - to be > snippet.hook_attrs['updated_at'] + expect(data[:snippet].except('updated_at')) + .to eq(snippet.reload.hook_attrs.except('updated_at')) + expect(data[:snippet]['updated_at']) + .to be > snippet.hook_attrs['updated_at'] end include_examples 'project hook data' diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 5eff7e8425b..edd01d032c8 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -120,8 +120,8 @@ describe Gitlab::Database, lib: true do pool = described_class.create_connection_pool(5) begin - expect(pool). - to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) + expect(pool) + .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool) expect(pool.spec.config[:pool]).to eq(5) ensure diff --git a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb index c141762421f..08a42fd27a2 100644 --- a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb @@ -7,8 +7,8 @@ describe Gitlab::ImportExport::AvatarRestorer, lib: true do let(:project) { create(:empty_project) } before do - allow_any_instance_of(described_class).to receive(:avatar_export_file). - and_return(uploaded_image_temp_path) + allow_any_instance_of(described_class).to receive(:avatar_export_file) + .and_return(uploaded_image_temp_path) end after do diff --git a/spec/lib/gitlab/incoming_email_spec.rb b/spec/lib/gitlab/incoming_email_spec.rb index d54753ccf90..698bd72d0f8 100644 --- a/spec/lib/gitlab/incoming_email_spec.rb +++ b/spec/lib/gitlab/incoming_email_spec.rb @@ -99,10 +99,10 @@ describe Gitlab::IncomingEmail, lib: true do end it 'returns reply key' do - expect(described_class.scan_fallback_references(references)). - to eq(%w[issue_1@localhost - reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost - exchange@microsoft.com]) + expect(described_class.scan_fallback_references(references)) + .to eq(%w[issue_1@localhost + reply-59d8df8370b7e95c5a49fbf86aeb2c93@localhost + exchange@microsoft.com]) end end end diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb index fe3709f30e1..563c074017a 100644 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/ldap/adapter_spec.rb @@ -34,8 +34,8 @@ describe Gitlab::LDAP::Adapter, lib: true do end it 'searches with the proper options when searching with a limit' do - expect(adapter). - to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) + expect(adapter) + .to receive(:ldap_search).with(hash_including(size: 100)).and_return({}) adapter.users('uid', 'johndoe', 100) end diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 4de5991db37..c49d2b286ff 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -188,8 +188,8 @@ describe Gitlab::OAuth::User, lib: true do oauth_user.save identities_as_hash = gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } } - expect(identities_as_hash). - to match_array( + expect(identities_as_hash) + .to match_array( [ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' }, { provider: 'twitter', extern_uid: uid } diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb index e05160da7a6..519eb1b274f 100644 --- a/spec/lib/gitlab/serializer/pagination_spec.rb +++ b/spec/lib/gitlab/serializer/pagination_spec.rb @@ -6,11 +6,11 @@ describe Gitlab::Serializer::Pagination do let(:headers) { spy('headers') } before do - allow(request).to receive(:query_parameters). - and_return(params) + allow(request).to receive(:query_parameters) + .and_return(params) - allow(response).to receive(:headers). - and_return(headers) + allow(response).to receive(:headers) + .and_return(headers) end let(:pagination) { described_class.new(request, response) } diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 8688639168b..4086e00e363 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -32,9 +32,9 @@ describe ApplicationSetting, models: true do it { is_expected.to validate_presence_of(:max_attachment_size) } it do - is_expected.to validate_numericality_of(:max_attachment_size). - only_integer. - is_greater_than(0) + is_expected.to validate_numericality_of(:max_attachment_size) + .only_integer + .is_greater_than(0) end it_behaves_like 'an object with email-formated attributes', :admin_notification_email do diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index a173e3aeff6..63b6c3c65a6 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -212,15 +212,15 @@ describe Ci::Build, :models do retried_rspec = Ci::Build.retry(rspec_test, user) - expect(staging.depends_on_builds.map(&:id)). - to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) + expect(staging.depends_on_builds.map(&:id)) + .to contain_exactly(build.id, retried_rspec.id, rubocop_test.id) end end describe '#detailed_status' do it 'returns a detailed status' do - expect(build.detailed_status(user)). - to be_a Gitlab::Ci::Status::Build::Cancelable + expect(build.detailed_status(user)) + .to be_a Gitlab::Ci::Status::Build::Cancelable end end @@ -1151,8 +1151,8 @@ describe Ci::Build, :models do let!(:build) { create(:ci_build, artifacts_size: 23) } it 'updates project statistics when the artifact size changes' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(build.project_id, [], [:build_artifacts_size]) build.artifacts_size = 42 build.save! @@ -1166,8 +1166,8 @@ describe Ci::Build, :models do end it 'updates project statistics when the build is destroyed' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(build.project_id, [], [:build_artifacts_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(build.project_id, [], [:build_artifacts_size]) build.destroy end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index f770e6a9e34..36533bdd11e 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -253,8 +253,8 @@ describe CommitStatus, :models do let(:user) { create(:user) } it 'returns a detailed status' do - expect(commit_status.detailed_status(user)). - to be_a Gitlab::Ci::Status::Success + expect(commit_status.detailed_status(user)) + .to be_a Gitlab::Ci::Status::Success end end diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb index 4652af1cb97..fe4de1b2afb 100644 --- a/spec/models/email_spec.rb +++ b/spec/models/email_spec.rb @@ -8,7 +8,7 @@ describe Email, models: true do end it 'normalize email value' do - expect(described_class.new(email: ' inFO@exAMPLe.com ').email). - to eq 'info@example.com' + expect(described_class.new(email: ' inFO@exAMPLe.com ').email) + .to eq 'info@example.com' end end diff --git a/spec/models/group_label_spec.rb b/spec/models/group_label_spec.rb index c8d88022ec7..555a876daeb 100644 --- a/spec/models/group_label_spec.rb +++ b/spec/models/group_label_spec.rb @@ -49,8 +49,8 @@ describe GroupLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) }. - to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) } + .to raise_error StandardError, /Unknown format/ end end end diff --git a/spec/models/lfs_objects_project_spec.rb b/spec/models/lfs_objects_project_spec.rb index a2031beeab2..7bc278e350f 100644 --- a/spec/models/lfs_objects_project_spec.rb +++ b/spec/models/lfs_objects_project_spec.rb @@ -18,8 +18,8 @@ describe LfsObjectsProject, models: true do describe '#update_project_statistics' do it 'updates project statistics when the object is added' do - expect(ProjectCacheWorker).to receive(:perform_async). - with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(project.id, [], [:lfs_objects_size]) subject.save! end @@ -27,8 +27,8 @@ describe LfsObjectsProject, models: true do it 'updates project statistics when the object is removed' do subject.save! - expect(ProjectCacheWorker).to receive(:perform_async). - with(project.id, [], [:lfs_objects_size]) + expect(ProjectCacheWorker).to receive(:perform_async) + .with(project.id, [], [:lfs_objects_size]) subject.destroy end diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb index e74e4ae0e96..0a10ee01506 100644 --- a/spec/models/merge_request_diff_spec.rb +++ b/spec/models/merge_request_diff_spec.rb @@ -84,8 +84,8 @@ describe MergeRequestDiff, models: true do end it 'saves overflow state' do - allow(Commit).to receive(:max_diff_options). - and_return(max_lines: 0, max_files: 0) + allow(Commit).to receive(:max_diff_options) + .and_return(max_lines: 0, max_files: 0) mr_diff = create(:merge_request).merge_request_diff @@ -93,8 +93,8 @@ describe MergeRequestDiff, models: true do end it 'saves empty state' do - allow_any_instance_of(MergeRequestDiff).to receive(:commits). - and_return([]) + allow_any_instance_of(MergeRequestDiff).to receive(:commits) + .and_return([]) mr_diff = create(:merge_request).merge_request_diff diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 810c08256dc..a01741a9971 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -412,15 +412,15 @@ describe MergeRequest, models: true do it 'includes merge information as the title' do request = build(:merge_request, source_branch: 'source', target_branch: 'target') - expect(request.merge_commit_message). - to match("Merge branch 'source' into 'target'\n\n") + expect(request.merge_commit_message) + .to match("Merge branch 'source' into 'target'\n\n") end it 'includes its title in the body' do request = build(:merge_request, title: 'Remove all technical debt') - expect(request.merge_commit_message). - to match("Remove all technical debt\n\n") + expect(request.merge_commit_message) + .to match("Remove all technical debt\n\n") end it 'includes its closed issues in the body' do @@ -432,15 +432,15 @@ describe MergeRequest, models: true do allow(subject.project).to receive(:default_branch). and_return(subject.target_branch) - expect(subject.merge_commit_message). - to match("Closes #{issue.to_reference}") + expect(subject.merge_commit_message) + .to match("Closes #{issue.to_reference}") end it 'includes its reference in the body' do request = build_stubbed(:merge_request) - expect(request.merge_commit_message). - to match("See merge request #{request.to_reference}") + expect(request.merge_commit_message) + .to match("See merge request #{request.to_reference}") end it 'excludes multiple linebreak runs when description is blank' do @@ -452,15 +452,15 @@ describe MergeRequest, models: true do it 'includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message(include_description: true)). - to match("By removing all code\n\n") + expect(request.merge_commit_message(include_description: true)) + .to match("By removing all code\n\n") end it 'does not includes its description in the body' do request = build(:merge_request, description: 'By removing all code') - expect(request.merge_commit_message). - not_to match("By removing all code\n\n") + expect(request.merge_commit_message) + .not_to match("By removing all code\n\n") end end diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb index 3e9dd3758ed..9cdbfa44e5b 100644 --- a/spec/models/project_label_spec.rb +++ b/spec/models/project_label_spec.rb @@ -94,8 +94,8 @@ describe ProjectLabel, models: true do context 'using invalid format' do it 'raises error' do - expect { label.to_reference(format: :invalid) }. - to raise_error StandardError, /Unknown format/ + expect { label.to_reference(format: :invalid) } + .to raise_error StandardError, /Unknown format/ end end @@ -104,15 +104,15 @@ describe ProjectLabel, models: true do context 'using name' do it 'returns cross reference with label name' do - expect(label.to_reference(project, format: :name)). - to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") + expect(label.to_reference(project, format: :name)) + .to eq %Q(#{label.project.path_with_namespace}~"#{label.name}") end end context 'using id' do it 'returns cross reference with label id' do - expect(label.to_reference(project, format: :id)). - to eq %Q(#{label.project.path_with_namespace}~#{label.id}) + expect(label.to_reference(project, format: :id)) + .to eq %Q(#{label.project.path_with_namespace}~#{label.id}) end end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index a3fe412b229..43aac31d8b7 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -265,8 +265,8 @@ describe Repository, models: true do describe '#commit' do context 'when ref exists' do it 'returns commit object' do - expect(repository.commit('master')). - to be_an_instance_of Commit + expect(repository.commit('master')) + .to be_an_instance_of Commit end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d7aa7754834..b69fd24c586 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1146,8 +1146,8 @@ describe User, models: true do user = create(:user) project = create(:empty_project, :private, namespace: user.namespace) - expect(user.authorized_projects(Gitlab::Access::REPORTER)). - to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)) + .to contain_exactly(project) end it 'includes projects for which the user is a master' do @@ -1156,8 +1156,8 @@ describe User, models: true do project.team << [user, Gitlab::Access::MASTER] - expect(user.authorized_projects(Gitlab::Access::REPORTER)). - to contain_exactly(project) + expect(user.authorized_projects(Gitlab::Access::REPORTER)) + .to contain_exactly(project) end end diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb index 576eb80605b..921d8714173 100644 --- a/spec/requests/api/broadcast_messages_spec.rb +++ b/spec/requests/api/broadcast_messages_spec.rb @@ -27,8 +27,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_kind_of(Array) - expect(json_response.first.keys). - to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.first.keys) + .to match_array(%w(id message starts_at ends_at color font active)) end end @@ -52,8 +52,8 @@ describe API::BroadcastMessages, api: true do expect(response).to have_http_status(200) expect(json_response['id']).to eq message.id - expect(json_response.keys). - to match_array(%w(id message starts_at ends_at color font active)) + expect(json_response.keys) + .to match_array(%w(id message starts_at ends_at color font active)) end end @@ -174,8 +174,8 @@ describe API::BroadcastMessages, api: true do end it 'deletes the broadcast message for admins' do - expect { delete api("/broadcast_messages/#{message.id}", admin) }. - to change { BroadcastMessage.count }.by(-1) + expect { delete api("/broadcast_messages/#{message.id}", admin) } + .to change { BroadcastMessage.count }.by(-1) end end end diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index eface28976e..81a8856b8f1 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -207,8 +207,8 @@ describe API::CommitStatuses, api: true do it 'responds with bad request status and validation errors' do expect(response).to have_http_status(400) - expect(json_response['message']['target_url']). - to include 'must be a valid URL' + expect(json_response['message']['target_url']) + .to include 'must be a valid URL' end end end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index b82372b1b60..9c3a92bedbd 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -36,8 +36,8 @@ describe API::Groups, api: true do expect(response).to include_pagination_headers expect(json_response).to be_an Array expect(json_response.length).to eq(1) - expect(json_response). - to satisfy_one { |group| group['name'] == group1.name } + expect(json_response) + .to satisfy_one { |group| group['name'] == group1.name } end it "does not include statistics" do @@ -84,8 +84,8 @@ describe API::Groups, api: true do expect(response).to have_http_status(200) expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response). - to satisfy_one { |group| group['statistics'] == attributes } + expect(json_response) + .to satisfy_one { |group| group['statistics'] == attributes } end end diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index d1e765d1fdd..ffeacb15f17 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -74,8 +74,8 @@ describe API::Internal, api: true do context 'when two-factor is enabled' do it 'returns new recovery codes when the user exists' do allow_any_instance_of(User).to receive(:two_factor_enabled?).and_return(true) - allow_any_instance_of(User). - to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) + allow_any_instance_of(User) + .to receive(:generate_otp_backup_codes!).and_return(%w(119135e5a3ebce8e 34bd7b74adbc8861)) post api('/internal/two_factor_recovery_codes'), secret_token: secret_token, diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 2e596f4197e..103d6755888 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -202,8 +202,8 @@ describe API::Runners, api: true do expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql') expect(shared_runner.run_untagged?).to be(false) expect(shared_runner.locked?).to be(true) - expect(shared_runner.ensure_runner_queue_value). - not_to eq(runner_queue_value) + expect(shared_runner.ensure_runner_queue_value) + .not_to eq(runner_queue_value) end end @@ -218,8 +218,8 @@ describe API::Runners, api: true do expect(response).to have_http_status(200) expect(specific_runner.description).to eq('test') expect(specific_runner.description).not_to eq(description) - expect(specific_runner.ensure_runner_queue_value). - not_to eq(runner_queue_value) + expect(specific_runner.ensure_runner_queue_value) + .not_to eq(runner_queue_value) end end diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index 6d79f2e7b41..444258e312d 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -38,8 +38,8 @@ describe Ci::API::Builds do it 'gives 204 and set the same X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']). - to eq(last_update) + expect(response.header['X-GitLab-Last-Update']) + .to eq(last_update) end end @@ -49,8 +49,8 @@ describe Ci::API::Builds do it 'gives 204 and set a new X-GitLab-Last-Update' do expect(response).to have_http_status(204) - expect(response.header['X-GitLab-Last-Update']). - to eq(new_update) + expect(response.header['X-GitLab-Last-Update']) + .to eq(new_update) end end @@ -260,8 +260,8 @@ describe Ci::API::Builds do end it 'does not update runner info' do - expect { register_builds }. - not_to change { runner.reload.contacted_at } + expect { register_builds } + .not_to change { runner.reload.contacted_at } end end diff --git a/spec/serializers/analytics_build_serializer_spec.rb b/spec/serializers/analytics_build_serializer_spec.rb index c8bad5ef105..e3b1dd93dc2 100644 --- a/spec/serializers/analytics_build_serializer_spec.rb +++ b/spec/serializers/analytics_build_serializer_spec.rb @@ -7,8 +7,8 @@ describe AnalyticsBuildSerializer do context 'when there is a single object provided' do it 'contains important elements of analyticsBuild' do - expect(subject). - to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) + expect(subject) + .to include(:name, :branch, :short_sha, :date, :total_time, :url, :author) end end end diff --git a/spec/serializers/analytics_issue_serializer_spec.rb b/spec/serializers/analytics_issue_serializer_spec.rb index fe26b001740..2f08958a783 100644 --- a/spec/serializers/analytics_issue_serializer_spec.rb +++ b/spec/serializers/analytics_issue_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsIssueSerializer do subject do - described_class. - new(project: project, entity: :merge_request). - represent(resource) + described_class + .new(project: project, entity: :merge_request) + .represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_merge_request_serializer_spec.rb b/spec/serializers/analytics_merge_request_serializer_spec.rb index ee08762d237..62067cc0ef2 100644 --- a/spec/serializers/analytics_merge_request_serializer_spec.rb +++ b/spec/serializers/analytics_merge_request_serializer_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe AnalyticsMergeRequestSerializer do subject do - described_class. - new(project: project, entity: :merge_request). - represent(resource) + described_class + .new(project: project, entity: :merge_request) + .represent(resource) end let(:user) { create(:user) } diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb index 3106af0ded7..5d7a94c2d02 100644 --- a/spec/serializers/analytics_summary_serializer_spec.rb +++ b/spec/serializers/analytics_summary_serializer_spec.rb @@ -9,13 +9,13 @@ describe AnalyticsSummarySerializer do let(:user) { create(:user) } let(:resource) do - Gitlab::CycleAnalytics::Summary::Issue. - new(project: double, from: 1.day.ago, current_user: user) + Gitlab::CycleAnalytics::Summary::Issue + .new(project: double, from: 1.day.ago, current_user: user) end before do - allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue). - to receive(:value).and_return(1.12) + allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue) + .to receive(:value).and_return(1.12) end it 'it generates payload for single object' do diff --git a/spec/serializers/build_artifact_entity_spec.rb b/spec/serializers/build_artifact_entity_spec.rb index 6ccea199376..2fc60aa9de6 100644 --- a/spec/serializers/build_artifact_entity_spec.rb +++ b/spec/serializers/build_artifact_entity_spec.rb @@ -15,8 +15,8 @@ describe BuildArtifactEntity do end it 'contains path to the artifacts' do - expect(subject[:path]). - to include "builds/#{build.id}/artifacts/download" + expect(subject[:path]) + .to include "builds/#{build.id}/artifacts/download" end end end diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index 895aeb30035..0333d73b5b5 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -42,8 +42,8 @@ describe CommitEntity do end it 'needs to receive project in the request' do - expect(request).to receive(:project). - and_return(project) + expect(request).to receive(:project) + .and_return(project) subject end diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb index 61b2fce8e8a..6a6df377b35 100644 --- a/spec/serializers/environment_serializer_spec.rb +++ b/spec/serializers/environment_serializer_spec.rb @@ -5,9 +5,9 @@ describe EnvironmentSerializer do let(:project) { create(:project) } let(:json) do - described_class. - new(user: user, project: project). - represent(resource) + described_class + .new(user: user, project: project) + .represent(resource) end context 'when there is a single object provided' do @@ -27,15 +27,15 @@ describe EnvironmentSerializer do let(:resource) { deployment.environment } it 'contains important elements of environment' do - expect(json). - to include(:name, :external_url, :environment_path, :last_deployment) + expect(json) + .to include(:name, :external_url, :environment_path, :last_deployment) end it 'contains relevant information about last deployment' do last_deployment = json.fetch(:last_deployment) - expect(last_deployment). - to include(:ref, :user, :commit, :deployable, :manual_actions) + expect(last_deployment) + .to include(:ref, :user, :commit, :deployable, :manual_actions) end end @@ -44,8 +44,8 @@ describe EnvironmentSerializer do let(:resource) { create_list(:environment, 2) } it 'contains important elements of environment' do - expect(json.first). - to include(:last_deployment, :name, :external_url) + expect(json.first) + .to include(:last_deployment, :name, :external_url) end it 'generates payload for collection' do @@ -122,13 +122,13 @@ describe EnvironmentSerializer do let(:pagination) { { page: 1, per_page: 2 } } let(:serializer) do - described_class.new(project: project). - with_pagination(request, response) + described_class.new(project: project) + .with_pagination(request, response) end before do - allow(request).to receive(:query_parameters). - and_return(pagination) + allow(request).to receive(:query_parameters) + .and_return(pagination) end subject { serializer.represent(resource) } @@ -164,9 +164,9 @@ describe EnvironmentSerializer do context 'when grouping environments within folders' do let(:serializer) do - described_class.new(project: project). - with_pagination(request, response). - within_folders + described_class.new(project: project) + .with_pagination(request, response) + .within_folders end before do diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb index 96ef1d3c071..ccb72973f9c 100644 --- a/spec/serializers/pipeline_entity_spec.rb +++ b/spec/serializers/pipeline_entity_spec.rb @@ -26,17 +26,17 @@ describe PipelineEntity do it 'contains details' do expect(subject).to include :details - expect(subject[:details]). - to include :duration, :finished_at - expect(subject[:details]). - to include :stages, :artifacts, :manual_actions + expect(subject[:details]) + .to include :duration, :finished_at + expect(subject[:details]) + .to include :stages, :artifacts, :manual_actions expect(subject[:details][:status]).to include :icon, :text, :label end it 'contains flags' do expect(subject).to include :flags - expect(subject[:flags]). - to include :latest, :triggered, :stuck, + expect(subject[:flags]) + .to include :latest, :triggered, :stuck, :yaml_errors, :retryable, :cancelable end end diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index 5f84a98f06d..2aaef03cb93 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -38,14 +38,14 @@ describe PipelineSerializer do let(:pagination) { {} } before do - allow(request). - to receive(:query_parameters). - and_return(pagination) + allow(request) + .to receive(:query_parameters) + .and_return(pagination) end let(:serializer) do - described_class.new(user: user). - with_pagination(request, response) + described_class.new(user: user) + .with_pagination(request, response) end it 'created a paginated serializer' do diff --git a/spec/serializers/request_aware_entity_spec.rb b/spec/serializers/request_aware_entity_spec.rb index 94dbf02aee8..aa666b961dc 100644 --- a/spec/serializers/request_aware_entity_spec.rb +++ b/spec/serializers/request_aware_entity_spec.rb @@ -14,8 +14,8 @@ describe RequestAwareEntity do end it 'fetches request from options' do - expect(subject).to receive(:options). - and_return({ request: 'some value' }) + expect(subject).to receive(:options) + .and_return({ request: 'some value' }) expect(subject.request).to eq 'some value' end diff --git a/spec/serializers/stage_entity_spec.rb b/spec/serializers/stage_entity_spec.rb index 42f19935453..4ab40d08432 100644 --- a/spec/serializers/stage_entity_spec.rb +++ b/spec/serializers/stage_entity_spec.rb @@ -35,13 +35,13 @@ describe StageEntity do end it 'contains path to the stage' do - expect(subject[:path]). - to include "pipelines/#{pipeline.id}##{stage.name}" + expect(subject[:path]) + .to include "pipelines/#{pipeline.id}##{stage.name}" end it 'contains path to the stage dropdown' do - expect(subject[:dropdown_path]). - to include "pipelines/#{pipeline.id}/stage.json?stage=test" + expect(subject[:dropdown_path]) + .to include "pipelines/#{pipeline.id}/stage.json?stage=test" end it 'contains stage title' do diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index 65544c57431..b818dfdd50c 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -284,14 +284,14 @@ describe Ci::ProcessPipelineService, :services do pipeline.builds.running_or_pending.each(&:success) - expect(builds.pluck(:name)). - to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)) + .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') pipeline.builds.find_by(name: 'test:1').success pipeline.builds.find_by(name: 'test:2').drop - expect(builds.pluck(:name)). - to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') + expect(builds.pluck(:name)) + .to contain_exactly('build:1', 'build:2', 'test:1', 'test:2') Ci::Build.retry(pipeline.builds.find_by(name: 'test:2'), user).success diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb index 6499c7ad63e..d03f7505eac 100644 --- a/spec/services/ci/retry_build_service_spec.rb +++ b/spec/services/ci/retry_build_service_spec.rb @@ -61,8 +61,8 @@ describe Ci::RetryBuildService, :services do end it 'resolves todos for old build that failed' do - expect(MergeRequests::AddTodoWhenBuildFailsService). - to receive_message_chain(:new, :close) + expect(MergeRequests::AddTodoWhenBuildFailsService) + .to receive_message_chain(:new, :close) service.execute(build) end @@ -82,8 +82,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.execute(build) }. - to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(build) } + .to raise_error Gitlab::Access::AccessDeniedError end end end @@ -109,8 +109,8 @@ describe Ci::RetryBuildService, :services do context 'when user does not have ability to execute build' do it 'raises an error' do - expect { service.reprocess(build) }. - to raise_error Gitlab::Access::AccessDeniedError + expect { service.reprocess(build) } + .to raise_error Gitlab::Access::AccessDeniedError end end end diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb index 84915b5f1aa..c0af8b8450a 100644 --- a/spec/services/ci/retry_pipeline_service_spec.rb +++ b/spec/services/ci/retry_pipeline_service_spec.rb @@ -134,8 +134,8 @@ describe Ci::RetryPipelineService, '#execute', :services do end it 'closes all todos about failed jobs for pipeline' do - expect(MergeRequests::AddTodoWhenBuildFailsService). - to receive_message_chain(:new, :close_all) + expect(MergeRequests::AddTodoWhenBuildFailsService) + .to receive_message_chain(:new, :close_all) service.execute(pipeline) end @@ -149,8 +149,8 @@ describe Ci::RetryPipelineService, '#execute', :services do context 'when user is not allowed to retry pipeline' do it 'raises an error' do - expect { service.execute(pipeline) }. - to raise_error Gitlab::Access::AccessDeniedError + expect { service.execute(pipeline) } + .to raise_error Gitlab::Access::AccessDeniedError end end diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb index 23e0856fecd..560f83d94f7 100644 --- a/spec/services/ci/stop_environments_service_spec.rb +++ b/spec/services/ci/stop_environments_service_spec.rb @@ -44,8 +44,8 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment is not stopped' do before do - allow_any_instance_of(Environment). - to receive(:state).and_return(:stopped) + allow_any_instance_of(Environment) + .to receive(:state).and_return(:stopped) end it 'does not stop environment' do @@ -83,22 +83,22 @@ describe Ci::StopEnvironmentsService, services: true do context 'when environment does not exist' do it 'does not raise error' do - expect { service.execute('master') }. - not_to raise_error + expect { service.execute('master') } + .not_to raise_error end end end def expect_environment_stopped_on(branch) - expect_any_instance_of(Environment). - to receive(:stop!) + expect_any_instance_of(Environment) + .to receive(:stop!) service.execute(branch) end def expect_environment_not_stopped_on(branch) - expect_any_instance_of(Environment). - not_to receive(:stop!) + expect_any_instance_of(Environment) + .not_to receive(:stop!) service.execute(branch) end diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb index 14092d9dcca..f01a388b895 100644 --- a/spec/services/ci/update_build_queue_service_spec.rb +++ b/spec/services/ci/update_build_queue_service_spec.rb @@ -12,15 +12,15 @@ describe Ci::UpdateBuildQueueService, :services do before { build.project.runners << runner } it 'ticks runner queue value' do - expect { subject.execute(build) }. - to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .to change { runner.ensure_runner_queue_value } end end context 'when there are no runners that can pick build' do it 'does not tick runner queue value' do - expect { subject.execute(build) }. - not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .not_to change { runner.ensure_runner_queue_value } end end end @@ -30,8 +30,8 @@ describe Ci::UpdateBuildQueueService, :services do context 'when there are runner that can pick build' do it 'ticks runner queue value' do - expect { subject.execute(build) }. - to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .to change { runner.ensure_runner_queue_value } end end @@ -39,8 +39,8 @@ describe Ci::UpdateBuildQueueService, :services do before { build.tag_list = [:docker] } it 'does not tick runner queue value' do - expect { subject.execute(build) }. - not_to change { runner.ensure_runner_queue_value } + expect { subject.execute(build) } + .not_to change { runner.ensure_runner_queue_value } end end end diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb index 87da8581e68..0475f38fe5e 100644 --- a/spec/services/issuable/bulk_update_service_spec.rb +++ b/spec/services/issuable/bulk_update_service_spec.rb @@ -5,8 +5,8 @@ describe Issuable::BulkUpdateService, services: true do let(:project) { create(:empty_project, namespace: user.namespace) } def bulk_update(issues, extra_params = {}) - bulk_update_params = extra_params. - reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) + bulk_update_params = extra_params + .reverse_merge(issuable_ids: Array(issues).map(&:id).join(',')) Issuable::BulkUpdateService.new(project, user, bulk_update_params).execute('issue') end @@ -65,22 +65,22 @@ describe Issuable::BulkUpdateService, services: true do assignee = create(:user) project.team << [assignee, :developer] - expect { bulk_update(issue, assignee_id: assignee.id) }. - to change { issue.reload.assignee }.from(user).to(assignee) + expect { bulk_update(issue, assignee_id: assignee.id) } + .to change { issue.reload.assignee }.from(user).to(assignee) end end context "when the new assignee ID is #{IssuableFinder::NONE}" do it "unassigns the issues" do - expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) }. - to change { issue.reload.assignee }.to(nil) + expect { bulk_update(issue, assignee_id: IssuableFinder::NONE) } + .to change { issue.reload.assignee }.to(nil) end end context 'when the new assignee ID is not present' do it 'does not unassign' do - expect { bulk_update(issue, assignee_id: nil) }. - not_to change { issue.reload.assignee } + expect { bulk_update(issue, assignee_id: nil) } + .not_to change { issue.reload.assignee } end end end @@ -97,8 +97,8 @@ describe Issuable::BulkUpdateService, services: true do end it 'updates the issue milestone' do - expect { bulk_update(issue, milestone_id: milestone.id) }. - to change { issue.reload.milestone }.from(nil).to(milestone) + expect { bulk_update(issue, milestone_id: milestone.id) } + .to change { issue.reload.milestone }.from(nil).to(milestone) end end diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index 59c0fa50994..db196ed5751 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -188,8 +188,8 @@ describe Issues::MoveService, services: true do let(:new_note) { new_issue.notes.first } it 'rewrites references using a cross reference to old project' do - expect(new_note.note). - to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" + expect(new_note.note) + .to eq "Note with reference to merge request #{old_project.to_reference(new_project)}!1" end end @@ -201,8 +201,8 @@ describe Issues::MoveService, services: true do it 'rewrites uploads in description' do expect(new_issue.description).not_to eq description - expect(new_issue.description). - to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) + expect(new_issue.description) + .to match(/Text and #{FileUploader::MARKDOWN_PATTERN}/) expect(new_issue.description).not_to include uploader.secret end end @@ -216,8 +216,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{another_issue.to_reference}" } it 'rewrites referenced issues creating cross project reference' do - expect(new_issue.description). - to eq "Some description #{another_issue.to_reference(new_project)}" + expect(new_issue.description) + .to eq "Some description #{another_issue.to_reference(new_project)}" end end @@ -226,8 +226,8 @@ describe Issues::MoveService, services: true do let(:description) { "Some description #{user.to_reference}" } it "doesn't throw any errors for issues containing user references" do - expect(new_issue.description). - to eq "Some description #{user.to_reference}" + expect(new_issue.description) + .to eq "Some description #{user.to_reference}" end end end @@ -236,8 +236,8 @@ describe Issues::MoveService, services: true do let(:new_project) { old_project } it 'raises error' do - expect { move_service.execute(old_issue, new_project) }. - to raise_error(StandardError, /Cannot move issue/) + expect { move_service.execute(old_issue, new_project) } + .to raise_error(StandardError, /Cannot move issue/) end end end diff --git a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb index 881458c190f..d80fb8a1af1 100644 --- a/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb +++ b/spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb @@ -29,9 +29,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do end before do - allow_any_instance_of(MergeRequest). - to receive(:head_pipeline). - and_return(pipeline) + allow_any_instance_of(MergeRequest) + .to receive(:head_pipeline) + .and_return(pipeline) allow(service).to receive(:todo_service).and_return(todo_service) end @@ -113,9 +113,9 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'resolves todos about failed builds for pipeline' do service.close_all(pipeline) - expect(todo_service). - to have_received(:merge_request_build_retried). - with(merge_request) + expect(todo_service) + .to have_received(:merge_request_build_retried) + .with(merge_request) end end @@ -125,8 +125,8 @@ describe MergeRequests::AddTodoWhenBuildFailsService do it 'does not resolve any todos about failed builds' do service.close_all(pipeline) - expect(todo_service). - not_to have_received(:merge_request_build_retried) + expect(todo_service) + .not_to have_received(:merge_request_build_retried) end end end diff --git a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb index 65c08ce15f7..f92978a33a3 100644 --- a/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_pipeline_succeeds_service_spec.rb @@ -27,9 +27,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do context 'first time enabling' do before do - allow(merge_request). - to receive(:head_pipeline). - and_return(pipeline) + allow(merge_request) + .to receive(:head_pipeline) + .and_return(pipeline) service.execute(merge_request) end @@ -52,11 +52,11 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) } before do - allow(mr_merge_if_green_enabled).to receive(:head_pipeline). - and_return(pipeline) + allow(mr_merge_if_green_enabled).to receive(:head_pipeline) + .and_return(pipeline) - allow(mr_merge_if_green_enabled).to receive(:mergeable?). - and_return(true) + allow(mr_merge_if_green_enabled).to receive(:mergeable?) + .and_return(true) allow(pipeline).to receive(:success?).and_return(true) end @@ -152,9 +152,9 @@ describe MergeRequests::MergeWhenPipelineSucceedsService do before do # This behavior of MergeRequest: we instantiate a new object # - allow_any_instance_of(MergeRequest). - to receive(:head_pipeline). - and_wrap_original do + allow_any_instance_of(MergeRequest) + .to receive(:head_pipeline) + .and_wrap_original do Ci::Pipeline.find(pipeline.id) end end diff --git a/spec/services/merge_requests/resolve_service_spec.rb b/spec/services/merge_requests/resolve_service_spec.rb index 57b1c088ce4..c3b468ac47f 100644 --- a/spec/services/merge_requests/resolve_service_spec.rb +++ b/spec/services/merge_requests/resolve_service_spec.rb @@ -60,7 +60,7 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request.source_branch_head.parents.map(&:id)). to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 - 824be604a34828eb682305f0d963056cfac87b2d)) + 824be604a34828eb682305f0d963056cfac87b2d)) end end @@ -86,7 +86,7 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request_from_fork.source_branch_head.parents.map(&:id)). to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', - target_head]) + target_head]) end end end @@ -126,7 +126,7 @@ describe MergeRequests::ResolveService do it 'creates a commit with the correct parents' do expect(merge_request.source_branch_head.parents.map(&:id)). to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06 - 824be604a34828eb682305f0d963056cfac87b2d)) + 824be604a34828eb682305f0d963056cfac87b2d)) end it 'sets the content to the content given' do diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 6dfcb702510..9f24cc0f3f2 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -768,15 +768,15 @@ describe TodoService, services: true do create(:todo, :mentioned, user: john_doe, target: issue, project: project) todos = TodosFinder.new(john_doe, {}).execute - expect { TodoService.new.mark_todos_as_done(todos, john_doe) }. - to change { john_doe.todos.done.count }.from(0).to(1) + expect { TodoService.new.mark_todos_as_done(todos, john_doe) } + .to change { john_doe.todos.done.count }.from(0).to(1) end it 'marks an array of todos as done' do todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project) - expect { TodoService.new.mark_todos_as_done([todo], john_doe) }. - to change { todo.reload.state }.from('pending').to('done') + expect { TodoService.new.mark_todos_as_done([todo], john_doe) } + .to change { todo.reload.state }.from('pending').to('done') end it 'returns the number of updated todos' do # Needed on API diff --git a/spec/support/ldap_helpers.rb b/spec/support/ldap_helpers.rb index ab635711cf7..079f244475c 100644 --- a/spec/support/ldap_helpers.rb +++ b/spec/support/ldap_helpers.rb @@ -16,8 +16,8 @@ module LdapHelpers # ) def stub_ldap_config(messages) messages.each do |config, value| - allow_any_instance_of(::Gitlab::LDAP::Config). - to receive(config.to_sym).and_return(value) + allow_any_instance_of(::Gitlab::LDAP::Config) + .to receive(config.to_sym).and_return(value) end end @@ -32,8 +32,8 @@ module LdapHelpers def stub_ldap_person_find_by_uid(uid, entry, provider = 'ldapmain') return_value = ::Gitlab::LDAP::Person.new(entry, provider) if entry.present? - allow(::Gitlab::LDAP::Person). - to receive(:find_by_uid).with(uid, any_args).and_return(return_value) + allow(::Gitlab::LDAP::Person) + .to receive(:find_by_uid).with(uid, any_args).and_return(return_value) end # Create a simple LDAP user entry. diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 07602c0cb40..a01ef576234 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -53,7 +53,7 @@ module StubGitlabCalls stub_request(:post, "#{gitlab_url}api/v3/session.json"). with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}", - headers: { 'Content-Type' => 'application/json' }). + headers: { 'Content-Type' => 'application/json' }). to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' }) end diff --git a/spec/tasks/gitlab/check_rake_spec.rb b/spec/tasks/gitlab/check_rake_spec.rb index a808ef7dcc0..538ff952bf4 100644 --- a/spec/tasks/gitlab/check_rake_spec.rb +++ b/spec/tasks/gitlab/check_rake_spec.rb @@ -23,8 +23,8 @@ describe 'gitlab:ldap:check rake task' do let(:adapter) { ldap_adapter('ldapmain', ldap) } before do - allow(Gitlab::LDAP::Config). - to receive_messages( + allow(Gitlab::LDAP::Config) + .to receive_messages( enabled?: true, providers: ['ldapmain'] ) diff --git a/spec/tasks/gitlab/shell_rake_spec.rb b/spec/tasks/gitlab/shell_rake_spec.rb index 0787894ad2c..226d34fe2c9 100644 --- a/spec/tasks/gitlab/shell_rake_spec.rb +++ b/spec/tasks/gitlab/shell_rake_spec.rb @@ -17,8 +17,8 @@ describe 'gitlab:shell rake tasks' do describe 'create_hooks task' do it 'calls gitlab-shell bin/create_hooks' do - expect_any_instance_of(Object).to receive(:system). - with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) + expect_any_instance_of(Object).to receive(:system) + .with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args) run_rake_task('gitlab:shell:create_hooks') end diff --git a/spec/views/layouts/_head.html.haml_spec.rb b/spec/views/layouts/_head.html.haml_spec.rb index 254672a5612..8020faa1f9c 100644 --- a/spec/views/layouts/_head.html.haml_spec.rb +++ b/spec/views/layouts/_head.html.haml_spec.rb @@ -26,7 +26,7 @@ describe 'layouts/_head' do end def stub_helper_with_safe_string(method) - allow_any_instance_of(PageLayoutHelper).to receive(method). - and_return(%q{foo" http-equiv="refresh}.html_safe) + allow_any_instance_of(PageLayoutHelper).to receive(method) + .and_return(%q{foo" http-equiv="refresh}.html_safe) end end diff --git a/spec/views/projects/merge_requests/edit.html.haml_spec.rb b/spec/views/projects/merge_requests/edit.html.haml_spec.rb index 2e4390d6797..3650b22c389 100644 --- a/spec/views/projects/merge_requests/edit.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/edit.html.haml_spec.rb @@ -23,8 +23,8 @@ describe 'projects/merge_requests/edit.html.haml' do assign(:merge_request, closed_merge_request) allow(view).to receive(:can?).and_return(true) - allow(view).to receive(:current_user). - and_return(User.find(closed_merge_request.author_id)) + allow(view).to receive(:current_user) + .and_return(User.find(closed_merge_request.author_id)) end context 'when a merge request without fork' do diff --git a/spec/workers/build_coverage_worker_spec.rb b/spec/workers/build_coverage_worker_spec.rb index 8ebf00374a1..ba20488f663 100644 --- a/spec/workers/build_coverage_worker_spec.rb +++ b/spec/workers/build_coverage_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildCoverageWorker do let!(:build) { create(:ci_build) } it 'updates code coverage' do - expect_any_instance_of(Ci::Build). - to receive(:update_coverage) + expect_any_instance_of(Ci::Build) + .to receive(:update_coverage) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildCoverageWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index f8119913116..2868167c7d4 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -6,15 +6,15 @@ describe BuildFinishedWorker do let(:build) { create(:ci_build) } it 'calculates coverage and calls hooks' do - expect(BuildCoverageWorker). - to receive(:new).ordered.and_call_original - expect(BuildHooksWorker). - to receive(:new).ordered.and_call_original + expect(BuildCoverageWorker) + .to receive(:new).ordered.and_call_original + expect(BuildHooksWorker) + .to receive(:new).ordered.and_call_original - expect_any_instance_of(BuildCoverageWorker). - to receive(:perform) - expect_any_instance_of(BuildHooksWorker). - to receive(:perform) + expect_any_instance_of(BuildCoverageWorker) + .to receive(:perform) + expect_any_instance_of(BuildHooksWorker) + .to receive(:perform) described_class.new.perform(build.id) end @@ -22,8 +22,8 @@ describe BuildFinishedWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/build_hooks_worker_spec.rb b/spec/workers/build_hooks_worker_spec.rb index 51abc1d89a1..97654a93f5c 100644 --- a/spec/workers/build_hooks_worker_spec.rb +++ b/spec/workers/build_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe BuildHooksWorker do let!(:build) { create(:ci_build) } it 'calls build hooks' do - expect_any_instance_of(Ci::Build). - to receive(:execute_hooks) + expect_any_instance_of(Ci::Build) + .to receive(:execute_hooks) described_class.new.perform(build.id) end @@ -15,8 +15,8 @@ describe BuildHooksWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/build_success_worker_spec.rb b/spec/workers/build_success_worker_spec.rb index d016ecbb738..dba70883130 100644 --- a/spec/workers/build_success_worker_spec.rb +++ b/spec/workers/build_success_worker_spec.rb @@ -7,8 +7,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, environment: 'production') } it 'executes deployment service' do - expect_any_instance_of(CreateDeploymentService). - to receive(:execute) + expect_any_instance_of(CreateDeploymentService) + .to receive(:execute) described_class.new.perform(build.id) end @@ -18,8 +18,8 @@ describe BuildSuccessWorker do let!(:build) { create(:ci_build, project: nil) } it 'does not create deployment' do - expect_any_instance_of(CreateDeploymentService). - not_to receive(:execute) + expect_any_instance_of(CreateDeploymentService) + .not_to receive(:execute) described_class.new.perform(build.id) end @@ -28,8 +28,8 @@ describe BuildSuccessWorker do context 'when build does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_hooks_worker_spec.rb b/spec/workers/pipeline_hooks_worker_spec.rb index 061f4bda36c..035e329839f 100644 --- a/spec/workers/pipeline_hooks_worker_spec.rb +++ b/spec/workers/pipeline_hooks_worker_spec.rb @@ -6,8 +6,8 @@ describe PipelineHooksWorker do let(:pipeline) { create(:ci_pipeline) } it 'executes hooks for the pipeline' do - expect_any_instance_of(Ci::Pipeline). - to receive(:execute_hooks) + expect_any_instance_of(Ci::Pipeline) + .to receive(:execute_hooks) described_class.new.perform(pipeline.id) end @@ -15,8 +15,8 @@ describe PipelineHooksWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_proccess_worker_spec.rb b/spec/workers/pipeline_proccess_worker_spec.rb index fd6ee0714ea..86e9d7f6684 100644 --- a/spec/workers/pipeline_proccess_worker_spec.rb +++ b/spec/workers/pipeline_proccess_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineProcessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_success_worker_spec.rb b/spec/workers/pipeline_success_worker_spec.rb index f6c56465feb..d1c84adda6f 100644 --- a/spec/workers/pipeline_success_worker_spec.rb +++ b/spec/workers/pipeline_success_worker_spec.rb @@ -16,8 +16,8 @@ describe PipelineSuccessWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/pipeline_update_worker_spec.rb b/spec/workers/pipeline_update_worker_spec.rb index 24d78aae112..0b456cfd0da 100644 --- a/spec/workers/pipeline_update_worker_spec.rb +++ b/spec/workers/pipeline_update_worker_spec.rb @@ -14,8 +14,8 @@ describe PipelineUpdateWorker do context 'when pipeline does not exist' do it 'does not raise exception' do - expect { described_class.new.perform(123) }. - not_to raise_error + expect { described_class.new.perform(123) } + .not_to raise_error end end end diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb index 0fc274f1a01..f4f63b57a5f 100644 --- a/spec/workers/project_cache_worker_spec.rb +++ b/spec/workers/project_cache_worker_spec.rb @@ -31,9 +31,9 @@ describe ProjectCacheWorker do context 'with an existing project' do it 'updates the project statistics' do - expect(worker).to receive(:update_statistics). - with(kind_of(Project), %i(repository_size)). - and_call_original + expect(worker).to receive(:update_statistics) + .with(kind_of(Project), %i(repository_size)) + .and_call_original worker.perform(project.id, [], %w(repository_size)) end @@ -67,9 +67,9 @@ describe ProjectCacheWorker do with(project.id, :update_statistics). and_return(true) - expect(statistics).to receive(:refresh!). - with(only: %i(repository_size)). - and_call_original + expect(statistics).to receive(:refresh!) + .with(only: %i(repository_size)) + .and_call_original worker.update_statistics(project, %i(repository_size)) end diff --git a/spec/workers/use_key_worker_spec.rb b/spec/workers/use_key_worker_spec.rb index f8752c42a49..e50c788b82a 100644 --- a/spec/workers/use_key_worker_spec.rb +++ b/spec/workers/use_key_worker_spec.rb @@ -8,8 +8,8 @@ describe UseKeyWorker do current_time = Time.zone.now Timecop.freeze(current_time) do - expect { worker.perform(key.id) }. - to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) + expect { worker.perform(key.id) } + .to change { key.reload.last_used_at }.from(nil).to be_like_time(current_time) end end From 6f5cd03fcb63b379d218cf0b475f85f675dd9fb6 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 22 Feb 2017 17:07:29 -0600 Subject: [PATCH 244/247] Fix OAuth/SAML user blocking behavior --- lib/gitlab/o_auth/user.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 87af76cc122..95d2f559588 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -29,9 +29,11 @@ module Gitlab def save(provider = 'OAuth') unauthorized_to_create unless gl_user + block_after_save = needs_blocking? + gl_user.save! - gl_user.block if needs_blocking? + gl_user.block if block_after_save log.info "(#{provider}) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}" gl_user From f88ff0cc0c5c1db7089a5f0062a53d38eb27ebde Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 23 Feb 2017 09:27:36 -0600 Subject: [PATCH 245/247] Stylistic tweaks --- lib/extracts_path.rb | 2 +- lib/gitlab/ci/build/artifacts/metadata/entry.rb | 4 ++-- lib/gitlab/git/repository.rb | 8 ++++---- lib/gitlab/redis.rb | 7 +------ lib/tasks/gemojione.rake | 6 +++--- lib/tasks/gitlab/task_helpers.rb | 15 ++++++++++----- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index 1a6ad039bc0..9ece84cc469 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -42,7 +42,7 @@ module ExtractsPath return pair unless @project - if id =~ /^([[:alnum:]]{40})(.+)/ + if id =~ /^(\h{40})(.+)/ # If the ref appears to be a SHA, we're done, just split the string pair = $~.captures else diff --git a/lib/gitlab/ci/build/artifacts/metadata/entry.rb b/lib/gitlab/ci/build/artifacts/metadata/entry.rb index c1d4d541efb..6f799c2f031 100644 --- a/lib/gitlab/ci/build/artifacts/metadata/entry.rb +++ b/lib/gitlab/ci/build/artifacts/metadata/entry.rb @@ -27,6 +27,8 @@ module Gitlab end end + delegate :empty?, to: :children + def directory? blank_node? || @path.end_with?('/') end @@ -91,8 +93,6 @@ module Gitlab blank_node? || @entries.include?(@path) end - delegate :empty?, to: :children - def total_size descendant_pattern = %r{^#{Regexp.escape(@path)}} entries.sum do |path, entry| diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index d1dd3da5ed2..4b6ad8037ce 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -31,6 +31,10 @@ module Gitlab @attributes = Gitlab::Git::Attributes.new(path) end + delegate :empty?, + :bare?, + to: :rugged + # Default branch in the repository def root_ref @root_ref ||= discover_default_branch @@ -160,10 +164,6 @@ module Gitlab !empty? end - delegate :empty?, - :bare?, - to: :rugged - def repo_exists? !!rugged end diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb index e9c07095042..62dbd429156 100644 --- a/lib/gitlab/redis.rb +++ b/lib/gitlab/redis.rb @@ -12,12 +12,7 @@ module Gitlab CONFIG_FILE = File.expand_path('../../config/resque.yml', __dir__) class << self - # Do NOT cache in an instance variable. Result may be mutated by caller. - delegate :params, to: :new - - # Do NOT cache in an instance variable. Result may be mutated by caller. - # @deprecated Use .params instead to get sentinel support - delegate :url, to: :new + delegate :params, :url, to: :new def with @pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) } diff --git a/lib/tasks/gemojione.rake b/lib/tasks/gemojione.rake index f5ff29415e8..993112aee3b 100644 --- a/lib/tasks/gemojione.rake +++ b/lib/tasks/gemojione.rake @@ -81,9 +81,9 @@ namespace :gemojione do # SpriteFactory's SCSS is a bit too verbose for our purposes here, so # let's simplify it - system(%(sed -i '' "s/width: #{SIZE}px; height: #{SIZE}px; background: image-url('emoji.png')/background-position:/" #{style_path})) - system(%(sed -i '' "s/ no-repeat//" #{style_path})) - system(%(sed -i '' "s/ 0px/ 0/" #{style_path})) + system(%Q(sed -i '' "s/width: #{SIZE}px; height: #{SIZE}px; background: image-url('emoji.png')/background-position:/" #{style_path})) + system(%Q(sed -i '' "s/ no-repeat//" #{style_path})) + system(%Q(sed -i '' "s/ 0px/ 0/" #{style_path})) # Append a generic rule that applies to all Emojis File.open(style_path, 'a') do |f| diff --git a/lib/tasks/gitlab/task_helpers.rb b/lib/tasks/gitlab/task_helpers.rb index e5de3e22165..2a999ad6959 100644 --- a/lib/tasks/gitlab/task_helpers.rb +++ b/lib/tasks/gitlab/task_helpers.rb @@ -20,14 +20,19 @@ module Gitlab # It has fallbacks to Debian, SuSE, OS X and systems running systemd. def os_name os_name = run_command(%w(lsb_release -irs)) - os_name ||= File.read('/etc/system-release') if File.readable?('/etc/system-release') - os_name ||= "Debian #{File.read('/etc/debian_version')}" if File.readable?('/etc/debian_version') - os_name ||= File.read('/etc/SuSE-release') if File.readable?('/etc/SuSE-release') os_name ||= - if os_x_version = run_command(%w(sw_vers -productVersion)) + if File.readable?('/etc/system-release') + File.read('/etc/system-release') + elsif File.readable?('/etc/debian_version') + "Debian #{File.read('/etc/debian_version')}" + elsif File.readable?('/etc/SuSE-release') + File.read('/etc/SuSE-release') + elsif os_x_version = run_command(%w(sw_vers -productVersion)) "Mac OS X #{os_x_version}" + elsif File.readable?('/etc/os-release') + File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1] end - os_name ||= File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1] if File.readable?('/etc/os-release') + os_name.try(:squish!) end From ade5e0b1ba04047c72cb0aff3d635a2cdaaab43c Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Thu, 23 Feb 2017 09:44:37 -0600 Subject: [PATCH 246/247] Fix new offenses --- app/controllers/projects/pipelines_controller.rb | 8 ++++---- lib/api/v3/notes.rb | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index e436c6666c3..8657bc4dfdc 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -13,16 +13,16 @@ class Projects::PipelinesController < Projects::ApplicationController .page(params[:page]) .per(30) - @running_count = PipelinesFinder. + @running_count = PipelinesFinder .new(project).execute(scope: 'running').count - @pending_count = PipelinesFinder. + @pending_count = PipelinesFinder .new(project).execute(scope: 'pending').count - @finished_count = PipelinesFinder. + @finished_count = PipelinesFinder .new(project).execute(scope: 'finished').count - @pipelines_count = PipelinesFinder. + @pipelines_count = PipelinesFinder .new(project).execute.count respond_to do |format| diff --git a/lib/api/v3/notes.rb b/lib/api/v3/notes.rb index 6531598d590..0796bb62e68 100644 --- a/lib/api/v3/notes.rb +++ b/lib/api/v3/notes.rb @@ -5,7 +5,7 @@ module API before { authenticate! } - NOTEABLE_TYPES = [Issue, MergeRequest, Snippet] + NOTEABLE_TYPES = [Issue, MergeRequest, Snippet].freeze params do requires :id, type: String, desc: 'The ID of a project' @@ -85,7 +85,7 @@ module API note = ::Notes::CreateService.new(user_project, current_user, opts).execute if note.valid? - present note, with: ::API::V3::Entities::const_get(note.class.name) + present note, with: ::API::V3::Entities.const_get(note.class.name) else not_found!("Note #{note.errors.messages}") end From 8a619408cfa042d2cea84ef67f6b26e9ca1f912a Mon Sep 17 00:00:00 2001 From: James Edwards-Jones Date: Thu, 23 Feb 2017 17:59:38 +0000 Subject: [PATCH 247/247] Switched CONTRIBUTING.md style guide recommendation for method chaining --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de32a953f63..eed63127d9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -426,7 +426,7 @@ merge request: 1. [Ruby](https://github.com/bbatsov/ruby-style-guide). Important sections include [Source Code Layout][rss-source] and [Naming][rss-naming]. Use: - - multi-line method chaining style **Option B**: dot `.` on previous line + - multi-line method chaining style **Option A**: dot `.` on the second line - string literal quoting style **Option A**: single quoted by default 1. [Rails](https://github.com/bbatsov/rails-style-guide) 1. [Newlines styleguide][newlines-styleguide]