From f9eb3fc0aa3c99fd36d3f344dc95f6b4edad5e07 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 7 Mar 2016 18:26:15 +0100 Subject: [PATCH 001/714] WIP - initial export service and spec --- app/services/projects/import_export.rb | 23 +++++ .../projects/import_export/export_service.rb | 15 ++++ .../import_export/project_tree_saver.rb | 42 ++++++++++ .../import_export/project_tree_saver_spec.rb | 83 +++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 app/services/projects/import_export.rb create mode 100644 app/services/projects/import_export/export_service.rb create mode 100644 app/services/projects/import_export/project_tree_saver.rb create mode 100644 spec/services/projects/import_export/project_tree_saver_spec.rb diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb new file mode 100644 index 00000000000000..f87b10390a5af2 --- /dev/null +++ b/app/services/projects/import_export.rb @@ -0,0 +1,23 @@ +module Projects + module ImportExport + extend self + + def export_path(project_name:) + File.join(storage_path, "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_gitlab_export_#{project_name}") + end + + def project_atts + %i(id name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) + end + + def project_tree + %i(issues merge_requests labels milestones snippets releases events commit_statuses) + end + + private + + def storage_path + File.join(Settings.shared['path'], 'tmp/project_exports') + end + end +end diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb new file mode 100644 index 00000000000000..c89dd3d12edbd9 --- /dev/null +++ b/app/services/projects/import_export/export_service.rb @@ -0,0 +1,15 @@ +module Projects + module ImportExport + class ExportService < BaseService + def execute(options = {}) + save_project_tree + end + + private + + def save_project_tree + Projects::ImportExport::ProjectTreeSaver.save(project: project) + end + end + end +end diff --git a/app/services/projects/import_export/project_tree_saver.rb b/app/services/projects/import_export/project_tree_saver.rb new file mode 100644 index 00000000000000..4801c791ffecbb --- /dev/null +++ b/app/services/projects/import_export/project_tree_saver.rb @@ -0,0 +1,42 @@ +module Projects + module ImportExport + class ProjectTreeSaver + attr_reader :full_path + + def initialize(project: ) + @project = project + end + + def save + @full_path = File.join(export_path, project_filename) + save_to_disk + end + + private + + def save_to_disk + FileUtils.mkdir_p(export_path) + File.write(full_path, project_json_tree) + true + rescue + #TODO: handle error + false + end + + def export_path + @export_path ||= ImportExport.export_path(@project.name) + end + + def project_filename + # TODO sanitize name + "#{@project.name}.json" + end + + def project_json_tree + # TODO confirm children, also add subchildren (i.e comments) + # TODO confirm atts for children + @project.to_json(only: ImportExport.project_atts, include: ImportExport.project_tree) + end + end + end +end diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb new file mode 100644 index 00000000000000..00e44a9f33529e --- /dev/null +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' + +describe Projects::ImportExport::ProjectTreeSaver, services: true do + describe :save do + + let(:user) { create(:user) } + let!(:project) { create(:project, :public, name: 'searchable_project') } + let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project) } + + before(:each) do + project.team << [user, :master] + allow_any_instance_of(Projects::ImportExport::ProjectTreeSaver).to receive(:export_path).and_return(export_path) + end + + after(:each) do + FileUtils.rm_rf(export_path) + end + + it 'saves project successfully' do + expect(project_tree_saver.save).to be true + end + + it 'saves the correct json' do + project_tree_saver.save + expect(project_json(project_tree_saver.full_path)).to include({ "name" => project.name }) + end + end + + def project_json(filename) + JSON.parse(IO.read(filename)) + end + + # TODO: Remove this. Current JSON pretty printed: + # { + # "id": 1, + # "name": "searchable_project", + # "path": "gitlabhq", + # "description": null, + # "issues_enabled": true, + # "wall_enabled": false, + # "merge_requests_enabled": true, + # "wiki_enabled": true, + # "snippets_enabled": true, + # "visibility_level": 20, + # "archived": false, + # "issues": [ + # + # ], + # "merge_requests": [ + # + # ], + # "labels": [ + # + # ], + # "milestones": [ + # + # ], + # "snippets": [ + # + # ], + # "releases": [ + # + # ], + # "events": [ + # { + # "id": 1, + # "target_type": null, + # "target_id": null, + # "title": null, + # "data": null, + # "project_id": 1, + # "created_at": "2016-03-07T17:05:20.926Z", + # "updated_at": "2016-03-07T17:05:20.926Z", + # "action": 8, + # "author_id": 3 + # } + # ], + # "commit_statuses": [ + # + # ] + # } +end -- GitLab From e228453f47a98c1da51878fb9feeff8ae9ddd7a9 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 7 Mar 2016 19:14:06 +0100 Subject: [PATCH 002/714] updated spec --- .../import_export/project_tree_saver_spec.rb | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 00e44a9f33529e..b9768441bae6e7 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -4,7 +4,8 @@ describe :save do let(:user) { create(:user) } - let!(:project) { create(:project, :public, name: 'searchable_project') } + let(:issue) { create(:issue, assignee: user) } + let!(:project) { create(:project, :public, name: 'searchable_project', issues: [issue] )} let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project) } @@ -21,9 +22,24 @@ expect(project_tree_saver.save).to be true end - it 'saves the correct json' do - project_tree_saver.save - expect(project_json(project_tree_saver.full_path)).to include({ "name" => project.name }) + context 'JSON' do + + let(:saved_project_json) do + project_tree_saver.save + project_json(project_tree_saver.full_path) + end + + it 'saves the correct json' do + expect(saved_project_json).to include({ "name" => project.name }) + end + + it 'has events' do + expect(saved_project_json['events']).not_to be_empty + end + + it 'has issues' do + expect(saved_project_json['issues']).not_to be_empty + end end end -- GitLab From 68eae04538f296a15863235d7f1f59f3e9e8a1dd Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 8 Mar 2016 10:21:02 +0100 Subject: [PATCH 003/714] finish project tree saver spec --- .../import_export/project_tree_saver_spec.rb | 221 +++++++++++++++--- 1 file changed, 185 insertions(+), 36 deletions(-) diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index b9768441bae6e7..42302ffee8fb21 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -5,7 +5,23 @@ let(:user) { create(:user) } let(:issue) { create(:issue, assignee: user) } - let!(:project) { create(:project, :public, name: 'searchable_project', issues: [issue] )} + let(:merge_request) { create(:merge_request) } + let(:label) { create(:label) } + let(:snippet) { create(:project_snippet) } + let(:commit_status) { create(:commit_status) } + let(:release) { create(:release) } + let!(:project) do + create(:project, + :public, + name: 'searchable_project', + issues: [issue], + merge_requests: [merge_request], + labels: [label], + snippets: [snippet], + releases: [release], + commit_statuses: [commit_status]) + end + let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project) } @@ -37,9 +53,33 @@ expect(saved_project_json['events']).not_to be_empty end + it 'has milestones' do + expect(saved_project_json['milestones']).not_to be_empty + end + + it 'has merge requests' do + expect(saved_project_json['merge_requests']).not_to be_empty + end + + it 'has labels' do + expect(saved_project_json['labels']).not_to be_empty + end + + it 'has snippets' do + expect(saved_project_json['snippets']).not_to be_empty + end + + it 'has releases' do + expect(saved_project_json['releases']).not_to be_empty + end + it 'has issues' do expect(saved_project_json['issues']).not_to be_empty end + + it 'has commit statuses' do + expect(saved_project_json['commit_statuses']).not_to be_empty + end end end @@ -49,51 +89,160 @@ def project_json(filename) # TODO: Remove this. Current JSON pretty printed: # { - # "id": 1, - # "name": "searchable_project", - # "path": "gitlabhq", - # "description": null, - # "issues_enabled": true, - # "wall_enabled": false, - # "merge_requests_enabled": true, - # "wiki_enabled": true, - # "snippets_enabled": true, - # "visibility_level": 20, - # "archived": false, - # "issues": [ - # + # "id":7, + # "name":"searchable_project", + # "path":"gitlabhq", + # "description":null, + # "issues_enabled":true, + # "wall_enabled":false, + # "merge_requests_enabled":true, + # "wiki_enabled":true, + # "snippets_enabled":true, + # "visibility_level":20, + # "archived":false, + # "issues":[ + # { + # "id":1, + # "title":"Voluptas dolores molestias iste excepturi quia atque sint et.", + # "assignee_id":1, + # "author_id":2, + # "project_id":7, + # "created_at":"2016-03-08T09:14:31.726Z", + # "updated_at":"2016-03-08T09:14:36.293Z", + # "position":0, + # "branch_name":null, + # "description":null, + # "milestone_id":null, + # "state":"opened", + # "iid":1, + # "updated_by_id":null + # } # ], - # "merge_requests": [ + # "merge_requests":[ + # { + # "id":1, + # "target_branch":"feature", + # "source_branch":"master", + # "source_project_id":2, + # "author_id":5, + # "assignee_id":null, + # "title":"Quam velit cupiditate culpa perspiciatis esse maiores quaerat.", + # "created_at":"2016-03-08T09:14:32.597Z", + # "updated_at":"2016-03-08T09:14:32.597Z", + # "milestone_id":null, + # "state":"opened", + # "merge_status":"can_be_merged", + # "target_project_id":7, + # "iid":1, + # "description":null, + # "position":0, + # "locked_at":null, + # "updated_by_id":null, + # "merge_error":null, + # "merge_params":{ # + # }, + # "merge_when_build_succeeds":false, + # "merge_user_id":null, + # "merge_commit_sha":null + # } # ], - # "labels": [ - # + # "labels":[ + # { + # "id":1, + # "title":"Bug", + # "color":"#990000", + # "project_id":7, + # "created_at":"2016-03-08T09:14:33.774Z", + # "updated_at":"2016-03-08T09:14:36.314Z", + # "template":false, + # "description":null + # } # ], - # "milestones": [ - # + # "milestones":[ + # { + # "id":1, + # "title":"Milestone v1.2", + # "project_id":7, + # "description":null, + # "due_date":null, + # "created_at":"2016-03-08T09:14:36.526Z", + # "updated_at":"2016-03-08T09:14:36.526Z", + # "state":"active", + # "iid":1 + # } # ], - # "snippets": [ - # + # "snippets":[ + # { + # "id":1, + # "title":"Voluptatem qui officiis modi ut fugit distinctio dolor qui.", + # "content":"Quaerat sunt eligendi voluptatum magnam.", + # "author_id":12, + # "project_id":7, + # "created_at":"2016-03-08T09:14:34.539Z", + # "updated_at":"2016-03-08T09:14:36.332Z", + # "file_name":"rowland.tremblay", + # "expires_at":null, + # "visibility_level":0 + # } # ], - # "releases": [ - # + # "releases":[ + # { + # "id":1, + # "tag":"v1.1.0", + # "description":"Awesome release", + # "project_id":7, + # "created_at":"2016-03-08T09:14:35.023Z", + # "updated_at":"2016-03-08T09:14:36.351Z" + # } # ], - # "events": [ + # "events":[ # { - # "id": 1, - # "target_type": null, - # "target_id": null, - # "title": null, - # "data": null, - # "project_id": 1, - # "created_at": "2016-03-07T17:05:20.926Z", - # "updated_at": "2016-03-07T17:05:20.926Z", - # "action": 8, - # "author_id": 3 + # "id":1, + # "target_type":null, + # "target_id":null, + # "title":null, + # "data":null, + # "project_id":7, + # "created_at":"2016-03-08T09:14:36.806Z", + # "updated_at":"2016-03-08T09:14:36.806Z", + # "action":8, + # "author_id":1 # } # ], - # "commit_statuses": [ - # + # "commit_statuses":[ + # { + # "id":1, + # "project_id":null, + # "status":"success", + # "finished_at":"2016-01-26T07:23:42.000Z", + # "trace":null, + # "created_at":"2016-03-08T09:14:35.633Z", + # "updated_at":"2016-03-08T09:14:36.385Z", + # "started_at":"2016-01-26T07:21:42.000Z", + # "runner_id":null, + # "coverage":null, + # "commit_id":1, + # "commands":null, + # "job_id":null, + # "name":"default", + # "deploy":false, + # "options":null, + # "allow_failure":false, + # "stage":null, + # "trigger_request_id":null, + # "stage_idx":null, + # "tag":null, + # "ref":null, + # "user_id":null, + # "target_url":null, + # "description":"commit status", + # "artifacts_file":null, + # "gl_project_id":7, + # "artifacts_metadata":null, + # "erased_by_id":null, + # "erased_at":null + # } # ] # } end -- GitLab From 4e73f9827cc5b164e409a6beb9a305ef5604423d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 8 Mar 2016 12:35:37 +0100 Subject: [PATCH 004/714] WIP - started working on bundle the repo, refactored some stuff and updated spec --- .../import_export/command_line_util.rb | 11 ++++++ .../projects/import_export/export_service.rb | 8 +++- .../import_export/project_tree_saver.rb | 11 ++---- .../projects/import_export/repo_bundler.rb | 37 +++++++++++++++++++ app/services/projects/import_export/shared.rb | 13 +++++++ .../import_export/project_tree_saver_spec.rb | 3 +- 6 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 app/services/projects/import_export/command_line_util.rb create mode 100644 app/services/projects/import_export/repo_bundler.rb create mode 100644 app/services/projects/import_export/shared.rb diff --git a/app/services/projects/import_export/command_line_util.rb b/app/services/projects/import_export/command_line_util.rb new file mode 100644 index 00000000000000..7b0cc08763b606 --- /dev/null +++ b/app/services/projects/import_export/command_line_util.rb @@ -0,0 +1,11 @@ +module Projects + module ImportExport + module CommandLineUtil + def tar_cf(archive:, dir:) + cmd = %W(tar -cf #{archive} -C #{dir} .) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end + end + end +end diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index c89dd3d12edbd9..b3ad278733a538 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -2,13 +2,19 @@ module Projects module ImportExport class ExportService < BaseService def execute(options = {}) + @shared = Projects::ImportExport::Shared.new(project_name: @project_name) save_project_tree + bundle_repo end private def save_project_tree - Projects::ImportExport::ProjectTreeSaver.save(project: project) + Projects::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared).save + end + + def bundle_repo + Projects::ImportExport::RepoBundler.new(project: project, shared: @shared).bundle end end end diff --git a/app/services/projects/import_export/project_tree_saver.rb b/app/services/projects/import_export/project_tree_saver.rb index 4801c791ffecbb..3ca90d1f79aed9 100644 --- a/app/services/projects/import_export/project_tree_saver.rb +++ b/app/services/projects/import_export/project_tree_saver.rb @@ -3,19 +3,20 @@ module ImportExport class ProjectTreeSaver attr_reader :full_path - def initialize(project: ) + def initialize(project: , shared: ) @project = project + @export_path = shared.export_path end def save - @full_path = File.join(export_path, project_filename) + @full_path = File.join(@export_path, project_filename) save_to_disk end private def save_to_disk - FileUtils.mkdir_p(export_path) + FileUtils.mkdir_p(@export_path) File.write(full_path, project_json_tree) true rescue @@ -23,10 +24,6 @@ def save_to_disk false end - def export_path - @export_path ||= ImportExport.export_path(@project.name) - end - def project_filename # TODO sanitize name "#{@project.name}.json" diff --git a/app/services/projects/import_export/repo_bundler.rb b/app/services/projects/import_export/repo_bundler.rb new file mode 100644 index 00000000000000..27f1d5c87e598e --- /dev/null +++ b/app/services/projects/import_export/repo_bundler.rb @@ -0,0 +1,37 @@ +module Projects + module ImportExport + class RepoBundler + include Projects::ImportExport::CommandLineUtil + + attr_reader :full_path + + def initialize(project: , shared: ) + @project = project + @export_path = shared.export_path + end + + def bundle + return false if project.empty_repo? + @full_path = File.join(export_path, project_filename) + bundle_to_disk + end + + private + + def bundle_to_disk + tar_cf(archive: full_path, dir: path_to_repo) + rescue + #TODO: handle error + false + end + + def project_filename + @project.path_with_namespace + ".bundle" + end + + def path_to_repo + @project.repository.path_to_repo + end + end + end +end diff --git a/app/services/projects/import_export/shared.rb b/app/services/projects/import_export/shared.rb new file mode 100644 index 00000000000000..cdff8b02dd3199 --- /dev/null +++ b/app/services/projects/import_export/shared.rb @@ -0,0 +1,13 @@ +module Projects + module ImportExport + class Shared + def initialize(opts) + @opts = opts + end + + def export_path + @export_path ||= ImportExport.export_path(project_name: @opts[:project_name]) + end + end + end +end \ No newline at end of file diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 42302ffee8fb21..816171ca7e50b4 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -23,7 +23,8 @@ end let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } - let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project) } + let(:shared) { Projects::ImportExport::Shared.new(project_name: @project_name) } + let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) } before(:each) do project.team << [user, :master] -- GitLab From 556cafa44e7baae4de0f4169703d8a6174de458a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 8 Mar 2016 15:53:32 +0100 Subject: [PATCH 005/714] added repo bundler spec and refactored some of the export code --- app/services/projects/import_export.rb | 4 +-- .../projects/import_export/export_service.rb | 2 +- .../projects/import_export/repo_bundler.rb | 7 +++--- app/services/projects/import_export/shared.rb | 2 +- .../import_export/project_tree_saver_spec.rb | 4 +-- .../import_export/repo_bundler_spec.rb | 25 +++++++++++++++++++ 6 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 spec/services/projects/import_export/repo_bundler_spec.rb diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index f87b10390a5af2..2fc0d5dd7fe873 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -2,8 +2,8 @@ module Projects module ImportExport extend self - def export_path(project_name:) - File.join(storage_path, "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_gitlab_export_#{project_name}") + def export_path(relative_path:) + File.join(storage_path, "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_gitlab_export/#{relative_path}") end def project_atts diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index b3ad278733a538..99aa8489f65228 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -2,7 +2,7 @@ module Projects module ImportExport class ExportService < BaseService def execute(options = {}) - @shared = Projects::ImportExport::Shared.new(project_name: @project_name) + @shared = Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) save_project_tree bundle_repo end diff --git a/app/services/projects/import_export/repo_bundler.rb b/app/services/projects/import_export/repo_bundler.rb index 27f1d5c87e598e..b0b2df1c14cd46 100644 --- a/app/services/projects/import_export/repo_bundler.rb +++ b/app/services/projects/import_export/repo_bundler.rb @@ -11,14 +11,15 @@ def initialize(project: , shared: ) end def bundle - return false if project.empty_repo? - @full_path = File.join(export_path, project_filename) + return false if @project.empty_repo? + @full_path = File.join(@export_path, project_filename) bundle_to_disk end private def bundle_to_disk + FileUtils.mkdir_p(@export_path) tar_cf(archive: full_path, dir: path_to_repo) rescue #TODO: handle error @@ -26,7 +27,7 @@ def bundle_to_disk end def project_filename - @project.path_with_namespace + ".bundle" + "#{@project.namespace}#{@project.name}.bundle" end def path_to_repo diff --git a/app/services/projects/import_export/shared.rb b/app/services/projects/import_export/shared.rb index cdff8b02dd3199..5101f514ab2b9d 100644 --- a/app/services/projects/import_export/shared.rb +++ b/app/services/projects/import_export/shared.rb @@ -6,7 +6,7 @@ def initialize(opts) end def export_path - @export_path ||= ImportExport.export_path(project_name: @opts[:project_name]) + @export_path ||= Projects::ImportExport.export_path(relative_path: @opts[:relative_path]) end end end diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 816171ca7e50b4..1b3568bb7a88e1 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -23,12 +23,12 @@ end let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } - let(:shared) { Projects::ImportExport::Shared.new(project_name: @project_name) } + let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) } before(:each) do project.team << [user, :master] - allow_any_instance_of(Projects::ImportExport::ProjectTreeSaver).to receive(:export_path).and_return(export_path) + allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) end after(:each) do diff --git a/spec/services/projects/import_export/repo_bundler_spec.rb b/spec/services/projects/import_export/repo_bundler_spec.rb new file mode 100644 index 00000000000000..1f8ed41718f82f --- /dev/null +++ b/spec/services/projects/import_export/repo_bundler_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Projects::ImportExport::RepoBundler, services: true do + describe :bundle do + + let(:user) { create(:user) } + let!(:project) { create(:project, :public, name: 'searchable_project') } + let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } + let(:bundler) { Projects::ImportExport::RepoBundler.new(project: project, shared: shared) } + + before(:each) do + project.team << [user, :master] + allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) + end + + after(:each) do + FileUtils.rm_rf(export_path) + end + + it 'bundles the repo successfully' do + expect(bundler.bundle).to be true + end + end +end -- GitLab From 99d87d8698437f87c21ced1d5a7fab4f9d253493 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 8 Mar 2016 18:17:57 +0100 Subject: [PATCH 006/714] WIP - added wiki repo bundler --- .../import_export/command_line_util.rb | 6 ++++ .../import_export/wiki_repo_bundler.rb | 30 +++++++++++++++++++ .../import_export/wiki_repo_bundler_spec.rb | 25 ++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 app/services/projects/import_export/wiki_repo_bundler.rb create mode 100644 spec/services/projects/import_export/wiki_repo_bundler_spec.rb diff --git a/app/services/projects/import_export/command_line_util.rb b/app/services/projects/import_export/command_line_util.rb index 7b0cc08763b606..3ca49e76c7fd04 100644 --- a/app/services/projects/import_export/command_line_util.rb +++ b/app/services/projects/import_export/command_line_util.rb @@ -6,6 +6,12 @@ def tar_cf(archive:, dir:) _output, status = Gitlab::Popen.popen(cmd) status.zero? end + + def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) + cmd = %W(#{git_bin_path} --git-dir=#{repo_path} bundle create #{bundle_path} --all) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end end end end diff --git a/app/services/projects/import_export/wiki_repo_bundler.rb b/app/services/projects/import_export/wiki_repo_bundler.rb new file mode 100644 index 00000000000000..793c8efd142e5d --- /dev/null +++ b/app/services/projects/import_export/wiki_repo_bundler.rb @@ -0,0 +1,30 @@ +module Projects + module ImportExport + class WikiRepoBundler < RepoBundler + def bundle + @wiki = ProjectWiki.new(@project) + return false if !wiki? + @full_path = File.join(@export_path, project_filename) + bundle_to_disk + end + + def bundle_to_disk + FileUtils.mkdir_p(@export_path) + git_bundle(repo_path: path_to_repo, bundle_path: @full_path) + rescue + #TODO: handle error + false + end + + private + + def path_to_repo + @wiki.repository.path_to_repo + end + + def wiki? + File.exists?(@wiki.repository.path_to_repo) && !@wiki.repository.empty? + end + end + end +end diff --git a/spec/services/projects/import_export/wiki_repo_bundler_spec.rb b/spec/services/projects/import_export/wiki_repo_bundler_spec.rb new file mode 100644 index 00000000000000..351419d0619020 --- /dev/null +++ b/spec/services/projects/import_export/wiki_repo_bundler_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Projects::ImportExport::WikiRepoBundler, services: true do + describe :bundle do + + let(:user) { create(:user) } + let!(:project) { create(:project, :public, name: 'searchable_project') } + let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } + let(:wiki_bundler) { Projects::ImportExport::WikiRepoBundler.new(project: project, shared: shared) } + + before(:each) do + project.team << [user, :master] + allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) + end + + after(:each) do + FileUtils.rm_rf(export_path) + end + + it 'bundles the repo successfully' do + expect(wiki_bundler.bundle).to be true + end + end +end -- GitLab From f9c6168cc47496ac92e1a8c38dd9bd4ac39fd3d5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 8 Mar 2016 18:20:32 +0100 Subject: [PATCH 007/714] fix new line issue --- app/services/projects/import_export/shared.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/projects/import_export/shared.rb b/app/services/projects/import_export/shared.rb index 5101f514ab2b9d..04fe01c0d6c2d4 100644 --- a/app/services/projects/import_export/shared.rb +++ b/app/services/projects/import_export/shared.rb @@ -10,4 +10,4 @@ def export_path end end end -end \ No newline at end of file +end -- GitLab From 4b88b4ffd5f49ea4cef189776783b58f7c6c141f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 9 Mar 2016 10:35:38 +0100 Subject: [PATCH 008/714] fix wiki path issues and spec --- app/services/projects/import_export/repo_bundler.rb | 2 +- app/services/projects/import_export/wiki_repo_bundler.rb | 4 ++++ .../services/projects/import_export/wiki_repo_bundler_spec.rb | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/services/projects/import_export/repo_bundler.rb b/app/services/projects/import_export/repo_bundler.rb index b0b2df1c14cd46..d43fb4ea09e648 100644 --- a/app/services/projects/import_export/repo_bundler.rb +++ b/app/services/projects/import_export/repo_bundler.rb @@ -27,7 +27,7 @@ def bundle_to_disk end def project_filename - "#{@project.namespace}#{@project.name}.bundle" + "#{@project.name}.bundle" end def path_to_repo diff --git a/app/services/projects/import_export/wiki_repo_bundler.rb b/app/services/projects/import_export/wiki_repo_bundler.rb index 793c8efd142e5d..bf69936503d1bf 100644 --- a/app/services/projects/import_export/wiki_repo_bundler.rb +++ b/app/services/projects/import_export/wiki_repo_bundler.rb @@ -18,6 +18,10 @@ def bundle_to_disk private + def project_filename + "#{@project.name}.wiki.bundle" + end + def path_to_repo @wiki.repository.path_to_repo end diff --git a/spec/services/projects/import_export/wiki_repo_bundler_spec.rb b/spec/services/projects/import_export/wiki_repo_bundler_spec.rb index 351419d0619020..a589f81c5f9f46 100644 --- a/spec/services/projects/import_export/wiki_repo_bundler_spec.rb +++ b/spec/services/projects/import_export/wiki_repo_bundler_spec.rb @@ -8,10 +8,13 @@ let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } let(:wiki_bundler) { Projects::ImportExport::WikiRepoBundler.new(project: project, shared: shared) } + let!(:project_wiki) { ProjectWiki.new(project, user) } before(:each) do project.team << [user, :master] allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) + project_wiki.wiki + project_wiki.create_page("index", "test content") end after(:each) do -- GitLab From 2dc2ce45d788e296a7b8c11417833573fcd721ea Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 9 Mar 2016 16:21:02 +0100 Subject: [PATCH 009/714] WIP - broken spec and some import stuff so I can create a MR on this. --- .../projects/import_export/import_service.rb | 19 ++++++++++++ .../import_export/project_tree_restorer.rb | 30 +++++++++++++++++++ .../import_export/relation_factory.rb | 18 +++++++++++ fixtures/import_export/project.json | 1 + .../project_tree_restorer_spec.rb | 29 ++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 app/services/projects/import_export/import_service.rb create mode 100644 app/services/projects/import_export/project_tree_restorer.rb create mode 100644 app/services/projects/import_export/relation_factory.rb create mode 100644 fixtures/import_export/project.json create mode 100644 spec/services/projects/import_export/project_tree_restorer_spec.rb diff --git a/app/services/projects/import_export/import_service.rb b/app/services/projects/import_export/import_service.rb new file mode 100644 index 00000000000000..3efddf75e48994 --- /dev/null +++ b/app/services/projects/import_export/import_service.rb @@ -0,0 +1,19 @@ +module Projects + module ImportExport + class ExportService < BaseService + def execute(options = {}) + @import_path = options[:import_path] + end + + private + + def restore_project_tree + Projects::ImportExport::ProjectTreeRestorer.new(path: @import_path).restore + end + + def restore_repo + + end + end + end +end diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb new file mode 100644 index 00000000000000..c6aabc42f40d78 --- /dev/null +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -0,0 +1,30 @@ +module Projects + module ImportExport + class ProjectTreeRestorer + attr_reader :full_path + + def initialize(path: ) + @path = path + end + + def restore + json = IO.read(@path) + tree_hash = ActiveSupport::JSON.decode(json) + ImportExport.project_tree.each do |relation| + next if tree_hash[relation.to_s].empty? + tree_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s]) + end + project = Project.new(tree_hash) + project + end + + private + + def create_relation(relation, tree_hash) + Projects::ImportExport::RelationFactory.create( + relation_sym: relation, relation_hash: tree_hash[relation.to_s]) + end + + end + end +end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb new file mode 100644 index 00000000000000..03fa36428c9a37 --- /dev/null +++ b/app/services/projects/import_export/relation_factory.rb @@ -0,0 +1,18 @@ +module Projects + module ImportExport + module RelationFactory + extend self + + def create(relation_sym: , relation_hash:) + klass = relation_class(relation_sym) + klass.new(relation_hash) + end + + private + + def relation_class(relation_sym) + relation_sym.to_s.classify.constantize + end + end + end +end diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json new file mode 100644 index 00000000000000..8ea17e4d99c13b --- /dev/null +++ b/fixtures/import_export/project.json @@ -0,0 +1 @@ +{"id":14,"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Eos ut accusamus provident quis qui.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-09T11:41:00.754Z","updated_at":"2016-03-09T11:41:05.728Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Eos dolores molestias eum magni ut consequatur deleniti distinctio.","created_at":"2016-03-09T11:41:01.820Z","updated_at":"2016-03-09T11:41:01.820Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-09T11:41:02.959Z","updated_at":"2016-03-09T11:41:05.750Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-09T11:41:05.846Z","updated_at":"2016-03-09T11:41:05.846Z","state":"active","iid":1}],"snippets":[{"id":2,"title":"Unde adipisci molestiae modi quisquam qui itaque ut aut.","content":"Temporibus qui nisi ipsam maiores voluptatum.","author_id":30,"project_id":14,"created_at":"2016-03-09T11:41:03.720Z","updated_at":"2016-03-09T11:41:05.763Z","file_name":"sarah","expires_at":null,"visibility_level":0}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-09T11:41:04.342Z","updated_at":"2016-03-09T11:41:05.776Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-09T11:41:05.998Z","updated_at":"2016-03-09T11:41:05.998Z","action":8,"author_id":19}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-09T11:41:05.011Z","updated_at":"2016-03-09T11:41:05.801Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}]} \ No newline at end of file diff --git a/spec/services/projects/import_export/project_tree_restorer_spec.rb b/spec/services/projects/import_export/project_tree_restorer_spec.rb new file mode 100644 index 00000000000000..f5b4340805cf05 --- /dev/null +++ b/spec/services/projects/import_export/project_tree_restorer_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe Projects::ImportExport::ProjectTreeRestorer, services: true do + describe :restore do + + let(:user) { create(:user) } + let(:project_tree_restorer) { Projects::ImportExport::ProjectTreeRestorer.new(path: "fixtures/import_export/project.json") } + + before(:each) do + #allow(project_tree_restorer) + # .to receive(:full_path).and_return("fixtures/import_export/project.json") + end + + context 'JSON' do + let(:restored_project_json) do + project_tree_restorer.restore + #project_json(project_tree_restorer.full_path) + end + + it 'restores models based on JSON' do + expect(restored_project_json).to be true + end + end + end + + def project_json + JSON.parse(IO.read("fixtures/import_export/project.json")) + end +end -- GitLab From 2cc6aaec4910be1c37b4eeab028ffcdb4c8b9b7f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 9 Mar 2016 18:42:04 +0100 Subject: [PATCH 010/714] WIP (broken) - playing with import stuff --- .../import_export/project_tree_restorer.rb | 24 ++++++++++++------- .../import_export/relation_factory.rb | 10 +++++++- .../project_tree_restorer_spec.rb | 12 +--------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index c6aabc42f40d78..e30cb25ea61a09 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -1,30 +1,36 @@ module Projects module ImportExport class ProjectTreeRestorer - attr_reader :full_path + attr_reader :project - def initialize(path: ) + def initialize(path: , user: user) @path = path + @user = user end + #TODO deal with ID issues. + #TODO refactor this method def restore json = IO.read(@path) tree_hash = ActiveSupport::JSON.decode(json) + relation_hash = {} ImportExport.project_tree.each do |relation| next if tree_hash[relation.to_s].empty? - tree_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s]) + relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s]) end - project = Project.new(tree_hash) - project + project_params = tree_hash.delete_if { |_key, value | value.is_a?(Array)} + @project = ::Projects::CreateService.new(@user, project_params).execute + @project.saved? end private - def create_relation(relation, tree_hash) - Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: tree_hash[relation.to_s]) + def create_relation(relation, relation_hash_list) + relation_hash_list.map do |relation_hash| + Projects::ImportExport::RelationFactory.create( + relation_sym: relation, relation_hash: relation_hash) + end end - end end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 03fa36428c9a37..9f4bc7b99eccf7 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -3,8 +3,12 @@ module ImportExport module RelationFactory extend self - def create(relation_sym: , relation_hash:) + OVERRIDES = { snippets: :project_snippets } + + def create(relation_sym:, relation_hash:) + relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) + relation_hash.delete('id') #screw IDs for now klass.new(relation_hash) end @@ -13,6 +17,10 @@ def create(relation_sym: , relation_hash:) def relation_class(relation_sym) relation_sym.to_s.classify.constantize end + + def parse_relation_sym(relation_sym) + OVERRIDES[relation_sym] || relation_sym + end end end end diff --git a/spec/services/projects/import_export/project_tree_restorer_spec.rb b/spec/services/projects/import_export/project_tree_restorer_spec.rb index f5b4340805cf05..4c8d182a21313a 100644 --- a/spec/services/projects/import_export/project_tree_restorer_spec.rb +++ b/spec/services/projects/import_export/project_tree_restorer_spec.rb @@ -4,17 +4,11 @@ describe :restore do let(:user) { create(:user) } - let(:project_tree_restorer) { Projects::ImportExport::ProjectTreeRestorer.new(path: "fixtures/import_export/project.json") } - - before(:each) do - #allow(project_tree_restorer) - # .to receive(:full_path).and_return("fixtures/import_export/project.json") - end + let(:project_tree_restorer) { Projects::ImportExport::ProjectTreeRestorer.new(path: "fixtures/import_export/project.json", user: user) } context 'JSON' do let(:restored_project_json) do project_tree_restorer.restore - #project_json(project_tree_restorer.full_path) end it 'restores models based on JSON' do @@ -22,8 +16,4 @@ end end end - - def project_json - JSON.parse(IO.read("fixtures/import_export/project.json")) - end end -- GitLab From f0ce83b1902e78b8adc819db49022ed98d12342e Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 10 Mar 2016 13:04:11 +0100 Subject: [PATCH 011/714] modify model creation to use services when they are available --- .../import_export/project_tree_restorer.rb | 6 +-- .../import_export/relation_factory.rb | 39 ++++++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index e30cb25ea61a09..161081bd75d868 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -14,12 +14,12 @@ def restore json = IO.read(@path) tree_hash = ActiveSupport::JSON.decode(json) relation_hash = {} + project_params = tree_hash.reject { |_key, value | value.is_a?(Array)} + @project = ::Projects::CreateService.new(@user, project_params.except('id')).execute ImportExport.project_tree.each do |relation| next if tree_hash[relation.to_s].empty? relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s]) end - project_params = tree_hash.delete_if { |_key, value | value.is_a?(Array)} - @project = ::Projects::CreateService.new(@user, project_params).execute @project.saved? end @@ -28,7 +28,7 @@ def restore def create_relation(relation, relation_hash_list) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash) + relation_sym: relation, relation_hash: relation_hash, project: @project, user: @user) end end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 9f4bc7b99eccf7..f27903ef10fba4 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -1,24 +1,43 @@ module Projects module ImportExport - module RelationFactory - extend self + class RelationFactory OVERRIDES = { snippets: :project_snippets } - def create(relation_sym:, relation_hash:) - relation_sym = parse_relation_sym(relation_sym) - klass = relation_class(relation_sym) - relation_hash.delete('id') #screw IDs for now - klass.new(relation_hash) + def self.create(*args) + new(*args).create + end + + def initialize(relation_sym:, relation_hash:, project:, user:) + @relation_sym = parsed_relation_sym(relation_sym) + @relation_hash = relation_hash + @project = project + @user = user + end + + def create + @relation_hash.delete('id') + init_service_or_class end private - def relation_class(relation_sym) - relation_sym.to_s.classify.constantize + def init_service_or_class + # Attempt service first + relation_service.new(@project, @user, @relation_hash).execute + rescue NameError + relation_class.new(@relation_hash) + end + + def relation_service + "#{@relation_sym.to_s.classify}::CreateService".constantize + end + + def relation_class + @relation_sym.to_s.classify.constantize end - def parse_relation_sym(relation_sym) + def parsed_relation_sym(relation_sym) OVERRIDES[relation_sym] || relation_sym end end -- GitLab From 40de1b46342ce11668498d725571d253ff99172e Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 9 Mar 2016 18:42:04 +0100 Subject: [PATCH 012/714] revert back services changes (cherry picked from commit 2cc6aae) --- .../import_export/project_tree_restorer.rb | 6 +-- .../import_export/relation_factory.rb | 39 +++++-------------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 161081bd75d868..e30cb25ea61a09 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -14,12 +14,12 @@ def restore json = IO.read(@path) tree_hash = ActiveSupport::JSON.decode(json) relation_hash = {} - project_params = tree_hash.reject { |_key, value | value.is_a?(Array)} - @project = ::Projects::CreateService.new(@user, project_params.except('id')).execute ImportExport.project_tree.each do |relation| next if tree_hash[relation.to_s].empty? relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s]) end + project_params = tree_hash.delete_if { |_key, value | value.is_a?(Array)} + @project = ::Projects::CreateService.new(@user, project_params).execute @project.saved? end @@ -28,7 +28,7 @@ def restore def create_relation(relation, relation_hash_list) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash, project: @project, user: @user) + relation_sym: relation, relation_hash: relation_hash) end end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index f27903ef10fba4..9f4bc7b99eccf7 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -1,43 +1,24 @@ module Projects module ImportExport - class RelationFactory + module RelationFactory + extend self OVERRIDES = { snippets: :project_snippets } - def self.create(*args) - new(*args).create - end - - def initialize(relation_sym:, relation_hash:, project:, user:) - @relation_sym = parsed_relation_sym(relation_sym) - @relation_hash = relation_hash - @project = project - @user = user - end - - def create - @relation_hash.delete('id') - init_service_or_class + def create(relation_sym:, relation_hash:) + relation_sym = parse_relation_sym(relation_sym) + klass = relation_class(relation_sym) + relation_hash.delete('id') #screw IDs for now + klass.new(relation_hash) end private - def init_service_or_class - # Attempt service first - relation_service.new(@project, @user, @relation_hash).execute - rescue NameError - relation_class.new(@relation_hash) - end - - def relation_service - "#{@relation_sym.to_s.classify}::CreateService".constantize - end - - def relation_class - @relation_sym.to_s.classify.constantize + def relation_class(relation_sym) + relation_sym.to_s.classify.constantize end - def parsed_relation_sym(relation_sym) + def parse_relation_sym(relation_sym) OVERRIDES[relation_sym] || relation_sym end end -- GitLab From e90b1e147e69fb05bd10c2a9b4198af7ee386eb1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 10 Mar 2016 15:35:44 +0100 Subject: [PATCH 013/714] refactored project creation to create the associations as well --- .../projects/import_export/project_factory.rb | 40 +++++++++++++++++++ .../import_export/project_tree_restorer.rb | 15 +++---- 2 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 app/services/projects/import_export/project_factory.rb diff --git a/app/services/projects/import_export/project_factory.rb b/app/services/projects/import_export/project_factory.rb new file mode 100644 index 00000000000000..1ca0cfb8673bbf --- /dev/null +++ b/app/services/projects/import_export/project_factory.rb @@ -0,0 +1,40 @@ +module Projects + module ImportExport + module ProjectFactory + extend self + + def create(project_params:, user:) + project = Project.new(project_params.except('id')) + project.creator = user + check_namespace(project_params['namespace_id'], project, user) + end + + def check_namespace(namespace_id, project, user) + if namespace_id + # Find matching namespace and check if it allowed + # for current user if namespace_id passed. + unless allowed_namespace?(user, namespace_id) + project.namespace_id = nil + deny_namespace(project) + end + else + # Set current user namespace if namespace_id is nil + project.namespace_id = user.namespace_id + end + project + end + + private + + def allowed_namespace?(user, namespace_id) + namespace = Namespace.find_by(id: namespace_id) + user.can?(:create_projects, namespace) + end + + def deny_namespace(project) + project.errors.add(:namespace, "is not valid") + end + + end + end +end diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index e30cb25ea61a09..980a376be16c40 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -3,7 +3,7 @@ module ImportExport class ProjectTreeRestorer attr_reader :project - def initialize(path: , user: user) + def initialize(path:, user:) @path = path @user = user end @@ -13,22 +13,23 @@ def initialize(path: , user: user) def restore json = IO.read(@path) tree_hash = ActiveSupport::JSON.decode(json) + project_params = tree_hash.reject { |_key, value| value.is_a?(Array) } + project = Projects::ImportExport::ProjectFactory.create(project_params: project_params, user: @user) + project.save relation_hash = {} ImportExport.project_tree.each do |relation| next if tree_hash[relation.to_s].empty? - relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s]) + relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s], project.id) + project.update_attribute(relation, relation_hash[relation.to_s]) end - project_params = tree_hash.delete_if { |_key, value | value.is_a?(Array)} - @project = ::Projects::CreateService.new(@user, project_params).execute - @project.saved? end private - def create_relation(relation, relation_hash_list) + def create_relation(relation, relation_hash_list, project_id) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash) + relation_sym: relation, relation_hash: relation_hash.merge(project_id: project_id)) end end end -- GitLab From 2a7a1bcc3aa606a0aab46620c2b262a33c276c7f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 10 Mar 2016 16:21:17 +0100 Subject: [PATCH 014/714] refactored methods in project tree restorer --- .../import_export/project_tree_restorer.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 980a376be16c40..3ad42f41457441 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -13,19 +13,23 @@ def initialize(path:, user:) def restore json = IO.read(@path) tree_hash = ActiveSupport::JSON.decode(json) - project_params = tree_hash.reject { |_key, value| value.is_a?(Array) } - project = Projects::ImportExport::ProjectFactory.create(project_params: project_params, user: @user) - project.save - relation_hash = {} + project = create_project(tree_hash) ImportExport.project_tree.each do |relation| next if tree_hash[relation.to_s].empty? - relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s], project.id) - project.update_attribute(relation, relation_hash[relation.to_s]) + relation_hash = create_relation(relation, tree_hash[relation.to_s], project.id) + project.update_attribute(relation, relation_hash) end end private + def create_project(tree_hash) + project_params = tree_hash.reject { |_key, value| value.is_a?(Array) } + project = Projects::ImportExport::ProjectFactory.create(project_params: project_params, user: @user) + project.save + project + end + def create_relation(relation, relation_hash_list, project_id) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( -- GitLab From a7acfa6614c0645f61a070814e0250b8fbe0cf78 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 10 Mar 2016 16:29:38 +0100 Subject: [PATCH 015/714] add project members to export --- app/services/projects/import_export.rb | 2 +- .../projects/import_export/project_tree_saver_spec.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index 2fc0d5dd7fe873..601762e00e29c7 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -7,7 +7,7 @@ def export_path(relative_path:) end def project_atts - %i(id name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) + %i(project_members name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) end def project_tree diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 1b3568bb7a88e1..839e1b766924f0 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -81,6 +81,10 @@ it 'has commit statuses' do expect(saved_project_json['commit_statuses']).not_to be_empty end + + it 'has project members' do + expect(saved_project_json['commit_statuses']).not_to be_empty + end end end -- GitLab From cc8aafeded77cf09580fe3a9f4718dd1b7d33c19 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 10 Mar 2016 18:41:57 +0100 Subject: [PATCH 016/714] typo --- spec/services/projects/import_export/project_tree_saver_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 839e1b766924f0..383b3e4ce8ba8d 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -83,7 +83,7 @@ end it 'has project members' do - expect(saved_project_json['commit_statuses']).not_to be_empty + expect(saved_project_json['project_members']).not_to be_empty end end end -- GitLab From febff153cc850ef662301dd2a6b19df91186477f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 10 Mar 2016 18:43:57 +0100 Subject: [PATCH 017/714] started mapping members --- .../projects/import_export/members_mapper.rb | 18 ++++++++++ .../projects/import_export/project_factory.rb | 2 +- .../import_export/project_tree_restorer.rb | 36 ++++++++++++------- fixtures/import_export/project.json | 2 +- 4 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 app/services/projects/import_export/members_mapper.rb diff --git a/app/services/projects/import_export/members_mapper.rb b/app/services/projects/import_export/members_mapper.rb new file mode 100644 index 00000000000000..ebb50c30b845a4 --- /dev/null +++ b/app/services/projects/import_export/members_mapper.rb @@ -0,0 +1,18 @@ +module Projects + module ImportExport + class MembersMapper + + def self.map(*args) + new(*args).map + end + + def initialize(exported_members:) + @exported_members = exported_members + end + + def map + #TODO + end + end + end +end diff --git a/app/services/projects/import_export/project_factory.rb b/app/services/projects/import_export/project_factory.rb index 1ca0cfb8673bbf..2df38bff1f8e3a 100644 --- a/app/services/projects/import_export/project_factory.rb +++ b/app/services/projects/import_export/project_factory.rb @@ -3,7 +3,7 @@ module ImportExport module ProjectFactory extend self - def create(project_params:, user:) + def create(project_params:, user:, members:) project = Project.new(project_params.except('id')) project.creator = user check_namespace(project_params['namespace_id'], project, user) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 3ad42f41457441..8785c80e2414ae 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -8,32 +8,42 @@ def initialize(path:, user:) @user = user end - #TODO deal with ID issues. - #TODO refactor this method def restore json = IO.read(@path) - tree_hash = ActiveSupport::JSON.decode(json) - project = create_project(tree_hash) - ImportExport.project_tree.each do |relation| - next if tree_hash[relation.to_s].empty? - relation_hash = create_relation(relation, tree_hash[relation.to_s], project.id) + @tree_hash = ActiveSupport::JSON.decode(json) + create_relations + end + + private + + def members + @members ||= Projects::ImportExport::MembersMapper.map(exported_members: @tree_hash.delete('project_members')) + end + + def create_relations + (ImportExport.project_tree - [:project_members]).each do |relation| + next if @tree_hash[relation.to_s].empty? + relation_hash = create_relation(relation, @tree_hash[relation.to_s]) project.update_attribute(relation, relation_hash) end end - private + def project + @project ||= create_project + end - def create_project(tree_hash) - project_params = tree_hash.reject { |_key, value| value.is_a?(Array) } - project = Projects::ImportExport::ProjectFactory.create(project_params: project_params, user: @user) + def create_project + project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } + project = Projects::ImportExport::ProjectFactory.create( + project_params: project_params, user: @user, members: members) project.save project end - def create_relation(relation, relation_hash_list, project_id) + def create_relation(relation, relation_hash_list) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash.merge(project_id: project_id)) + relation_sym: relation, relation_hash: relation_hash.merge(project_id: project.id), members: members) end end end diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json index 8ea17e4d99c13b..fe8bb17e6c36a5 100644 --- a/fixtures/import_export/project.json +++ b/fixtures/import_export/project.json @@ -1 +1 @@ -{"id":14,"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Eos ut accusamus provident quis qui.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-09T11:41:00.754Z","updated_at":"2016-03-09T11:41:05.728Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Eos dolores molestias eum magni ut consequatur deleniti distinctio.","created_at":"2016-03-09T11:41:01.820Z","updated_at":"2016-03-09T11:41:01.820Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-09T11:41:02.959Z","updated_at":"2016-03-09T11:41:05.750Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-09T11:41:05.846Z","updated_at":"2016-03-09T11:41:05.846Z","state":"active","iid":1}],"snippets":[{"id":2,"title":"Unde adipisci molestiae modi quisquam qui itaque ut aut.","content":"Temporibus qui nisi ipsam maiores voluptatum.","author_id":30,"project_id":14,"created_at":"2016-03-09T11:41:03.720Z","updated_at":"2016-03-09T11:41:05.763Z","file_name":"sarah","expires_at":null,"visibility_level":0}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-09T11:41:04.342Z","updated_at":"2016-03-09T11:41:05.776Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-09T11:41:05.998Z","updated_at":"2016-03-09T11:41:05.998Z","action":8,"author_id":19}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-09T11:41:05.011Z","updated_at":"2016-03-09T11:41:05.801Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}]} \ No newline at end of file +{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Culpa dolores et nostrum magni quo.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-10T15:54:30.960Z","updated_at":"2016-03-10T15:54:36.624Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Distinctio voluptas qui suscipit asperiores.","created_at":"2016-03-10T15:54:31.921Z","updated_at":"2016-03-10T15:54:31.921Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-10T15:54:33.128Z","updated_at":"2016-03-10T15:54:36.645Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-10T15:54:36.756Z","updated_at":"2016-03-10T15:54:36.756Z","state":"active","iid":1}],"snippets":[{"id":2,"title":"In voluptatibus possimus fugiat qui.","content":"Qui exercitationem culpa in dolore ab.","author_id":30,"project_id":14,"created_at":"2016-03-10T15:54:34.253Z","updated_at":"2016-03-10T15:54:36.658Z","file_name":"patrick","expires_at":null,"visibility_level":0}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-10T15:54:35.211Z","updated_at":"2016-03-10T15:54:36.671Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-10T15:54:36.906Z","updated_at":"2016-03-10T15:54:36.906Z","action":8,"author_id":19}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-10T15:54:35.937Z","updated_at":"2016-03-10T15:54:36.699Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}]} \ No newline at end of file -- GitLab From 2fd30231867226d8c921ec74f388e6f30769e2a8 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 09:46:00 +0100 Subject: [PATCH 018/714] fix project members export --- app/services/projects/import_export.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index 601762e00e29c7..99336487ebc170 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -7,11 +7,11 @@ def export_path(relative_path:) end def project_atts - %i(project_members name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) + %i(name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) end def project_tree - %i(issues merge_requests labels milestones snippets releases events commit_statuses) + %i(project_members issues merge_requests labels milestones snippets releases events commit_statuses) end private -- GitLab From b7149266eac2277108757d34cce05eb372d562ab Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 10:25:34 +0100 Subject: [PATCH 019/714] WIP project members - json not quite right yet --- app/services/projects/import_export/project_factory.rb | 2 +- .../projects/import_export/project_tree_restorer.rb | 6 +++--- app/services/projects/import_export/relation_factory.rb | 2 +- fixtures/import_export/project.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/services/projects/import_export/project_factory.rb b/app/services/projects/import_export/project_factory.rb index 2df38bff1f8e3a..825907df537004 100644 --- a/app/services/projects/import_export/project_factory.rb +++ b/app/services/projects/import_export/project_factory.rb @@ -3,7 +3,7 @@ module ImportExport module ProjectFactory extend self - def create(project_params:, user:, members:) + def create(project_params:, user:, members_map:) project = Project.new(project_params.except('id')) project.creator = user check_namespace(project_params['namespace_id'], project, user) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 8785c80e2414ae..64ac3a534e2d19 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -16,7 +16,7 @@ def restore private - def members + def members_map @members ||= Projects::ImportExport::MembersMapper.map(exported_members: @tree_hash.delete('project_members')) end @@ -35,7 +35,7 @@ def project def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } project = Projects::ImportExport::ProjectFactory.create( - project_params: project_params, user: @user, members: members) + project_params: project_params, user: @user, members_map: members_map) project.save project end @@ -43,7 +43,7 @@ def create_project def create_relation(relation, relation_hash_list) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash.merge(project_id: project.id), members: members) + relation_sym: relation, relation_hash: relation_hash.merge(project_id: project.id), members_map: members_map) end end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 9f4bc7b99eccf7..624453a6aded7f 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -5,7 +5,7 @@ module RelationFactory OVERRIDES = { snippets: :project_snippets } - def create(relation_sym:, relation_hash:) + def create(relation_sym:, relation_hash:, members_map:) relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') #screw IDs for now diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json index fe8bb17e6c36a5..5eaaf1cd8afdb5 100644 --- a/fixtures/import_export/project.json +++ b/fixtures/import_export/project.json @@ -1 +1 @@ -{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Culpa dolores et nostrum magni quo.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-10T15:54:30.960Z","updated_at":"2016-03-10T15:54:36.624Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Distinctio voluptas qui suscipit asperiores.","created_at":"2016-03-10T15:54:31.921Z","updated_at":"2016-03-10T15:54:31.921Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-10T15:54:33.128Z","updated_at":"2016-03-10T15:54:36.645Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-10T15:54:36.756Z","updated_at":"2016-03-10T15:54:36.756Z","state":"active","iid":1}],"snippets":[{"id":2,"title":"In voluptatibus possimus fugiat qui.","content":"Qui exercitationem culpa in dolore ab.","author_id":30,"project_id":14,"created_at":"2016-03-10T15:54:34.253Z","updated_at":"2016-03-10T15:54:36.658Z","file_name":"patrick","expires_at":null,"visibility_level":0}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-10T15:54:35.211Z","updated_at":"2016-03-10T15:54:36.671Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-10T15:54:36.906Z","updated_at":"2016-03-10T15:54:36.906Z","action":8,"author_id":19}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-10T15:54:35.937Z","updated_at":"2016-03-10T15:54:36.699Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}]} \ No newline at end of file +{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"project_members":[{"id":11,"access_level":40,"source_id":77,"source_type":"Project","user_id":181,"notification_level":3,"created_at":"2016-03-11T09:02:34.007Z","updated_at":"2016-03-11T09:02:34.007Z","created_by_id":null,"invite_email":null,"invite_token":null,"invite_accepted_at":null}],"issues":[{"id":11,"title":"Voluptatibus eius eaque qui officiis fugit.","assignee_id":181,"author_id":182,"project_id":77,"created_at":"2016-03-11T09:02:27.677Z","updated_at":"2016-03-11T09:02:33.728Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":11,"target_branch":"feature","source_branch":"master","source_project_id":72,"author_id":185,"assignee_id":null,"title":"Dolorum similique voluptate odio id unde a maxime officiis.","created_at":"2016-03-11T09:02:28.616Z","updated_at":"2016-03-11T09:02:28.616Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":77,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":11,"title":"Bug","color":"#990000","project_id":77,"created_at":"2016-03-11T09:02:29.974Z","updated_at":"2016-03-11T09:02:33.752Z","template":false,"description":null}],"milestones":[{"id":11,"title":"Milestone v1.2","project_id":77,"description":null,"due_date":null,"created_at":"2016-03-11T09:02:33.882Z","updated_at":"2016-03-11T09:02:33.882Z","state":"active","iid":1}],"snippets":[{"id":11,"title":"Voluptas et expedita autem quia totam voluptate culpa quis.","content":"Veritatis esse fugiat sint eos.","author_id":192,"project_id":77,"created_at":"2016-03-11T09:02:31.022Z","updated_at":"2016-03-11T09:02:33.768Z","file_name":"dexter.hessel","expires_at":null,"visibility_level":0}],"releases":[{"id":11,"tag":"v1.1.0","description":"Awesome release","project_id":77,"created_at":"2016-03-11T09:02:32.099Z","updated_at":"2016-03-11T09:02:33.787Z"}],"events":[{"id":11,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":77,"created_at":"2016-03-11T09:02:34.069Z","updated_at":"2016-03-11T09:02:34.069Z","action":8,"author_id":181}],"commit_statuses":[{"id":11,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-11T09:02:32.916Z","updated_at":"2016-03-11T09:02:33.825Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":11,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":77,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}]} \ No newline at end of file -- GitLab From eb2b9e3efc335b07ade0a44b22af6214089c528b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 11:23:59 +0100 Subject: [PATCH 020/714] fix project members json to include user --- app/services/projects/import_export.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index 99336487ebc170..e281925fe9cf0e 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -11,11 +11,15 @@ def project_atts end def project_tree - %i(project_members issues merge_requests labels milestones snippets releases events commit_statuses) + %i(issues merge_requests labels milestones snippets releases events commit_statuses) + members end private + def members + [{ project_members: { include: [user: { only: [:email, :username] }] } }] + end + def storage_path File.join(Settings.shared['path'], 'tmp/project_exports') end -- GitLab From cbae4038acc2ac1d4644aa719d11ecbf368ce06c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 11:37:42 +0100 Subject: [PATCH 021/714] updated test json --- fixtures/import_export/project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json index 5eaaf1cd8afdb5..38c999e8fb1a29 100644 --- a/fixtures/import_export/project.json +++ b/fixtures/import_export/project.json @@ -1 +1 @@ -{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"project_members":[{"id":11,"access_level":40,"source_id":77,"source_type":"Project","user_id":181,"notification_level":3,"created_at":"2016-03-11T09:02:34.007Z","updated_at":"2016-03-11T09:02:34.007Z","created_by_id":null,"invite_email":null,"invite_token":null,"invite_accepted_at":null}],"issues":[{"id":11,"title":"Voluptatibus eius eaque qui officiis fugit.","assignee_id":181,"author_id":182,"project_id":77,"created_at":"2016-03-11T09:02:27.677Z","updated_at":"2016-03-11T09:02:33.728Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":11,"target_branch":"feature","source_branch":"master","source_project_id":72,"author_id":185,"assignee_id":null,"title":"Dolorum similique voluptate odio id unde a maxime officiis.","created_at":"2016-03-11T09:02:28.616Z","updated_at":"2016-03-11T09:02:28.616Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":77,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":11,"title":"Bug","color":"#990000","project_id":77,"created_at":"2016-03-11T09:02:29.974Z","updated_at":"2016-03-11T09:02:33.752Z","template":false,"description":null}],"milestones":[{"id":11,"title":"Milestone v1.2","project_id":77,"description":null,"due_date":null,"created_at":"2016-03-11T09:02:33.882Z","updated_at":"2016-03-11T09:02:33.882Z","state":"active","iid":1}],"snippets":[{"id":11,"title":"Voluptas et expedita autem quia totam voluptate culpa quis.","content":"Veritatis esse fugiat sint eos.","author_id":192,"project_id":77,"created_at":"2016-03-11T09:02:31.022Z","updated_at":"2016-03-11T09:02:33.768Z","file_name":"dexter.hessel","expires_at":null,"visibility_level":0}],"releases":[{"id":11,"tag":"v1.1.0","description":"Awesome release","project_id":77,"created_at":"2016-03-11T09:02:32.099Z","updated_at":"2016-03-11T09:02:33.787Z"}],"events":[{"id":11,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":77,"created_at":"2016-03-11T09:02:34.069Z","updated_at":"2016-03-11T09:02:34.069Z","action":8,"author_id":181}],"commit_statuses":[{"id":11,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-11T09:02:32.916Z","updated_at":"2016-03-11T09:02:33.825Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":11,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":77,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}]} \ No newline at end of file +{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Voluptatem quia repudiandae id rem ducimus.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-11T10:21:37.525Z","updated_at":"2016-03-11T10:21:44.516Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Enim dolor veritatis suscipit sed laboriosam consequatur doloremque.","created_at":"2016-03-11T10:21:38.628Z","updated_at":"2016-03-11T10:21:38.628Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-11T10:21:39.964Z","updated_at":"2016-03-11T10:21:44.539Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-11T10:21:44.688Z","updated_at":"2016-03-11T10:21:44.688Z","state":"active","iid":1}],"snippets":[{"id":2,"title":"Dolorem perspiciatis unde aut similique aperiam totam qui iste.","content":"Sed similique praesentium tempora et ad dolor quis ut.","author_id":30,"project_id":14,"created_at":"2016-03-11T10:21:41.034Z","updated_at":"2016-03-11T10:21:44.557Z","file_name":"dee","expires_at":null,"visibility_level":0}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-11T10:21:42.531Z","updated_at":"2016-03-11T10:21:44.576Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-11T10:21:44.892Z","updated_at":"2016-03-11T10:21:44.892Z","action":8,"author_id":19}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-11T10:21:43.493Z","updated_at":"2016-03-11T10:21:44.620Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}],"project_members":[{"id":2,"access_level":40,"source_id":14,"source_type":"Project","user_id":19,"notification_level":3,"created_at":"2016-03-11T10:21:44.822Z","updated_at":"2016-03-11T10:21:44.822Z","created_by_id":null,"invite_email":null,"invite_token":null,"invite_accepted_at":null,"user":{"email":"claudie.lemke@prohaskamarquardt.co.uk","username":"hiram_conroy19"}}]} \ No newline at end of file -- GitLab From 7b855b75f2699f3189610886d8b2acf7912bf7ef Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 12:55:50 +0100 Subject: [PATCH 022/714] project members import stuff --- .../projects/import_export/members_mapper.rb | 47 ++++++++++++++++++- .../projects/import_export/project_factory.rb | 2 +- .../import_export/project_tree_restorer.rb | 5 +- .../import_export/members_mapper_spec.rb | 42 +++++++++++++++++ 4 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 spec/services/projects/import_export/members_mapper_spec.rb diff --git a/app/services/projects/import_export/members_mapper.rb b/app/services/projects/import_export/members_mapper.rb index ebb50c30b845a4..56abc131b16a81 100644 --- a/app/services/projects/import_export/members_mapper.rb +++ b/app/services/projects/import_export/members_mapper.rb @@ -6,12 +6,55 @@ def self.map(*args) new(*args).map end - def initialize(exported_members:) + def initialize(exported_members:, user:, project_id:) @exported_members = exported_members + @user = user + @project_id = project_id end def map - #TODO + @project_member_map ||= project_member_map + end + + private + + def project_member_map + @project_member_map = Hash.new(default_project_member) + @exported_members.each do |member| + existing_user = User.where(find_project_user_query(member)).first + assign_member(existing_user, member) if existing_user + end + @project_member_map + end + + def assign_member(existing_user, member) + member['user'] = existing_user + project_member = ProjectMember.new(member_hash(member)) + @project_member_map[member['id']] = project_member if project_member.save + end + + def member_hash(member) + member.except('id').merge(source_id: @project_id) + end + + def default_project_member + @default_project_member ||= + begin + default_member = ProjectMember.new(default_project_member_hash) + default_member if default_member.save + end + end + + def default_project_member_hash + { user: @user, access_level: ProjectMember::MASTER, source_id: @project_id } + end + + def find_project_user_query(member) + user_arel[:username].eq(member['user']['username']).or(user_arel[:email].eq(member['user']['email'])) + end + + def user_arel + @user_arel ||= User.arel_table end end end diff --git a/app/services/projects/import_export/project_factory.rb b/app/services/projects/import_export/project_factory.rb index 825907df537004..1ca0cfb8673bbf 100644 --- a/app/services/projects/import_export/project_factory.rb +++ b/app/services/projects/import_export/project_factory.rb @@ -3,7 +3,7 @@ module ImportExport module ProjectFactory extend self - def create(project_params:, user:, members_map:) + def create(project_params:, user:) project = Project.new(project_params.except('id')) project.creator = user check_namespace(project_params['namespace_id'], project, user) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 64ac3a534e2d19..87b78197cd6a22 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -17,7 +17,8 @@ def restore private def members_map - @members ||= Projects::ImportExport::MembersMapper.map(exported_members: @tree_hash.delete('project_members')) + @members ||= Projects::ImportExport::MembersMapper.map( + exported_members: @tree_hash.delete('project_members'), user: @user, project_id: project.id) end def create_relations @@ -35,7 +36,7 @@ def project def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } project = Projects::ImportExport::ProjectFactory.create( - project_params: project_params, user: @user, members_map: members_map) + project_params: project_params, user: @user) project.save project end diff --git a/spec/services/projects/import_export/members_mapper_spec.rb b/spec/services/projects/import_export/members_mapper_spec.rb new file mode 100644 index 00000000000000..431626d5e78f32 --- /dev/null +++ b/spec/services/projects/import_export/members_mapper_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe Projects::ImportExport::MembersMapper, services: true do + describe :map do + + let(:user) { create(:user) } + let(:project) { create(:project, :public, name: 'searchable_project') } + let(:user2) { create(:user) } + let(:exported_members) { [ + { + "id" => 2, + "access_level" => 40, + "source_id" => 14, + "source_type" => "Project", + "user_id" => 19, + "notification_level" => 3, + "created_at" => "2016-03-11T10:21:44.822Z", + "updated_at" => "2016-03-11T10:21:44.822Z", + "created_by_id" => nil, + "invite_email" => nil, + "invite_token" => nil, + "invite_accepted_at" => nil, + "user" => { "email" => user2.email, "username" => user2.username } }] } + + let(:members_mapper) do + Projects::ImportExport::MembersMapper.new( + exported_members: exported_members, user: user, project_id: project.id) + end + + it 'maps a project member' do + expect(project_member_map_id(user2.id)).to eq(user2.id) + end + + it 'defaults to importer project member if it does not exist' do + expect(project_member_map_id(-1)).to eq(user.id) + end + end + + def project_member_map_id(id) + members_mapper.map[id]['id'] + end +end -- GitLab From 18d3b38e464e3b8c759401b8a8fe643313931152 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 15:14:30 +0100 Subject: [PATCH 023/714] project members: fixed a few issues. Specs now passing --- .../projects/import_export/members_mapper.rb | 3 +- .../import_export/members_mapper_spec.rb | 44 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/services/projects/import_export/members_mapper.rb b/app/services/projects/import_export/members_mapper.rb index 56abc131b16a81..634683da5ce12e 100644 --- a/app/services/projects/import_export/members_mapper.rb +++ b/app/services/projects/import_export/members_mapper.rb @@ -30,13 +30,14 @@ def project_member_map def assign_member(existing_user, member) member['user'] = existing_user project_member = ProjectMember.new(member_hash(member)) - @project_member_map[member['id']] = project_member if project_member.save + @project_member_map[existing_user.id] = project_member if project_member.save end def member_hash(member) member.except('id').merge(source_id: @project_id) end + #TODO: If default, then we need to leave a comment 'Comment by ' on comments def default_project_member @default_project_member ||= begin diff --git a/spec/services/projects/import_export/members_mapper_spec.rb b/spec/services/projects/import_export/members_mapper_spec.rb index 431626d5e78f32..dc6ccb5012187b 100644 --- a/spec/services/projects/import_export/members_mapper_spec.rb +++ b/spec/services/projects/import_export/members_mapper_spec.rb @@ -6,21 +6,27 @@ let(:user) { create(:user) } let(:project) { create(:project, :public, name: 'searchable_project') } let(:user2) { create(:user) } - let(:exported_members) { [ - { - "id" => 2, - "access_level" => 40, - "source_id" => 14, - "source_type" => "Project", - "user_id" => 19, - "notification_level" => 3, - "created_at" => "2016-03-11T10:21:44.822Z", - "updated_at" => "2016-03-11T10:21:44.822Z", - "created_by_id" => nil, - "invite_email" => nil, - "invite_token" => nil, - "invite_accepted_at" => nil, - "user" => { "email" => user2.email, "username" => user2.username } }] } + let(:exported_members) do + [{ + "id" => 2, + "access_level" => 40, + "source_id" => 14, + "source_type" => "Project", + "user_id" => 19, + "notification_level" => 3, + "created_at" => "2016-03-11T10:21:44.822Z", + "updated_at" => "2016-03-11T10:21:44.822Z", + "created_by_id" => nil, + "invite_email" => nil, + "invite_token" => nil, + "invite_accepted_at" => nil, + "user" => + { + "email" => user2.email, + "username" => user2.username + } + }] + end let(:members_mapper) do Projects::ImportExport::MembersMapper.new( @@ -28,15 +34,15 @@ end it 'maps a project member' do - expect(project_member_map_id(user2.id)).to eq(user2.id) + expect(project_member_user_id(user2.id)).to eq(user2.id) end it 'defaults to importer project member if it does not exist' do - expect(project_member_map_id(-1)).to eq(user.id) + expect(project_member_user_id(-1)).to eq(user.id) end end - def project_member_map_id(id) - members_mapper.map[id]['id'] + def project_member_user_id(id) + members_mapper.map[id].user.id end end -- GitLab From 66d3f98582e2a9fbdff93402de1075b4f7f01eb3 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 17:06:12 +0100 Subject: [PATCH 024/714] add id to project member user json --- app/services/projects/import_export.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index e281925fe9cf0e..b0c0891edb5a4c 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -17,7 +17,7 @@ def project_tree private def members - [{ project_members: { include: [user: { only: [:email, :username] }] } }] + [{ project_members: { include: [user: { only: [:id, :email, :username] }] } }] end def storage_path -- GitLab From 1d8e02c4ceba34addae175ac7797535eac2c7457 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 17:33:45 +0100 Subject: [PATCH 025/714] solved a bunch of issues with mapping members/users --- .../projects/import_export/members_mapper.rb | 5 +++-- .../projects/import_export/relation_factory.rb | 13 ++++++++++++- .../projects/import_export/members_mapper_spec.rb | 8 +++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/app/services/projects/import_export/members_mapper.rb b/app/services/projects/import_export/members_mapper.rb index 634683da5ce12e..8d47422b10c530 100644 --- a/app/services/projects/import_export/members_mapper.rb +++ b/app/services/projects/import_export/members_mapper.rb @@ -28,9 +28,10 @@ def project_member_map end def assign_member(existing_user, member) + old_user_id = member['user']['id'] member['user'] = existing_user project_member = ProjectMember.new(member_hash(member)) - @project_member_map[existing_user.id] = project_member if project_member.save + @project_member_map[old_user_id] = project_member.user.id if project_member.save end def member_hash(member) @@ -42,7 +43,7 @@ def default_project_member @default_project_member ||= begin default_member = ProjectMember.new(default_project_member_hash) - default_member if default_member.save + default_member.user.id if default_member.save end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 624453a6aded7f..39ac29e3f80dbf 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -3,17 +3,28 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets } + OVERRIDES = { snippets: :project_snippets }.freeze + USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze def create(relation_sym:, relation_hash:, members_map:) relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') #screw IDs for now + update_user_references(relation_hash, members_map) klass.new(relation_hash) end private + #TODO nice to have, optimize this to only get called for specific models + def update_user_references(relation_hash, members_map) + USER_REFERENCES.each do |reference| + if relation_hash[reference] + relation_hash[reference] = members_map[relation_hash[reference]] + end + end + end + def relation_class(relation_sym) relation_sym.to_s.classify.constantize end diff --git a/spec/services/projects/import_export/members_mapper_spec.rb b/spec/services/projects/import_export/members_mapper_spec.rb index dc6ccb5012187b..e222dd420536a2 100644 --- a/spec/services/projects/import_export/members_mapper_spec.rb +++ b/spec/services/projects/import_export/members_mapper_spec.rb @@ -6,6 +6,7 @@ let(:user) { create(:user) } let(:project) { create(:project, :public, name: 'searchable_project') } let(:user2) { create(:user) } + let(:exported_user_id) { 99 } let(:exported_members) do [{ "id" => 2, @@ -22,6 +23,7 @@ "invite_accepted_at" => nil, "user" => { + "id" => exported_user_id, "email" => user2.email, "username" => user2.username } @@ -34,15 +36,15 @@ end it 'maps a project member' do - expect(project_member_user_id(user2.id)).to eq(user2.id) + expect(members_mapper.map[exported_user_id]).to eq(user2.id) end it 'defaults to importer project member if it does not exist' do - expect(project_member_user_id(-1)).to eq(user.id) + expect(members_mapper.map[-1]).to eq(user.id) end end def project_member_user_id(id) - members_mapper.map[id].user.id + members_mapper.map[id] end end -- GitLab From 76efdea78839af27127cc81358ea1ffd911191f4 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 11 Mar 2016 18:17:57 +0100 Subject: [PATCH 026/714] fixing MR issues with import --- app/models/merge_request.rb | 4 +++- .../projects/import_export/project_tree_restorer.rb | 2 +- app/services/projects/import_export/relation_factory.rb | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 8271dc83116516..714d55323d4302 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -50,6 +50,8 @@ class MergeRequest < ActiveRecord::Base delegate :commits, :diffs, :real_size, to: :merge_request_diff, prefix: nil + attr_accessor :importing + # When this attribute is true some MR validation is ignored # It allows us to close or modify broken merge requests attr_accessor :allow_broken @@ -128,7 +130,7 @@ class MergeRequest < ActiveRecord::Base validates :target_project, presence: true validates :target_branch, presence: true validates :merge_user, presence: true, if: :merge_when_build_succeeds? - validate :validate_branches + validate :validate_branches, unless: :importing validate :validate_fork scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.projects.select(:id).reorder(nil)) } diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 87b78197cd6a22..ac9b7132004420 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -44,7 +44,7 @@ def create_project def create_relation(relation, relation_hash_list) relation_hash_list.map do |relation_hash| Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash.merge(project_id: project.id), members_map: members_map) + relation_sym: relation, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) end end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 39ac29e3f80dbf..1b9bd234a4316b 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -10,6 +10,12 @@ def create(relation_sym:, relation_hash:, members_map:) relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') #screw IDs for now + #TODO refactor this... + if relation_sym == :merge_requests + relation_hash['target_project_id'] = relation_hash.delete('project_id') + relation_hash['source_project_id'] = -1 + relation_hash['importing'] = true + end update_user_references(relation_hash, members_map) klass.new(relation_hash) end -- GitLab From 3a131383b68dcb14abd9d31a2a462ffa57841095 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 14 Mar 2016 10:35:41 +0100 Subject: [PATCH 027/714] fixed MR issue and refactored some stuff --- app/models/merge_request.rb | 2 +- .../projects/import_export/members_mapper.rb | 8 ++------ .../projects/import_export/relation_factory.rb | 13 +++++++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 714d55323d4302..de6189b2dc8e8c 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -125,7 +125,7 @@ class MergeRequest < ActiveRecord::Base end end - validates :source_project, presence: true, unless: :allow_broken + validates :source_project, presence: true, unless: [:allow_broken, :importing] validates :source_branch, presence: true validates :target_project, presence: true validates :target_branch, presence: true diff --git a/app/services/projects/import_export/members_mapper.rb b/app/services/projects/import_export/members_mapper.rb index 8d47422b10c530..6d49d901bf3fca 100644 --- a/app/services/projects/import_export/members_mapper.rb +++ b/app/services/projects/import_export/members_mapper.rb @@ -13,12 +13,6 @@ def initialize(exported_members:, user:, project_id:) end def map - @project_member_map ||= project_member_map - end - - private - - def project_member_map @project_member_map = Hash.new(default_project_member) @exported_members.each do |member| existing_user = User.where(find_project_user_query(member)).first @@ -27,6 +21,8 @@ def project_member_map @project_member_map end + private + def assign_member(existing_user, member) old_user_id = member['user']['id'] member['user'] = existing_user diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 1b9bd234a4316b..6ccaa409ce9792 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -10,18 +10,19 @@ def create(relation_sym:, relation_hash:, members_map:) relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') #screw IDs for now - #TODO refactor this... - if relation_sym == :merge_requests - relation_hash['target_project_id'] = relation_hash.delete('project_id') - relation_hash['source_project_id'] = -1 - relation_hash['importing'] = true - end + handle_merge_requests(relation_hash) if relation_sym == :merge_requests update_user_references(relation_hash, members_map) klass.new(relation_hash) end private + def handle_merge_requests(relation_hash) + relation_hash['target_project_id'] = relation_hash.delete('project_id') + relation_hash['source_project_id'] = -1 + relation_hash['importing'] = true + end + #TODO nice to have, optimize this to only get called for specific models def update_user_references(relation_hash, members_map) USER_REFERENCES.each do |reference| -- GitLab From 37c68fe025b3b4dd4ac3b510cbb32d42cbe6b23b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 14 Mar 2016 11:12:00 +0100 Subject: [PATCH 028/714] don't create MR diff as this can be imported presumably --- app/models/merge_request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index de6189b2dc8e8c..d9fbbb85003aeb 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -45,7 +45,7 @@ class MergeRequest < ActiveRecord::Base serialize :merge_params, Hash - after_create :create_merge_request_diff + after_create :create_merge_request_diff, unless: :importing after_update :update_merge_request_diff delegate :commits, :diffs, :real_size, to: :merge_request_diff, prefix: nil -- GitLab From ba1fcf36197b86049b5e6a0f2da8842b236bcf62 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 14 Mar 2016 12:29:46 +0100 Subject: [PATCH 029/714] added commits and merge request diffs to export --- app/services/projects/import_export.rb | 12 ++++++++++-- .../import_export/project_tree_saver_spec.rb | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index b0c0891edb5a4c..373916a0c4c9d1 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -11,13 +11,21 @@ def project_atts end def project_tree - %i(issues merge_requests labels milestones snippets releases events commit_statuses) + members + %i(issues labels milestones snippets releases events) + [members, merge_requests, commit_statuses] end private + def merge_requests + { merge_requests: { include: :merge_request_diff } } + end + + def commit_statuses + { commit_statuses: { include: :commit } } + end + def members - [{ project_members: { include: [user: { only: [:id, :email, :username] }] } }] + { project_members: { include: [user: { only: [:id, :email, :username] }] } } end def storage_path diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 383b3e4ce8ba8d..960109e0c84ebe 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -85,6 +85,14 @@ it 'has project members' do expect(saved_project_json['project_members']).not_to be_empty end + + it 'has merge requests diffs' do + expect(saved_project_json['merge_requests'].first['merge_request_diff']).not_to be_empty + end + + it 'has ci commits' do + expect(saved_project_json['commit_statuses'].first['commit']).not_to be_empty + end end end -- GitLab From e05bc6114491f4c1f84505b4c4746faa8c269420 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 14 Mar 2016 12:58:01 +0100 Subject: [PATCH 030/714] fix project snippets json issue --- app/services/projects/import_export.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index 373916a0c4c9d1..e1d7458a13baba 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -11,11 +11,15 @@ def project_atts end def project_tree - %i(issues labels milestones snippets releases events) + [members, merge_requests, commit_statuses] + %i(issues labels milestones releases events) + [snippets, members, merge_requests, commit_statuses] end private + def snippets + { snippets: { except: :expired_at } } + end + def merge_requests { merge_requests: { include: :merge_request_diff } } end -- GitLab From a59ba217ae6796d4589575e97913aa80add75b43 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 14 Mar 2016 18:32:56 +0100 Subject: [PATCH 031/714] WIP - building up import tree with sub relations, etc --- app/services/projects/import_export.rb | 4 +++ .../import_export/project_tree_restorer.rb | 35 +++++++++++++++---- fixtures/import_export/project.json | 2 +- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index 373916a0c4c9d1..51a1732a6752a3 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -10,6 +10,10 @@ def project_atts %i(name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) end + def project_tree_list + project_tree.map {|r| r.is_a?(Hash) ? r.keys.first : r } + end + def project_tree %i(issues labels milestones snippets releases events) + [members, merge_requests, commit_statuses] end diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index ac9b7132004420..ae1d0506c0d69e 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -12,6 +12,7 @@ def restore json = IO.read(@path) @tree_hash = ActiveSupport::JSON.decode(json) create_relations + puts project.inspect end private @@ -21,11 +22,33 @@ def members_map exported_members: @tree_hash.delete('project_members'), user: @user, project_id: project.id) end - def create_relations - (ImportExport.project_tree - [:project_members]).each do |relation| - next if @tree_hash[relation.to_s].empty? - relation_hash = create_relation(relation, @tree_hash[relation.to_s]) - project.update_attribute(relation, relation_hash) + #TODO Definitely refactor this method! + def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) + relation_list.each do |relation| + relation_hash = nil + # FIXME + # next if tree_hash[relation.to_s].blank? + if (relation.is_a?(Hash) && relation.values.first[:include]) + #TODO name stuff properly + relation_sym = relation.keys.first + #TODO remove sub-relation hashes from here so we can save the parent relation first + relation_hash = create_relation(relation_sym, tree_hash[relation_sym.to_s]) + sub_relations = [] + sub_relation = relation.values.first[:include] + sub_relation_hash_list = tree_hash[relation.keys.first.to_s] + sub_relation_hash_list.each do |sub_relation_hash| + sub_relations << create_relation(relation, sub_relation_hash[relation.to_s]) + end + relation_hash.update_attribute(sub_relation, sub_relations) + end + relation_hash ||= create_relation(relation, tree_hash[relation.to_s]) + project.update_attribute(relation, relation_hash) + end + end + + def default_relation_list + ImportExport.project_tree.reject do |rel| + rel.is_a?(Hash) && !rel[:project_members].blank? end end @@ -42,7 +65,7 @@ def create_project end def create_relation(relation, relation_hash_list) - relation_hash_list.map do |relation_hash| + [relation_hash_list].flatten.map do |relation_hash| Projects::ImportExport::RelationFactory.create( relation_sym: relation, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) end diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json index 38c999e8fb1a29..d21e754ce3d186 100644 --- a/fixtures/import_export/project.json +++ b/fixtures/import_export/project.json @@ -1 +1 @@ -{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Voluptatem quia repudiandae id rem ducimus.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-11T10:21:37.525Z","updated_at":"2016-03-11T10:21:44.516Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Enim dolor veritatis suscipit sed laboriosam consequatur doloremque.","created_at":"2016-03-11T10:21:38.628Z","updated_at":"2016-03-11T10:21:38.628Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-11T10:21:39.964Z","updated_at":"2016-03-11T10:21:44.539Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-11T10:21:44.688Z","updated_at":"2016-03-11T10:21:44.688Z","state":"active","iid":1}],"snippets":[{"id":2,"title":"Dolorem perspiciatis unde aut similique aperiam totam qui iste.","content":"Sed similique praesentium tempora et ad dolor quis ut.","author_id":30,"project_id":14,"created_at":"2016-03-11T10:21:41.034Z","updated_at":"2016-03-11T10:21:44.557Z","file_name":"dee","expires_at":null,"visibility_level":0}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-11T10:21:42.531Z","updated_at":"2016-03-11T10:21:44.576Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-11T10:21:44.892Z","updated_at":"2016-03-11T10:21:44.892Z","action":8,"author_id":19}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-11T10:21:43.493Z","updated_at":"2016-03-11T10:21:44.620Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null}],"project_members":[{"id":2,"access_level":40,"source_id":14,"source_type":"Project","user_id":19,"notification_level":3,"created_at":"2016-03-11T10:21:44.822Z","updated_at":"2016-03-11T10:21:44.822Z","created_by_id":null,"invite_email":null,"invite_token":null,"invite_accepted_at":null,"user":{"email":"claudie.lemke@prohaskamarquardt.co.uk","username":"hiram_conroy19"}}]} \ No newline at end of file +{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Libero explicabo dolores atque quae debitis sit ipsam unde.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-14T11:56:57.324Z","updated_at":"2016-03-14T11:57:02.118Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-14T11:56:59.538Z","updated_at":"2016-03-14T11:57:02.132Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-14T11:57:02.241Z","updated_at":"2016-03-14T11:57:02.241Z","state":"active","iid":1}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-14T11:57:00.950Z","updated_at":"2016-03-14T11:57:02.159Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-14T11:57:02.392Z","updated_at":"2016-03-14T11:57:02.392Z","action":8,"author_id":19}],"snippets":[{"id":2,"title":"Et qui optio blanditiis non.","content":"Repudiandae hic id vero adipisci.","author_id":28,"project_id":14,"created_at":"2016-03-14T11:57:00.372Z","updated_at":"2016-03-14T11:57:02.144Z","file_name":"krystina","visibility_level":0}],"project_members":[{"id":2,"access_level":40,"source_id":14,"source_type":"Project","user_id":19,"notification_level":3,"created_at":"2016-03-14T11:57:02.335Z","updated_at":"2016-03-14T11:57:02.335Z","created_by_id":null,"invite_email":null,"invite_token":null,"invite_accepted_at":null,"user":{"id":19,"email":"braxton@greenholttromp.ca","username":"elena19"}}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Cum est in est et.","created_at":"2016-03-14T11:56:58.333Z","updated_at":"2016-03-14T11:56:58.333Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null,"merge_request_diff":{"id":2,"state":"collected","st_commits":[{"id":"5937ac0a7beb003549fc5fd26fc247adbce4a52e","message":"Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["570e7b2abdd848b95f2f578043fc23bd6f6fd24d"],"authored_date":"2014-02-27T10:01:38.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T10:01:38.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"570e7b2abdd848b95f2f578043fc23bd6f6fd24d","message":"Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"],"authored_date":"2014-02-27T09:57:31.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:57:31.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9","message":"More submodules\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["d14d6c0abdd253381df51a723d58691b2ee1ab08"],"authored_date":"2014-02-27T09:54:21.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:54:21.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"d14d6c0abdd253381df51a723d58691b2ee1ab08","message":"Remove ds_store files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["c1acaa58bbcbc3eafe538cb8274ba387047b69f8"],"authored_date":"2014-02-27T09:49:50.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:49:50.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"c1acaa58bbcbc3eafe538cb8274ba387047b69f8","message":"Ignore DS files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["ae73cb07c9eeaf35924a10f713b364d32b2dd34f"],"authored_date":"2014-02-27T09:48:32.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:48:32.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"}],"st_diffs":[{"diff":"Binary files a/.DS_Store and /dev/null differ\n","new_path":".DS_Store","old_path":".DS_Store","a_mode":"100644","b_mode":"0","new_file":false,"renamed_file":false,"deleted_file":true},{"diff":"--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n","new_path":".gitignore","old_path":".gitignore","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n","new_path":".gitmodules","old_path":".gitmodules","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"Binary files a/files/.DS_Store and /dev/null differ\n","new_path":"files/.DS_Store","old_path":"files/.DS_Store","a_mode":"100644","b_mode":"0","new_file":false,"renamed_file":false,"deleted_file":true},{"diff":"--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" =\u003e path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" =\u003e path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output \u003c\u003c stdout.read\n @cmd_output \u003c\u003c stderr.read\n","new_path":"files/ruby/popen.rb","old_path":"files/ruby/popen.rb","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n","new_path":"files/ruby/regex.rb","old_path":"files/ruby/regex.rb","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n","new_path":"gitlab-grack","old_path":"gitlab-grack","a_mode":"0","b_mode":"160000","new_file":true,"renamed_file":false,"deleted_file":false},{"diff":"--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n","new_path":"gitlab-shell","old_path":"gitlab-shell","a_mode":"0","b_mode":"160000","new_file":true,"renamed_file":false,"deleted_file":false}],"merge_request_id":2,"created_at":"2016-03-14T11:56:58.353Z","updated_at":"2016-03-14T11:56:58.635Z","base_commit_sha":"ae73cb07c9eeaf35924a10f713b364d32b2dd34f","real_size":"8"}}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-14T11:57:01.483Z","updated_at":"2016-03-14T11:57:02.190Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null,"commit":{"id":2,"project_id":13,"ref":null,"sha":"97de212e80737a608d939f648d959671fb0a0142","before_sha":null,"push_data":null,"created_at":"2016-03-14T11:57:01.468Z","updated_at":"2016-03-14T11:57:01.468Z","tag":false,"yaml_errors":null,"committed_at":null,"gl_project_id":13}}]} \ No newline at end of file -- GitLab From e17c7f41fc9fc95399896622eac053fb276888df Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 15 Mar 2016 09:17:44 +0100 Subject: [PATCH 032/714] add TODO --- app/services/projects/import_export/project_tree_restorer.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index ae1d0506c0d69e..3a767c1980ee91 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -23,6 +23,7 @@ def members_map end #TODO Definitely refactor this method! + #TODO Think about having a yaml file to describe the tree instead of just hashes? def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) relation_list.each do |relation| relation_hash = nil -- GitLab From ac4d753863e32a3f1da2d073983e418d88401e67 Mon Sep 17 00:00:00 2001 From: Jasper Denkers Date: Fri, 26 Feb 2016 12:31:35 +0100 Subject: [PATCH 033/714] Added CI example for Scala and SBT Added CI test coverage parse regex for scoverage --- doc/ci/examples/README.md | 1 + doc/ci/examples/test-scala-application.md | 28 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 doc/ci/examples/test-scala-application.md diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md index cc059dc437633f..20eeaad3fa3a46 100644 --- a/doc/ci/examples/README.md +++ b/doc/ci/examples/README.md @@ -4,6 +4,7 @@ - [Test and deploy a Ruby application to Heroku](test-and-deploy-ruby-application-to-heroku.md) - [Test and deploy a Python application to Heroku](test-and-deploy-python-application-to-heroku.md) - [Test a Clojure application](test-clojure-application.md) +- [Test a Scala application](test-scala-application.md) - [Using `dpl` as deployment tool](deployment/README.md) - Help your favorite programming language and GitLab by sending a merge request with a guide for that language. diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md new file mode 100644 index 00000000000000..2df60321cfe396 --- /dev/null +++ b/doc/ci/examples/test-scala-application.md @@ -0,0 +1,28 @@ +## Test a Scala application + +This example demonstrates the integration of Gitlab CI with Scala applications using SBT. Checkout the example [project](https://gitlab.com/jasperdenkers/scala-sbt-sample-app) and [build status](https://gitlab.com/jasperdenkers/scala-sbt-sample-app/builds). + +### Add `.gitlab-ci.yml` file to project + +The following `.gitlab-ci.yml` should be added in the root of your repository to trigger CI: + +```yaml +before_script: + # Install SBT + - echo "deb http://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list + - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823 + - apt-get update -y + - apt-get install sbt -y + - sbt sbt-version + +test: + script: + - sbt clean coverage test coverageReport +``` + +The `before_script` installs [SBT](http://www.scala-sbt.org/) and displays the version that is being used. The `test` stage executes SBT to compile and test the project. [scoverage](https://github.com/scoverage/sbt-scoverage) is used as a SBT plugin to measure test coverage. + +You can use other versions of Scala and SBT by defining them in `build.sbt`. + +### Display test coverage in build +Add the `Coverage was \[\d+.\d+\%\]` regular expression in the `Continuous Integration > Test coverage parsing` project setting to retrieve the test coverage rate from the build trace and have it displayed with your builds. -- GitLab From 707ca4bb91a29baf43908d025be356b6e00353fe Mon Sep 17 00:00:00 2001 From: Jasper Denkers Date: Thu, 10 Mar 2016 17:06:20 +0100 Subject: [PATCH 034/714] Refer to example project in gitlab-examples group --- doc/ci/examples/test-scala-application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md index 2df60321cfe396..f1753157e9b468 100644 --- a/doc/ci/examples/test-scala-application.md +++ b/doc/ci/examples/test-scala-application.md @@ -1,6 +1,6 @@ ## Test a Scala application -This example demonstrates the integration of Gitlab CI with Scala applications using SBT. Checkout the example [project](https://gitlab.com/jasperdenkers/scala-sbt-sample-app) and [build status](https://gitlab.com/jasperdenkers/scala-sbt-sample-app/builds). +This example demonstrates the integration of Gitlab CI with Scala applications using SBT. Checkout the example [project](https://gitlab.com/gitlab-examples/scala-sbt) and [build status](https://gitlab.com/gitlab-examples/scala-sbt/builds). ### Add `.gitlab-ci.yml` file to project -- GitLab From 9169c7e81fb906cf9f419d195d73a585b19dafbc Mon Sep 17 00:00:00 2001 From: Jasper Denkers Date: Thu, 10 Mar 2016 17:32:37 +0100 Subject: [PATCH 035/714] Add Java 8 image to Scala CI instructions --- doc/ci/examples/test-scala-application.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/ci/examples/test-scala-application.md b/doc/ci/examples/test-scala-application.md index f1753157e9b468..58947f0f9f4091 100644 --- a/doc/ci/examples/test-scala-application.md +++ b/doc/ci/examples/test-scala-application.md @@ -7,6 +7,8 @@ This example demonstrates the integration of Gitlab CI with Scala applications u The following `.gitlab-ci.yml` should be added in the root of your repository to trigger CI: ```yaml +image: java:8 + before_script: # Install SBT - echo "deb http://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list -- GitLab From efde96e9cd4b0096c19ecfa46237b7eda28038aa Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 6 Apr 2016 18:12:41 +0200 Subject: [PATCH 036/714] started refactored the dynamic rules to be defined in a yml file --- .../projects/import_export/import_export.yml | 31 ++++++++++++ .../import_export/import_export_reader.rb | 47 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 app/services/projects/import_export/import_export.yml create mode 100644 app/services/projects/import_export/import_export_reader.rb diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml new file mode 100644 index 00000000000000..d02ec5df2ff5d6 --- /dev/null +++ b/app/services/projects/import_export/import_export.yml @@ -0,0 +1,31 @@ +# Class relationships to be included in the import/export +:project_tree: + - :issues + - :labels + - :milestones + - :snippets + - :releases + - :events + - :project_members: + - :user + - :merge_requests: + - :merge_request_diff + - :commit_statuses: + - :commit + +:attributes_only: + :project: + - :name + - :path + - :description + - :issues_enabled + - :wall_enabled + - :merge_requests_enabled + - :wiki_enabled + - :snippets_enabled + - :visibility_level + - :archived + :user: + - :id + - :email + - :username \ No newline at end of file diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb new file mode 100644 index 00000000000000..af8c8c3c251465 --- /dev/null +++ b/app/services/projects/import_export/import_export_reader.rb @@ -0,0 +1,47 @@ +module Projects + module ImportExport + module ImportExportReader + extend self + + def project_tree + { only: atts_only[:project], include: build_hash(tree) } + end + + def config + @config ||= YAML.load_file('app/services/projects/import_export/import_export.yml') + end + + def atts_only + config[:attributes_only] + end + + def atts_except + config[:attributes_except] + end + + def tree + config[:project_tree] + end + + def build_hash(array) + array.map { |el| el.is_a?(Hash) ? process_include(el) : el } + end + + def process_include(hash) + included_classes_hash = {} + hash.values.flatten.each do |value| + value = value.is_a?(Hash) ? process_include(hash) : value + new_hash = { :include => value } + new_hash.merge!(check_only(value)) + included_classes_hash[hash.keys.first] = new_hash + end + included_classes_hash + end + + def check_only(value) + key = value.is_a?(Hash) ? value.keys.first : value + atts_only[key].nil? ? {} : { only: atts_only[key] } + end + end + end +end \ No newline at end of file -- GitLab From acfa0b69d5370749cee9768bf79b58daf6d916a4 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 7 Apr 2016 13:19:57 +0200 Subject: [PATCH 037/714] continuing to refactor config, added spec and fixed a few problems --- .../projects/import_export/import_export.yml | 2 +- .../import_export/import_export_reader.rb | 51 ++++++++++++++++--- .../import_export_reader_spec.rb | 24 +++++++++ spec/support/import_export/import_export.yml | 20 ++++++++ 4 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 spec/services/projects/import_export/import_export_reader_spec.rb create mode 100644 spec/support/import_export/import_export.yml diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml index d02ec5df2ff5d6..40fd98b80926f7 100644 --- a/app/services/projects/import_export/import_export.yml +++ b/app/services/projects/import_export/import_export.yml @@ -1,4 +1,4 @@ -# Class relationships to be included in the import/export +# Class relationships to be included in the project import/export :project_tree: - :issues - :labels diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb index af8c8c3c251465..77a1abb851b5d9 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/app/services/projects/import_export/import_export_reader.rb @@ -7,6 +7,8 @@ def project_tree { only: atts_only[:project], include: build_hash(tree) } end + private + def config @config ||= YAML.load_file('app/services/projects/import_export/import_export.yml') end @@ -27,21 +29,56 @@ def build_hash(array) array.map { |el| el.is_a?(Hash) ? process_include(el) : el } end - def process_include(hash) - included_classes_hash = {} + def process_include(hash, included_classes_hash = {}) hash.values.flatten.each do |value| - value = value.is_a?(Hash) ? process_include(hash) : value - new_hash = { :include => value } - new_hash.merge!(check_only(value)) - included_classes_hash[hash.keys.first] = new_hash + current_key, value = process_current_class(hash, included_classes_hash, value) + if included_classes_hash[current_key] + add_class(current_key, included_classes_hash, value) + else + add_new_class(current_key, included_classes_hash, value) + end end included_classes_hash end + def process_current_class(hash, included_classes_hash, value) + value = value.is_a?(Hash) ? process_include(hash, included_classes_hash) : value + current_key = hash.keys.first + current_key_only = check_only_and_except(current_key) + included_classes_hash[current_key] ||= current_key_only unless current_key_only.empty? + return current_key, value + end + + def add_new_class(current_key, included_classes_hash, value) + new_hash = { :include => value } + new_hash.merge!(check_only_and_except(value)) + included_classes_hash[current_key] = new_hash + end + + def add_class(current_key, included_classes_hash, value) + check_only_hash = check_only_and_except(value) + value = { value => check_only_hash } unless check_only_hash.empty? + old_values = included_classes_hash[current_key][:include] + included_classes_hash[current_key][:include] = ([old_values] + [value]).compact.flatten + end + + def check_only_and_except(value) + check_only(value).merge(check_except(value)) + end + def check_only(value) - key = value.is_a?(Hash) ? value.keys.first : value + key = key_from_hash(value) atts_only[key].nil? ? {} : { only: atts_only[key] } end + + def check_except(value) + key = key_from_hash(value) + atts_except[key].nil? ? {} : { except: atts_except[key] } + end + + def key_from_hash(value) + value.is_a?(Hash) ? value.keys.first : value + end end end end \ No newline at end of file diff --git a/spec/services/projects/import_export/import_export_reader_spec.rb b/spec/services/projects/import_export/import_export_reader_spec.rb new file mode 100644 index 00000000000000..73e043e52ce5be --- /dev/null +++ b/spec/services/projects/import_export/import_export_reader_spec.rb @@ -0,0 +1,24 @@ +require 'rspec' + +describe Projects::ImportExport::ImportExportReader do + + let(:test_config) { 'spec/support/import_export/import_export.yml' } + let(:project_tree_hash) do + { + :only => [:name, :path], + :include => [:issues, :labels, + { :merge_requests => { + :only => [:id], + :except => [:iid], + :include => [:merge_request_diff, :merge_request_test] + } }, + { :commit_statuses => { :include => :commit } }] + } + end + + it 'should generate hash from project tree config' do + allow(described_class).to receive(:config).and_return(YAML.load_file(test_config)) + + expect(described_class.project_tree).to eq(project_tree_hash) + end +end \ No newline at end of file diff --git a/spec/support/import_export/import_export.yml b/spec/support/import_export/import_export.yml new file mode 100644 index 00000000000000..e6985d6413cd98 --- /dev/null +++ b/spec/support/import_export/import_export.yml @@ -0,0 +1,20 @@ +# Class relationships to be included in the project import/export +:project_tree: + - :issues + - :labels + - :merge_requests: + - :merge_request_diff + - :merge_request_test + - :commit_statuses: + - :commit + +:attributes_only: + :project: + - :name + - :path + :merge_requests: + - :id + +:attributes_except: + :merge_requests: + - :iid \ No newline at end of file -- GitLab From de6c44e983a788262b72355b85d085a675c9fccc Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 7 Apr 2016 18:14:42 +0200 Subject: [PATCH 038/714] using new config --- app/services/projects/import_export.rb | 18 +----------------- .../projects/import_export/import_export.yml | 6 +++++- .../import_export/import_export_reader.rb | 17 ++++++++++++----- .../import_export/project_tree_saver.rb | 2 +- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/app/services/projects/import_export.rb b/app/services/projects/import_export.rb index e1d7458a13baba..c74f1d3149072e 100644 --- a/app/services/projects/import_export.rb +++ b/app/services/projects/import_export.rb @@ -11,27 +11,11 @@ def project_atts end def project_tree - %i(issues labels milestones releases events) + [snippets, members, merge_requests, commit_statuses] + Projects::ImportExport::ImportExportReader.project_tree end private - def snippets - { snippets: { except: :expired_at } } - end - - def merge_requests - { merge_requests: { include: :merge_request_diff } } - end - - def commit_statuses - { commit_statuses: { include: :commit } } - end - - def members - { project_members: { include: [user: { only: [:id, :email, :username] }] } } - end - def storage_path File.join(Settings.shared['path'], 'tmp/project_exports') end diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml index 40fd98b80926f7..be7680775bae5c 100644 --- a/app/services/projects/import_export/import_export.yml +++ b/app/services/projects/import_export/import_export.yml @@ -28,4 +28,8 @@ :user: - :id - :email - - :username \ No newline at end of file + - :username + +:attributes_except: + :snippets: + - :expired_at \ No newline at end of file diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb index 77a1abb851b5d9..981f19c0acb8ff 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/app/services/projects/import_export/import_export_reader.rb @@ -26,7 +26,14 @@ def tree end def build_hash(array) - array.map { |el| el.is_a?(Hash) ? process_include(el) : el } + array.map do |el| + if el.is_a?(Hash) + process_include(el) + else + only_except_hash = check_only_and_except(el) + only_except_hash.empty? ? el : { el => only_except_hash } + end + end end def process_include(hash, included_classes_hash = {}) @@ -44,8 +51,8 @@ def process_include(hash, included_classes_hash = {}) def process_current_class(hash, included_classes_hash, value) value = value.is_a?(Hash) ? process_include(hash, included_classes_hash) : value current_key = hash.keys.first - current_key_only = check_only_and_except(current_key) - included_classes_hash[current_key] ||= current_key_only unless current_key_only.empty? + only_except_hash = check_only_and_except(current_key) + included_classes_hash[current_key] ||= only_except_hash unless only_except_hash.empty? return current_key, value end @@ -56,8 +63,8 @@ def add_new_class(current_key, included_classes_hash, value) end def add_class(current_key, included_classes_hash, value) - check_only_hash = check_only_and_except(value) - value = { value => check_only_hash } unless check_only_hash.empty? + only_except_hash = check_only_and_except(value) + value = { value => only_except_hash } unless only_except_hash.empty? old_values = included_classes_hash[current_key][:include] included_classes_hash[current_key][:include] = ([old_values] + [value]).compact.flatten end diff --git a/app/services/projects/import_export/project_tree_saver.rb b/app/services/projects/import_export/project_tree_saver.rb index 3ca90d1f79aed9..44d100acd1dd12 100644 --- a/app/services/projects/import_export/project_tree_saver.rb +++ b/app/services/projects/import_export/project_tree_saver.rb @@ -32,7 +32,7 @@ def project_filename def project_json_tree # TODO confirm children, also add subchildren (i.e comments) # TODO confirm atts for children - @project.to_json(only: ImportExport.project_atts, include: ImportExport.project_tree) + @project.to_json(Projects::ImportExport.project_tree) end end end -- GitLab From 5d642fb7aa666063d5e1761833463bc95241889a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 8 Apr 2016 15:07:12 +0200 Subject: [PATCH 039/714] fix rubocop warnings --- .../import_export/import_export_reader.rb | 14 +++++++------- .../import_export/import_export_reader_spec.rb | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb index 981f19c0acb8ff..e0617ce851c5d0 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/app/services/projects/import_export/import_export_reader.rb @@ -38,7 +38,8 @@ def build_hash(array) def process_include(hash, included_classes_hash = {}) hash.values.flatten.each do |value| - current_key, value = process_current_class(hash, included_classes_hash, value) + current_key = hash.keys.first + value = process_current_class(hash, included_classes_hash, value) if included_classes_hash[current_key] add_class(current_key, included_classes_hash, value) else @@ -50,14 +51,13 @@ def process_include(hash, included_classes_hash = {}) def process_current_class(hash, included_classes_hash, value) value = value.is_a?(Hash) ? process_include(hash, included_classes_hash) : value - current_key = hash.keys.first - only_except_hash = check_only_and_except(current_key) - included_classes_hash[current_key] ||= only_except_hash unless only_except_hash.empty? - return current_key, value + only_except_hash = check_only_and_except(hash.keys.first) + included_classes_hash[hash.keys.first] ||= only_except_hash unless only_except_hash.empty? + value end def add_new_class(current_key, included_classes_hash, value) - new_hash = { :include => value } + new_hash = { include: value } new_hash.merge!(check_only_and_except(value)) included_classes_hash[current_key] = new_hash end @@ -88,4 +88,4 @@ def key_from_hash(value) end end end -end \ No newline at end of file +end diff --git a/spec/services/projects/import_export/import_export_reader_spec.rb b/spec/services/projects/import_export/import_export_reader_spec.rb index 73e043e52ce5be..f825292ce7e79e 100644 --- a/spec/services/projects/import_export/import_export_reader_spec.rb +++ b/spec/services/projects/import_export/import_export_reader_spec.rb @@ -5,14 +5,14 @@ let(:test_config) { 'spec/support/import_export/import_export.yml' } let(:project_tree_hash) do { - :only => [:name, :path], - :include => [:issues, :labels, - { :merge_requests => { - :only => [:id], - :except => [:iid], - :include => [:merge_request_diff, :merge_request_test] - } }, - { :commit_statuses => { :include => :commit } }] + only: [:name, :path], + include: [:issues, :labels, + { merge_requests: { + only: [:id], + except: [:iid], + include: [:merge_request_diff, :merge_request_test] + } }, + { commit_statuses: { include: :commit } }] } end @@ -21,4 +21,4 @@ expect(described_class.project_tree).to eq(project_tree_hash) end -end \ No newline at end of file +end -- GitLab From a28be02e88f1d213649ef2c25858313caeb83b59 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 8 Apr 2016 18:13:19 +0200 Subject: [PATCH 040/714] starting to use the new dynamic stuff on the import --- .../import_export/import_export_reader.rb | 8 ++-- .../import_export/project_tree_restorer.rb | 47 +++++++++++-------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb index e0617ce851c5d0..001d24af604d8a 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/app/services/projects/import_export/import_export_reader.rb @@ -7,6 +7,10 @@ def project_tree { only: atts_only[:project], include: build_hash(tree) } end + def tree + config[:project_tree] + end + private def config @@ -21,10 +25,6 @@ def atts_except config[:attributes_except] end - def tree - config[:project_tree] - end - def build_hash(array) array.map do |el| if el.is_a?(Hash) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 3a767c1980ee91..ca68840e988da4 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -25,32 +25,41 @@ def members_map #TODO Definitely refactor this method! #TODO Think about having a yaml file to describe the tree instead of just hashes? def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) + members_map # TODO remove this and fix project_members relation_list.each do |relation| - relation_hash = nil - # FIXME - # next if tree_hash[relation.to_s].blank? - if (relation.is_a?(Hash) && relation.values.first[:include]) - #TODO name stuff properly - relation_sym = relation.keys.first - #TODO remove sub-relation hashes from here so we can save the parent relation first - relation_hash = create_relation(relation_sym, tree_hash[relation_sym.to_s]) - sub_relations = [] - sub_relation = relation.values.first[:include] - sub_relation_hash_list = tree_hash[relation.keys.first.to_s] - sub_relation_hash_list.each do |sub_relation_hash| - sub_relations << create_relation(relation, sub_relation_hash[relation.to_s]) + if relation.is_a?(Hash) + relation.values.each do |value| + create_relations(value, @tree_hash[relation.to_s]) end - relation_hash.update_attribute(sub_relation, sub_relations) end - relation_hash ||= create_relation(relation, tree_hash[relation.to_s]) - project.update_attribute(relation, relation_hash) + relation_hash = create_relation(relation, tree_hash[relation.to_s]) + project.update_attribute(relation, relation_hash) + # relation_hash = nil + # # FIXME + # # next if tree_hash[relation.to_s].blank? + # if (relation.is_a?(Hash) && relation.values.first[:include]) + # #TODO name stuff properly + # relation_sym = relation.keys.first + # #TODO remove sub-relation hashes from here so we can save the parent relation first + # relation_hash = create_relation(relation_sym, tree_hash[relation_sym.to_s]) + # sub_relations = [] + # sub_relation = relation.values.first[:include] + # sub_relation_hash_list = tree_hash[relation.keys.first.to_s] + # sub_relation_hash_list.each do |sub_relation_hash| + # sub_relations << create_relation(relation, sub_relation_hash[relation.to_s]) + # end + # relation_hash.update_attribute(sub_relation, sub_relations) + # end + # relation_hash ||= create_relation(relation, tree_hash[relation.to_s]) + # project.update_attribute(relation, relation_hash) end end def default_relation_list - ImportExport.project_tree.reject do |rel| - rel.is_a?(Hash) && !rel[:project_members].blank? - end + Projects::ImportExport::ImportExportReader.tree + # ImportExport.project_tree.reject do |rel| + # rel.is_a?(Hash) && !rel[:project_members].blank? + # end end def project -- GitLab From 56fc58930cec501bd63046781c06be510feee029 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 11 Apr 2016 18:30:54 +0200 Subject: [PATCH 041/714] more refactoring to use dynamic import --- .../projects/import_export/import_export.yml | 4 ++- .../import_export/project_tree_restorer.rb | 35 +++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml index be7680775bae5c..16a212d4c38603 100644 --- a/app/services/projects/import_export/import_export.yml +++ b/app/services/projects/import_export/import_export.yml @@ -1,4 +1,4 @@ -# Class relationships to be included in the project import/export +# Model relationships to be included in the project import/export :project_tree: - :issues - :labels @@ -13,6 +13,7 @@ - :commit_statuses: - :commit +# Only include the following attributes for the models specified. :attributes_only: :project: - :name @@ -30,6 +31,7 @@ - :email - :username +# Do not include the following attributes for the models specified. :attributes_except: :snippets: - :expired_at \ No newline at end of file diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index ca68840e988da4..9512fcb2a1ab79 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -11,29 +11,25 @@ def initialize(path:, user:) def restore json = IO.read(@path) @tree_hash = ActiveSupport::JSON.decode(json) + @project_members = @tree_hash.delete('project_members') create_relations - puts project.inspect end private def members_map @members ||= Projects::ImportExport::MembersMapper.map( - exported_members: @tree_hash.delete('project_members'), user: @user, project_id: project.id) + exported_members: @project_members, user: @user, project_id: project.id) end - #TODO Definitely refactor this method! - #TODO Think about having a yaml file to describe the tree instead of just hashes? def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) - members_map # TODO remove this and fix project_members relation_list.each do |relation| if relation.is_a?(Hash) - relation.values.each do |value| - create_relations(value, @tree_hash[relation.to_s]) - end + create_sub_relations(relation, tree_hash) end - relation_hash = create_relation(relation, tree_hash[relation.to_s]) - project.update_attribute(relation, relation_hash) + relation_key = relation.is_a?(Hash) ? relation.keys.first : relation + relation_hash = create_relation(relation_key, tree_hash[relation_key.to_s]) + project.update_attribute(relation_key, relation_hash) # relation_hash = nil # # FIXME # # next if tree_hash[relation.to_s].blank? @@ -56,10 +52,7 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha end def default_relation_list - Projects::ImportExport::ImportExportReader.tree - # ImportExport.project_tree.reject do |rel| - # rel.is_a?(Hash) && !rel[:project_members].blank? - # end + Projects::ImportExport::ImportExportReader.tree.reject { |model| model.is_a?(Hash) && model[:project_members] } end def project @@ -74,6 +67,20 @@ def create_project project end + def create_sub_relations(relation, tree_hash) + # TODO refactor this + relation_key = relation.keys.first + tree_hash[relation_key.to_s].each do |relation_item| + relation.values.each do |sub_relation| + relation_hash = relation_item[sub_relation.to_s] + next if relation_hash.blank? + sub_relation_object = Projects::ImportExport::RelationFactory.create( + relation_sym: sub_relation, relation_hash: relation_hash, members_map: members_map) + relation_item[sub_relation.to_s] = sub_relation_object + end + end + end + def create_relation(relation, relation_hash_list) [relation_hash_list].flatten.map do |relation_hash| Projects::ImportExport::RelationFactory.create( -- GitLab From da60baf2a5fc5e2f7e84ea592b8ba6747a63abb3 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 10:36:18 +0200 Subject: [PATCH 042/714] fixing more importing issues --- app/models/merge_request_diff.rb | 4 +++- app/services/projects/import_export/project_tree_restorer.rb | 3 ++- app/services/projects/import_export/relation_factory.rb | 5 +++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 33884118595cd3..03daac2822c495 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -37,7 +37,9 @@ class MergeRequestDiff < ActiveRecord::Base serialize :st_commits serialize :st_diffs - after_create :reload_content + after_create :reload_content, unless: :importing + + attr_accessor :importing def reload_content reload_commits diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 9512fcb2a1ab79..c498d7bd9bc368 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -71,9 +71,10 @@ def create_sub_relations(relation, tree_hash) # TODO refactor this relation_key = relation.keys.first tree_hash[relation_key.to_s].each do |relation_item| - relation.values.each do |sub_relation| + relation.values.flatten.each do |sub_relation| relation_hash = relation_item[sub_relation.to_s] next if relation_hash.blank? + relation_hash.merge!('project_id' => project.id) if sub_relation == :merge_requests sub_relation_object = Projects::ImportExport::RelationFactory.create( relation_sym: sub_relation, relation_hash: relation_hash, members_map: members_map) relation_item[sub_relation.to_s] = sub_relation_object diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 6ccaa409ce9792..4f1c753ac69a16 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -7,12 +7,14 @@ module RelationFactory USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze def create(relation_sym:, relation_hash:, members_map:) + #TODO refactor this relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') #screw IDs for now handle_merge_requests(relation_hash) if relation_sym == :merge_requests update_user_references(relation_hash, members_map) - klass.new(relation_hash) + imported_object = klass.new(relation_hash) + imported_object.importing = true if imported_object.respond_to?(:importing) end private @@ -20,7 +22,6 @@ def create(relation_sym:, relation_hash:, members_map:) def handle_merge_requests(relation_hash) relation_hash['target_project_id'] = relation_hash.delete('project_id') relation_hash['source_project_id'] = -1 - relation_hash['importing'] = true end #TODO nice to have, optimize this to only get called for specific models -- GitLab From dbf755ae56f17d9b62a95a1f631ff583b6a50fb3 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 11:34:58 +0200 Subject: [PATCH 043/714] small fix --- app/services/projects/import_export/relation_factory.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 4f1c753ac69a16..123dd43dad0168 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -15,6 +15,7 @@ def create(relation_sym:, relation_hash:, members_map:) update_user_references(relation_hash, members_map) imported_object = klass.new(relation_hash) imported_object.importing = true if imported_object.respond_to?(:importing) + imported_object end private -- GitLab From 4ffcd427800b9d252b6b6a8cd9dafe03d203229a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 11:42:37 +0200 Subject: [PATCH 044/714] import working! --- app/services/projects/import_export/project_tree_restorer.rb | 3 +-- app/services/projects/import_export/relation_factory.rb | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index c498d7bd9bc368..be0c7066099616 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -74,9 +74,8 @@ def create_sub_relations(relation, tree_hash) relation.values.flatten.each do |sub_relation| relation_hash = relation_item[sub_relation.to_s] next if relation_hash.blank? - relation_hash.merge!('project_id' => project.id) if sub_relation == :merge_requests sub_relation_object = Projects::ImportExport::RelationFactory.create( - relation_sym: sub_relation, relation_hash: relation_hash, members_map: members_map) + relation_sym: sub_relation, relation_hash: relation_hash.merge!('project_id' => project.id), members_map: members_map) relation_item[sub_relation.to_s] = sub_relation_object end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 123dd43dad0168..0eb7a03b6e95d8 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -3,7 +3,7 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets }.freeze + OVERRIDES = { snippets: :project_snippets, commit: 'Ci::Commit' }.freeze USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze def create(relation_sym:, relation_hash:, members_map:) @@ -11,6 +11,7 @@ def create(relation_sym:, relation_hash:, members_map:) relation_sym = parse_relation_sym(relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') #screw IDs for now + relation_hash.delete('project_id') unless klass.column_names.include?(:project_id) handle_merge_requests(relation_hash) if relation_sym == :merge_requests update_user_references(relation_hash, members_map) imported_object = klass.new(relation_hash) -- GitLab From eb55cb927b668e7e4e507ad87e65895c6a96f14d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 12:24:40 +0200 Subject: [PATCH 045/714] more refactoring --- .../import_export/project_tree_restorer.rb | 35 ++++++------------- .../import_export/relation_factory.rb | 24 +++++++++---- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index be0c7066099616..df0363e0ecaaa1 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -30,24 +30,8 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha relation_key = relation.is_a?(Hash) ? relation.keys.first : relation relation_hash = create_relation(relation_key, tree_hash[relation_key.to_s]) project.update_attribute(relation_key, relation_hash) - # relation_hash = nil - # # FIXME - # # next if tree_hash[relation.to_s].blank? - # if (relation.is_a?(Hash) && relation.values.first[:include]) - # #TODO name stuff properly - # relation_sym = relation.keys.first - # #TODO remove sub-relation hashes from here so we can save the parent relation first - # relation_hash = create_relation(relation_sym, tree_hash[relation_sym.to_s]) - # sub_relations = [] - # sub_relation = relation.values.first[:include] - # sub_relation_hash_list = tree_hash[relation.keys.first.to_s] - # sub_relation_hash_list.each do |sub_relation_hash| - # sub_relations << create_relation(relation, sub_relation_hash[relation.to_s]) - # end - # relation_hash.update_attribute(sub_relation, sub_relations) - # end - # relation_hash ||= create_relation(relation, tree_hash[relation.to_s]) - # project.update_attribute(relation, relation_hash) + # FIXME + # next if tree_hash[relation.to_s].blank? end end @@ -68,14 +52,11 @@ def create_project end def create_sub_relations(relation, tree_hash) - # TODO refactor this - relation_key = relation.keys.first - tree_hash[relation_key.to_s].each do |relation_item| + tree_hash[relation.keys.first.to_s].each do |relation_item| relation.values.flatten.each do |sub_relation| relation_hash = relation_item[sub_relation.to_s] next if relation_hash.blank? - sub_relation_object = Projects::ImportExport::RelationFactory.create( - relation_sym: sub_relation, relation_hash: relation_hash.merge!('project_id' => project.id), members_map: members_map) + sub_relation_object = relation_from_factory(relation, relation_hash) relation_item[sub_relation.to_s] = sub_relation_object end end @@ -83,10 +64,14 @@ def create_sub_relations(relation, tree_hash) def create_relation(relation, relation_hash_list) [relation_hash_list].flatten.map do |relation_hash| - Projects::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) + relation_from_factory(relation, relation_hash) end end + + def relation_from_factory(relation, relation_hash) + Projects::ImportExport::RelationFactory.create( + relation_sym: relation, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) + end end end end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 0eb7a03b6e95d8..31d812036456f9 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -7,16 +7,13 @@ module RelationFactory USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze def create(relation_sym:, relation_hash:, members_map:) - #TODO refactor this relation_sym = parse_relation_sym(relation_sym) - klass = relation_class(relation_sym) - relation_hash.delete('id') #screw IDs for now - relation_hash.delete('project_id') unless klass.column_names.include?(:project_id) + klass = parse_relation(relation_hash, relation_sym) + handle_merge_requests(relation_hash) if relation_sym == :merge_requests update_user_references(relation_hash, members_map) - imported_object = klass.new(relation_hash) - imported_object.importing = true if imported_object.respond_to?(:importing) - imported_object + + imported_object(klass, relation_hash) end private @@ -42,6 +39,19 @@ def relation_class(relation_sym) def parse_relation_sym(relation_sym) OVERRIDES[relation_sym] || relation_sym end + + def imported_object(klass, relation_hash) + imported_object = klass.new(relation_hash) + imported_object.importing = true if imported_object.respond_to?(:importing) + imported_object + end + + def parse_relation(relation_hash, relation_sym) + klass = relation_class(relation_sym) + relation_hash.delete('id') #screw IDs for now + relation_hash.delete('project_id') unless klass.column_names.include?(:project_id) + klass + end end end end -- GitLab From 495397793e1530bb1ec453d1ae5ea9b77cd22c54 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 12:57:00 +0200 Subject: [PATCH 046/714] fix spec --- .../projects/import_export/project_tree_restorer.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index df0363e0ecaaa1..251221c2a6f6c7 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -23,16 +23,18 @@ def members_map end def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) + saved = [] relation_list.each do |relation| if relation.is_a?(Hash) create_sub_relations(relation, tree_hash) end relation_key = relation.is_a?(Hash) ? relation.keys.first : relation relation_hash = create_relation(relation_key, tree_hash[relation_key.to_s]) - project.update_attribute(relation_key, relation_hash) + saved << project.update_attribute(relation_key, relation_hash) # FIXME # next if tree_hash[relation.to_s].blank? end + saved.all? end def default_relation_list @@ -56,7 +58,7 @@ def create_sub_relations(relation, tree_hash) relation.values.flatten.each do |sub_relation| relation_hash = relation_item[sub_relation.to_s] next if relation_hash.blank? - sub_relation_object = relation_from_factory(relation, relation_hash) + sub_relation_object = relation_from_factory(sub_relation, relation_hash) relation_item[sub_relation.to_s] = sub_relation_object end end -- GitLab From 3b99e4ae5bc9e4d1bf54c65bf633ad449361b9df Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 15:32:25 +0200 Subject: [PATCH 047/714] add issue and MR comments to default export. Fix spec --- .../projects/import_export/import_export.yml | 4 +- .../import_export/import_export_reader.rb | 8 +- .../import_export/project_tree_saver.rb | 2 - .../import_export/project_tree_saver_spec.rb | 171 ++---------------- 4 files changed, 19 insertions(+), 166 deletions(-) diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml index be7680775bae5c..c622447ef042fe 100644 --- a/app/services/projects/import_export/import_export.yml +++ b/app/services/projects/import_export/import_export.yml @@ -1,6 +1,7 @@ # Class relationships to be included in the project import/export :project_tree: - - :issues + - :issues: + - :notes - :labels - :milestones - :snippets @@ -10,6 +11,7 @@ - :user - :merge_requests: - :merge_request_diff + - :notes - :commit_statuses: - :commit diff --git a/app/services/projects/import_export/import_export_reader.rb b/app/services/projects/import_export/import_export_reader.rb index e0617ce851c5d0..001d24af604d8a 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/app/services/projects/import_export/import_export_reader.rb @@ -7,6 +7,10 @@ def project_tree { only: atts_only[:project], include: build_hash(tree) } end + def tree + config[:project_tree] + end + private def config @@ -21,10 +25,6 @@ def atts_except config[:attributes_except] end - def tree - config[:project_tree] - end - def build_hash(array) array.map do |el| if el.is_a?(Hash) diff --git a/app/services/projects/import_export/project_tree_saver.rb b/app/services/projects/import_export/project_tree_saver.rb index 44d100acd1dd12..b2ca85bd7c687b 100644 --- a/app/services/projects/import_export/project_tree_saver.rb +++ b/app/services/projects/import_export/project_tree_saver.rb @@ -30,8 +30,6 @@ def project_filename end def project_json_tree - # TODO confirm children, also add subchildren (i.e comments) - # TODO confirm atts for children @project.to_json(Projects::ImportExport.project_tree) end end diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index 960109e0c84ebe..eda9e08cdce2e8 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -3,6 +3,8 @@ describe Projects::ImportExport::ProjectTreeSaver, services: true do describe :save do + # TODO refactor this into a setup method + let(:user) { create(:user) } let(:issue) { create(:issue, assignee: user) } let(:merge_request) { create(:merge_request) } @@ -25,6 +27,8 @@ let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) } + let!(:issue_note) { create(:note, note: ":+1: issue", noteable: issue) } + let!(:merge_request_note) { create(:note, note: ":+1: merge_request", noteable: merge_request) } before(:each) do project.team << [user, :master] @@ -78,6 +82,10 @@ expect(saved_project_json['issues']).not_to be_empty end + it 'has issue comments' do + expect(saved_project_json['issues'].first['notes']).not_to be_empty + end + it 'has commit statuses' do expect(saved_project_json['commit_statuses']).not_to be_empty end @@ -90,6 +98,10 @@ expect(saved_project_json['merge_requests'].first['merge_request_diff']).not_to be_empty end + it 'has merge requests comments' do + expect(saved_project_json['merge_requests'].first['notes']).not_to be_empty + end + it 'has ci commits' do expect(saved_project_json['commit_statuses'].first['commit']).not_to be_empty end @@ -99,163 +111,4 @@ def project_json(filename) JSON.parse(IO.read(filename)) end - - # TODO: Remove this. Current JSON pretty printed: - # { - # "id":7, - # "name":"searchable_project", - # "path":"gitlabhq", - # "description":null, - # "issues_enabled":true, - # "wall_enabled":false, - # "merge_requests_enabled":true, - # "wiki_enabled":true, - # "snippets_enabled":true, - # "visibility_level":20, - # "archived":false, - # "issues":[ - # { - # "id":1, - # "title":"Voluptas dolores molestias iste excepturi quia atque sint et.", - # "assignee_id":1, - # "author_id":2, - # "project_id":7, - # "created_at":"2016-03-08T09:14:31.726Z", - # "updated_at":"2016-03-08T09:14:36.293Z", - # "position":0, - # "branch_name":null, - # "description":null, - # "milestone_id":null, - # "state":"opened", - # "iid":1, - # "updated_by_id":null - # } - # ], - # "merge_requests":[ - # { - # "id":1, - # "target_branch":"feature", - # "source_branch":"master", - # "source_project_id":2, - # "author_id":5, - # "assignee_id":null, - # "title":"Quam velit cupiditate culpa perspiciatis esse maiores quaerat.", - # "created_at":"2016-03-08T09:14:32.597Z", - # "updated_at":"2016-03-08T09:14:32.597Z", - # "milestone_id":null, - # "state":"opened", - # "merge_status":"can_be_merged", - # "target_project_id":7, - # "iid":1, - # "description":null, - # "position":0, - # "locked_at":null, - # "updated_by_id":null, - # "merge_error":null, - # "merge_params":{ - # - # }, - # "merge_when_build_succeeds":false, - # "merge_user_id":null, - # "merge_commit_sha":null - # } - # ], - # "labels":[ - # { - # "id":1, - # "title":"Bug", - # "color":"#990000", - # "project_id":7, - # "created_at":"2016-03-08T09:14:33.774Z", - # "updated_at":"2016-03-08T09:14:36.314Z", - # "template":false, - # "description":null - # } - # ], - # "milestones":[ - # { - # "id":1, - # "title":"Milestone v1.2", - # "project_id":7, - # "description":null, - # "due_date":null, - # "created_at":"2016-03-08T09:14:36.526Z", - # "updated_at":"2016-03-08T09:14:36.526Z", - # "state":"active", - # "iid":1 - # } - # ], - # "snippets":[ - # { - # "id":1, - # "title":"Voluptatem qui officiis modi ut fugit distinctio dolor qui.", - # "content":"Quaerat sunt eligendi voluptatum magnam.", - # "author_id":12, - # "project_id":7, - # "created_at":"2016-03-08T09:14:34.539Z", - # "updated_at":"2016-03-08T09:14:36.332Z", - # "file_name":"rowland.tremblay", - # "expires_at":null, - # "visibility_level":0 - # } - # ], - # "releases":[ - # { - # "id":1, - # "tag":"v1.1.0", - # "description":"Awesome release", - # "project_id":7, - # "created_at":"2016-03-08T09:14:35.023Z", - # "updated_at":"2016-03-08T09:14:36.351Z" - # } - # ], - # "events":[ - # { - # "id":1, - # "target_type":null, - # "target_id":null, - # "title":null, - # "data":null, - # "project_id":7, - # "created_at":"2016-03-08T09:14:36.806Z", - # "updated_at":"2016-03-08T09:14:36.806Z", - # "action":8, - # "author_id":1 - # } - # ], - # "commit_statuses":[ - # { - # "id":1, - # "project_id":null, - # "status":"success", - # "finished_at":"2016-01-26T07:23:42.000Z", - # "trace":null, - # "created_at":"2016-03-08T09:14:35.633Z", - # "updated_at":"2016-03-08T09:14:36.385Z", - # "started_at":"2016-01-26T07:21:42.000Z", - # "runner_id":null, - # "coverage":null, - # "commit_id":1, - # "commands":null, - # "job_id":null, - # "name":"default", - # "deploy":false, - # "options":null, - # "allow_failure":false, - # "stage":null, - # "trigger_request_id":null, - # "stage_idx":null, - # "tag":null, - # "ref":null, - # "user_id":null, - # "target_url":null, - # "description":"commit status", - # "artifacts_file":null, - # "gl_project_id":7, - # "artifacts_metadata":null, - # "erased_by_id":null, - # "erased_at":null - # } - # ] - # } end -- GitLab From 0d8a97dcef64967e3a8912e53ec8c91b54ccfe2e Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 17:10:30 +0200 Subject: [PATCH 048/714] some more fixes to import projects --- .../import_export/project_tree_restorer.rb | 13 +- .../import_export/relation_factory.rb | 4 +- fixtures/import_export/project.json | 433 +++++++++++++++++- 3 files changed, 445 insertions(+), 5 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 251221c2a6f6c7..2d9dee1031a416 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -58,12 +58,21 @@ def create_sub_relations(relation, tree_hash) relation.values.flatten.each do |sub_relation| relation_hash = relation_item[sub_relation.to_s] next if relation_hash.blank? - sub_relation_object = relation_from_factory(sub_relation, relation_hash) - relation_item[sub_relation.to_s] = sub_relation_object + process_sub_relation(relation_hash, relation_item, sub_relation) end end end + def process_sub_relation(relation_hash, relation_item, sub_relation) + sub_relation_object = nil + if relation_hash.is_a?(Array) + sub_relation_object = create_relation(sub_relation, relation_hash) + else + sub_relation_object = relation_from_factory(sub_relation, relation_hash) + end + relation_item[sub_relation.to_s] = sub_relation_object + end + def create_relation(relation, relation_hash_list) [relation_hash_list].flatten.map do |relation_hash| relation_from_factory(relation, relation_hash) diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 31d812036456f9..29917fce2bac38 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -48,8 +48,8 @@ def imported_object(klass, relation_hash) def parse_relation(relation_hash, relation_sym) klass = relation_class(relation_sym) - relation_hash.delete('id') #screw IDs for now - relation_hash.delete('project_id') unless klass.column_names.include?(:project_id) + relation_hash.delete('id') + relation_hash.delete('project_id') unless klass.column_names.include?('project_id') klass end end diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json index d21e754ce3d186..a2fed10b85efc7 100644 --- a/fixtures/import_export/project.json +++ b/fixtures/import_export/project.json @@ -1 +1,432 @@ -{"name":"searchable_project","path":"gitlabhq","description":null,"issues_enabled":true,"wall_enabled":false,"merge_requests_enabled":true,"wiki_enabled":true,"snippets_enabled":true,"visibility_level":20,"archived":false,"issues":[{"id":2,"title":"Libero explicabo dolores atque quae debitis sit ipsam unde.","assignee_id":19,"author_id":20,"project_id":14,"created_at":"2016-03-14T11:56:57.324Z","updated_at":"2016-03-14T11:57:02.118Z","position":0,"branch_name":null,"description":null,"milestone_id":null,"state":"opened","iid":1,"updated_by_id":null}],"labels":[{"id":2,"title":"Bug","color":"#990000","project_id":14,"created_at":"2016-03-14T11:56:59.538Z","updated_at":"2016-03-14T11:57:02.132Z","template":false,"description":null}],"milestones":[{"id":2,"title":"Milestone v1.2","project_id":14,"description":null,"due_date":null,"created_at":"2016-03-14T11:57:02.241Z","updated_at":"2016-03-14T11:57:02.241Z","state":"active","iid":1}],"releases":[{"id":2,"tag":"v1.1.0","description":"Awesome release","project_id":14,"created_at":"2016-03-14T11:57:00.950Z","updated_at":"2016-03-14T11:57:02.159Z"}],"events":[{"id":2,"target_type":null,"target_id":null,"title":null,"data":null,"project_id":14,"created_at":"2016-03-14T11:57:02.392Z","updated_at":"2016-03-14T11:57:02.392Z","action":8,"author_id":19}],"snippets":[{"id":2,"title":"Et qui optio blanditiis non.","content":"Repudiandae hic id vero adipisci.","author_id":28,"project_id":14,"created_at":"2016-03-14T11:57:00.372Z","updated_at":"2016-03-14T11:57:02.144Z","file_name":"krystina","visibility_level":0}],"project_members":[{"id":2,"access_level":40,"source_id":14,"source_type":"Project","user_id":19,"notification_level":3,"created_at":"2016-03-14T11:57:02.335Z","updated_at":"2016-03-14T11:57:02.335Z","created_by_id":null,"invite_email":null,"invite_token":null,"invite_accepted_at":null,"user":{"id":19,"email":"braxton@greenholttromp.ca","username":"elena19"}}],"merge_requests":[{"id":2,"target_branch":"feature","source_branch":"master","source_project_id":9,"author_id":23,"assignee_id":null,"title":"Cum est in est et.","created_at":"2016-03-14T11:56:58.333Z","updated_at":"2016-03-14T11:56:58.333Z","milestone_id":null,"state":"opened","merge_status":"can_be_merged","target_project_id":14,"iid":1,"description":null,"position":0,"locked_at":null,"updated_by_id":null,"merge_error":null,"merge_params":{},"merge_when_build_succeeds":false,"merge_user_id":null,"merge_commit_sha":null,"merge_request_diff":{"id":2,"state":"collected","st_commits":[{"id":"5937ac0a7beb003549fc5fd26fc247adbce4a52e","message":"Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["570e7b2abdd848b95f2f578043fc23bd6f6fd24d"],"authored_date":"2014-02-27T10:01:38.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T10:01:38.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"570e7b2abdd848b95f2f578043fc23bd6f6fd24d","message":"Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"],"authored_date":"2014-02-27T09:57:31.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:57:31.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9","message":"More submodules\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["d14d6c0abdd253381df51a723d58691b2ee1ab08"],"authored_date":"2014-02-27T09:54:21.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:54:21.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"d14d6c0abdd253381df51a723d58691b2ee1ab08","message":"Remove ds_store files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["c1acaa58bbcbc3eafe538cb8274ba387047b69f8"],"authored_date":"2014-02-27T09:49:50.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:49:50.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"},{"id":"c1acaa58bbcbc3eafe538cb8274ba387047b69f8","message":"Ignore DS files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n","parent_ids":["ae73cb07c9eeaf35924a10f713b364d32b2dd34f"],"authored_date":"2014-02-27T09:48:32.000+01:00","author_name":"Dmitriy Zaporozhets","author_email":"dmitriy.zaporozhets@gmail.com","committed_date":"2014-02-27T09:48:32.000+01:00","committer_name":"Dmitriy Zaporozhets","committer_email":"dmitriy.zaporozhets@gmail.com"}],"st_diffs":[{"diff":"Binary files a/.DS_Store and /dev/null differ\n","new_path":".DS_Store","old_path":".DS_Store","a_mode":"100644","b_mode":"0","new_file":false,"renamed_file":false,"deleted_file":true},{"diff":"--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n","new_path":".gitignore","old_path":".gitignore","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n","new_path":".gitmodules","old_path":".gitmodules","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"Binary files a/files/.DS_Store and /dev/null differ\n","new_path":"files/.DS_Store","old_path":"files/.DS_Store","a_mode":"100644","b_mode":"0","new_file":false,"renamed_file":false,"deleted_file":true},{"diff":"--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" =\u003e path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" =\u003e path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output \u003c\u003c stdout.read\n @cmd_output \u003c\u003c stderr.read\n","new_path":"files/ruby/popen.rb","old_path":"files/ruby/popen.rb","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n","new_path":"files/ruby/regex.rb","old_path":"files/ruby/regex.rb","a_mode":"100644","b_mode":"100644","new_file":false,"renamed_file":false,"deleted_file":false},{"diff":"--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n","new_path":"gitlab-grack","old_path":"gitlab-grack","a_mode":"0","b_mode":"160000","new_file":true,"renamed_file":false,"deleted_file":false},{"diff":"--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n","new_path":"gitlab-shell","old_path":"gitlab-shell","a_mode":"0","b_mode":"160000","new_file":true,"renamed_file":false,"deleted_file":false}],"merge_request_id":2,"created_at":"2016-03-14T11:56:58.353Z","updated_at":"2016-03-14T11:56:58.635Z","base_commit_sha":"ae73cb07c9eeaf35924a10f713b364d32b2dd34f","real_size":"8"}}],"commit_statuses":[{"id":2,"project_id":null,"status":"success","finished_at":"2016-01-26T07:23:42.000Z","trace":null,"created_at":"2016-03-14T11:57:01.483Z","updated_at":"2016-03-14T11:57:02.190Z","started_at":"2016-01-26T07:21:42.000Z","runner_id":null,"coverage":null,"commit_id":2,"commands":null,"job_id":null,"name":"default","deploy":false,"options":null,"allow_failure":false,"stage":null,"trigger_request_id":null,"stage_idx":null,"tag":null,"ref":null,"user_id":null,"target_url":null,"description":"commit status","artifacts_file":null,"gl_project_id":14,"artifacts_metadata":null,"erased_by_id":null,"erased_at":null,"commit":{"id":2,"project_id":13,"ref":null,"sha":"97de212e80737a608d939f648d959671fb0a0142","before_sha":null,"push_data":null,"created_at":"2016-03-14T11:57:01.468Z","updated_at":"2016-03-14T11:57:01.468Z","tag":false,"yaml_errors":null,"committed_at":null,"gl_project_id":13}}]} \ No newline at end of file +{ + "name": "searchable_project", + "path": "gitlabhq", + "description": null, + "issues_enabled": true, + "wall_enabled": false, + "merge_requests_enabled": true, + "wiki_enabled": true, + "snippets_enabled": true, + "visibility_level": 20, + "archived": false, + "issues": [ + { + "id": 1, + "title": "Ad est est quia inventore eius suscipit molestiae.", + "assignee_id": 1, + "author_id": 2, + "project_id": 7, + "created_at": "2016-04-12T13:26:48.974Z", + "updated_at": "2016-04-12T13:26:55.496Z", + "position": 0, + "branch_name": null, + "description": null, + "milestone_id": null, + "state": "opened", + "iid": 1, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "notes": [ + { + "id": 1, + "note": ":+1: issue", + "noteable_type": "Issue", + "author_id": 21, + "created_at": "2016-04-12T13:26:55.480Z", + "updated_at": "2016-04-12T13:26:55.480Z", + "project_id": 8, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 1, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false + } + ] + } + ], + "labels": [ + { + "id": 1, + "title": "label1", + "color": "#990000", + "project_id": 7, + "created_at": "2016-04-12T13:26:51.027Z", + "updated_at": "2016-04-12T13:26:53.799Z", + "template": false, + "description": null + } + ], + "milestones": [ + { + "id": 1, + "title": "Milestone v1.2", + "project_id": 7, + "description": null, + "due_date": null, + "created_at": "2016-04-12T13:26:53.993Z", + "updated_at": "2016-04-12T13:26:53.993Z", + "state": "active", + "iid": 1 + } + ], + "snippets": [ + { + "id": 1, + "title": "Possimus harum est mollitia fugiat in.", + "content": "Itaque ipsum culpa quibusdam mollitia.", + "author_id": 10, + "project_id": 7, + "created_at": "2016-04-12T13:26:51.821Z", + "updated_at": "2016-04-12T13:26:53.811Z", + "file_name": "thomas_marquardt", + "visibility_level": 0 + } + ], + "releases": [ + { + "id": 1, + "tag": "v1.1.0", + "description": "Awesome release", + "project_id": 7, + "created_at": "2016-04-12T13:26:52.353Z", + "updated_at": "2016-04-12T13:26:53.823Z" + } + ], + "events": [ + { + "id": 1, + "target_type": null, + "target_id": null, + "title": null, + "data": null, + "project_id": 7, + "created_at": "2016-04-12T13:26:57.139Z", + "updated_at": "2016-04-12T13:26:57.139Z", + "action": 8, + "author_id": 1 + } + ], + "project_members": [ + { + "id": 1, + "user": { + "id": 1, + "email": "maybell_auer@gleasonolson.com", + "created_at": "2016-04-12T13:26:47.499Z", + "updated_at": "2016-04-12T13:26:47.499Z", + "name": "Charles Nitzsche", + "admin": false, + "projects_limit": 42, + "skype": "", + "linkedin": "", + "twitter": "", + "authentication_token": "nCBdoTPWP-5adipsFwEq", + "theme_id": 2, + "bio": null, + "username": "koby.zieme1", + "can_create_group": true, + "can_create_team": false, + "state": "active", + "color_scheme_id": 1, + "notification_level": 1, + "password_expires_at": null, + "created_by_id": null, + "last_credential_check_at": null, + "avatar": { + "url": null + }, + "hide_no_ssh_key": false, + "website_url": "", + "notification_email": "maybell_auer@gleasonolson.com", + "hide_no_password": false, + "password_automatically_set": false, + "location": null, + "encrypted_otp_secret": null, + "encrypted_otp_secret_iv": null, + "encrypted_otp_secret_salt": null, + "otp_required_for_login": false, + "otp_backup_codes": null, + "public_email": "", + "dashboard": "projects", + "project_view": "readme", + "consumed_timestep": null, + "layout": "fixed", + "hide_project_limit": false, + "otp_grace_period_started_at": null, + "ldap_email": false, + "external": false + } + } + ], + "merge_requests": [ + { + "id": 1, + "target_branch": "feature", + "source_branch": "master", + "source_project_id": 2, + "author_id": 5, + "assignee_id": null, + "title": "Natus vel molestiae ab et dolorem odit ut.", + "created_at": "2016-04-12T13:26:49.813Z", + "updated_at": "2016-04-12T13:26:56.806Z", + "milestone_id": null, + "state": "opened", + "merge_status": "can_be_merged", + "target_project_id": 7, + "iid": 1, + "description": null, + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "merge_request_diff": { + "id": 1, + "state": "collected", + "st_commits": [ + { + "id": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "message": "Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \n", + "parent_ids": [ + "570e7b2abdd848b95f2f578043fc23bd6f6fd24d" + ], + "authored_date": "2014-02-27T10:01:38.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T10:01:38.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d", + "message": "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \n", + "parent_ids": [ + "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" + ], + "authored_date": "2014-02-27T09:57:31.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:57:31.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9", + "message": "More submodules\n\nSigned-off-by: Dmitriy Zaporozhets \n", + "parent_ids": [ + "d14d6c0abdd253381df51a723d58691b2ee1ab08" + ], + "authored_date": "2014-02-27T09:54:21.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:54:21.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "d14d6c0abdd253381df51a723d58691b2ee1ab08", + "message": "Remove ds_store files\n\nSigned-off-by: Dmitriy Zaporozhets \n", + "parent_ids": [ + "c1acaa58bbcbc3eafe538cb8274ba387047b69f8" + ], + "authored_date": "2014-02-27T09:49:50.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:49:50.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "c1acaa58bbcbc3eafe538cb8274ba387047b69f8", + "message": "Ignore DS files\n\nSigned-off-by: Dmitriy Zaporozhets \n", + "parent_ids": [ + "ae73cb07c9eeaf35924a10f713b364d32b2dd34f" + ], + "authored_date": "2014-02-27T09:48:32.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:48:32.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + } + ], + "st_diffs": [ + { + "diff": "Binary files a/.DS_Store and /dev/null differ\n", + "new_path": ".DS_Store", + "old_path": ".DS_Store", + "a_mode": "100644", + "b_mode": "0", + "new_file": false, + "renamed_file": false, + "deleted_file": true, + "too_large": false + }, + { + "diff": "--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n", + "new_path": ".gitignore", + "old_path": ".gitignore", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n", + "new_path": ".gitmodules", + "old_path": ".gitmodules", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "Binary files a/files/.DS_Store and /dev/null differ\n", + "new_path": "files/.DS_Store", + "old_path": "files/.DS_Store", + "a_mode": "100644", + "b_mode": "0", + "new_file": false, + "renamed_file": false, + "deleted_file": true, + "too_large": false + }, + { + "diff": "--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" => path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" => path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output << stdout.read\n @cmd_output << stderr.read\n", + "new_path": "files/ruby/popen.rb", + "old_path": "files/ruby/popen.rb", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n", + "new_path": "files/ruby/regex.rb", + "old_path": "files/ruby/regex.rb", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n", + "new_path": "gitlab-grack", + "old_path": "gitlab-grack", + "a_mode": "0", + "b_mode": "160000", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n", + "new_path": "gitlab-shell", + "old_path": "gitlab-shell", + "a_mode": "0", + "b_mode": "160000", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 1, + "created_at": "2016-04-12T13:26:49.896Z", + "updated_at": "2016-04-12T13:26:50.189Z", + "base_commit_sha": "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", + "real_size": "8" + }, + "notes": [ + { + "id": 2, + "note": ":+1: merge_request", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-04-12T13:26:56.790Z", + "updated_at": "2016-04-12T13:26:56.790Z", + "project_id": 9, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 1, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false + } + ] + } + ], + "commit_statuses": [ + { + "id": 1, + "project_id": null, + "status": "success", + "finished_at": "2016-01-26T07:23:42.000Z", + "trace": null, + "created_at": "2016-04-12T13:26:53.034Z", + "updated_at": "2016-04-12T13:26:53.850Z", + "started_at": "2016-01-26T07:21:42.000Z", + "runner_id": null, + "coverage": null, + "commit_id": 1, + "commands": null, + "job_id": null, + "name": "default", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": null, + "trigger_request_id": null, + "stage_idx": null, + "tag": null, + "ref": null, + "user_id": null, + "target_url": null, + "description": "commit status", + "artifacts_file": null, + "gl_project_id": 7, + "artifacts_metadata": null, + "erased_by_id": null, + "erased_at": null, + "commit": { + "id": 1, + "project_id": 6, + "ref": null, + "sha": "97de212e80737a608d939f648d959671fb0a0142", + "before_sha": null, + "push_data": null, + "created_at": "2016-04-12T13:26:53.010Z", + "updated_at": "2016-04-12T13:26:53.010Z", + "tag": false, + "yaml_errors": null, + "committed_at": null, + "gl_project_id": 6 + } + } + ] +} \ No newline at end of file -- GitLab From 6f74c7d4827955d44f53eeef0701e4e3c0f718a1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 12 Apr 2016 18:06:57 +0200 Subject: [PATCH 049/714] fix export commits stuff --- .../projects/import_export/import_export.yml | 4 ++-- .../projects/import_export/project_tree_saver.rb | 2 +- .../import_export/project_tree_saver_spec.rb | 15 ++++++++------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/app/services/projects/import_export/import_export.yml b/app/services/projects/import_export/import_export.yml index c622447ef042fe..92f492e9013af9 100644 --- a/app/services/projects/import_export/import_export.yml +++ b/app/services/projects/import_export/import_export.yml @@ -12,8 +12,8 @@ - :merge_requests: - :merge_request_diff - :notes - - :commit_statuses: - - :commit + - :ci_commits: + - :statuses :attributes_only: :project: diff --git a/app/services/projects/import_export/project_tree_saver.rb b/app/services/projects/import_export/project_tree_saver.rb index b2ca85bd7c687b..37bf3e8e54552d 100644 --- a/app/services/projects/import_export/project_tree_saver.rb +++ b/app/services/projects/import_export/project_tree_saver.rb @@ -20,7 +20,7 @@ def save_to_disk File.write(full_path, project_json_tree) true rescue - #TODO: handle error + # TODO: handle error false end diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/services/projects/import_export/project_tree_saver_spec.rb index eda9e08cdce2e8..05ece41341069a 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/services/projects/import_export/project_tree_saver_spec.rb @@ -20,9 +20,10 @@ merge_requests: [merge_request], labels: [label], snippets: [snippet], - releases: [release], - commit_statuses: [commit_status]) + releases: [release] + ) end + let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) } let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } @@ -86,10 +87,6 @@ expect(saved_project_json['issues'].first['notes']).not_to be_empty end - it 'has commit statuses' do - expect(saved_project_json['commit_statuses']).not_to be_empty - end - it 'has project members' do expect(saved_project_json['project_members']).not_to be_empty end @@ -102,8 +99,12 @@ expect(saved_project_json['merge_requests'].first['notes']).not_to be_empty end + it 'has commit statuses' do + expect(saved_project_json['ci_commits'].first['statuses']).not_to be_empty + end + it 'has ci commits' do - expect(saved_project_json['commit_statuses'].first['commit']).not_to be_empty + expect(saved_project_json['ci_commits']).not_to be_empty end end end -- GitLab From 267fd01ce8fa1620d5fd597825c653630909d415 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 13 Apr 2016 17:47:14 +0200 Subject: [PATCH 050/714] fixed import and spec is now passing! --- .../import_export/project_tree_restorer.rb | 3 +- .../import_export/relation_factory.rb | 21 ++- fixtures/import_export/project.json | 170 +++++++++--------- 3 files changed, 99 insertions(+), 95 deletions(-) diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb index 2d9dee1031a416..62d3e06fdcdd72 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/app/services/projects/import_export/project_tree_restorer.rb @@ -25,14 +25,13 @@ def members_map def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) saved = [] relation_list.each do |relation| + next if !relation.is_a?(Hash) && tree_hash[relation.to_s].blank? if relation.is_a?(Hash) create_sub_relations(relation, tree_hash) end relation_key = relation.is_a?(Hash) ? relation.keys.first : relation relation_hash = create_relation(relation_key, tree_hash[relation_key.to_s]) saved << project.update_attribute(relation_key, relation_hash) - # FIXME - # next if tree_hash[relation.to_s].blank? end saved.all? end diff --git a/app/services/projects/import_export/relation_factory.rb b/app/services/projects/import_export/relation_factory.rb index 29917fce2bac38..8fce8757228b01 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/app/services/projects/import_export/relation_factory.rb @@ -3,27 +3,21 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets, commit: 'Ci::Commit' }.freeze + OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status' }.freeze USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze def create(relation_sym:, relation_hash:, members_map:) relation_sym = parse_relation_sym(relation_sym) klass = parse_relation(relation_hash, relation_sym) - handle_merge_requests(relation_hash) if relation_sym == :merge_requests update_user_references(relation_hash, members_map) + update_project_references(relation_hash, klass) imported_object(klass, relation_hash) end private - def handle_merge_requests(relation_hash) - relation_hash['target_project_id'] = relation_hash.delete('project_id') - relation_hash['source_project_id'] = -1 - end - - #TODO nice to have, optimize this to only get called for specific models def update_user_references(relation_hash, members_map) USER_REFERENCES.each do |reference| if relation_hash[reference] @@ -32,6 +26,16 @@ def update_user_references(relation_hash, members_map) end end + def update_project_references(relation_hash, klass) + project_id = relation_hash.delete('project_id') + + # project_id may not be part of the export, but we always need to populate it if required. + relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') + relation_hash['gl_project_id'] = project_id if relation_hash ['gl_project_id'] + relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] + relation_hash['source_project_id'] = -1 if relation_hash['source_project_id'] + end + def relation_class(relation_sym) relation_sym.to_s.classify.constantize end @@ -49,7 +53,6 @@ def imported_object(klass, relation_hash) def parse_relation(relation_hash, relation_sym) klass = relation_class(relation_sym) relation_hash.delete('id') - relation_hash.delete('project_id') unless klass.column_names.include?('project_id') klass end end diff --git a/fixtures/import_export/project.json b/fixtures/import_export/project.json index a2fed10b85efc7..4a12c951dcbc49 100644 --- a/fixtures/import_export/project.json +++ b/fixtures/import_export/project.json @@ -12,12 +12,12 @@ "issues": [ { "id": 1, - "title": "Ad est est quia inventore eius suscipit molestiae.", + "title": "Debitis vero omnis cum accusamus nihil rerum cupiditate.", "assignee_id": 1, "author_id": 2, - "project_id": 7, - "created_at": "2016-04-12T13:26:48.974Z", - "updated_at": "2016-04-12T13:26:55.496Z", + "project_id": 6, + "created_at": "2016-04-13T14:40:32.471Z", + "updated_at": "2016-04-13T14:40:38.956Z", "position": 0, "branch_name": null, "description": null, @@ -34,8 +34,8 @@ "note": ":+1: issue", "noteable_type": "Issue", "author_id": 21, - "created_at": "2016-04-12T13:26:55.480Z", - "updated_at": "2016-04-12T13:26:55.480Z", + "created_at": "2016-04-13T14:40:38.944Z", + "updated_at": "2016-04-13T14:40:38.944Z", "project_id": 8, "attachment": { "url": null @@ -56,9 +56,9 @@ "id": 1, "title": "label1", "color": "#990000", - "project_id": 7, - "created_at": "2016-04-12T13:26:51.027Z", - "updated_at": "2016-04-12T13:26:53.799Z", + "project_id": 6, + "created_at": "2016-04-13T14:40:34.704Z", + "updated_at": "2016-04-13T14:40:36.891Z", "template": false, "description": null } @@ -67,11 +67,11 @@ { "id": 1, "title": "Milestone v1.2", - "project_id": 7, + "project_id": 6, "description": null, "due_date": null, - "created_at": "2016-04-12T13:26:53.993Z", - "updated_at": "2016-04-12T13:26:53.993Z", + "created_at": "2016-04-13T14:40:37.901Z", + "updated_at": "2016-04-13T14:40:37.901Z", "state": "active", "iid": 1 } @@ -79,13 +79,13 @@ "snippets": [ { "id": 1, - "title": "Possimus harum est mollitia fugiat in.", - "content": "Itaque ipsum culpa quibusdam mollitia.", + "title": "Illo ipsa maxime magni aut.", + "content": "Excepturi delectus ut harum est molestiae dolor.", "author_id": 10, - "project_id": 7, - "created_at": "2016-04-12T13:26:51.821Z", - "updated_at": "2016-04-12T13:26:53.811Z", - "file_name": "thomas_marquardt", + "project_id": 6, + "created_at": "2016-04-13T14:40:35.603Z", + "updated_at": "2016-04-13T14:40:36.903Z", + "file_name": "daphne.mraz", "visibility_level": 0 } ], @@ -94,9 +94,9 @@ "id": 1, "tag": "v1.1.0", "description": "Awesome release", - "project_id": 7, - "created_at": "2016-04-12T13:26:52.353Z", - "updated_at": "2016-04-12T13:26:53.823Z" + "project_id": 6, + "created_at": "2016-04-13T14:40:36.223Z", + "updated_at": "2016-04-13T14:40:36.913Z" } ], "events": [ @@ -106,9 +106,9 @@ "target_id": null, "title": null, "data": null, - "project_id": 7, - "created_at": "2016-04-12T13:26:57.139Z", - "updated_at": "2016-04-12T13:26:57.139Z", + "project_id": 6, + "created_at": "2016-04-13T14:40:40.122Z", + "updated_at": "2016-04-13T14:40:40.122Z", "action": 8, "author_id": 1 } @@ -118,19 +118,19 @@ "id": 1, "user": { "id": 1, - "email": "maybell_auer@gleasonolson.com", - "created_at": "2016-04-12T13:26:47.499Z", - "updated_at": "2016-04-12T13:26:47.499Z", - "name": "Charles Nitzsche", + "email": "norval.gulgowski@schambergerboyle.co.uk", + "created_at": "2016-04-13T14:40:30.963Z", + "updated_at": "2016-04-13T14:40:30.963Z", + "name": "Jalon Cormier DVM", "admin": false, "projects_limit": 42, "skype": "", "linkedin": "", "twitter": "", - "authentication_token": "nCBdoTPWP-5adipsFwEq", + "authentication_token": "tt-mPSZFvRBu8QzkW1Ss", "theme_id": 2, "bio": null, - "username": "koby.zieme1", + "username": "vance.turner1", "can_create_group": true, "can_create_team": false, "state": "active", @@ -144,7 +144,7 @@ }, "hide_no_ssh_key": false, "website_url": "", - "notification_email": "maybell_auer@gleasonolson.com", + "notification_email": "norval.gulgowski@schambergerboyle.co.uk", "hide_no_password": false, "password_automatically_set": false, "location": null, @@ -173,13 +173,13 @@ "source_project_id": 2, "author_id": 5, "assignee_id": null, - "title": "Natus vel molestiae ab et dolorem odit ut.", - "created_at": "2016-04-12T13:26:49.813Z", - "updated_at": "2016-04-12T13:26:56.806Z", + "title": "Dignissimos officia sit aut id dolor iure voluptatem expedita.", + "created_at": "2016-04-13T14:40:33.381Z", + "updated_at": "2016-04-13T14:40:39.850Z", "milestone_id": null, "state": "opened", "merge_status": "can_be_merged", - "target_project_id": 7, + "target_project_id": 6, "iid": 1, "description": null, "position": 0, @@ -353,8 +353,8 @@ } ], "merge_request_id": 1, - "created_at": "2016-04-12T13:26:49.896Z", - "updated_at": "2016-04-12T13:26:50.189Z", + "created_at": "2016-04-13T14:40:33.474Z", + "updated_at": "2016-04-13T14:40:33.834Z", "base_commit_sha": "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", "real_size": "8" }, @@ -364,8 +364,8 @@ "note": ":+1: merge_request", "noteable_type": "MergeRequest", "author_id": 24, - "created_at": "2016-04-12T13:26:56.790Z", - "updated_at": "2016-04-12T13:26:56.790Z", + "created_at": "2016-04-13T14:40:39.832Z", + "updated_at": "2016-04-13T14:40:39.832Z", "project_id": 9, "attachment": { "url": null @@ -381,52 +381,54 @@ ] } ], - "commit_statuses": [ + "ci_commits": [ { - "id": 1, - "project_id": null, - "status": "success", - "finished_at": "2016-01-26T07:23:42.000Z", - "trace": null, - "created_at": "2016-04-12T13:26:53.034Z", - "updated_at": "2016-04-12T13:26:53.850Z", - "started_at": "2016-01-26T07:21:42.000Z", - "runner_id": null, - "coverage": null, - "commit_id": 1, - "commands": null, - "job_id": null, - "name": "default", - "deploy": false, - "options": null, - "allow_failure": false, - "stage": null, - "trigger_request_id": null, - "stage_idx": null, - "tag": null, - "ref": null, - "user_id": null, - "target_url": null, - "description": "commit status", - "artifacts_file": null, - "gl_project_id": 7, - "artifacts_metadata": null, - "erased_by_id": null, - "erased_at": null, - "commit": { - "id": 1, - "project_id": 6, - "ref": null, - "sha": "97de212e80737a608d939f648d959671fb0a0142", - "before_sha": null, - "push_data": null, - "created_at": "2016-04-12T13:26:53.010Z", - "updated_at": "2016-04-12T13:26:53.010Z", - "tag": false, - "yaml_errors": null, - "committed_at": null, - "gl_project_id": 6 - } + "id": 2, + "project_id": 6, + "ref": "master", + "sha": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "before_sha": null, + "push_data": null, + "created_at": "2016-04-13T14:40:37.759Z", + "updated_at": "2016-04-13T14:40:37.759Z", + "tag": false, + "yaml_errors": null, + "committed_at": null, + "gl_project_id": 6, + "statuses": [ + { + "id": 1, + "project_id": null, + "status": "success", + "finished_at": "2016-01-26T07:23:42.000Z", + "trace": null, + "created_at": "2016-04-13T14:40:37.717Z", + "updated_at": "2016-04-13T14:40:37.771Z", + "started_at": "2016-01-26T07:21:42.000Z", + "runner_id": null, + "coverage": null, + "commit_id": 2, + "commands": null, + "job_id": null, + "name": "default", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": null, + "trigger_request_id": null, + "stage_idx": null, + "tag": null, + "ref": null, + "user_id": null, + "target_url": null, + "description": "commit status", + "artifacts_file": null, + "gl_project_id": 7, + "artifacts_metadata": null, + "erased_by_id": null, + "erased_at": null + } + ] } ] } \ No newline at end of file -- GitLab From 0852f539aa389c66ef377b7d567c931f928e147f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 14 Apr 2016 16:57:25 +0200 Subject: [PATCH 051/714] refactored stuff, added a save and compress all class and moved mostly everything to lib --- .../projects/import_export/export_service.rb | 11 ++++-- .../projects => lib/gitlab}/import_export.rb | 6 +-- .../import_export/command_line_util.rb | 16 ++++++-- .../gitlab}/import_export/import_export.yml | 0 .../import_export/import_export_reader.rb | 4 +- .../import_export/project_tree_saver.rb | 5 +-- .../gitlab}/import_export/repo_bundler.rb | 4 +- lib/gitlab/import_export/saver.rb | 38 +++++++++++++++++++ .../gitlab}/import_export/shared.rb | 4 +- .../import_export/wiki_repo_bundler.rb | 2 +- .../import_export_reader_spec.rb | 2 +- .../import_export/project_tree_saver_spec.rb | 8 ++-- .../import_export/repo_bundler_spec.rb | 8 ++-- .../import_export/wiki_repo_bundler_spec.rb | 8 ++-- 14 files changed, 83 insertions(+), 33 deletions(-) rename {app/services/projects => lib/gitlab}/import_export.rb (68%) rename {app/services/projects => lib/gitlab}/import_export/command_line_util.rb (58%) rename {app/services/projects => lib/gitlab}/import_export/import_export.yml (100%) rename {app/services/projects => lib/gitlab}/import_export/import_export_reader.rb (96%) rename {app/services/projects => lib/gitlab}/import_export/project_tree_saver.rb (85%) rename {app/services/projects => lib/gitlab}/import_export/repo_bundler.rb (91%) create mode 100644 lib/gitlab/import_export/saver.rb rename {app/services/projects => lib/gitlab}/import_export/shared.rb (56%) rename {app/services/projects => lib/gitlab}/import_export/wiki_repo_bundler.rb (97%) rename spec/{services/projects => lib/gitlab}/import_export/import_export_reader_spec.rb (92%) rename spec/{services/projects => lib/gitlab}/import_export/project_tree_saver_spec.rb (89%) rename spec/{services/projects => lib/gitlab}/import_export/repo_bundler_spec.rb (55%) rename spec/{services/projects => lib/gitlab}/import_export/wiki_repo_bundler_spec.rb (61%) diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 99aa8489f65228..ce13942c5d723f 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -2,19 +2,24 @@ module Projects module ImportExport class ExportService < BaseService def execute(options = {}) - @shared = Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) + @shared = Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) save_project_tree bundle_repo + save_all end private def save_project_tree - Projects::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared).save + Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared).save end def bundle_repo - Projects::ImportExport::RepoBundler.new(project: project, shared: @shared).bundle + Gitlab::ImportExport::RepoBundler.new(project: project, shared: @shared).bundle + end + + def save_all + Gitlab::ImportExport::Saver.save(storage_path: @shared.export_path) end end end diff --git a/app/services/projects/import_export.rb b/lib/gitlab/import_export.rb similarity index 68% rename from app/services/projects/import_export.rb rename to lib/gitlab/import_export.rb index c74f1d3149072e..fe88850c33dca4 100644 --- a/app/services/projects/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -1,9 +1,9 @@ -module Projects +module Gitlab module ImportExport extend self def export_path(relative_path:) - File.join(storage_path, "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_gitlab_export/#{relative_path}") + File.join(storage_path, relative_path, "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_gitlab_export") end def project_atts @@ -11,7 +11,7 @@ def project_atts end def project_tree - Projects::ImportExport::ImportExportReader.project_tree + Gitlab::ImportExport::ImportExportReader.project_tree end private diff --git a/app/services/projects/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb similarity index 58% rename from app/services/projects/import_export/command_line_util.rb rename to lib/gitlab/import_export/command_line_util.rb index 3ca49e76c7fd04..7bf4b476b6c8d6 100644 --- a/app/services/projects/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -1,10 +1,12 @@ -module Projects +module Gitlab module ImportExport module CommandLineUtil def tar_cf(archive:, dir:) - cmd = %W(tar -cf #{archive} -C #{dir} .) - _output, status = Gitlab::Popen.popen(cmd) - status.zero? + tar_with_options(archive: archive, dir: dir, options: 'cf') + end + + def tar_czf(archive:, dir:) + tar_with_options(archive: archive, dir: dir, options: 'czf') end def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) @@ -12,6 +14,12 @@ def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path _output, status = Gitlab::Popen.popen(cmd) status.zero? end + + def tar_with_options(archive:, dir:, options:) + cmd = %W(tar -#{options} #{archive} -C #{dir} .) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end end end end diff --git a/app/services/projects/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml similarity index 100% rename from app/services/projects/import_export/import_export.yml rename to lib/gitlab/import_export/import_export.yml diff --git a/app/services/projects/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb similarity index 96% rename from app/services/projects/import_export/import_export_reader.rb rename to lib/gitlab/import_export/import_export_reader.rb index 001d24af604d8a..717d3026f9e668 100644 --- a/app/services/projects/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport module ImportExportReader extend self @@ -14,7 +14,7 @@ def tree private def config - @config ||= YAML.load_file('app/services/projects/import_export/import_export.yml') + @config ||= YAML.load_file('lib/gitlab/import_export/import_export.yml') end def atts_only diff --git a/app/services/projects/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb similarity index 85% rename from app/services/projects/import_export/project_tree_saver.rb rename to lib/gitlab/import_export/project_tree_saver.rb index 37bf3e8e54552d..b2615f8273b382 100644 --- a/app/services/projects/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport class ProjectTreeSaver attr_reader :full_path @@ -25,12 +25,11 @@ def save_to_disk end def project_filename - # TODO sanitize name "#{@project.name}.json" end def project_json_tree - @project.to_json(Projects::ImportExport.project_tree) + @project.to_json(Gitlab::ImportExport.project_tree) end end end diff --git a/app/services/projects/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb similarity index 91% rename from app/services/projects/import_export/repo_bundler.rb rename to lib/gitlab/import_export/repo_bundler.rb index d43fb4ea09e648..7a1c2a12a53613 100644 --- a/app/services/projects/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -1,7 +1,7 @@ -module Projects +module Gitlab module ImportExport class RepoBundler - include Projects::ImportExport::CommandLineUtil + include Gitlab::ImportExport::CommandLineUtil attr_reader :full_path diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb new file mode 100644 index 00000000000000..f26804d240289e --- /dev/null +++ b/lib/gitlab/import_export/saver.rb @@ -0,0 +1,38 @@ +module Gitlab + module ImportExport + class Saver + include Gitlab::ImportExport::CommandLineUtil + + def self.save(*args) + new(*args).save + end + + def initialize(storage_path:) + @storage_path = storage_path + end + + def save + if compress_and_save + remove_storage_path + archive_file + else + false + end + end + + private + + def compress_and_save + tar_czf(archive: archive_file, dir: @storage_path) + end + + def remove_storage_path + FileUtils.rm_rf(@storage_path) + end + + def archive_file + @archive_file ||= File.join(@storage_path, '..', 'project.tar.gz') + end + end + end +end diff --git a/app/services/projects/import_export/shared.rb b/lib/gitlab/import_export/shared.rb similarity index 56% rename from app/services/projects/import_export/shared.rb rename to lib/gitlab/import_export/shared.rb index 04fe01c0d6c2d4..a4ec33a6cf7fc9 100644 --- a/app/services/projects/import_export/shared.rb +++ b/lib/gitlab/import_export/shared.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport class Shared def initialize(opts) @@ -6,7 +6,7 @@ def initialize(opts) end def export_path - @export_path ||= Projects::ImportExport.export_path(relative_path: @opts[:relative_path]) + @export_path ||= Gitlab::ImportExport.export_path(relative_path: @opts[:relative_path]) end end end diff --git a/app/services/projects/import_export/wiki_repo_bundler.rb b/lib/gitlab/import_export/wiki_repo_bundler.rb similarity index 97% rename from app/services/projects/import_export/wiki_repo_bundler.rb rename to lib/gitlab/import_export/wiki_repo_bundler.rb index bf69936503d1bf..9ef0febee54f1c 100644 --- a/app/services/projects/import_export/wiki_repo_bundler.rb +++ b/lib/gitlab/import_export/wiki_repo_bundler.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport class WikiRepoBundler < RepoBundler def bundle diff --git a/spec/services/projects/import_export/import_export_reader_spec.rb b/spec/lib/gitlab/import_export/import_export_reader_spec.rb similarity index 92% rename from spec/services/projects/import_export/import_export_reader_spec.rb rename to spec/lib/gitlab/import_export/import_export_reader_spec.rb index f825292ce7e79e..e71c7b60b80d98 100644 --- a/spec/services/projects/import_export/import_export_reader_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_reader_spec.rb @@ -1,6 +1,6 @@ require 'rspec' -describe Projects::ImportExport::ImportExportReader do +describe Gitlab::ImportExport::ImportExportReader do let(:test_config) { 'spec/support/import_export/import_export.yml' } let(:project_tree_hash) do diff --git a/spec/services/projects/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb similarity index 89% rename from spec/services/projects/import_export/project_tree_saver_spec.rb rename to spec/lib/gitlab/import_export/project_tree_saver_spec.rb index 05ece41341069a..8a923dde46792d 100644 --- a/spec/services/projects/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Projects::ImportExport::ProjectTreeSaver, services: true do +describe Gitlab::ImportExport::ProjectTreeSaver, services: true do describe :save do # TODO refactor this into a setup method @@ -26,14 +26,14 @@ let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) } let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } - let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } - let(:project_tree_saver) { Projects::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) } + let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } + let(:project_tree_saver) { Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) } let!(:issue_note) { create(:note, note: ":+1: issue", noteable: issue) } let!(:merge_request_note) { create(:note, note: ":+1: merge_request", noteable: merge_request) } before(:each) do project.team << [user, :master] - allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) + allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) end after(:each) do diff --git a/spec/services/projects/import_export/repo_bundler_spec.rb b/spec/lib/gitlab/import_export/repo_bundler_spec.rb similarity index 55% rename from spec/services/projects/import_export/repo_bundler_spec.rb rename to spec/lib/gitlab/import_export/repo_bundler_spec.rb index 1f8ed41718f82f..23447d878a8bb9 100644 --- a/spec/services/projects/import_export/repo_bundler_spec.rb +++ b/spec/lib/gitlab/import_export/repo_bundler_spec.rb @@ -1,17 +1,17 @@ require 'spec_helper' -describe Projects::ImportExport::RepoBundler, services: true do +describe Gitlab::ImportExport::RepoBundler, services: true do describe :bundle do let(:user) { create(:user) } let!(:project) { create(:project, :public, name: 'searchable_project') } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } - let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } - let(:bundler) { Projects::ImportExport::RepoBundler.new(project: project, shared: shared) } + let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } + let(:bundler) { Gitlab::ImportExport::RepoBundler.new(project: project, shared: shared) } before(:each) do project.team << [user, :master] - allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) + allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) end after(:each) do diff --git a/spec/services/projects/import_export/wiki_repo_bundler_spec.rb b/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb similarity index 61% rename from spec/services/projects/import_export/wiki_repo_bundler_spec.rb rename to spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb index a589f81c5f9f46..6cc95edc2178c2 100644 --- a/spec/services/projects/import_export/wiki_repo_bundler_spec.rb +++ b/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb @@ -1,18 +1,18 @@ require 'spec_helper' -describe Projects::ImportExport::WikiRepoBundler, services: true do +describe Gitlab::ImportExport::WikiRepoBundler, services: true do describe :bundle do let(:user) { create(:user) } let!(:project) { create(:project, :public, name: 'searchable_project') } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } - let(:shared) { Projects::ImportExport::Shared.new(relative_path: project.path_with_namespace) } - let(:wiki_bundler) { Projects::ImportExport::WikiRepoBundler.new(project: project, shared: shared) } + let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } + let(:wiki_bundler) { Gitlab::ImportExport::WikiRepoBundler.new(project: project, shared: shared) } let!(:project_wiki) { ProjectWiki.new(project, user) } before(:each) do project.team << [user, :master] - allow_any_instance_of(Projects::ImportExport).to receive(:storage_path).and_return(export_path) + allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) project_wiki.wiki project_wiki.create_page("index", "test content") end -- GitLab From 97c3aff16fa94cee622cd00ffaa2e3a6469c1439 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 14 Apr 2016 17:10:57 +0200 Subject: [PATCH 052/714] refactored import stuff, moved to lib --- app/services/projects/import_export/import_service.rb | 2 +- .../gitlab}/import_export/members_mapper.rb | 2 +- .../gitlab}/import_export/project_factory.rb | 2 +- .../gitlab}/import_export/project_tree_restorer.rb | 10 +++++----- .../gitlab}/import_export/relation_factory.rb | 2 +- .../gitlab}/import_export/members_mapper_spec.rb | 4 ++-- .../import_export/project_tree_restorer_spec.rb | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) rename {app/services/projects => lib/gitlab}/import_export/members_mapper.rb (99%) rename {app/services/projects => lib/gitlab}/import_export/project_factory.rb (98%) rename {app/services/projects => lib/gitlab}/import_export/project_tree_restorer.rb (89%) rename {app/services/projects => lib/gitlab}/import_export/relation_factory.rb (99%) rename spec/{services/projects => lib/gitlab}/import_export/members_mapper_spec.rb (91%) rename spec/{services/projects => lib/gitlab}/import_export/project_tree_restorer_spec.rb (59%) diff --git a/app/services/projects/import_export/import_service.rb b/app/services/projects/import_export/import_service.rb index 3efddf75e48994..d188b2dc83bbb6 100644 --- a/app/services/projects/import_export/import_service.rb +++ b/app/services/projects/import_export/import_service.rb @@ -8,7 +8,7 @@ def execute(options = {}) private def restore_project_tree - Projects::ImportExport::ProjectTreeRestorer.new(path: @import_path).restore + Gitlab::ImportExport::ProjectTreeRestorer.new(path: @import_path).restore end def restore_repo diff --git a/app/services/projects/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb similarity index 99% rename from app/services/projects/import_export/members_mapper.rb rename to lib/gitlab/import_export/members_mapper.rb index 6d49d901bf3fca..d6124106f575fc 100644 --- a/app/services/projects/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport class MembersMapper diff --git a/app/services/projects/import_export/project_factory.rb b/lib/gitlab/import_export/project_factory.rb similarity index 98% rename from app/services/projects/import_export/project_factory.rb rename to lib/gitlab/import_export/project_factory.rb index 1ca0cfb8673bbf..c7137844a0a286 100644 --- a/app/services/projects/import_export/project_factory.rb +++ b/lib/gitlab/import_export/project_factory.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport module ProjectFactory extend self diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb similarity index 89% rename from app/services/projects/import_export/project_tree_restorer.rb rename to lib/gitlab/import_export/project_tree_restorer.rb index 62d3e06fdcdd72..4c0f6a2267bf75 100644 --- a/app/services/projects/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport class ProjectTreeRestorer attr_reader :project @@ -18,7 +18,7 @@ def restore private def members_map - @members ||= Projects::ImportExport::MembersMapper.map( + @members ||= Gitlab::ImportExport::MembersMapper.map( exported_members: @project_members, user: @user, project_id: project.id) end @@ -37,7 +37,7 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha end def default_relation_list - Projects::ImportExport::ImportExportReader.tree.reject { |model| model.is_a?(Hash) && model[:project_members] } + Gitlab::ImportExport::ImportExportReader.tree.reject { |model| model.is_a?(Hash) && model[:project_members] } end def project @@ -46,7 +46,7 @@ def project def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } - project = Projects::ImportExport::ProjectFactory.create( + project = Gitlab::ImportExport::ProjectFactory.create( project_params: project_params, user: @user) project.save project @@ -79,7 +79,7 @@ def create_relation(relation, relation_hash_list) end def relation_from_factory(relation, relation_hash) - Projects::ImportExport::RelationFactory.create( + Gitlab::ImportExport::RelationFactory.create( relation_sym: relation, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) end end diff --git a/app/services/projects/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb similarity index 99% rename from app/services/projects/import_export/relation_factory.rb rename to lib/gitlab/import_export/relation_factory.rb index 8fce8757228b01..dd992ef443eed3 100644 --- a/app/services/projects/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -1,4 +1,4 @@ -module Projects +module Gitlab module ImportExport module RelationFactory extend self diff --git a/spec/services/projects/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb similarity index 91% rename from spec/services/projects/import_export/members_mapper_spec.rb rename to spec/lib/gitlab/import_export/members_mapper_spec.rb index e222dd420536a2..9175356c641a1a 100644 --- a/spec/services/projects/import_export/members_mapper_spec.rb +++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Projects::ImportExport::MembersMapper, services: true do +describe Gitlab::ImportExport::MembersMapper, services: true do describe :map do let(:user) { create(:user) } @@ -31,7 +31,7 @@ end let(:members_mapper) do - Projects::ImportExport::MembersMapper.new( + Gitlab::ImportExport::MembersMapper.new( exported_members: exported_members, user: user, project_id: project.id) end diff --git a/spec/services/projects/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb similarity index 59% rename from spec/services/projects/import_export/project_tree_restorer_spec.rb rename to spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index 4c8d182a21313a..f3d3a57ddd7b7e 100644 --- a/spec/services/projects/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' -describe Projects::ImportExport::ProjectTreeRestorer, services: true do +describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do describe :restore do let(:user) { create(:user) } - let(:project_tree_restorer) { Projects::ImportExport::ProjectTreeRestorer.new(path: "fixtures/import_export/project.json", user: user) } + let(:project_tree_restorer) { Gitlab::ImportExport::ProjectTreeRestorer.new(path: "fixtures/import_export/project.json", user: user) } context 'JSON' do let(:restored_project_json) do -- GitLab From 41163fd55251edbfa0d0dd341e34c878563e4981 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 14 Apr 2016 18:01:21 +0200 Subject: [PATCH 053/714] some experimental UI stuff to test export --- app/controllers/projects_controller.rb | 9 +++++++++ .../projects/import_export/export_service.rb | 1 + app/views/projects/edit.html.haml | 13 +++++++++++++ config/routes.rb | 1 + 4 files changed, 24 insertions(+) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3cc37e59855d64..39ae3659a82b40 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -186,6 +186,15 @@ def housekeeping ) end + def export + ::Projects::ImportExport::ExportService.new(@project, current_user).execute + + redirect_to( + project_path(@project), + notice: "Project export successfully started" + ) + end + def toggle_star current_user.toggle_star(@project) @project.reload diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index ce13942c5d723f..8b641008a88e40 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -1,6 +1,7 @@ module Projects module ImportExport class ExportService < BaseService + def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) save_project_tree diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 6d872cd0b21883..8097ef5d889a83 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -132,6 +132,19 @@ = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project), method: :post, class: "btn btn-default" + .panel.panel-default + .panel-heading Export + .errors-holder + .panel-body + %p + Downloads a compressed version of the project that can be imported. + %br + + .form-actions + = link_to 'Export', export_namespace_project_path(@project.namespace, @project), + method: :post, class: "btn btn-default" + + - if can? current_user, :archive_project, @project - if @project.archived? .panel.panel-success diff --git a/config/routes.rb b/config/routes.rb index 842fbb99843a92..55d3084ed675e6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -433,6 +433,7 @@ post :housekeeping post :toggle_star post :markdown_preview + post :export get :autocomplete_sources get :activity end -- GitLab From 05edd5e6dc169e4987e5e98e9243fa85c5b6e4b8 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 15 Apr 2016 15:38:34 +0200 Subject: [PATCH 054/714] download export now working --- app/controllers/projects_controller.rb | 11 ++++++++++- app/views/projects/edit.html.haml | 7 +++++-- config/routes.rb | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 39ae3659a82b40..9fb4370ef90426 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -190,11 +190,15 @@ def export ::Projects::ImportExport::ExportService.new(@project, current_user).execute redirect_to( - project_path(@project), + edit_project_path(@project), notice: "Project export successfully started" ) end + def download_export + send_file export_project_path, disposition: 'attachment' + end + def toggle_star current_user.toggle_star(@project) @project.reload @@ -256,4 +260,9 @@ def repo_exists? def get_id project.repository.root_ref end + + def export_project_path + # TODO: move this, probably to ImportExport and refactor + File.join(Settings.shared['path'], 'tmp/project_exports', @project.path_with_namespace, 'project.tar.gz') + end end diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 8097ef5d889a83..37ac0aa1f5862c 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -133,7 +133,7 @@ method: :post, class: "btn btn-default" .panel.panel-default - .panel-heading Export + .panel-heading Export project .errors-holder .panel-body %p @@ -141,9 +141,12 @@ %br .form-actions - = link_to 'Export', export_namespace_project_path(@project.namespace, @project), + = link_to 'Generate new export', export_namespace_project_path(@project.namespace, @project), method: :post, class: "btn btn-default" + = link_to 'Download export', download_export_namespace_project_path(@project.namespace, @project), + method: :post, class: "btn btn-default" + - if can? current_user, :archive_project, @project - if @project.archived? diff --git a/config/routes.rb b/config/routes.rb index 55d3084ed675e6..21164ba0edaa68 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -434,6 +434,7 @@ post :toggle_star post :markdown_preview post :export + post :download_export get :autocomplete_sources get :activity end -- GitLab From ae777ea0618e8db8a552a831dc331fe7a7b1fe7a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 15 Apr 2016 18:14:28 +0200 Subject: [PATCH 055/714] WIP - importing file and repo --- .../projects/import_export/import_service.rb | 11 +++++-- lib/gitlab/import_export/command_line_util.rb | 14 +++++++++ lib/gitlab/import_export/importer.rb | 26 ++++++++++++++++ lib/gitlab/import_export/repo_restorer.rb | 31 +++++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 lib/gitlab/import_export/importer.rb create mode 100644 lib/gitlab/import_export/repo_restorer.rb diff --git a/app/services/projects/import_export/import_service.rb b/app/services/projects/import_export/import_service.rb index d188b2dc83bbb6..b252692cd77cc6 100644 --- a/app/services/projects/import_export/import_service.rb +++ b/app/services/projects/import_export/import_service.rb @@ -2,17 +2,24 @@ module Projects module ImportExport class ExportService < BaseService def execute(options = {}) + @import_path = options[:import_path] + restore_project_tree + restore_repo(project_tree.project) end private def restore_project_tree - Gitlab::ImportExport::ProjectTreeRestorer.new(path: @import_path).restore + project_tree.restore end - def restore_repo + def project_tree + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: @import_path, user: @current_user) + end + def restore_repo(project) + Gitlab::ImportExport::RepoRestorer.new(path: @import_path, project: project).restore end end end diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 7bf4b476b6c8d6..f9041e9f4e588d 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -5,6 +5,14 @@ def tar_cf(archive:, dir:) tar_with_options(archive: archive, dir: dir, options: 'cf') end + def untar_czf(archive:, dir:) + untar_with_options(archive: archive, dir: dir, options: 'czf') + end + + def untar_cf(archive:, dir:) + untar_with_options(archive: archive, dir: dir, options: 'cf') + end + def tar_czf(archive:, dir:) tar_with_options(archive: archive, dir: dir, options: 'czf') end @@ -20,6 +28,12 @@ def tar_with_options(archive:, dir:, options:) _output, status = Gitlab::Popen.popen(cmd) status.zero? end + + def untar_with_options(archive:, dir:, options:) + cmd = %W(tar -#{options} #{archive)} -C #{dir}) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end end end end diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb new file mode 100644 index 00000000000000..79f54000bb03ef --- /dev/null +++ b/lib/gitlab/import_export/importer.rb @@ -0,0 +1,26 @@ +module Gitlab + module ImportExport + class Importer + include Gitlab::ImportExport::CommandLineUtil + + def self.import(*args) + new(*args).import + end + + def initialize(archive_file:, storage_path:) + @archive_file = archive_file + @storage_path = storage_path + end + + def import + decompress_export + end + + private + + def decompress + untar_czf(archive: archive_file, dir: @storage_path) + end + end + end +end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb new file mode 100644 index 00000000000000..42126cabd9780d --- /dev/null +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -0,0 +1,31 @@ +module Gitlab + module ImportExport + class RepoRestorer + include Gitlab::ImportExport::CommandLineUtil + + def initialize(project: , path: ) + @project = project + @path = path + end + + def restore + return false unless File.exists?(@path) + # Move repos dir to 'repositories.old' dir + + FileUtils.mkdir_p(repos_path) + FileUtils.mkdir_p(path_to_repo) + untar_cf(archive: @path, dir: path_to_repo) + end + + private + + def repos_path + Gitlab.config.gitlab_shell.repos_path + end + + def path_to_repo + @project.repository.path_to_repo + end + end + end +end -- GitLab From 42567436863c96b7f184cc7a728b2da3d18852c8 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 22 Apr 2016 12:18:11 +0200 Subject: [PATCH 056/714] refactored path stuff --- lib/gitlab/import_export.rb | 4 +--- lib/gitlab/import_export/saver.rb | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index fe88850c33dca4..539eae13f33d05 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -3,7 +3,7 @@ module ImportExport extend self def export_path(relative_path:) - File.join(storage_path, relative_path, "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_gitlab_export") + File.join(storage_path, relative_path) end def project_atts @@ -14,8 +14,6 @@ def project_tree Gitlab::ImportExport::ImportExportReader.project_tree end - private - def storage_path File.join(Settings.shared['path'], 'tmp/project_exports') end diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index f26804d240289e..f87e0fdc7ea20a 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -31,7 +31,7 @@ def remove_storage_path end def archive_file - @archive_file ||= File.join(@storage_path, '..', 'project.tar.gz') + @archive_file ||= File.join(@storage_path, '..', "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_project_export.tar.gz") end end end -- GitLab From 8f973b8f6887da082c4e4c777dc3961fae32ab16 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 22 Apr 2016 12:45:20 +0200 Subject: [PATCH 057/714] more refactoring - easier guessing path changes --- .../projects/import_export/import_service.rb | 12 ++++++++---- lib/gitlab/import_export/command_line_util.rb | 4 ++-- lib/gitlab/import_export/importer.rb | 8 ++++---- lib/gitlab/import_export/project_tree_restorer.rb | 2 +- lib/gitlab/import_export/repo_restorer.rb | 4 ++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/services/projects/import_export/import_service.rb b/app/services/projects/import_export/import_service.rb index b252692cd77cc6..20eda2f228de14 100644 --- a/app/services/projects/import_export/import_service.rb +++ b/app/services/projects/import_export/import_service.rb @@ -2,8 +2,8 @@ module Projects module ImportExport class ExportService < BaseService def execute(options = {}) - - @import_path = options[:import_path] + archive_file = options[:archive_file] + Gitlab::ImportExport::Importer.import(archive_file: archive_file, storage_path: storage_path) restore_project_tree restore_repo(project_tree.project) end @@ -15,11 +15,15 @@ def restore_project_tree end def project_tree - @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: @import_path, user: @current_user) + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user) end def restore_repo(project) - Gitlab::ImportExport::RepoRestorer.new(path: @import_path, project: project).restore + Gitlab::ImportExport::RepoRestorer.new(path: storage_path, project: project).restore + end + + def storage_path + @storage_path ||= Gitlab::ImportExport.export_path(relative_path: project.path_with_namespace) end end end diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index f9041e9f4e588d..3665e2edb7d6f5 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -24,13 +24,13 @@ def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path end def tar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive} -C #{dir} .) + cmd = %W(tar -#{options} #{archive} -C #{dir}) _output, status = Gitlab::Popen.popen(cmd) status.zero? end def untar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive)} -C #{dir}) + cmd = %W(tar -#{options} #{archive} -C #{dir}) _output, status = Gitlab::Popen.popen(cmd) status.zero? end diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 79f54000bb03ef..9f399845437169 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -7,19 +7,19 @@ def self.import(*args) new(*args).import end - def initialize(archive_file:, storage_path:) + def initialize(archive_file: , storage_path:) @archive_file = archive_file @storage_path = storage_path end def import - decompress_export + decompress_archive end private - def decompress - untar_czf(archive: archive_file, dir: @storage_path) + def decompress_archive + untar_czf(archive: @archive_file, dir: @storage_path) end end end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 4c0f6a2267bf75..4e0f555afe93fc 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -4,7 +4,7 @@ class ProjectTreeRestorer attr_reader :project def initialize(path:, user:) - @path = path + @path = File.join(path, 'project.json') @user = user end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 42126cabd9780d..47be303e22ae83 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,9 +3,9 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project: , path: ) + def initialize(project: , path:, bundler_file: ) @project = project - @path = path + @path = File.join(path, bundler_file) end def restore -- GitLab From fedfba55194ed51c6a7510c01fa94091e92c71cf Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 22 Apr 2016 12:49:37 +0200 Subject: [PATCH 058/714] more refactoring - easier guessing path changes --- lib/gitlab/import_export/project_tree_saver.rb | 2 +- lib/gitlab/import_export/repo_bundler.rb | 2 +- lib/gitlab/import_export/wiki_repo_bundler.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index b2615f8273b382..f6fab0fe22d7cf 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -25,7 +25,7 @@ def save_to_disk end def project_filename - "#{@project.name}.json" + "project.json" end def project_json_tree diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index 7a1c2a12a53613..86c9501b708697 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -27,7 +27,7 @@ def bundle_to_disk end def project_filename - "#{@project.name}.bundle" + "project.bundle" end def path_to_repo diff --git a/lib/gitlab/import_export/wiki_repo_bundler.rb b/lib/gitlab/import_export/wiki_repo_bundler.rb index 9ef0febee54f1c..7821c671628094 100644 --- a/lib/gitlab/import_export/wiki_repo_bundler.rb +++ b/lib/gitlab/import_export/wiki_repo_bundler.rb @@ -19,7 +19,7 @@ def bundle_to_disk private def project_filename - "#{@project.name}.wiki.bundle" + "project.wiki.bundle" end def path_to_repo -- GitLab From acf297955a5546161ac5e52589ba4740f234a0ae Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 22 Apr 2016 17:44:59 +0200 Subject: [PATCH 059/714] gitlab import UI - icon, file selector, etc... Also updated font-awesome and modified import source settings. --- Gemfile | 2 +- Gemfile.lock | 4 ++-- app/assets/javascripts/behaviors/toggler_behavior.coffee | 1 + app/controllers/application_controller.rb | 6 +++++- app/models/application_setting.rb | 2 +- app/views/projects/_project_import_form.html.haml | 8 ++++++++ app/views/projects/new.html.haml | 9 ++++++++- db/schema.rb | 4 ++-- lib/gitlab/current_settings.rb | 2 +- lib/gitlab/import_sources.rb | 1 + 10 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 app/views/projects/_project_import_form.html.haml diff --git a/Gemfile b/Gemfile index 67cc3f34b8c7d3..f8bd26f36f3ed1 100644 --- a/Gemfile +++ b/Gemfile @@ -213,7 +213,7 @@ gem 'jquery-turbolinks', '~> 2.1.0' gem 'addressable', '~> 2.3.8' gem 'bootstrap-sass', '~> 3.3.0' -gem 'font-awesome-rails', '~> 4.2' +gem 'font-awesome-rails', '~> 4.6.1' gem 'gitlab_emoji', '~> 0.3.0' gem 'gon', '~> 6.0.1' gem 'jquery-atwho-rails', '~> 1.3.2' diff --git a/Gemfile.lock b/Gemfile.lock index b00d7b35c84561..7ce19ba7b70708 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -322,7 +322,7 @@ GEM fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) - font-awesome-rails (4.5.0.1) + font-awesome-rails (4.6.1.0) railties (>= 3.2, < 5.1) foreman (0.78.0) thor (~> 0.19.1) @@ -931,7 +931,7 @@ DEPENDENCIES flay flog fog (~> 1.36.0) - font-awesome-rails (~> 4.2) + font-awesome-rails (~> 4.6.1) foreman fuubar (~> 2.0.0) gemnasium-gitlab-service (~> 0.2) diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee index 177b6918270dcc..640cdfe15f633a 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee @@ -7,6 +7,7 @@ $ -> # %div.js-toggle-content # $("body").on "click", ".js-toggle-button", (e) -> + console.log(e); $(@).find('i'). toggleClass('fa fa-chevron-down'). toggleClass('fa fa-chevron-up') diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1c53b0b21a3695..7afde111a34e8a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,7 +23,7 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception helper_method :abilities, :can?, :current_application_settings - helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled? + helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?, :gitlab_project_import_enabled? rescue_from Encoding::CompatibilityError do |exception| log_exception(exception) @@ -325,6 +325,10 @@ def git_import_enabled? current_application_settings.import_sources.include?('git') end + def gitlab_project_import_enabled? + current_application_settings.import_sources.include?('gitlab_project') + end + def two_factor_authentication_required? current_application_settings.require_two_factor_authentication end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 36f88154232319..4e2c7c82406005 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -147,7 +147,7 @@ def self.create_from_defaults default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], restricted_signup_domains: Settings.gitlab['restricted_signup_domains'], - import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'], + import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git', 'gitlab_project'], shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'], max_artifacts_size: Settings.artifacts['max_size'], require_two_factor_authentication: false, diff --git a/app/views/projects/_project_import_form.html.haml b/app/views/projects/_project_import_form.html.haml new file mode 100644 index 00000000000000..62d4b55424c238 --- /dev/null +++ b/app/views/projects/_project_import_form.html.haml @@ -0,0 +1,8 @@ +.form-group.import-url-data + = f.label :import_url, class: 'control-label' do + %span GitLab export file + .col-sm-10 + = f.file_field :file, class: '' + + .well.prepend-top-20 + The project must have a valid Gitlab export format \ No newline at end of file diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index a4c6094c69af07..cf24c4cacf3f7b 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -88,10 +88,17 @@ - if git_import_enabled? = link_to "#", class: 'btn js-toggle-button import_git' do %i.fa.fa-git - %span Any repo by URL + %span Repo by URL + + - if gitlab_project_import_enabled? + = link_to "#", class: 'btn import_gitlab_project', onclick: '$(".js-toggle-content2").toggle();' do + %i.fa.fa-gitlab + %span GitLab project .js-toggle-content.hide = render "shared/import_form", f: f + .js-toggle-content2.hide + = render "project_import_form", f: f .prepend-botton-10 diff --git a/db/schema.rb b/db/schema.rb index 42457d92353468..f7dfd296aea7ae 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -78,8 +78,8 @@ t.boolean "email_author_in_body", default: false t.integer "default_group_visibility" t.boolean "repository_checks_enabled", default: false - t.integer "metrics_packet_size", default: 1 t.text "shared_runners_text" + t.integer "metrics_packet_size", default: 1 end create_table "audit_events", force: :cascade do |t| @@ -426,9 +426,9 @@ t.string "state" t.integer "iid" t.integer "updated_by_id" - t.integer "moved_to_id" t.boolean "confidential", default: false t.datetime "deleted_at" + t.integer "moved_to_id" t.date "due_date" end diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index f44d1b3a44ec91..688e780c13d739 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -29,7 +29,7 @@ def fake_application_settings default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], restricted_signup_domains: Settings.gitlab['restricted_signup_domains'], - import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'], + import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git', 'gitlab_project'], shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'], max_artifacts_size: Settings.artifacts['max_size'], require_two_factor_authentication: false, diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index ccfdfbe73e8fa9..2b5658a8b64fdc 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -21,6 +21,7 @@ def options 'Google Code' => 'google_code', 'FogBugz' => 'fogbugz', 'Any repo by URL' => 'git', + 'GitLab project' => 'gitlab_project' } end -- GitLab From e5a59331cf5221d39f9430480d449f30bbe8e63f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 22 Apr 2016 17:56:20 +0200 Subject: [PATCH 060/714] remove debug statement --- app/assets/javascripts/behaviors/toggler_behavior.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee index 640cdfe15f633a..177b6918270dcc 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee @@ -7,7 +7,6 @@ $ -> # %div.js-toggle-content # $("body").on "click", ".js-toggle-button", (e) -> - console.log(e); $(@).find('i'). toggleClass('fa fa-chevron-down'). toggleClass('fa fa-chevron-up') -- GitLab From 10f1609535742173d8747d3a1097ed7e919fb9e2 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 25 Apr 2016 18:00:15 +0200 Subject: [PATCH 061/714] changes to be picked by the UI branch --- .../import/gitlab_project_controller.rb | 46 +++++++++++++++++++ config/routes.rb | 6 +++ .../gitlab}/import_export/import_service.rb | 19 ++++++-- 3 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 app/controllers/import/gitlab_project_controller.rb rename {app/services/projects => lib/gitlab}/import_export/import_service.rb (63%) diff --git a/app/controllers/import/gitlab_project_controller.rb b/app/controllers/import/gitlab_project_controller.rb new file mode 100644 index 00000000000000..fa3e0c7876d2a5 --- /dev/null +++ b/app/controllers/import/gitlab_project_controller.rb @@ -0,0 +1,46 @@ +class Import::GitlabProjectController < Import::BaseController + before_action :verify_gitlab_project_import_enabled + before_action :gitlab_project_auth, except: :callback + + rescue_from OAuth::Error, with: :gitlab_project_unauthorized + + #TODO permissions stuff + + def callback + + redirect_to status_import_gitlab_project_url + end + + def status + @repos = client.projects + @incompatible_repos = client.incompatible_projects + + @already_added_projects = current_user.created_projects.where(import_type: "gitlab_project") + already_added_projects_names = @already_added_projects.pluck(:import_source) + + @repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } + end + + def jobs + jobs = current_user.created_projects.where(import_type: "gitlab_project").to_json(only: [:id, :import_status]) + render json: jobs + end + + def create + @file = params[:file] + # @project_name = + + repo_owner = current_user.username + @target_namespace = params[:new_namespace].presence || repo_owner + + namespace = get_or_create_namespace || (render and return) + + @project = Gitlab::ImportExport::ImportService.execute(archive_file: file, owner: repo_owner) + end + + private + + def verify_gitlab_project_import_enabled + render_404 unless gitlab_project_import_enabled? + end +end diff --git a/config/routes.rb b/config/routes.rb index 79b62a0b1bb4e0..df6116b6eaf335 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -156,6 +156,12 @@ get :new_user_map, path: :user_map post :create_user_map, path: :user_map end + + resource :gitlab_project, only: [:create, :new], controller: :gitlab_projects do + get :status + get :callback + get :jobs + end end # diff --git a/app/services/projects/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb similarity index 63% rename from app/services/projects/import_export/import_service.rb rename to lib/gitlab/import_export/import_service.rb index 20eda2f228de14..978a581f57add6 100644 --- a/app/services/projects/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -1,9 +1,18 @@ -module Projects +module Gitlab module ImportExport - class ExportService < BaseService - def execute(options = {}) - archive_file = options[:archive_file] - Gitlab::ImportExport::Importer.import(archive_file: archive_file, storage_path: storage_path) + class ImportService + + def self.execute(*args) + new(args).execute + end + + def initialize(options = {}) + @archive_file = options[:archive_file] + @current_user = options[:owner] + end + + def execute + Gitlab::ImportExport::Importer.import(archive_file: @archive_file, storage_path: storage_path) restore_project_tree restore_repo(project_tree.project) end -- GitLab From 28b0208e93cbc949e1c733c60ec577740d824623 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 26 Apr 2016 10:59:00 +0200 Subject: [PATCH 062/714] refactoring, mainly UI stuff to follow other import actions --- ...oller.rb => gitlab_projects_controller.rb} | 7 +-- .../import/gitlab_projects/new.html.haml | 17 ++++++ .../import/gitlab_projects/status.html.haml | 55 +++++++++++++++++++ .../projects/_project_import_form.html.haml | 8 --- app/views/projects/new.html.haml | 4 +- config/routes.rb | 1 - 6 files changed, 76 insertions(+), 16 deletions(-) rename app/controllers/import/{gitlab_project_controller.rb => gitlab_projects_controller.rb} (86%) create mode 100644 app/views/import/gitlab_projects/new.html.haml create mode 100644 app/views/import/gitlab_projects/status.html.haml delete mode 100644 app/views/projects/_project_import_form.html.haml diff --git a/app/controllers/import/gitlab_project_controller.rb b/app/controllers/import/gitlab_projects_controller.rb similarity index 86% rename from app/controllers/import/gitlab_project_controller.rb rename to app/controllers/import/gitlab_projects_controller.rb index fa3e0c7876d2a5..c99c97893ad594 100644 --- a/app/controllers/import/gitlab_project_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -1,14 +1,13 @@ -class Import::GitlabProjectController < Import::BaseController +class Import::GitlabProjectsController < Import::BaseController before_action :verify_gitlab_project_import_enabled - before_action :gitlab_project_auth, except: :callback + #before_action :gitlab_project_auth, except: :callback rescue_from OAuth::Error, with: :gitlab_project_unauthorized #TODO permissions stuff - def callback + def new - redirect_to status_import_gitlab_project_url end def status diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml new file mode 100644 index 00000000000000..64ea536698dc2e --- /dev/null +++ b/app/views/import/gitlab_projects/new.html.haml @@ -0,0 +1,17 @@ +- page_title "FogBugz Import" +- header_title "Projects", root_path +%h3.page-title + %i.fa.fa-bug + Import projects from FogBugz +%hr + += form_tag status_import_gitlab_project_url, class: 'form-horizontal' do + %p + To get started you add your project export file below. + .form-group + = label_tag :file, class: 'control-label' do + %span GitLab export file + .col-sm-10 + = file_field_tag :file, class: '' + .form-actions + = submit_tag 'Continue to the next step', class: 'btn btn-create' diff --git a/app/views/import/gitlab_projects/status.html.haml b/app/views/import/gitlab_projects/status.html.haml new file mode 100644 index 00000000000000..2b879f0c5954a2 --- /dev/null +++ b/app/views/import/gitlab_projects/status.html.haml @@ -0,0 +1,55 @@ +- page_title "Gitlab_project import" +- header_title "Projects", root_path +%h3.page-title + %i.icon-gitlab.icon-gitlab-big + Import Gitlab projects + +%p.light + Select projects you want to import. +%hr +%p + = button_tag class: "btn btn-import btn-success js-import-all" do + Import all projects + = icon("spinner spin", class: "loading-icon") + +.table-responsive + %table.table.import-jobs + %colgroup.import-jobs-from-col + %colgroup.import-jobs-to-col + %colgroup.import-jobs-status-col + %thead + %tr + %th From Gitlab_project.org + %th To GitLab + %th Status + %tbody + - @already_added_projects.each do |project| + %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} + %td + = link_to project.import_source, "https://gitlab_project.org/#{project.import_source}", target: "_blank" + %td + = link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] + %td.job-status + - if project.import_status == 'finished' + %span + %i.fa.fa-check + done + - elsif project.import_status == 'started' + %i.fa.fa-spinner.fa-spin + started + - else + = project.human_import_status_name + + - @repos.each do |repo| + %tr{id: "repo_#{repo.id}"} + %td + = link_to repo.full_name, "https://gitlab_project.org/#{repo.full_name}", target: "_blank" + %td.import-target + = repo.full_name + %td.import-actions.job-status + = button_tag class: "btn btn-import js-add-to-import" do + Import + = icon("spinner spin", class: "loading-icon") + +:javascript + new ImporterStatus("#{jobs_import_gitlab_project_path}", "#{import_gitlab_project_path}"); diff --git a/app/views/projects/_project_import_form.html.haml b/app/views/projects/_project_import_form.html.haml deleted file mode 100644 index 62d4b55424c238..00000000000000 --- a/app/views/projects/_project_import_form.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -.form-group.import-url-data - = f.label :import_url, class: 'control-label' do - %span GitLab export file - .col-sm-10 - = f.file_field :file, class: '' - - .well.prepend-top-20 - The project must have a valid Gitlab export format \ No newline at end of file diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index cf24c4cacf3f7b..d4bb57aafc7195 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -91,14 +91,12 @@ %span Repo by URL - if gitlab_project_import_enabled? - = link_to "#", class: 'btn import_gitlab_project', onclick: '$(".js-toggle-content2").toggle();' do + = link_to new_import_gitlab_project_path, class: 'btn import_gitlab_project' do %i.fa.fa-gitlab %span GitLab project .js-toggle-content.hide = render "shared/import_form", f: f - .js-toggle-content2.hide - = render "project_import_form", f: f .prepend-botton-10 diff --git a/config/routes.rb b/config/routes.rb index b4e1abd2768915..05e89e815009dd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -159,7 +159,6 @@ resource :gitlab_project, only: [:create, :new], controller: :gitlab_projects do get :status - get :callback get :jobs end end -- GitLab From 1d4c3fa1507fdfdecdc15091ac8ef8d9f5fb63d9 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 26 Apr 2016 13:01:51 +0200 Subject: [PATCH 063/714] more refactoring, now using custom job for processing project imports --- .../import/gitlab_projects_controller.rb | 4 ++-- app/models/project.rb | 10 +++++++++ .../import/gitlab_projects/new.html.haml | 2 +- app/workers/project_import_worker.rb | 22 +++++++++++++++++++ config/routes.rb | 1 + 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 app/workers/project_import_worker.rb diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index c99c97893ad594..0e94915765ce2f 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -26,7 +26,7 @@ def jobs end def create - @file = params[:file] + file = params[:file] # @project_name = repo_owner = current_user.username @@ -34,7 +34,7 @@ def create namespace = get_or_create_namespace || (render and return) - @project = Gitlab::ImportExport::ImportService.execute(archive_file: file, owner: repo_owner) + @project = Project.create_from_import_job(current_user.id, File.expand_path(file.path)) end private diff --git a/app/models/project.rb b/app/models/project.rb index 0420c6a61aee21..18e647045cd5eb 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -359,6 +359,16 @@ def trending(since = 1.month.ago) def visible_to_user(user) where(id: user.authorized_projects.select(:id).reorder(nil)) end + + def create_from_import_job(current_user_id:, tmp_file:) + job_id = ProjectImportWorker.perform_async(current_user_id, tmp_file) + + if job_id + Rails.logger.info "Import job started for #{path_with_namespace} with job ID #{job_id}" + else + Rails.logger.error "Import job failed to start for #{path_with_namespace}" + end + end end def team diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 64ea536698dc2e..9e798b8a63fe1a 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -5,7 +5,7 @@ Import projects from FogBugz %hr -= form_tag status_import_gitlab_project_url, class: 'form-horizontal' do += form_tag import_gitlab_project_path, class: 'form-horizontal' do %p To get started you add your project export file below. .form-group diff --git a/app/workers/project_import_worker.rb b/app/workers/project_import_worker.rb new file mode 100644 index 00000000000000..6dd514b56a0c1e --- /dev/null +++ b/app/workers/project_import_worker.rb @@ -0,0 +1,22 @@ +class ProjectImportWorker + include Sidekiq::Worker + include Gitlab::ShellAdapter + + sidekiq_options queue: :gitlab_shell + + def perform(current_user_id, tmp_file) + current_user = User.find(current_user_id) + + project = Gitlab::ImportExport::ImportService.execute(archive_file: tmp_file, owner: current_user) + + # TODO: Move this to import service + # if result[:status] == :error + # project.update(import_error: result[:message]) + # project.import_fail + # return + # end + + project.repository.after_import + project.import_finish + end +end diff --git a/config/routes.rb b/config/routes.rb index 05e89e815009dd..99ce0118104475 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -159,6 +159,7 @@ resource :gitlab_project, only: [:create, :new], controller: :gitlab_projects do get :status + post :create get :jobs end end -- GitLab From cbbc42e0c4e5888413a690a4e0760e3cadd55a63 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 26 Apr 2016 17:12:50 +0200 Subject: [PATCH 064/714] adding more UI changes, updated controller, worker and refactored import service --- .../import/gitlab_projects_controller.rb | 17 +++++++++++----- app/models/project.rb | 8 ++++---- .../import/gitlab_projects/new.html.haml | 2 +- app/workers/project_import_worker.rb | 9 ++++++--- lib/gitlab/import_export/import_service.rb | 20 ++++++++++++------- .../import_export/project_tree_restorer.rb | 1 + 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index 0e94915765ce2f..36be79a39c4acb 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -7,7 +7,8 @@ class Import::GitlabProjectsController < Import::BaseController #TODO permissions stuff def new - + @namespace_id = project_params[:namespace_id] + @path = project_params[:path] end def status @@ -27,14 +28,14 @@ def jobs def create file = params[:file] - # @project_name = repo_owner = current_user.username @target_namespace = params[:new_namespace].presence || repo_owner - namespace = get_or_create_namespace || (render and return) - - @project = Project.create_from_import_job(current_user.id, File.expand_path(file.path)) + @project = Project.create_from_import_job(current_user_id: current_user.id, + tmp_file: File.expand_path(file.path), + namespace_id: @namespace_id, + project_path: @path) end private @@ -42,4 +43,10 @@ def create def verify_gitlab_project_import_enabled render_404 unless gitlab_project_import_enabled? end + + def project_params + params.require(:project).permit( + :path, :namespace_id, + ) + end end diff --git a/app/models/project.rb b/app/models/project.rb index 18e647045cd5eb..70921e02759c41 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -360,13 +360,13 @@ def visible_to_user(user) where(id: user.authorized_projects.select(:id).reorder(nil)) end - def create_from_import_job(current_user_id:, tmp_file:) - job_id = ProjectImportWorker.perform_async(current_user_id, tmp_file) + def create_from_import_job(current_user_id:, tmp_file:, namespace_id:, project_path:) + job_id = ProjectImportWorker.perform_async(current_user_id, tmp_file, namespace_id, project_path) if job_id - Rails.logger.info "Import job started for #{path_with_namespace} with job ID #{job_id}" + Rails.logger.info "Import job started for export #{tmp_file} with job ID #{job_id}" else - Rails.logger.error "Import job failed to start for #{path_with_namespace}" + Rails.logger.error "Import job failed to start for #{tmp_file}" end end end diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 9e798b8a63fe1a..323b7810c591c5 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -5,7 +5,7 @@ Import projects from FogBugz %hr -= form_tag import_gitlab_project_path, class: 'form-horizontal' do += form_tag import_gitlab_project_path, class: 'form-horizontal', multipart: true do %p To get started you add your project export file below. .form-group diff --git a/app/workers/project_import_worker.rb b/app/workers/project_import_worker.rb index 6dd514b56a0c1e..0e8b9552442c30 100644 --- a/app/workers/project_import_worker.rb +++ b/app/workers/project_import_worker.rb @@ -2,12 +2,15 @@ class ProjectImportWorker include Sidekiq::Worker include Gitlab::ShellAdapter - sidekiq_options queue: :gitlab_shell + sidekiq_options queue: :gitlab_shell, retry: false - def perform(current_user_id, tmp_file) + def perform(current_user_id, tmp_file, namespace_id, path) current_user = User.find(current_user_id) - project = Gitlab::ImportExport::ImportService.execute(archive_file: tmp_file, owner: current_user) + project = Gitlab::ImportExport::ImportService.execute(archive_file: tmp_file, + owner: current_user, + namespace_id: namespace_id, + project_path: path) # TODO: Move this to import service # if result[:status] == :error diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 978a581f57add6..5152d6ac182e42 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -6,15 +6,17 @@ def self.execute(*args) new(args).execute end - def initialize(options = {}) - @archive_file = options[:archive_file] - @current_user = options[:owner] + def initialize(archive_file:, owner:, namespace_id:, project_path:) + @archive_file = archive_file + @current_user = owner + @namespace_path = Namespace.find(namespace_id).path + @project_path = project_path end def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, storage_path: storage_path) restore_project_tree - restore_repo(project_tree.project) + restore_repo end private @@ -27,12 +29,16 @@ def project_tree @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user) end - def restore_repo(project) - Gitlab::ImportExport::RepoRestorer.new(path: storage_path, project: project).restore + def restore_repo + Gitlab::ImportExport::RepoRestorer.new(path: storage_path, project: project_tree.project).restore end def storage_path - @storage_path ||= Gitlab::ImportExport.export_path(relative_path: project.path_with_namespace) + @storage_path ||= Gitlab::ImportExport.export_path(relative_path: path_with_namespace) + end + + def path_with_namespace + File.join(@namespace_path, @project_path) end end end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 4e0f555afe93fc..445f1d884d0661 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -49,6 +49,7 @@ def create_project project = Gitlab::ImportExport::ProjectFactory.create( project_params: project_params, user: @user) project.save + project.import_start project end -- GitLab From 34c826a3110700f401fac4242f6a5dd15884f33d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 27 Apr 2016 15:01:55 +0200 Subject: [PATCH 065/714] some JS magic to pass namespace and path importing projects --- app/controllers/import/gitlab_projects_controller.rb | 9 ++++++--- app/views/import/gitlab_projects/new.html.haml | 3 +++ app/views/projects/new.html.haml | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index 36be79a39c4acb..b141b5f472afd8 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -27,15 +27,18 @@ def jobs end def create + # TODO verify access to namespace and path file = params[:file] + namespace_id = project_params[:namespace_id] + path = project_params[:path] repo_owner = current_user.username @target_namespace = params[:new_namespace].presence || repo_owner @project = Project.create_from_import_job(current_user_id: current_user.id, tmp_file: File.expand_path(file.path), - namespace_id: @namespace_id, - project_path: @path) + namespace_id: namespace_id, + project_path: path) end private @@ -45,7 +48,7 @@ def verify_gitlab_project_import_enabled end def project_params - params.require(:project).permit( + params.permit( :path, :namespace_id, ) end diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 323b7810c591c5..1158a04ea46793 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -9,9 +9,12 @@ %p To get started you add your project export file below. .form-group + = hidden_field_tag :namespace_id, @namespace_id + = hidden_field_tag :path, @path = label_tag :file, class: 'control-label' do %span GitLab export file .col-sm-10 = file_field_tag :file, class: '' + .form-actions = submit_tag 'Continue to the next step', class: 'btn btn-create' diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index d4bb57aafc7195..b3d755b3790c77 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -91,7 +91,7 @@ %span Repo by URL - if gitlab_project_import_enabled? - = link_to new_import_gitlab_project_path, class: 'btn import_gitlab_project' do + = link_to new_import_gitlab_project_path, class: 'btn import_gitlab_project project-submit' do %i.fa.fa-gitlab %span GitLab project @@ -127,3 +127,7 @@ $('.modal-header .close').bind('click', function() { $(".modal").hide(); }); + $('.import_gitlab_project').bind('click', function() { + var _href = $("a.import_gitlab_project").attr("href"); + $(".import_gitlab_project").attr("href", _href + '?namespace_id=' + $("#project_namespace_id").val() + '&path=' + $("#project_path").val()); + }); -- GitLab From cec4ae55b728c76f797ada20125d5bbf2af0adb9 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 27 Apr 2016 18:07:40 +0200 Subject: [PATCH 066/714] quite a few fixes - import service --- lib/gitlab/import_export/command_line_util.rb | 12 +++--------- lib/gitlab/import_export/import_service.rb | 4 ++-- lib/gitlab/import_export/importer.rb | 1 + lib/gitlab/import_export/project_tree_restorer.rb | 4 +++- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 3665e2edb7d6f5..e8d41a6bd3dc21 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -6,11 +6,11 @@ def tar_cf(archive:, dir:) end def untar_czf(archive:, dir:) - untar_with_options(archive: archive, dir: dir, options: 'czf') + tar_with_options(archive: archive, dir: dir, options: 'czf') end def untar_cf(archive:, dir:) - untar_with_options(archive: archive, dir: dir, options: 'cf') + tar_with_options(archive: archive, dir: dir, options: 'cf') end def tar_czf(archive:, dir:) @@ -24,13 +24,7 @@ def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path end def tar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive} -C #{dir}) - _output, status = Gitlab::Popen.popen(cmd) - status.zero? - end - - def untar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive} -C #{dir}) + cmd = %W(tar -#{options} #{archive} #{dir}) _output, status = Gitlab::Popen.popen(cmd) status.zero? end diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 5152d6ac182e42..226499030afb43 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -3,7 +3,7 @@ module ImportExport class ImportService def self.execute(*args) - new(args).execute + new(*args).execute end def initialize(archive_file:, owner:, namespace_id:, project_path:) @@ -26,7 +26,7 @@ def restore_project_tree end def project_tree - @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user) + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user, project_path: @project_path) end def restore_repo diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 9f399845437169..225e6f349914a0 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -13,6 +13,7 @@ def initialize(archive_file: , storage_path:) end def import + FileUtils.mkdir_p(@storage_path) decompress_archive end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 445f1d884d0661..7b41ba0685b219 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -3,9 +3,10 @@ module ImportExport class ProjectTreeRestorer attr_reader :project - def initialize(path:, user:) + def initialize(path:, user:, project_path:) @path = File.join(path, 'project.json') @user = user + @project_path = project_path end def restore @@ -48,6 +49,7 @@ def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } project = Gitlab::ImportExport::ProjectFactory.create( project_params: project_params, user: @user) + project.path = @project_path project.save project.import_start project -- GitLab From 5908bdf3edb6f59674789e3d210999406d455f67 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 28 Apr 2016 13:53:16 +0200 Subject: [PATCH 067/714] fixing a few tar issues - and using gnu tar only --- lib/gitlab/import_export/command_line_util.rb | 14 ++++++++++---- lib/gitlab/import_export/importer.rb | 2 +- lib/gitlab/import_export/repo_restorer.rb | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index e8d41a6bd3dc21..1140e7beb9a169 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -5,12 +5,12 @@ def tar_cf(archive:, dir:) tar_with_options(archive: archive, dir: dir, options: 'cf') end - def untar_czf(archive:, dir:) - tar_with_options(archive: archive, dir: dir, options: 'czf') + def untar_zxf(archive:, dir:) + untar_with_options(archive: archive, dir: dir, options: 'zxf') end - def untar_cf(archive:, dir:) - tar_with_options(archive: archive, dir: dir, options: 'cf') + def untar_czf(archive:, dir:) + untar_with_options(archive: archive, dir: dir, options: 'xf') end def tar_czf(archive:, dir:) @@ -28,6 +28,12 @@ def tar_with_options(archive:, dir:, options:) _output, status = Gitlab::Popen.popen(cmd) status.zero? end + + def untar_with_options(archive:, dir:, options:) + cmd = %W(tar -#{options} #{archive} -C #{dir}) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end end end end diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 225e6f349914a0..8f838287f97696 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -20,7 +20,7 @@ def import private def decompress_archive - untar_czf(archive: @archive_file, dir: @storage_path) + untar_zxf(archive: @archive_file, dir: @storage_path) end end end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 47be303e22ae83..aa90f0536808c2 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -14,7 +14,7 @@ def restore FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) - untar_cf(archive: @path, dir: path_to_repo) + untar_czf(archive: @path, dir: path_to_repo) end private -- GitLab From c5bc262981a9fbfe748dfb0b527e4fb0fa597ccf Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 28 Apr 2016 18:00:30 +0200 Subject: [PATCH 068/714] few fixes - import from UI working --- app/controllers/projects_controller.rb | 4 +++- app/services/projects/import_export/export_service.rb | 2 +- lib/gitlab/import_export/command_line_util.rb | 2 +- lib/gitlab/import_export/saver.rb | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1d4684ca22ecd0..62f8b376c18bd2 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -191,6 +191,7 @@ def housekeeping end def export + #TODO: Move to worker ::Projects::ImportExport::ExportService.new(@project, current_user).execute redirect_to( @@ -267,6 +268,7 @@ def get_id def export_project_path # TODO: move this, probably to ImportExport and refactor - File.join(Settings.shared['path'], 'tmp/project_exports', @project.path_with_namespace, 'project.tar.gz') + folder = File.join(Settings.shared['path'], 'tmp/project_exports', @project.path_with_namespace) + Dir.glob("#{folder}/*export.tar.gz").max_by {|f| File.ctime(f)} end end diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 8b641008a88e40..5d5573cba5c7e0 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -3,7 +3,7 @@ module ImportExport class ExportService < BaseService def execute(options = {}) - @shared = Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) + @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) save_project_tree bundle_repo save_all diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 1140e7beb9a169..9fc83afc4f7525 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -24,7 +24,7 @@ def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path end def tar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive} #{dir}) + cmd = %W(tar -#{options} #{archive} -C #{dir} .) _output, status = Gitlab::Popen.popen(cmd) status.zero? end diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index f87e0fdc7ea20a..634e58e6039935 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -14,6 +14,7 @@ def initialize(storage_path:) def save if compress_and_save remove_storage_path + Rails.logger.info("Saved project export #{archive_file}") archive_file else false -- GitLab From 3a609038748055a27c7e01cf4b55d8249709c9cc Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 15 Apr 2016 13:06:44 +0530 Subject: [PATCH 069/714] Allow creating Personal Access Tokens through the website. --- .../personal_access_tokens_controller.rb | 22 ++++++++++ app/models/personal_access_token.rb | 9 ++++ app/models/user.rb | 1 + .../personal_access_tokens/create.html.haml | 2 + .../personal_access_tokens/index.html.haml | 44 +++++++++++++++++++ config/routes.rb | 1 + ...415062917_create_personal_access_tokens.rb | 11 +++++ db/schema.rb | 14 ++++++ 8 files changed, 104 insertions(+) create mode 100644 app/controllers/profiles/personal_access_tokens_controller.rb create mode 100644 app/models/personal_access_token.rb create mode 100644 app/views/profiles/personal_access_tokens/create.html.haml create mode 100644 app/views/profiles/personal_access_tokens/index.html.haml create mode 100644 db/migrate/20160415062917_create_personal_access_tokens.rb diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb new file mode 100644 index 00000000000000..dbf06cb4c6d87c --- /dev/null +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -0,0 +1,22 @@ +class Profiles::PersonalAccessTokensController < ApplicationController + def index + @user = current_user + @personal_access_token = current_user.personal_access_tokens.new + end + + def create + @personal_access_token = current_user.personal_access_tokens.generate(personal_access_token_params) + + if @personal_access_token.save + redirect_to profile_personal_access_tokens_path, notice: "Created personal access token!" + else + render :index + end + end + + private + + def personal_access_token_params + params.require(:personal_access_token).permit(:name) + end +end diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb new file mode 100644 index 00000000000000..29f2275475f31d --- /dev/null +++ b/app/models/personal_access_token.rb @@ -0,0 +1,9 @@ +class PersonalAccessToken < ActiveRecord::Base + belongs_to :user + + def self.generate(params) + personal_access_token = self.new(params) + personal_access_token.token = Devise.friendly_token(50) + personal_access_token + end +end diff --git a/app/models/user.rb b/app/models/user.rb index b6f405c698191f..7ac30d21cb7e61 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -109,6 +109,7 @@ class User < ActiveRecord::Base # Profile has_many :keys, dependent: :destroy has_many :emails, dependent: :destroy + has_many :personal_access_tokens, dependent: :destroy has_many :identities, dependent: :destroy, autosave: true # Groups diff --git a/app/views/profiles/personal_access_tokens/create.html.haml b/app/views/profiles/personal_access_tokens/create.html.haml new file mode 100644 index 00000000000000..89da41a75ef22b --- /dev/null +++ b/app/views/profiles/personal_access_tokens/create.html.haml @@ -0,0 +1,2 @@ +%h1 Profiles::PersonalAccessTokens#create +%p Find me in app/views/profiles/personal_access_tokens/create.html.haml diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml new file mode 100644 index 00000000000000..05eed3c5c3ca89 --- /dev/null +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -0,0 +1,44 @@ +- page_title "Personal Access Tokens" +- header_title page_title, profile_personal_access_tokens_path + +.row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = page_title + %p + You can generate a personal access token for each application you use that needs access to GitLab. + .col-lg-9 + %h5.prepend-top-0 + Add a Personal Access Token + %p.profile-settings-content + Pick a name for the application, and we'll give you a unique token. + = form_for [:profile, @personal_access_token], method: :post, html: { class: 'js-requires-input' } do |f| + + .form-group + = f.label :name, class: 'label-light' + = f.text_field :name, class: "form-control", required: true + + .prepend-top-default + = f.submit 'Add Personal Access Token', class: "btn btn-create" + + %hr + + %h5 + Active Personal Access Tokens + + - if @user.personal_access_tokens.exists? + .table-responsive + %table.table.table-striped + %thead + %tr + %th Name + %th Token + %th Created At + %tbody + - @user.personal_access_tokens.each do |token| + %tr + %td= token.name + %td= token.token + %td= token.created_at + - else + %span You don't have any tokens yet. \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index d664434e1a6a5a..d1be826d2a15b4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -333,6 +333,7 @@ resources :keys resources :emails, only: [:index, :create, :destroy] resource :avatar, only: [:destroy] + resources :personal_access_tokens, only: [:index, :create] resource :two_factor_auth, only: [:new, :create, :destroy] do member do post :codes diff --git a/db/migrate/20160415062917_create_personal_access_tokens.rb b/db/migrate/20160415062917_create_personal_access_tokens.rb new file mode 100644 index 00000000000000..42a41349a0c706 --- /dev/null +++ b/db/migrate/20160415062917_create_personal_access_tokens.rb @@ -0,0 +1,11 @@ +class CreatePersonalAccessTokens < ActiveRecord::Migration + def change + create_table :personal_access_tokens do |t| + t.references :user, index: true, foreign_key: true, null: false + t.string :token, index: {unique: true}, null: false + t.string :name, null: false + + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 42457d92353468..05c97003971fd1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -704,6 +704,19 @@ add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree + create_table "personal_access_tokens", force: :cascade do |t| + t.integer "user_id", null: false + t.string "token", null: false + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "revoked", default: false + t.datetime "expires_at" + end + + add_index "personal_access_tokens", ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree + add_index "personal_access_tokens", ["user_id"], name: "index_personal_access_tokens_on_user_id", using: :btree + create_table "project_group_links", force: :cascade do |t| t.integer "project_id", null: false t.integer "group_id", null: false @@ -1030,4 +1043,5 @@ add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree + add_foreign_key "personal_access_tokens", "users" end -- GitLab From e8314ccca5ff1cd9cf2b1d1aeccd699598b384a5 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 15 Apr 2016 19:37:21 +0530 Subject: [PATCH 070/714] Refactor `API::Helpers` into `API::Helpers::Core` and `API::Helpers::Authentication` --- lib/api/api.rb | 4 +- lib/api/helpers.rb | 385 ------------------------------ lib/api/helpers/authentication.rb | 41 ++++ lib/api/helpers/core.rb | 351 +++++++++++++++++++++++++++ lib/ci/api/api.rb | 3 +- spec/requests/api/users_spec.rb | 2 +- 6 files changed, 398 insertions(+), 388 deletions(-) delete mode 100644 lib/api/helpers.rb create mode 100644 lib/api/helpers/authentication.rb create mode 100644 lib/api/helpers/core.rb diff --git a/lib/api/api.rb b/lib/api/api.rb index cc1004f80059e8..537678863cbeb5 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -1,4 +1,5 @@ Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file} +Dir["#{Rails.root}/lib/api/helpers/*.rb"].each {|file| require file} module API class API < Grape::API @@ -25,7 +26,8 @@ class API < Grape::API format :json content_type :txt, "text/plain" - helpers Helpers + helpers Helpers::Core + helpers Helpers::Authentication mount Groups mount GroupMembers diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb deleted file mode 100644 index 5bbf721321d71e..00000000000000 --- a/lib/api/helpers.rb +++ /dev/null @@ -1,385 +0,0 @@ -module API - module Helpers - PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" - PRIVATE_TOKEN_PARAM = :private_token - SUDO_HEADER ="HTTP_SUDO" - SUDO_PARAM = :sudo - - def parse_boolean(value) - [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(value) - end - - def current_user - private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - @current_user ||= (User.find_by(authentication_token: private_token) || doorkeeper_guard) - - unless @current_user && Gitlab::UserAccess.allowed?(@current_user) - return nil - end - - identifier = sudo_identifier() - - # If the sudo is the current user do nothing - if identifier && !(@current_user.id == identifier || @current_user.username == identifier) - render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin? - @current_user = User.by_username_or_id(identifier) - not_found!("No user id or username for: #{identifier}") if @current_user.nil? - end - - @current_user - end - - def sudo_identifier() - identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER] - - # Regex for integers - if !!(identifier =~ /^[0-9]+$/) - identifier.to_i - else - identifier - end - end - - def user_project - @project ||= find_project(params[:id]) - @project || not_found!("Project") - end - - def find_project(id) - project = Project.find_with_namespace(id) || Project.find_by(id: id) - - if project && can?(current_user, :read_project, project) - project - else - nil - end - end - - def project_service - @project_service ||= begin - underscored_service = params[:service_slug].underscore - - if Service.available_services_names.include?(underscored_service) - user_project.build_missing_services - - service_method = "#{underscored_service}_service" - - send_service(service_method) - end - end - - @project_service || not_found!("Service") - end - - def send_service(service_method) - user_project.send(service_method) - end - - def service_attributes - @service_attributes ||= project_service.fields.inject([]) do |arr, hash| - arr << hash[:name].to_sym - end - end - - def find_group(id) - begin - group = Group.find(id) - rescue ActiveRecord::RecordNotFound - group = Group.find_by!(path: id) - end - - if can?(current_user, :read_group, group) - group - else - not_found!('Group') - end - end - - def paginate(relation) - relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| - add_pagination_headers(data) - end - end - - def authenticate! - unauthorized! unless current_user - end - - def authenticate_by_gitlab_shell_token! - input = params['secret_token'].try(:chomp) - unless Devise.secure_compare(secret_token, input) - unauthorized! - end - end - - def authenticated_as_admin! - forbidden! unless current_user.is_admin? - end - - def authorize!(action, subject) - forbidden! unless abilities.allowed?(current_user, action, subject) - end - - def authorize_push_project - authorize! :push_code, user_project - end - - def authorize_admin_project - authorize! :admin_project, user_project - end - - def require_gitlab_workhorse! - unless env['HTTP_GITLAB_WORKHORSE'].present? - forbidden!('Request should be executed via GitLab Workhorse') - end - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - # Checks the occurrences of required attributes, each attribute must be present in the params hash - # or a Bad Request error is invoked. - # - # Parameters: - # keys (required) - A hash consisting of keys that must be present - def required_attributes!(keys) - keys.each do |key| - bad_request!(key) unless params[key].present? - end - end - - def attributes_for_keys(keys, custom_params = nil) - 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) - attrs[key] = params_hash[key] - end - end - ActionController::Parameters.new(attrs).permit! - end - - # Helper method for validating all labels against its names - def validate_label_params(params) - errors = {} - - if params[:labels].present? - params[:labels].split(',').each do |label_name| - label = user_project.labels.create_with( - color: Label::DEFAULT_COLOR).find_or_initialize_by( - title: label_name.strip) - - if label.invalid? - errors[label.title] = label.errors - end - end - end - - errors - end - - def validate_access_level?(level) - Gitlab::Access.options_with_owner.values.include? level.to_i - end - - def issuable_order_by - if params["order_by"] == 'updated_at' - 'updated_at' - else - 'created_at' - end - end - - def issuable_sort - if params["sort"] == 'asc' - :asc - else - :desc - end - end - - def filter_by_iid(items, iid) - items.where(iid: iid) - end - - # error helpers - - def forbidden!(reason = nil) - message = ['403 Forbidden'] - message << " - #{reason}" if reason - render_api_error!(message.join(' '), 403) - end - - def bad_request!(attribute) - message = ["400 (Bad request)"] - message << "\"" + attribute.to_s + "\" not given" - render_api_error!(message.join(' '), 400) - end - - def not_found!(resource = nil) - message = ["404"] - message << resource if resource - message << "Not Found" - render_api_error!(message.join(' '), 404) - end - - def unauthorized! - render_api_error!('401 Unauthorized', 401) - end - - def not_allowed! - render_api_error!('405 Method Not Allowed', 405) - end - - def conflict!(message = nil) - render_api_error!(message || '409 Conflict', 409) - end - - def file_to_large! - render_api_error!('413 Request Entity Too Large', 413) - end - - def not_modified! - render_api_error!('304 Not Modified', 304) - end - - def render_validation_error!(model) - if model.errors.any? - render_api_error!(model.errors.messages || '400 Bad Request', 400) - end - end - - def render_api_error!(message, status) - error!({ 'message' => message }, status) - end - - # Projects helpers - - def filter_projects(projects) - # If the archived parameter is passed, limit results accordingly - if params[:archived].present? - projects = projects.where(archived: parse_boolean(params[:archived])) - end - - if params[:search].present? - projects = projects.search(params[:search]) - end - - if params[:visibility].present? - projects = projects.search_by_visibility(params[:visibility]) - end - - projects.reorder(project_order_by => project_sort) - end - - def project_order_by - order_fields = %w(id name path created_at updated_at last_activity_at) - - if order_fields.include?(params['order_by']) - params['order_by'] - else - 'created_at' - end - end - - def project_sort - if params["sort"] == 'asc' - :asc - else - :desc - end - end - - # file helpers - - def uploaded_file(field, uploads_path) - if params[field] - bad_request!("#{field} is not a file") unless params[field].respond_to?(:filename) - return params[field] - end - - return nil unless params["#{field}.path"] && params["#{field}.name"] - - # sanitize file paths - # this requires all paths to exist - required_attributes! %W(#{field}.path) - uploads_path = File.realpath(uploads_path) - file_path = File.realpath(params["#{field}.path"]) - bad_request!('Bad file path') unless file_path.start_with?(uploads_path) - - UploadedFile.new( - file_path, - params["#{field}.name"], - params["#{field}.type"] || 'application/octet-stream', - ) - end - - def present_file!(path, filename, content_type = 'application/octet-stream') - filename ||= File.basename(path) - header['Content-Disposition'] = "attachment; filename=#{filename}" - header['Content-Transfer-Encoding'] = 'binary' - content_type content_type - - # Support download acceleration - case headers['X-Sendfile-Type'] - when 'X-Sendfile' - header['X-Sendfile'] = path - body - else - file FileStreamer.new(path) - end - end - - private - - def add_pagination_headers(paginated_data) - header 'X-Total', paginated_data.total_count.to_s - header 'X-Total-Pages', paginated_data.total_pages.to_s - header 'X-Per-Page', paginated_data.limit_value.to_s - header 'X-Page', paginated_data.current_page.to_s - header 'X-Next-Page', paginated_data.next_page.to_s - header 'X-Prev-Page', paginated_data.prev_page.to_s - header 'Link', pagination_links(paginated_data) - end - - def pagination_links(paginated_data) - request_url = request.url.split('?').first - request_params = params.clone - request_params[:per_page] = paginated_data.limit_value - - links = [] - - request_params[:page] = paginated_data.current_page - 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") unless paginated_data.first_page? - - request_params[:page] = paginated_data.current_page + 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? - - request_params[:page] = 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="first") - - request_params[:page] = paginated_data.total_pages - links << %(<#{request_url}?#{request_params.to_query}>; rel="last") - - links.join(', ') - end - - def abilities - @abilities ||= begin - abilities = Six.new - abilities << Ability - abilities - end - end - - def secret_token - File.read(Gitlab.config.gitlab_shell.secret_file).chomp - end - - def handle_member_errors(errors) - error!(errors[:access_level], 422) if errors[:access_level].any? - not_found!(errors) - end - end -end diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb new file mode 100644 index 00000000000000..8c7bb2c8cdf4c4 --- /dev/null +++ b/lib/api/helpers/authentication.rb @@ -0,0 +1,41 @@ +module API + module Helpers + module Authentication + PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" + PRIVATE_TOKEN_PARAM = :private_token + SUDO_HEADER ="HTTP_SUDO" + SUDO_PARAM = :sudo + + def current_user + private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s + @current_user ||= (User.find_by(authentication_token: private_token) || doorkeeper_guard) + + unless @current_user && Gitlab::UserAccess.allowed?(@current_user) + return nil + end + + identifier = sudo_identifier() + + # If the sudo is the current user do nothing + if identifier && !(@current_user.id == identifier || @current_user.username == identifier) + render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin? + @current_user = User.by_username_or_id(identifier) + not_found!("No user id or username for: #{identifier}") if @current_user.nil? + end + + @current_user + end + + def sudo_identifier() + identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER] + + # Regex for integers + if !!(identifier =~ /^[0-9]+$/) + identifier.to_i + else + identifier + end + end + end + end +end \ No newline at end of file diff --git a/lib/api/helpers/core.rb b/lib/api/helpers/core.rb new file mode 100644 index 00000000000000..c37064d49ab763 --- /dev/null +++ b/lib/api/helpers/core.rb @@ -0,0 +1,351 @@ +module API + module Helpers + module Core + def parse_boolean(value) + [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(value) + end + + def user_project + @project ||= find_project(params[:id]) + @project || not_found!("Project") + end + + def find_project(id) + project = Project.find_with_namespace(id) || Project.find_by(id: id) + + if project && can?(current_user, :read_project, project) + project + else + nil + end + end + + def project_service + @project_service ||= begin + underscored_service = params[:service_slug].underscore + + if Service.available_services_names.include?(underscored_service) + user_project.build_missing_services + + service_method = "#{underscored_service}_service" + + send_service(service_method) + end + end + + @project_service || not_found!("Service") + end + + def send_service(service_method) + user_project.send(service_method) + end + + def service_attributes + @service_attributes ||= project_service.fields.inject([]) do |arr, hash| + arr << hash[:name].to_sym + end + end + + def find_group(id) + begin + group = Group.find(id) + rescue ActiveRecord::RecordNotFound + group = Group.find_by!(path: id) + end + + if can?(current_user, :read_group, group) + group + else + not_found!('Group') + end + end + + def paginate(relation) + relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| + add_pagination_headers(data) + end + end + + def authenticate! + unauthorized! unless current_user + end + + def authenticate_by_gitlab_shell_token! + input = params['secret_token'].try(:chomp) + unless Devise.secure_compare(secret_token, input) + unauthorized! + end + end + + def authenticated_as_admin! + forbidden! unless current_user.is_admin? + end + + def authorize!(action, subject) + forbidden! unless abilities.allowed?(current_user, action, subject) + end + + def authorize_push_project + authorize! :push_code, user_project + end + + def authorize_admin_project + authorize! :admin_project, user_project + end + + def require_gitlab_workhorse! + unless env['HTTP_GITLAB_WORKHORSE'].present? + forbidden!('Request should be executed via GitLab Workhorse') + end + end + + def can?(object, action, subject) + abilities.allowed?(object, action, subject) + end + + # Checks the occurrences of required attributes, each attribute must be present in the params hash + # or a Bad Request error is invoked. + # + # Parameters: + # keys (required) - A hash consisting of keys that must be present + def required_attributes!(keys) + keys.each do |key| + bad_request!(key) unless params[key].present? + end + end + + def attributes_for_keys(keys, custom_params = nil) + 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) + attrs[key] = params_hash[key] + end + end + ActionController::Parameters.new(attrs).permit! + end + + # Helper method for validating all labels against its names + def validate_label_params(params) + errors = {} + + if params[:labels].present? + params[:labels].split(',').each do |label_name| + label = user_project.labels.create_with( + color: Label::DEFAULT_COLOR).find_or_initialize_by( + title: label_name.strip) + + if label.invalid? + errors[label.title] = label.errors + end + end + end + + errors + end + + def validate_access_level?(level) + Gitlab::Access.options_with_owner.values.include? level.to_i + end + + def issuable_order_by + if params["order_by"] == 'updated_at' + 'updated_at' + else + 'created_at' + end + end + + def issuable_sort + if params["sort"] == 'asc' + :asc + else + :desc + end + end + + def filter_by_iid(items, iid) + items.where(iid: iid) + end + + # error helpers + + def forbidden!(reason = nil) + message = ['403 Forbidden'] + message << " - #{reason}" if reason + render_api_error!(message.join(' '), 403) + end + + def bad_request!(attribute) + message = ["400 (Bad request)"] + message << "\"" + attribute.to_s + "\" not given" + render_api_error!(message.join(' '), 400) + end + + def not_found!(resource = nil) + message = ["404"] + message << resource if resource + message << "Not Found" + render_api_error!(message.join(' '), 404) + end + + def unauthorized! + render_api_error!('401 Unauthorized', 401) + end + + def not_allowed! + render_api_error!('405 Method Not Allowed', 405) + end + + def conflict!(message = nil) + render_api_error!(message || '409 Conflict', 409) + end + + def file_to_large! + render_api_error!('413 Request Entity Too Large', 413) + end + + def not_modified! + render_api_error!('304 Not Modified', 304) + end + + def render_validation_error!(model) + if model.errors.any? + render_api_error!(model.errors.messages || '400 Bad Request', 400) + end + end + + def render_api_error!(message, status) + error!({ 'message' => message }, status) + end + + # Projects helpers + + def filter_projects(projects) + # If the archived parameter is passed, limit results accordingly + if params[:archived].present? + projects = projects.where(archived: parse_boolean(params[:archived])) + end + + if params[:search].present? + projects = projects.search(params[:search]) + end + + if params[:visibility].present? + projects = projects.search_by_visibility(params[:visibility]) + end + + projects.reorder(project_order_by => project_sort) + end + + def project_order_by + order_fields = %w(id name path created_at updated_at last_activity_at) + + if order_fields.include?(params['order_by']) + params['order_by'] + else + 'created_at' + end + end + + def project_sort + if params["sort"] == 'asc' + :asc + else + :desc + end + end + + # file helpers + + def uploaded_file(field, uploads_path) + if params[field] + bad_request!("#{field} is not a file") unless params[field].respond_to?(:filename) + return params[field] + end + + return nil unless params["#{field}.path"] && params["#{field}.name"] + + # sanitize file paths + # this requires all paths to exist + required_attributes! %W(#{field}.path) + uploads_path = File.realpath(uploads_path) + file_path = File.realpath(params["#{field}.path"]) + bad_request!('Bad file path') unless file_path.start_with?(uploads_path) + + UploadedFile.new( + file_path, + params["#{field}.name"], + params["#{field}.type"] || 'application/octet-stream', + ) + end + + def present_file!(path, filename, content_type = 'application/octet-stream') + filename ||= File.basename(path) + header['Content-Disposition'] = "attachment; filename=#{filename}" + header['Content-Transfer-Encoding'] = 'binary' + content_type content_type + + # Support download acceleration + case headers['X-Sendfile-Type'] + when 'X-Sendfile' + header['X-Sendfile'] = path + body + else + file FileStreamer.new(path) + end + end + + private + + def add_pagination_headers(paginated_data) + header 'X-Total', paginated_data.total_count.to_s + header 'X-Total-Pages', paginated_data.total_pages.to_s + header 'X-Per-Page', paginated_data.limit_value.to_s + header 'X-Page', paginated_data.current_page.to_s + header 'X-Next-Page', paginated_data.next_page.to_s + header 'X-Prev-Page', paginated_data.prev_page.to_s + header 'Link', pagination_links(paginated_data) + end + + def pagination_links(paginated_data) + request_url = request.url.split('?').first + request_params = params.clone + request_params[:per_page] = paginated_data.limit_value + + links = [] + + request_params[:page] = paginated_data.current_page - 1 + links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") unless paginated_data.first_page? + + request_params[:page] = paginated_data.current_page + 1 + links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? + + request_params[:page] = 1 + links << %(<#{request_url}?#{request_params.to_query}>; rel="first") + + request_params[:page] = paginated_data.total_pages + links << %(<#{request_url}?#{request_params.to_query}>; rel="last") + + links.join(', ') + end + + def abilities + @abilities ||= begin + abilities = Six.new + abilities << Ability + abilities + end + end + + def secret_token + File.read(Gitlab.config.gitlab_shell.secret_file).chomp + end + + def handle_member_errors(errors) + error!(errors[:access_level], 422) if errors[:access_level].any? + not_found!(errors) + end + end + end +end \ No newline at end of file diff --git a/lib/ci/api/api.rb b/lib/ci/api/api.rb index 353c4ddebf8edc..495f5792b084cc 100644 --- a/lib/ci/api/api.rb +++ b/lib/ci/api/api.rb @@ -28,7 +28,8 @@ class API < Grape::API format :json helpers ::Ci::API::Helpers - helpers ::API::Helpers + helpers ::API::Helpers::Core + helpers ::API::Helpers::Authentication helpers Gitlab::CurrentSettings mount Builds diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 40b24c125b54e4..628569d3e009d1 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -24,7 +24,7 @@ context "when public level is restricted" do before do stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) - allow_any_instance_of(API::Helpers).to receive(:authenticate!).and_return(true) + allow_any_instance_of(API::Helpers::Authentication).to receive(:authenticate!).and_return(true) end it "renders 403" do -- GitLab From 5fb44192964c962000f8c8708d823931ee6a6d8e Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 15 Apr 2016 19:48:47 +0530 Subject: [PATCH 071/714] Allow personal access tokens to be used for API authentication. --- lib/api/helpers/authentication.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb index 8c7bb2c8cdf4c4..f11c9725f3f561 100644 --- a/lib/api/helpers/authentication.rb +++ b/lib/api/helpers/authentication.rb @@ -5,10 +5,22 @@ module Authentication PRIVATE_TOKEN_PARAM = :private_token SUDO_HEADER ="HTTP_SUDO" SUDO_PARAM = :sudo + PERSONAL_ACCESS_TOKEN_PARAM = :personal_access_token - def current_user + def find_user_by_private_token private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - @current_user ||= (User.find_by(authentication_token: private_token) || doorkeeper_guard) + User.find_by_authentication_token(private_token) + end + + def find_user_by_personal_access_token + personal_access_token = PersonalAccessToken.find_by_token(params[PERSONAL_ACCESS_TOKEN_PARAM]) + if personal_access_token + personal_access_token.user + end + end + + def current_user + @current_user ||= (find_user_by_private_token || find_user_by_personal_access_token || doorkeeper_guard) unless @current_user && Gitlab::UserAccess.allowed?(@current_user) return nil -- GitLab From e2a4051cc3f4192849d7571bf83b0d9a7b2cbd4e Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 15 Apr 2016 19:55:38 +0530 Subject: [PATCH 072/714] Allow personal access tokens to be specified in a header. - In addition to a param. --- lib/api/helpers/authentication.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb index f11c9725f3f561..e1d7ac83ff6f87 100644 --- a/lib/api/helpers/authentication.rb +++ b/lib/api/helpers/authentication.rb @@ -6,6 +6,7 @@ module Authentication SUDO_HEADER ="HTTP_SUDO" SUDO_PARAM = :sudo PERSONAL_ACCESS_TOKEN_PARAM = :personal_access_token + PERSONAL_ACCESS_TOKEN_HEADER = "HTTP_PERSONAL_ACCESS_TOKEN" def find_user_by_private_token private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s @@ -13,10 +14,9 @@ def find_user_by_private_token end def find_user_by_personal_access_token - personal_access_token = PersonalAccessToken.find_by_token(params[PERSONAL_ACCESS_TOKEN_PARAM]) - if personal_access_token - personal_access_token.user - end + personal_access_token_string = (params[PERSONAL_ACCESS_TOKEN_PARAM] || env[PERSONAL_ACCESS_TOKEN_HEADER]).to_s + personal_access_token = PersonalAccessToken.find_by_token(personal_access_token_string) + personal_access_token.user if personal_access_token end def current_user -- GitLab From 6d76f14f54eb1af0e5c29eff1b8f5e70d2264ffd Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 15 Apr 2016 20:54:20 +0530 Subject: [PATCH 073/714] Allow revoking personal access tokens. --- app/assets/stylesheets/pages/profile.scss | 3 +++ .../personal_access_tokens_controller.rb | 16 +++++++++++++++- app/models/personal_access_token.rb | 7 +++++++ .../personal_access_tokens/index.html.haml | 9 ++++++++- config/locales/en.yml | 4 ++++ config/routes.rb | 6 +++++- ...d_column_revoked_to_personal_access_tokens.rb | 5 +++++ lib/api/helpers/authentication.rb | 2 +- 8 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 01f984796235ef..5a4d0a5c8b048f 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -205,3 +205,6 @@ text-align: center; } } +.personal-access-tokens-revoked-label { + color: #bbb; +} \ No newline at end of file diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index dbf06cb4c6d87c..59de0b26eeee26 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -1,7 +1,11 @@ class Profiles::PersonalAccessTokensController < ApplicationController def index @user = current_user - @personal_access_token = current_user.personal_access_tokens.new + + # Prefer this to `@user.personal_access_tokens.new`, because it + # litters the view's call to `@user.personal_access_tokens` with + # this stub personal access token. + @personal_access_token = PersonalAccessToken.new(user: @user) end def create @@ -14,6 +18,16 @@ def create end end + def revoke + @personal_access_token = current_user.personal_access_tokens.find(params[:id]) + + if @personal_access_token.revoke! + redirect_to profile_personal_access_tokens_path, notice: "Revoked personal access token #{@personal_access_token.name}!" + else + render :index + end + end + private def personal_access_token_params diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 29f2275475f31d..e5f1f9749f8c89 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -1,9 +1,16 @@ class PersonalAccessToken < ActiveRecord::Base belongs_to :user + scope :active, -> { where.not(revoked: true) } + def self.generate(params) personal_access_token = self.new(params) personal_access_token.token = Devise.friendly_token(50) personal_access_token end + + def revoke! + self.revoked = true + self.save + end end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 05eed3c5c3ca89..02d15269c85073 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -34,11 +34,18 @@ %th Name %th Token %th Created At + %th Actions %tbody - - @user.personal_access_tokens.each do |token| + - @user.personal_access_tokens.order(:revoked).each do |token| %tr %td= token.name %td= token.token %td= token.created_at + - if token.revoked? + %td + %span.personal-access-tokens-revoked-label Revoked + - else + %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: {confirm: t('profile.personal_access_tokens.revoke.confirmation')} + - else %span You don't have any tokens yet. \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index cedb5e207bd379..b5b8c4467b04dc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -12,3 +12,7 @@ en: pagination: previous: "Prev" next: "Next" + profile: + personal_access_tokens: + revoke: + confirmation: "Are you sure? This cannot be undone." diff --git a/config/routes.rb b/config/routes.rb index d1be826d2a15b4..4e4666762f8af2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -333,7 +333,11 @@ resources :keys resources :emails, only: [:index, :create, :destroy] resource :avatar, only: [:destroy] - resources :personal_access_tokens, only: [:index, :create] + resources :personal_access_tokens, only: [:index, :create] do + member do + put :revoke + end + end resource :two_factor_auth, only: [:new, :create, :destroy] do member do post :codes diff --git a/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb b/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb new file mode 100644 index 00000000000000..8eecdfc5a1c9aa --- /dev/null +++ b/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb @@ -0,0 +1,5 @@ +class AddColumnRevokedToPersonalAccessTokens < ActiveRecord::Migration + def change + add_column :personal_access_tokens, :revoked, :boolean, default: false + end +end diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb index e1d7ac83ff6f87..666bf3ffa169ba 100644 --- a/lib/api/helpers/authentication.rb +++ b/lib/api/helpers/authentication.rb @@ -15,7 +15,7 @@ def find_user_by_private_token def find_user_by_personal_access_token personal_access_token_string = (params[PERSONAL_ACCESS_TOKEN_PARAM] || env[PERSONAL_ACCESS_TOKEN_HEADER]).to_s - personal_access_token = PersonalAccessToken.find_by_token(personal_access_token_string) + personal_access_token = PersonalAccessToken.active.find_by_token(personal_access_token_string) personal_access_token.user if personal_access_token end -- GitLab From 1541d1de18c3e7707ce1289f882b4c1262ec8c71 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Mon, 18 Apr 2016 14:47:38 +0530 Subject: [PATCH 074/714] Rename `api_helpers_spec` to `api_authentication_spec` - And fix all tests. --- ...ers_spec.rb => api_authentication_spec.rb} | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) rename spec/requests/api/{api_helpers_spec.rb => api_authentication_spec.rb} (82%) diff --git a/spec/requests/api/api_helpers_spec.rb b/spec/requests/api/api_authentication_spec.rb similarity index 82% rename from spec/requests/api/api_helpers_spec.rb rename to spec/requests/api/api_authentication_spec.rb index 0c19094ec544ad..8bed3bb119b7cd 100644 --- a/spec/requests/api/api_helpers_spec.rb +++ b/spec/requests/api/api_authentication_spec.rb @@ -1,8 +1,10 @@ require 'spec_helper' -describe API, api: true do - include API::Helpers +describe API::Helpers::Authentication, api: true do + + include API::Helpers::Authentication include ApiHelpers + let(:user) { create(:user) } let(:admin) { create(:admin) } let(:key) { create(:key, user: user) } @@ -13,25 +15,25 @@ def set_env(token_usr, identifier) clear_env clear_param - env[API::Helpers::PRIVATE_TOKEN_HEADER] = token_usr.private_token - env[API::Helpers::SUDO_HEADER] = identifier + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = token_usr.private_token + env[API::Helpers::Authentication::SUDO_HEADER] = identifier end def set_param(token_usr, identifier) clear_env clear_param - params[API::Helpers::PRIVATE_TOKEN_PARAM] = token_usr.private_token - params[API::Helpers::SUDO_PARAM] = identifier + params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = token_usr.private_token + params[API::Helpers::Authentication::SUDO_PARAM] = identifier end def clear_env - env.delete(API::Helpers::PRIVATE_TOKEN_HEADER) - env.delete(API::Helpers::SUDO_HEADER) + env.delete(API::Helpers::Authentication::PRIVATE_TOKEN_HEADER) + env.delete(API::Helpers::Authentication::SUDO_HEADER) end def clear_param - params.delete(API::Helpers::PRIVATE_TOKEN_PARAM) - params.delete(API::Helpers::SUDO_PARAM) + params.delete(API::Helpers::Authentication::PRIVATE_TOKEN_PARAM) + params.delete(API::Helpers::Authentication::SUDO_PARAM) end def error!(message, status) @@ -40,22 +42,22 @@ def error!(message, status) describe ".current_user" do it "should return nil for an invalid token" do - env[API::Helpers::PRIVATE_TOKEN_HEADER] = 'invalid token' + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = 'invalid token' allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } expect(current_user).to be_nil end it "should return nil for a user without access" do - env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false) expect(current_user).to be_nil end it "should leave user as is when sudo not specified" do - env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token expect(current_user).to eq(user) clear_env - params[API::Helpers::PRIVATE_TOKEN_PARAM] = user.private_token + params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = user.private_token expect(current_user).to eq(user) end -- GitLab From e5cf527f279964a8952de544526e8def226b98d7 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Mon, 18 Apr 2016 15:48:54 +0530 Subject: [PATCH 075/714] Allow expiration of personal access tokens. --- app/assets/stylesheets/pages/profile.scss | 4 ++ .../personal_access_tokens_controller.rb | 2 +- app/models/personal_access_token.rb | 2 +- .../personal_access_tokens/index.html.haml | 20 +++++- ...mn_expires_at_to_personal_access_tokens.rb | 5 ++ spec/factories/personal_access_tokens.rb | 9 +++ spec/requests/api/api_authentication_spec.rb | 72 ++++++++++++++----- 7 files changed, 94 insertions(+), 20 deletions(-) create mode 100644 db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb create mode 100644 spec/factories/personal_access_tokens.rb diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 5a4d0a5c8b048f..8c62c97215f02b 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -207,4 +207,8 @@ } .personal-access-tokens-revoked-label { color: #bbb; +} + +.personal-access-tokens-never-expires-label { + color: #bbb; } \ No newline at end of file diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 59de0b26eeee26..d01afbfe119ff9 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -31,6 +31,6 @@ def revoke private def personal_access_token_params - params.require(:personal_access_token).permit(:name) + params.require(:personal_access_token).permit(:name, :expires_at) end end diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index e5f1f9749f8c89..dd64374481fffc 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -1,7 +1,7 @@ class PersonalAccessToken < ActiveRecord::Base belongs_to :user - scope :active, -> { where.not(revoked: true) } + scope :active, -> { where.not(revoked: true).where("expires_at >= :current", current: Time.current) } def self.generate(params) personal_access_token = self.new(params) diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 02d15269c85073..f3d5f07cdd36a3 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -18,6 +18,10 @@ = f.label :name, class: 'label-light' = f.text_field :name, class: "form-control", required: true + .form-group + = f.label :expires_at, class: 'label-light' + = f.text_field :expires_at, class: "form-control datepicker", required: false + .prepend-top-default = f.submit 'Add Personal Access Token', class: "btn btn-create" @@ -34,13 +38,19 @@ %th Name %th Token %th Created At + %th Expires At %th Actions %tbody - - @user.personal_access_tokens.order(:revoked).each do |token| + - @user.personal_access_tokens.order("revoked, expires_at").each do |token| %tr %td= token.name %td= token.token %td= token.created_at + - if token.expires_at.present? + %td= token.expires_at.to_date + - else + %td + %span.personal-access-tokens-never-expires-label Never - if token.revoked? %td %span.personal-access-tokens-revoked-label Revoked @@ -48,4 +58,10 @@ %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: {confirm: t('profile.personal_access_tokens.revoke.confirmation')} - else - %span You don't have any tokens yet. \ No newline at end of file + %span You don't have any tokens yet. + +:javascript + $(".datepicker").datepicker({ + dateFormat: "yy-mm-dd", + onSelect: function(dateText, inst) { $("#personal_access_token_expires_at").val(dateText) } + }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#personal_access_token_expires_at').val())); \ No newline at end of file diff --git a/db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb b/db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb new file mode 100644 index 00000000000000..9d99ebeadf535a --- /dev/null +++ b/db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb @@ -0,0 +1,5 @@ +class AddColumnExpiresAtToPersonalAccessTokens < ActiveRecord::Migration + def change + add_column :personal_access_tokens, :expires_at, :datetime + end +end diff --git a/spec/factories/personal_access_tokens.rb b/spec/factories/personal_access_tokens.rb new file mode 100644 index 00000000000000..da4c72bcb5b32a --- /dev/null +++ b/spec/factories/personal_access_tokens.rb @@ -0,0 +1,9 @@ +FactoryGirl.define do + factory :personal_access_token do + user + token { SecureRandom.hex(50) } + name { FFaker::Product.brand } + revoked false + expires_at { 5.days.from_now } + end +end diff --git a/spec/requests/api/api_authentication_spec.rb b/spec/requests/api/api_authentication_spec.rb index 8bed3bb119b7cd..0416e57c68b420 100644 --- a/spec/requests/api/api_authentication_spec.rb +++ b/spec/requests/api/api_authentication_spec.rb @@ -41,24 +41,64 @@ def error!(message, status) end describe ".current_user" do - it "should return nil for an invalid token" do - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = 'invalid token' - allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } - expect(current_user).to be_nil + describe "when authenticating using a user's private token" do + it "should return nil for an invalid token" do + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = 'invalid token' + allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } + expect(current_user).to be_nil + end + + it "should return nil for a user without access" do + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token + allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false) + expect(current_user).to be_nil + end + + it "should leave user as is when sudo not specified" do + env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token + expect(current_user).to eq(user) + clear_env + params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = user.private_token + expect(current_user).to eq(user) + end end - it "should return nil for a user without access" do - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token - allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false) - expect(current_user).to be_nil - end - - it "should leave user as is when sudo not specified" do - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token - expect(current_user).to eq(user) - clear_env - params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = user.private_token - expect(current_user).to eq(user) + describe "when authenticating using a user's personal access tokens" do + let(:personal_access_token) { create(:personal_access_token, user: user) } + + it "should return nil for an invalid token" do + env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = 'invalid token' + allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } + expect(current_user).to be_nil + end + + it "should return nil for a user without access" do + env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false) + expect(current_user).to be_nil + end + + it "should leave user as is when sudo not specified" do + env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + expect(current_user).to eq(user) + clear_env + params[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_PARAM] = personal_access_token.token + expect(current_user).to eq(user) + end + + it 'does not allow revoked tokens' do + personal_access_token.revoke! + env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } + expect(current_user).to be_nil + end + + it 'does not allow expired tokens' do + personal_access_token.update_attributes!(expires_at: 1.day.ago) + env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } + expect(current_user).to be_nil + end end it "should change current user to sudo when admin" do -- GitLab From 41b4e119e9b076cc0f36bd31cbb42f87e5ecb08f Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Tue, 19 Apr 2016 14:01:21 +0530 Subject: [PATCH 076/714] Add an entry for Personal Access Tokens in the sidebar. --- .../profiles/personal_access_tokens_controller.rb | 2 +- app/views/layouts/nav/_profile.html.haml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index d01afbfe119ff9..a5804cc0d73663 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -1,4 +1,4 @@ -class Profiles::PersonalAccessTokensController < ApplicationController +class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def index @user = current_user diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index d730840d63a9e9..297f3e4063a8e9 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -14,6 +14,11 @@ = icon('cloud fw') %span Applications + = nav_link(controller: :personal_access_tokens) do + = link_to profile_personal_access_tokens_path, title: 'Personal Access Tokens' do + = icon('ticket fw') + %span + Personal Access Tokens = nav_link(controller: :emails) do = link_to profile_emails_path, title: 'Emails' do = icon('envelope-o fw') -- GitLab From fb2da6795c8503db5fed0f856760289e87ea9419 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Tue, 19 Apr 2016 15:28:35 +0530 Subject: [PATCH 077/714] Add an "Inactive Personal Access Tokens" section. - Show the count for each section in parens - Remove the `revoked?` check, because everything in the active section is guaranteed to not be revoked. --- app/assets/stylesheets/pages/profile.scss | 4 ++ .../personal_access_tokens_controller.rb | 3 +- app/models/personal_access_token.rb | 3 +- .../personal_access_tokens/index.html.haml | 56 ++++++++++++++----- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 8c62c97215f02b..85d9173afb325f 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -211,4 +211,8 @@ .personal-access-tokens-never-expires-label { color: #bbb; +} + +.personal-access-tokens-token-column { + max-width: 500px } \ No newline at end of file diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index a5804cc0d73663..5a6026f58cb440 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -1,6 +1,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def index - @user = current_user + @active_personal_access_tokens = current_user.personal_access_tokens.active.order(:expires_at) + @inactive_personal_access_tokens = current_user.personal_access_tokens.inactive # Prefer this to `@user.personal_access_tokens.new`, because it # litters the view's call to `@user.personal_access_tokens` with diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index dd64374481fffc..fff3f76fb93c98 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -1,7 +1,8 @@ class PersonalAccessToken < ActiveRecord::Base belongs_to :user - scope :active, -> { where.not(revoked: true).where("expires_at >= :current", current: Time.current) } + scope :active, -> { where(revoked: false).where("expires_at >= :current OR expires_at IS NULL", current: Time.current) } + scope :inactive, -> { where("revoked = true OR expires_at < :current", current: Time.current) } def self.generate(params) personal_access_token = self.new(params) diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index f3d5f07cdd36a3..77726d34fbc8aa 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -27,38 +27,64 @@ %hr - %h5 - Active Personal Access Tokens + %h5= "Active Personal Access Tokens (#{@active_personal_access_tokens.count})" - - if @user.personal_access_tokens.exists? + - if @active_personal_access_tokens.exists? .table-responsive - %table.table.table-striped + %table.table.table-striped.table-hover %thead %tr %th Name %th Token - %th Created At - %th Expires At + %th Created + %th Expires %th Actions %tbody - - @user.personal_access_tokens.order("revoked, expires_at").each do |token| + - @active_personal_access_tokens.active.each do |token| %tr %td= token.name - %td= token.token - %td= token.created_at + %td.input-group.personal-access-tokens-token-column + %input.form-control{type: "text", value: token.token, readonly: true} + %div.input-group-btn + %button.btn.btn-default{type: "button", data: {clipboard_text: token.token}} + %i.fa.fa-clipboard + %td= token.created_at.to_date - if token.expires_at.present? %td= token.expires_at.to_date - else %td %span.personal-access-tokens-never-expires-label Never - - if token.revoked? - %td - %span.personal-access-tokens-revoked-label Revoked - - else - %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: {confirm: t('profile.personal_access_tokens.revoke.confirmation')} + %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: {confirm: t('profile.personal_access_tokens.revoke.confirmation')} - else - %span You don't have any tokens yet. + %span You don't have any active tokens yet. + + %hr + + %h5= "Inactive Personal Access Tokens (#{@inactive_personal_access_tokens.count})" + + - if @inactive_personal_access_tokens.exists? + .table-responsive + %table.table.table-striped.table-hover + %thead + %tr + %th Name + %th Token + %th Created + %tbody + - @inactive_personal_access_tokens.order("revoked, expires_at").each do |token| + %tr + %td= token.name + %td.input-group.personal-access-tokens-token-column + %input.form-control{type: "text", value: token.token, readonly: true} + %div.input-group-btn + %button.btn.btn-default{type: "button", data: {clipboard_text: token.token}} + %i.fa.fa-clipboard + %td= token.created_at.to_date + + - else + %span No inactive tokens. + :javascript $(".datepicker").datepicker({ -- GitLab From ade40fdcd2a4ee879bd2aba939cffaff39c65228 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Tue, 19 Apr 2016 16:22:15 +0530 Subject: [PATCH 078/714] Authenticate non-API requests with personal access tokens. - Rename the `authenticate_user_from_token!` filter to `authenticate_user_from_private_token!` - Add a new `authenticate_user_from_personal_access_token!` filter - Add tests for both. --- app/controllers/application_controller.rb | 19 +++++- .../application_controller_spec.rb | 66 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1c53b0b21a3695..590f9383f7fc24 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,7 +7,8 @@ class ApplicationController < ActionController::Base include GitlabRoutingHelper include PageLayoutHelper - before_action :authenticate_user_from_token! + before_action :authenticate_user_from_private_token! + before_action :authenticate_user_from_personal_access_token! before_action :authenticate_user! before_action :validate_user_service_ticket! before_action :reject_blocked! @@ -65,7 +66,7 @@ def sentry_program_context # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 - def authenticate_user_from_token! + def authenticate_user_from_private_token! user_token = if params[:authenticity_token].presence params[:authenticity_token].presence elsif params[:private_token].presence @@ -84,6 +85,20 @@ def authenticate_user_from_token! end end + def authenticate_user_from_personal_access_token! + token_string = params[:personal_access_token].presence || request.headers['PERSONAL_ACCESS_TOKEN'].presence + personal_access_token = PersonalAccessToken.active.find_by_token(token_string) + user = personal_access_token && personal_access_token.user + + if user + # Notice we are passing store false, so the user is not + # actually stored in the session and a token is needed + # for every request. If you want the token to work as a + # sign in token, you can simply remove store: false. + sign_in user, store: false + end + end + def authenticate_user!(*args) if redirect_to_home_page_url? redirect_to current_application_settings.home_page_url and return diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 186239d3096b6a..1ec51465cd3685 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -30,4 +30,70 @@ controller.send(:check_password_expiration) end end + + describe "#authenticate_user_from_private_token!" do + controller(ApplicationController) do + def index + render text: "authenticated" + end + end + + let(:user) { create(:user) } + + it "logs the user in when the 'authenticity_token' param is populated with the private token" do + get :index, authenticity_token: user.private_token + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end + + it "logs the user in when the 'private_token' param is populated with the private token" do + get :index, private_token: user.private_token + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end + + it "logs the user in when the 'PRIVATE-TOKEN' header is populated with the private token" do + @request.headers['PRIVATE-TOKEN'] = user.private_token + get :index + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end + + it "doesn't log the user in otherwise" do + @request.headers['PRIVATE-TOKEN'] = "token" + get :index, private_token: "token", authenticity_token: "token" + expect(response.status).to_not eq(200) + expect(response.body).to_not eq("authenticated") + end + end + + describe "#authenticate_user_from_personal_access_token!" do + controller(ApplicationController) do + def index + render text: 'authenticated' + end + end + + let(:user) { create(:user) } + let(:personal_access_token) { create(:personal_access_token, user: user) } + + it "logs the user in when the 'personal_access_token' param is populated with the personal access token" do + get :index, personal_access_token: personal_access_token.token + expect(response.status).to eq(200) + expect(response.body).to eq('authenticated') + end + + it "logs the user in when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do + @request.headers["PERSONAL_ACCESS_TOKEN"] = personal_access_token.token + get :index + expect(response.status).to eq(200) + expect(response.body).to eq('authenticated') + end + + it "doesn't log the user in otherwise" do + get :index, personal_access_token: "token" + expect(response.status).to_not eq(200) + expect(response.body).to_not eq('authenticated') + end + end end -- GitLab From 051324e12a7384b15aaa68f53dd43ad0b3c67812 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Tue, 19 Apr 2016 16:24:33 +0530 Subject: [PATCH 079/714] Refactor `authenticate_user_from_private_token!` - No need to use `if`s when we have a `presence` check already. --- app/controllers/application_controller.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 590f9383f7fc24..2b2726c048ca7c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -67,13 +67,7 @@ def sentry_program_context # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 def authenticate_user_from_private_token! - user_token = if params[:authenticity_token].presence - params[:authenticity_token].presence - elsif params[:private_token].presence - params[:private_token].presence - elsif request.headers['PRIVATE-TOKEN'].present? - request.headers['PRIVATE-TOKEN'] - end + user_token = params[:authenticity_token].presence || params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence user = user_token && User.find_by_authentication_token(user_token.to_s) if user -- GitLab From abd8eccae7d0566ed6966c5f681d4f7c07bfb016 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Tue, 19 Apr 2016 16:46:03 +0530 Subject: [PATCH 080/714] Remove an unused view file. --- app/views/profiles/personal_access_tokens/create.html.haml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 app/views/profiles/personal_access_tokens/create.html.haml diff --git a/app/views/profiles/personal_access_tokens/create.html.haml b/app/views/profiles/personal_access_tokens/create.html.haml deleted file mode 100644 index 89da41a75ef22b..00000000000000 --- a/app/views/profiles/personal_access_tokens/create.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%h1 Profiles::PersonalAccessTokens#create -%p Find me in app/views/profiles/personal_access_tokens/create.html.haml -- GitLab From 611f3ad2683a1103ef3c2af244a10ac9f3ae6734 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 20 Apr 2016 11:14:08 +0530 Subject: [PATCH 081/714] Fix rubocop complaints. --- lib/api/helpers/authentication.rb | 2 +- lib/api/helpers/core.rb | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb index 666bf3ffa169ba..4109c97ed04619 100644 --- a/lib/api/helpers/authentication.rb +++ b/lib/api/helpers/authentication.rb @@ -50,4 +50,4 @@ def sudo_identifier() end end end -end \ No newline at end of file +end diff --git a/lib/api/helpers/core.rb b/lib/api/helpers/core.rb index c37064d49ab763..05cda8b84beb90 100644 --- a/lib/api/helpers/core.rb +++ b/lib/api/helpers/core.rb @@ -132,7 +132,7 @@ def validate_label_params(params) if params[:labels].present? params[:labels].split(',').each do |label_name| label = user_project.labels.create_with( - color: Label::DEFAULT_COLOR).find_or_initialize_by( + color: Label::DEFAULT_COLOR).find_or_initialize_by( title: label_name.strip) if label.invalid? @@ -274,9 +274,9 @@ def uploaded_file(field, uploads_path) bad_request!('Bad file path') unless file_path.start_with?(uploads_path) UploadedFile.new( - file_path, - params["#{field}.name"], - params["#{field}.type"] || 'application/octet-stream', + file_path, + params["#{field}.name"], + params["#{field}.type"] || 'application/octet-stream', ) end @@ -288,11 +288,11 @@ def present_file!(path, filename, content_type = 'application/octet-stream') # Support download acceleration case headers['X-Sendfile-Type'] - when 'X-Sendfile' - header['X-Sendfile'] = path - body - else - file FileStreamer.new(path) + when 'X-Sendfile' + header['X-Sendfile'] = path + body + else + file FileStreamer.new(path) end end @@ -348,4 +348,4 @@ def handle_member_errors(errors) end end end -end \ No newline at end of file +end -- GitLab From 17f2fc10e6765d328b9c34a45815e183cca50466 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 20 Apr 2016 11:57:45 +0530 Subject: [PATCH 082/714] Change the root param while creating personal access tokens. - Can't use `personal_access_token` anymore, because the contents of that param are assumed to be a token string, and authenticated against. --- app/controllers/profiles/personal_access_tokens_controller.rb | 4 +++- app/views/profiles/personal_access_tokens/index.html.haml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 5a6026f58cb440..7fbf343edbdd20 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -32,6 +32,8 @@ def revoke private def personal_access_token_params - params.require(:personal_access_token).permit(:name, :expires_at) + # We aren't using `personal_access_token` as the root param because the authentication + # system expects to find a token string there - it's off-limits to us. + params.require(:personal_access_token_params).permit(:name, :expires_at) end end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 77726d34fbc8aa..72e67df4337dff 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -12,7 +12,8 @@ Add a Personal Access Token %p.profile-settings-content Pick a name for the application, and we'll give you a unique token. - = form_for [:profile, @personal_access_token], method: :post, html: { class: 'js-requires-input' } do |f| + = form_for [:profile, @personal_access_token], as: "personal_access_token_params", + method: :post, html: { class: 'js-requires-input' } do |f| .form-group = f.label :name, class: 'label-light' -- GitLab From 25aefde62b0ac57d93ff3a6ddeef3277e40cc7bd Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 20 Apr 2016 11:58:48 +0530 Subject: [PATCH 083/714] Add feature specs for personal access token management. --- .../personal_access_tokens/index.html.haml | 4 +- .../profiles/personal_access_tokens_spec.rb | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 spec/features/profiles/personal_access_tokens_spec.rb diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 72e67df4337dff..e61fa69af5472a 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -32,7 +32,7 @@ - if @active_personal_access_tokens.exists? .table-responsive - %table.table.table-striped.table-hover + %table.table.table-striped.table-hover.active-personal-access-tokens %thead %tr %th Name @@ -66,7 +66,7 @@ - if @inactive_personal_access_tokens.exists? .table-responsive - %table.table.table-striped.table-hover + %table.table.table-striped.table-hover.inactive-personal-access-tokens %thead %tr %th Name diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb new file mode 100644 index 00000000000000..ce972776ffe059 --- /dev/null +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe 'Profile > Personal Access Tokens', feature: true do + let(:user) { create(:user) } + + before do + login_as(user) + end + + describe "token creation" do + it "allows creation of a token with an optional expiry date" do + visit profile_personal_access_tokens_path + fill_in "Name", with: FFaker::Product.brand + expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) + + active_personal_access_tokens = find(".table.active-personal-access-tokens").native.inner_html + expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) + expect(active_personal_access_tokens).to match("Never") + expect(active_personal_access_tokens).to match(PersonalAccessToken.last.token) + + fill_in "Name", with: FFaker::Product.brand + fill_in "Expires at", with: 5.days.from_now + expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) + + active_personal_access_tokens = find(".table.active-personal-access-tokens").native.inner_html + expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) + expect(active_personal_access_tokens).to match(5.days.from_now.to_date.to_s) + expect(active_personal_access_tokens).to match(PersonalAccessToken.last.token) + end + end + + describe "inactive tokens" do + it "allows revocation of an active token" do + personal_access_token = create(:personal_access_token, user: user) + visit profile_personal_access_tokens_path + click_on "Revoke" + + inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native.inner_html + expect(inactive_personal_access_tokens).to match(personal_access_token.name) + expect(inactive_personal_access_tokens).to match(personal_access_token.token) + end + + it "moves expired tokens to the 'inactive' section" do + personal_access_token = create(:personal_access_token, expires_at: 5.days.ago, user: user) + visit profile_personal_access_tokens_path + + inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native.inner_html + expect(inactive_personal_access_tokens).to match(personal_access_token.name) + expect(inactive_personal_access_tokens).to match(personal_access_token.token) + end + end +end -- GitLab From 4e7acd88dc02e545ba696a2b4fd8c16bd6df31d5 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 20 Apr 2016 12:21:14 +0530 Subject: [PATCH 084/714] Remove unnecessary javascript from the datepicker initialization. - In the personal access tokens page. - Also fix the z-index so it doesn't appear below the token text fields. --- .../personal_access_tokens/index.html.haml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index e61fa69af5472a..af34eb389dfe73 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -90,5 +90,16 @@ :javascript $(".datepicker").datepicker({ dateFormat: "yy-mm-dd", - onSelect: function(dateText, inst) { $("#personal_access_token_expires_at").val(dateText) } - }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#personal_access_token_expires_at').val())); \ No newline at end of file + beforeShow: function() { + //////////////////////////////////////////////////////////////// + // 1. Need the setTimeout because the datepicker doesn't have // + // an `afterShow` callback. // + // 2. Need to set the z-index like this because we don't want // + // to target datepickers outside the current page, which // + // will happen if we set this in CSS directly. // + //////////////////////////////////////////////////////////////// + setTimeout(function(){ + $('.ui-datepicker').css('z-index', 3); + }, 0); + } + }); -- GitLab From c382bd266d256cdbd732be928ecb6a532bfa8ddd Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 20 Apr 2016 14:20:24 +0530 Subject: [PATCH 085/714] Improve performance of the personal access tokens page. --- .../profiles/personal_access_tokens/index.html.haml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index af34eb389dfe73..02800c37917d0b 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -28,9 +28,9 @@ %hr - %h5= "Active Personal Access Tokens (#{@active_personal_access_tokens.count})" + %h5= "Active Personal Access Tokens (#{@active_personal_access_tokens.length})" - - if @active_personal_access_tokens.exists? + - if @active_personal_access_tokens.present? .table-responsive %table.table.table-striped.table-hover.active-personal-access-tokens %thead @@ -41,7 +41,7 @@ %th Expires %th Actions %tbody - - @active_personal_access_tokens.active.each do |token| + - @active_personal_access_tokens.each do |token| %tr %td= token.name %td.input-group.personal-access-tokens-token-column @@ -62,9 +62,9 @@ %hr - %h5= "Inactive Personal Access Tokens (#{@inactive_personal_access_tokens.count})" + %h5= "Inactive Personal Access Tokens (#{@inactive_personal_access_tokens.length})" - - if @inactive_personal_access_tokens.exists? + - if @inactive_personal_access_tokens.present? .table-responsive %table.table.table-striped.table-hover.inactive-personal-access-tokens %thead @@ -73,7 +73,7 @@ %th Token %th Created %tbody - - @inactive_personal_access_tokens.order("revoked, expires_at").each do |token| + - @inactive_personal_access_tokens.each do |token| %tr %td= token.name %td.input-group.personal-access-tokens-token-column -- GitLab From 4076bce5d52b8a11eda48c36011666ea344ba3b7 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 22 Apr 2016 12:36:56 +0530 Subject: [PATCH 086/714] Merge the "personal access token"-related migrations. --- db/migrate/20160415062917_create_personal_access_tokens.rb | 2 ++ ...415144643_add_column_revoked_to_personal_access_tokens.rb | 5 ----- ...085954_add_column_expires_at_to_personal_access_tokens.rb | 5 ----- 3 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb delete mode 100644 db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb diff --git a/db/migrate/20160415062917_create_personal_access_tokens.rb b/db/migrate/20160415062917_create_personal_access_tokens.rb index 42a41349a0c706..2c9f773e3084f4 100644 --- a/db/migrate/20160415062917_create_personal_access_tokens.rb +++ b/db/migrate/20160415062917_create_personal_access_tokens.rb @@ -4,6 +4,8 @@ def change t.references :user, index: true, foreign_key: true, null: false t.string :token, index: {unique: true}, null: false t.string :name, null: false + t.boolean :revoked, default: false + t.datetime :expires_at t.timestamps null: false end diff --git a/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb b/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb deleted file mode 100644 index 8eecdfc5a1c9aa..00000000000000 --- a/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddColumnRevokedToPersonalAccessTokens < ActiveRecord::Migration - def change - add_column :personal_access_tokens, :revoked, :boolean, default: false - end -end diff --git a/db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb b/db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb deleted file mode 100644 index 9d99ebeadf535a..00000000000000 --- a/db/migrate/20160418085954_add_column_expires_at_to_personal_access_tokens.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddColumnExpiresAtToPersonalAccessTokens < ActiveRecord::Migration - def change - add_column :personal_access_tokens, :expires_at, :datetime - end -end -- GitLab From fc4bce755d19d570c4a00241048517c38aa839b3 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 22 Apr 2016 14:03:11 +0530 Subject: [PATCH 087/714] Make fixes based on @vsizov's comments on MR !3749 --- app/controllers/profiles/personal_access_tokens_controller.rb | 4 ---- app/models/personal_access_token.rb | 4 ++-- lib/api/helpers/authentication.rb | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 7fbf343edbdd20..af6def25e7f72c 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -2,10 +2,6 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def index @active_personal_access_tokens = current_user.personal_access_tokens.active.order(:expires_at) @inactive_personal_access_tokens = current_user.personal_access_tokens.inactive - - # Prefer this to `@user.personal_access_tokens.new`, because it - # litters the view's call to `@user.personal_access_tokens` with - # this stub personal access token. @personal_access_token = PersonalAccessToken.new(user: @user) end diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index fff3f76fb93c98..c7c3932ba40022 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -1,8 +1,8 @@ class PersonalAccessToken < ActiveRecord::Base belongs_to :user - scope :active, -> { where(revoked: false).where("expires_at >= :current OR expires_at IS NULL", current: Time.current) } - scope :inactive, -> { where("revoked = true OR expires_at < :current", current: Time.current) } + scope :active, -> { where(revoked: false).where("expires_at >= NOW() OR expires_at IS NULL") } + scope :inactive, -> { where("revoked = true OR expires_at < NOW()") } def self.generate(params) personal_access_token = self.new(params) diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb index 4109c97ed04619..4330c5802767bf 100644 --- a/lib/api/helpers/authentication.rb +++ b/lib/api/helpers/authentication.rb @@ -42,7 +42,7 @@ def sudo_identifier() identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER] # Regex for integers - if !!(identifier =~ /^[0-9]+$/) + if !!(identifier =~ /\A[0-9]+\z/) identifier.to_i else identifier -- GitLab From b22a47c62e076acddd254e2d659f38261085bf01 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Mon, 25 Apr 2016 09:00:20 +0530 Subject: [PATCH 088/714] Combine `API::Helpers::Core` and `API::Helpers::Authentication` back into `API::Helpers` - Makes the MR easier to read; this can go in a separate MR - This is a (sort of) revert of 99bea01 --- lib/api/api.rb | 4 +- lib/api/helpers.rb | 397 ++++++++++++++++++ lib/api/helpers/authentication.rb | 53 --- lib/api/helpers/core.rb | 351 ---------------- lib/ci/api/api.rb | 3 +- ...entication_spec.rb => api_helpers_spec.rb} | 40 +- spec/requests/api/users_spec.rb | 2 +- 7 files changed, 420 insertions(+), 430 deletions(-) create mode 100644 lib/api/helpers.rb delete mode 100644 lib/api/helpers/authentication.rb delete mode 100644 lib/api/helpers/core.rb rename spec/requests/api/{api_authentication_spec.rb => api_helpers_spec.rb} (79%) diff --git a/lib/api/api.rb b/lib/api/api.rb index 537678863cbeb5..cc1004f80059e8 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -1,5 +1,4 @@ Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file} -Dir["#{Rails.root}/lib/api/helpers/*.rb"].each {|file| require file} module API class API < Grape::API @@ -26,8 +25,7 @@ class API < Grape::API format :json content_type :txt, "text/plain" - helpers Helpers::Core - helpers Helpers::Authentication + helpers Helpers mount Groups mount GroupMembers diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb new file mode 100644 index 00000000000000..fb30ef3e25256b --- /dev/null +++ b/lib/api/helpers.rb @@ -0,0 +1,397 @@ +module API + module Helpers + PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" + PRIVATE_TOKEN_PARAM = :private_token + SUDO_HEADER ="HTTP_SUDO" + SUDO_PARAM = :sudo + PERSONAL_ACCESS_TOKEN_PARAM = :personal_access_token + PERSONAL_ACCESS_TOKEN_HEADER = "HTTP_PERSONAL_ACCESS_TOKEN" + + def parse_boolean(value) + [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(value) + end + + def find_user_by_private_token + private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s + User.find_by_authentication_token(private_token) + end + + def find_user_by_personal_access_token + personal_access_token_string = (params[PERSONAL_ACCESS_TOKEN_PARAM] || env[PERSONAL_ACCESS_TOKEN_HEADER]).to_s + personal_access_token = PersonalAccessToken.active.find_by_token(personal_access_token_string) + personal_access_token.user if personal_access_token + end + + def current_user + @current_user ||= (find_user_by_private_token || find_user_by_personal_access_token || doorkeeper_guard) + + unless @current_user && Gitlab::UserAccess.allowed?(@current_user) + return nil + end + + identifier = sudo_identifier() + + # If the sudo is the current user do nothing + if identifier && !(@current_user.id == identifier || @current_user.username == identifier) + render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin? + @current_user = User.by_username_or_id(identifier) + not_found!("No user id or username for: #{identifier}") if @current_user.nil? + end + + @current_user + end + + def sudo_identifier() + identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER] + + # Regex for integers + if !!(identifier =~ /\A[0-9]+\z/) + identifier.to_i + else + identifier + end + end + + def user_project + @project ||= find_project(params[:id]) + @project || not_found!("Project") + end + + def find_project(id) + project = Project.find_with_namespace(id) || Project.find_by(id: id) + + if project && can?(current_user, :read_project, project) + project + else + nil + end + end + + def project_service + @project_service ||= begin + underscored_service = params[:service_slug].underscore + + if Service.available_services_names.include?(underscored_service) + user_project.build_missing_services + + service_method = "#{underscored_service}_service" + + send_service(service_method) + end + end + + @project_service || not_found!("Service") + end + + def send_service(service_method) + user_project.send(service_method) + end + + def service_attributes + @service_attributes ||= project_service.fields.inject([]) do |arr, hash| + arr << hash[:name].to_sym + end + end + + def find_group(id) + begin + group = Group.find(id) + rescue ActiveRecord::RecordNotFound + group = Group.find_by!(path: id) + end + + if can?(current_user, :read_group, group) + group + else + not_found!('Group') + end + end + + def paginate(relation) + relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| + add_pagination_headers(data) + end + end + + def authenticate! + unauthorized! unless current_user + end + + def authenticate_by_gitlab_shell_token! + input = params['secret_token'].try(:chomp) + unless Devise.secure_compare(secret_token, input) + unauthorized! + end + end + + def authenticated_as_admin! + forbidden! unless current_user.is_admin? + end + + def authorize!(action, subject) + forbidden! unless abilities.allowed?(current_user, action, subject) + end + + def authorize_push_project + authorize! :push_code, user_project + end + + def authorize_admin_project + authorize! :admin_project, user_project + end + + def require_gitlab_workhorse! + unless env['HTTP_GITLAB_WORKHORSE'].present? + forbidden!('Request should be executed via GitLab Workhorse') + end + end + + def can?(object, action, subject) + abilities.allowed?(object, action, subject) + end + + # Checks the occurrences of required attributes, each attribute must be present in the params hash + # or a Bad Request error is invoked. + # + # Parameters: + # keys (required) - A hash consisting of keys that must be present + def required_attributes!(keys) + keys.each do |key| + bad_request!(key) unless params[key].present? + end + end + + def attributes_for_keys(keys, custom_params = nil) + 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) + attrs[key] = params_hash[key] + end + end + ActionController::Parameters.new(attrs).permit! + end + + # Helper method for validating all labels against its names + def validate_label_params(params) + errors = {} + + if params[:labels].present? + params[:labels].split(',').each do |label_name| + label = user_project.labels.create_with( + color: Label::DEFAULT_COLOR).find_or_initialize_by( + title: label_name.strip) + + if label.invalid? + errors[label.title] = label.errors + end + end + end + + errors + end + + def validate_access_level?(level) + Gitlab::Access.options_with_owner.values.include? level.to_i + end + + def issuable_order_by + if params["order_by"] == 'updated_at' + 'updated_at' + else + 'created_at' + end + end + + def issuable_sort + if params["sort"] == 'asc' + :asc + else + :desc + end + end + + def filter_by_iid(items, iid) + items.where(iid: iid) + end + + # error helpers + + def forbidden!(reason = nil) + message = ['403 Forbidden'] + message << " - #{reason}" if reason + render_api_error!(message.join(' '), 403) + end + + def bad_request!(attribute) + message = ["400 (Bad request)"] + message << "\"" + attribute.to_s + "\" not given" + render_api_error!(message.join(' '), 400) + end + + def not_found!(resource = nil) + message = ["404"] + message << resource if resource + message << "Not Found" + render_api_error!(message.join(' '), 404) + end + + def unauthorized! + render_api_error!('401 Unauthorized', 401) + end + + def not_allowed! + render_api_error!('405 Method Not Allowed', 405) + end + + def conflict!(message = nil) + render_api_error!(message || '409 Conflict', 409) + end + + def file_to_large! + render_api_error!('413 Request Entity Too Large', 413) + end + + def not_modified! + render_api_error!('304 Not Modified', 304) + end + + def render_validation_error!(model) + if model.errors.any? + render_api_error!(model.errors.messages || '400 Bad Request', 400) + end + end + + def render_api_error!(message, status) + error!({ 'message' => message }, status) + end + + # Projects helpers + + def filter_projects(projects) + # If the archived parameter is passed, limit results accordingly + if params[:archived].present? + projects = projects.where(archived: parse_boolean(params[:archived])) + end + + if params[:search].present? + projects = projects.search(params[:search]) + end + + if params[:visibility].present? + projects = projects.search_by_visibility(params[:visibility]) + end + + projects.reorder(project_order_by => project_sort) + end + + def project_order_by + order_fields = %w(id name path created_at updated_at last_activity_at) + + if order_fields.include?(params['order_by']) + params['order_by'] + else + 'created_at' + end + end + + def project_sort + if params["sort"] == 'asc' + :asc + else + :desc + end + end + + # file helpers + + def uploaded_file(field, uploads_path) + if params[field] + bad_request!("#{field} is not a file") unless params[field].respond_to?(:filename) + return params[field] + end + + return nil unless params["#{field}.path"] && params["#{field}.name"] + + # sanitize file paths + # this requires all paths to exist + required_attributes! %W(#{field}.path) + uploads_path = File.realpath(uploads_path) + file_path = File.realpath(params["#{field}.path"]) + bad_request!('Bad file path') unless file_path.start_with?(uploads_path) + + UploadedFile.new( + file_path, + params["#{field}.name"], + params["#{field}.type"] || 'application/octet-stream', + ) + end + + def present_file!(path, filename, content_type = 'application/octet-stream') + filename ||= File.basename(path) + header['Content-Disposition'] = "attachment; filename=#{filename}" + header['Content-Transfer-Encoding'] = 'binary' + content_type content_type + + # Support download acceleration + case headers['X-Sendfile-Type'] + when 'X-Sendfile' + header['X-Sendfile'] = path + body + else + file FileStreamer.new(path) + end + end + + private + + def add_pagination_headers(paginated_data) + header 'X-Total', paginated_data.total_count.to_s + header 'X-Total-Pages', paginated_data.total_pages.to_s + header 'X-Per-Page', paginated_data.limit_value.to_s + header 'X-Page', paginated_data.current_page.to_s + header 'X-Next-Page', paginated_data.next_page.to_s + header 'X-Prev-Page', paginated_data.prev_page.to_s + header 'Link', pagination_links(paginated_data) + end + + def pagination_links(paginated_data) + request_url = request.url.split('?').first + request_params = params.clone + request_params[:per_page] = paginated_data.limit_value + + links = [] + + request_params[:page] = paginated_data.current_page - 1 + links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") unless paginated_data.first_page? + + request_params[:page] = paginated_data.current_page + 1 + links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? + + request_params[:page] = 1 + links << %(<#{request_url}?#{request_params.to_query}>; rel="first") + + request_params[:page] = paginated_data.total_pages + links << %(<#{request_url}?#{request_params.to_query}>; rel="last") + + links.join(', ') + end + + def abilities + @abilities ||= begin + abilities = Six.new + abilities << Ability + abilities + end + end + + def secret_token + File.read(Gitlab.config.gitlab_shell.secret_file).chomp + end + + def handle_member_errors(errors) + error!(errors[:access_level], 422) if errors[:access_level].any? + not_found!(errors) + end + end +end diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb deleted file mode 100644 index 4330c5802767bf..00000000000000 --- a/lib/api/helpers/authentication.rb +++ /dev/null @@ -1,53 +0,0 @@ -module API - module Helpers - module Authentication - PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" - PRIVATE_TOKEN_PARAM = :private_token - SUDO_HEADER ="HTTP_SUDO" - SUDO_PARAM = :sudo - PERSONAL_ACCESS_TOKEN_PARAM = :personal_access_token - PERSONAL_ACCESS_TOKEN_HEADER = "HTTP_PERSONAL_ACCESS_TOKEN" - - def find_user_by_private_token - private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - User.find_by_authentication_token(private_token) - end - - def find_user_by_personal_access_token - personal_access_token_string = (params[PERSONAL_ACCESS_TOKEN_PARAM] || env[PERSONAL_ACCESS_TOKEN_HEADER]).to_s - personal_access_token = PersonalAccessToken.active.find_by_token(personal_access_token_string) - personal_access_token.user if personal_access_token - end - - def current_user - @current_user ||= (find_user_by_private_token || find_user_by_personal_access_token || doorkeeper_guard) - - unless @current_user && Gitlab::UserAccess.allowed?(@current_user) - return nil - end - - identifier = sudo_identifier() - - # If the sudo is the current user do nothing - if identifier && !(@current_user.id == identifier || @current_user.username == identifier) - render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin? - @current_user = User.by_username_or_id(identifier) - not_found!("No user id or username for: #{identifier}") if @current_user.nil? - end - - @current_user - end - - def sudo_identifier() - identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER] - - # Regex for integers - if !!(identifier =~ /\A[0-9]+\z/) - identifier.to_i - else - identifier - end - end - end - end -end diff --git a/lib/api/helpers/core.rb b/lib/api/helpers/core.rb deleted file mode 100644 index 05cda8b84beb90..00000000000000 --- a/lib/api/helpers/core.rb +++ /dev/null @@ -1,351 +0,0 @@ -module API - module Helpers - module Core - def parse_boolean(value) - [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(value) - end - - def user_project - @project ||= find_project(params[:id]) - @project || not_found!("Project") - end - - def find_project(id) - project = Project.find_with_namespace(id) || Project.find_by(id: id) - - if project && can?(current_user, :read_project, project) - project - else - nil - end - end - - def project_service - @project_service ||= begin - underscored_service = params[:service_slug].underscore - - if Service.available_services_names.include?(underscored_service) - user_project.build_missing_services - - service_method = "#{underscored_service}_service" - - send_service(service_method) - end - end - - @project_service || not_found!("Service") - end - - def send_service(service_method) - user_project.send(service_method) - end - - def service_attributes - @service_attributes ||= project_service.fields.inject([]) do |arr, hash| - arr << hash[:name].to_sym - end - end - - def find_group(id) - begin - group = Group.find(id) - rescue ActiveRecord::RecordNotFound - group = Group.find_by!(path: id) - end - - if can?(current_user, :read_group, group) - group - else - not_found!('Group') - end - end - - def paginate(relation) - relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| - add_pagination_headers(data) - end - end - - def authenticate! - unauthorized! unless current_user - end - - def authenticate_by_gitlab_shell_token! - input = params['secret_token'].try(:chomp) - unless Devise.secure_compare(secret_token, input) - unauthorized! - end - end - - def authenticated_as_admin! - forbidden! unless current_user.is_admin? - end - - def authorize!(action, subject) - forbidden! unless abilities.allowed?(current_user, action, subject) - end - - def authorize_push_project - authorize! :push_code, user_project - end - - def authorize_admin_project - authorize! :admin_project, user_project - end - - def require_gitlab_workhorse! - unless env['HTTP_GITLAB_WORKHORSE'].present? - forbidden!('Request should be executed via GitLab Workhorse') - end - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - # Checks the occurrences of required attributes, each attribute must be present in the params hash - # or a Bad Request error is invoked. - # - # Parameters: - # keys (required) - A hash consisting of keys that must be present - def required_attributes!(keys) - keys.each do |key| - bad_request!(key) unless params[key].present? - end - end - - def attributes_for_keys(keys, custom_params = nil) - 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) - attrs[key] = params_hash[key] - end - end - ActionController::Parameters.new(attrs).permit! - end - - # Helper method for validating all labels against its names - def validate_label_params(params) - errors = {} - - if params[:labels].present? - params[:labels].split(',').each do |label_name| - label = user_project.labels.create_with( - color: Label::DEFAULT_COLOR).find_or_initialize_by( - title: label_name.strip) - - if label.invalid? - errors[label.title] = label.errors - end - end - end - - errors - end - - def validate_access_level?(level) - Gitlab::Access.options_with_owner.values.include? level.to_i - end - - def issuable_order_by - if params["order_by"] == 'updated_at' - 'updated_at' - else - 'created_at' - end - end - - def issuable_sort - if params["sort"] == 'asc' - :asc - else - :desc - end - end - - def filter_by_iid(items, iid) - items.where(iid: iid) - end - - # error helpers - - def forbidden!(reason = nil) - message = ['403 Forbidden'] - message << " - #{reason}" if reason - render_api_error!(message.join(' '), 403) - end - - def bad_request!(attribute) - message = ["400 (Bad request)"] - message << "\"" + attribute.to_s + "\" not given" - render_api_error!(message.join(' '), 400) - end - - def not_found!(resource = nil) - message = ["404"] - message << resource if resource - message << "Not Found" - render_api_error!(message.join(' '), 404) - end - - def unauthorized! - render_api_error!('401 Unauthorized', 401) - end - - def not_allowed! - render_api_error!('405 Method Not Allowed', 405) - end - - def conflict!(message = nil) - render_api_error!(message || '409 Conflict', 409) - end - - def file_to_large! - render_api_error!('413 Request Entity Too Large', 413) - end - - def not_modified! - render_api_error!('304 Not Modified', 304) - end - - def render_validation_error!(model) - if model.errors.any? - render_api_error!(model.errors.messages || '400 Bad Request', 400) - end - end - - def render_api_error!(message, status) - error!({ 'message' => message }, status) - end - - # Projects helpers - - def filter_projects(projects) - # If the archived parameter is passed, limit results accordingly - if params[:archived].present? - projects = projects.where(archived: parse_boolean(params[:archived])) - end - - if params[:search].present? - projects = projects.search(params[:search]) - end - - if params[:visibility].present? - projects = projects.search_by_visibility(params[:visibility]) - end - - projects.reorder(project_order_by => project_sort) - end - - def project_order_by - order_fields = %w(id name path created_at updated_at last_activity_at) - - if order_fields.include?(params['order_by']) - params['order_by'] - else - 'created_at' - end - end - - def project_sort - if params["sort"] == 'asc' - :asc - else - :desc - end - end - - # file helpers - - def uploaded_file(field, uploads_path) - if params[field] - bad_request!("#{field} is not a file") unless params[field].respond_to?(:filename) - return params[field] - end - - return nil unless params["#{field}.path"] && params["#{field}.name"] - - # sanitize file paths - # this requires all paths to exist - required_attributes! %W(#{field}.path) - uploads_path = File.realpath(uploads_path) - file_path = File.realpath(params["#{field}.path"]) - bad_request!('Bad file path') unless file_path.start_with?(uploads_path) - - UploadedFile.new( - file_path, - params["#{field}.name"], - params["#{field}.type"] || 'application/octet-stream', - ) - end - - def present_file!(path, filename, content_type = 'application/octet-stream') - filename ||= File.basename(path) - header['Content-Disposition'] = "attachment; filename=#{filename}" - header['Content-Transfer-Encoding'] = 'binary' - content_type content_type - - # Support download acceleration - case headers['X-Sendfile-Type'] - when 'X-Sendfile' - header['X-Sendfile'] = path - body - else - file FileStreamer.new(path) - end - end - - private - - def add_pagination_headers(paginated_data) - header 'X-Total', paginated_data.total_count.to_s - header 'X-Total-Pages', paginated_data.total_pages.to_s - header 'X-Per-Page', paginated_data.limit_value.to_s - header 'X-Page', paginated_data.current_page.to_s - header 'X-Next-Page', paginated_data.next_page.to_s - header 'X-Prev-Page', paginated_data.prev_page.to_s - header 'Link', pagination_links(paginated_data) - end - - def pagination_links(paginated_data) - request_url = request.url.split('?').first - request_params = params.clone - request_params[:per_page] = paginated_data.limit_value - - links = [] - - request_params[:page] = paginated_data.current_page - 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="prev") unless paginated_data.first_page? - - request_params[:page] = paginated_data.current_page + 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="next") unless paginated_data.last_page? - - request_params[:page] = 1 - links << %(<#{request_url}?#{request_params.to_query}>; rel="first") - - request_params[:page] = paginated_data.total_pages - links << %(<#{request_url}?#{request_params.to_query}>; rel="last") - - links.join(', ') - end - - def abilities - @abilities ||= begin - abilities = Six.new - abilities << Ability - abilities - end - end - - def secret_token - File.read(Gitlab.config.gitlab_shell.secret_file).chomp - end - - def handle_member_errors(errors) - error!(errors[:access_level], 422) if errors[:access_level].any? - not_found!(errors) - end - end - end -end diff --git a/lib/ci/api/api.rb b/lib/ci/api/api.rb index 495f5792b084cc..353c4ddebf8edc 100644 --- a/lib/ci/api/api.rb +++ b/lib/ci/api/api.rb @@ -28,8 +28,7 @@ class API < Grape::API format :json helpers ::Ci::API::Helpers - helpers ::API::Helpers::Core - helpers ::API::Helpers::Authentication + helpers ::API::Helpers helpers Gitlab::CurrentSettings mount Builds diff --git a/spec/requests/api/api_authentication_spec.rb b/spec/requests/api/api_helpers_spec.rb similarity index 79% rename from spec/requests/api/api_authentication_spec.rb rename to spec/requests/api/api_helpers_spec.rb index 0416e57c68b420..06997147b090a3 100644 --- a/spec/requests/api/api_authentication_spec.rb +++ b/spec/requests/api/api_helpers_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' -describe API::Helpers::Authentication, api: true do +describe API::Helpers, api: true do - include API::Helpers::Authentication + include API::Helpers include ApiHelpers let(:user) { create(:user) } @@ -15,25 +15,25 @@ def set_env(token_usr, identifier) clear_env clear_param - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = token_usr.private_token - env[API::Helpers::Authentication::SUDO_HEADER] = identifier + env[API::Helpers::PRIVATE_TOKEN_HEADER] = token_usr.private_token + env[API::Helpers::SUDO_HEADER] = identifier end def set_param(token_usr, identifier) clear_env clear_param - params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = token_usr.private_token - params[API::Helpers::Authentication::SUDO_PARAM] = identifier + params[API::Helpers::PRIVATE_TOKEN_PARAM] = token_usr.private_token + params[API::Helpers::SUDO_PARAM] = identifier end def clear_env - env.delete(API::Helpers::Authentication::PRIVATE_TOKEN_HEADER) - env.delete(API::Helpers::Authentication::SUDO_HEADER) + env.delete(API::Helpers::PRIVATE_TOKEN_HEADER) + env.delete(API::Helpers::SUDO_HEADER) end def clear_param - params.delete(API::Helpers::Authentication::PRIVATE_TOKEN_PARAM) - params.delete(API::Helpers::Authentication::SUDO_PARAM) + params.delete(API::Helpers::PRIVATE_TOKEN_PARAM) + params.delete(API::Helpers::SUDO_PARAM) end def error!(message, status) @@ -43,22 +43,22 @@ def error!(message, status) describe ".current_user" do describe "when authenticating using a user's private token" do it "should return nil for an invalid token" do - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = 'invalid token' + env[API::Helpers::PRIVATE_TOKEN_HEADER] = 'invalid token' allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } expect(current_user).to be_nil end it "should return nil for a user without access" do - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token + env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false) expect(current_user).to be_nil end it "should leave user as is when sudo not specified" do - env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token + env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token expect(current_user).to eq(user) clear_env - params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = user.private_token + params[API::Helpers::PRIVATE_TOKEN_PARAM] = user.private_token expect(current_user).to eq(user) end end @@ -67,35 +67,35 @@ def error!(message, status) let(:personal_access_token) { create(:personal_access_token, user: user) } it "should return nil for an invalid token" do - env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = 'invalid token' + env[API::Helpers::PERSONAL_ACCESS_TOKEN_HEADER] = 'invalid token' allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } expect(current_user).to be_nil end it "should return nil for a user without access" do - env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + env[API::Helpers::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false) expect(current_user).to be_nil end it "should leave user as is when sudo not specified" do - env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + env[API::Helpers::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token expect(current_user).to eq(user) clear_env - params[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_PARAM] = personal_access_token.token + params[API::Helpers::PERSONAL_ACCESS_TOKEN_PARAM] = personal_access_token.token expect(current_user).to eq(user) end it 'does not allow revoked tokens' do personal_access_token.revoke! - env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + env[API::Helpers::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } expect(current_user).to be_nil end it 'does not allow expired tokens' do personal_access_token.update_attributes!(expires_at: 1.day.ago) - env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token + env[API::Helpers::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } expect(current_user).to be_nil end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 628569d3e009d1..40b24c125b54e4 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -24,7 +24,7 @@ context "when public level is restricted" do before do stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) - allow_any_instance_of(API::Helpers::Authentication).to receive(:authenticate!).and_return(true) + allow_any_instance_of(API::Helpers).to receive(:authenticate!).and_return(true) end it "renders 403" do -- GitLab From fe5eca8b38e28ad3c77d3d71297cca110306cab9 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Mon, 25 Apr 2016 09:19:25 +0530 Subject: [PATCH 089/714] Update CHANGELOG. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 91fdfe6216f77e..b3ea047475e07c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.8.0 (unreleased) - Make build status canceled if any of the jobs was canceled and none failed + - Allow authentication using personal acces tokens - Remove future dates from contribution calendar graph. - Use ActionDispatch Remote IP for Akismet checking - Fix error when visiting commit builds page before build was updated -- GitLab From bafbf22c6ab613d25287d7119d7e30770c531fdb Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Mon, 25 Apr 2016 14:30:59 +0530 Subject: [PATCH 090/714] Address @DouweM's feedback on !3749. - Use `TokenAuthenticatable` to generate the personal access token - Remove a check for `authenticity_token` in application controller; this should've been `authentication_token`, maybe, and doesn't make any sense now. - Have the datepicker appear inline --- app/controllers/application_controller.rb | 2 +- app/models/personal_access_token.rb | 5 ++++- .../personal_access_tokens/index.html.haml | 18 ++++-------------- .../controllers/application_controller_spec.rb | 6 ------ .../profiles/personal_access_tokens_spec.rb | 18 +++++++++++------- spec/models/personal_access_token_spec.rb | 15 +++++++++++++++ 6 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 spec/models/personal_access_token_spec.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2b2726c048ca7c..eb5ffc44c3ba2a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -67,7 +67,7 @@ def sentry_program_context # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 def authenticate_user_from_private_token! - user_token = params[:authenticity_token].presence || params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence + user_token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence user = user_token && User.find_by_authentication_token(user_token.to_s) if user diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index c7c3932ba40022..c4b095e0c0471c 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -1,4 +1,7 @@ class PersonalAccessToken < ActiveRecord::Base + include TokenAuthenticatable + add_authentication_token_field :token + belongs_to :user scope :active, -> { where(revoked: false).where("expires_at >= NOW() OR expires_at IS NULL") } @@ -6,7 +9,7 @@ class PersonalAccessToken < ActiveRecord::Base def self.generate(params) personal_access_token = self.new(params) - personal_access_token.token = Devise.friendly_token(50) + personal_access_token.ensure_token personal_access_token end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 02800c37917d0b..f7482d2c87d901 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -21,7 +21,8 @@ .form-group = f.label :expires_at, class: 'label-light' - = f.text_field :expires_at, class: "form-control datepicker", required: false + = f.hidden_field :expires_at, class: "form-control", required: false + .datepicker .prepend-top-default = f.submit 'Add Personal Access Token', class: "btn btn-create" @@ -90,16 +91,5 @@ :javascript $(".datepicker").datepicker({ dateFormat: "yy-mm-dd", - beforeShow: function() { - //////////////////////////////////////////////////////////////// - // 1. Need the setTimeout because the datepicker doesn't have // - // an `afterShow` callback. // - // 2. Need to set the z-index like this because we don't want // - // to target datepickers outside the current page, which // - // will happen if we set this in CSS directly. // - //////////////////////////////////////////////////////////////// - setTimeout(function(){ - $('.ui-datepicker').css('z-index', 3); - }, 0); - } - }); + onSelect: function(dateText, inst) { $("#personal_access_token_params_expires_at").val(dateText) } + }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#personal_access_token_params_expires_at').val())); diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 1ec51465cd3685..e8bdbf1afb72e8 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -40,12 +40,6 @@ def index let(:user) { create(:user) } - it "logs the user in when the 'authenticity_token' param is populated with the private token" do - get :index, authenticity_token: user.private_token - expect(response.status).to eq(200) - expect(response.body).to eq("authenticated") - end - it "logs the user in when the 'private_token' param is populated with the private token" do get :index, private_token: user.private_token expect(response.status).to eq(200) diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index ce972776ffe059..e9fbeefae75c7a 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'Profile > Personal Access Tokens', feature: true do +describe 'Profile > Personal Access Tokens', feature: true, js: true do let(:user) { create(:user) } before do @@ -13,18 +13,22 @@ fill_in "Name", with: FFaker::Product.brand expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) - active_personal_access_tokens = find(".table.active-personal-access-tokens").native.inner_html + active_personal_access_tokens = find(".table.active-personal-access-tokens").native['innerHTML'] expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) expect(active_personal_access_tokens).to match("Never") expect(active_personal_access_tokens).to match(PersonalAccessToken.last.token) fill_in "Name", with: FFaker::Product.brand - fill_in "Expires at", with: 5.days.from_now + + # Set date to 1st of next month + find("a[title='Next']").click + click_on "1" + expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) - active_personal_access_tokens = find(".table.active-personal-access-tokens").native.inner_html + active_personal_access_tokens = find(".table.active-personal-access-tokens").native['innerHTML'] expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) - expect(active_personal_access_tokens).to match(5.days.from_now.to_date.to_s) + expect(active_personal_access_tokens).to match(Date.today.next_month.at_beginning_of_month.to_s) expect(active_personal_access_tokens).to match(PersonalAccessToken.last.token) end end @@ -35,7 +39,7 @@ visit profile_personal_access_tokens_path click_on "Revoke" - inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native.inner_html + inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native['innerHTML'] expect(inactive_personal_access_tokens).to match(personal_access_token.name) expect(inactive_personal_access_tokens).to match(personal_access_token.token) end @@ -44,7 +48,7 @@ personal_access_token = create(:personal_access_token, expires_at: 5.days.ago, user: user) visit profile_personal_access_tokens_path - inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native.inner_html + inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native['innerHTML'] expect(inactive_personal_access_tokens).to match(personal_access_token.name) expect(inactive_personal_access_tokens).to match(personal_access_token.token) end diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb new file mode 100644 index 00000000000000..3e80a48175a7b3 --- /dev/null +++ b/spec/models/personal_access_token_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe PersonalAccessToken, models: true do + describe ".generate" do + it "generates a random token" do + personal_access_token = PersonalAccessToken.generate({}) + expect(personal_access_token.token).to be_present + end + + it "doesn't save the record" do + personal_access_token = PersonalAccessToken.generate({}) + expect(personal_access_token).to_not be_persisted + end + end +end -- GitLab From 2768e99ac386598480a7ac5490deee644125dfa1 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Thu, 28 Apr 2016 17:18:49 +0530 Subject: [PATCH 091/714] Add documentation for personal access tokens. --- doc/api/README.md | 61 ++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/doc/api/README.md b/doc/api/README.md index ff039f1886f161..0e9dc7acfed2d6 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -37,13 +37,11 @@ following locations: ## Authentication -All API requests require authentication. You need to pass a `private_token` -parameter via query string or header. If passed as a header, the header name -must be `PRIVATE-TOKEN` (uppercase and with a dash instead of an underscore). -You can find or reset your private token in your account page (`/profile/account`). +All API requests require authentication via a token. There are three types of tokens +available: private tokens, OAuth 2 tokens, and personal access tokens. -If `private_token` is invalid or omitted, then an error message will be -returned with status code `401`: +If a token is invalid or omitted, an error message will be returned with +status code `401`: ```json { @@ -51,42 +49,56 @@ returned with status code `401`: } ``` -API requests should be prefixed with `api` and the API version. The API version -is defined in [`lib/api.rb`][lib-api-url]. +### Private Tokens -Example of a valid API request: +You need to pass a `private_token` parameter via query string or header. If passed as a +header, the header name must be `PRIVATE-TOKEN` (uppercase and with a dash instead of +an underscore). You can find or reset your private token in your account page +(`/profile/account`). -```shell -GET https://gitlab.example.com/api/v3/projects?private_token=9koXpg98eAheJpvBs5tK -``` +### OAuth 2 Tokens -Example of a valid API request using cURL and authentication via header: +You can use an OAuth 2 token to authenticate with the API by passing it either in the +`access_token` parameter or in the `Authorization` header. + +Example of using the OAuth2 token in the header: ```shell -curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects" +curl -H "Authorization: Bearer OAUTH-TOKEN" https://gitlab.example.com/api/v3/projects ``` -The API uses JSON to serialize data. You don't need to specify `.json` at the -end of an API URL. +Read more about [GitLab as an OAuth2 client](oauth2.md). + +### Personal Access Tokens -## Authentication with OAuth2 token +> **Note:** This feature was [introduced][ce-3749] in GitLab 8.8 -Instead of the `private_token` you can transmit the OAuth2 access token as a -header or as a parameter. +You can create as many personal access tokens as you like from your GitLab +profile (`/profile/personal_access_tokens`); perhaps one for each application +that needs access to the GitLab API. -Example of OAuth2 token as a parameter: +Once you have your token, pass it to the API using either the `personal_access_token` +parameter or the `PERSONAL-ACCESS-TOKEN` header. + +## Basic Usage + +API requests should be prefixed with `api` and the API version. The API version +is defined in [`lib/api.rb`][lib-api-url]. + +Example of a valid API request: ```shell -curl https://gitlab.example.com/api/v3/user?access_token=OAUTH-TOKEN +GET https://gitlab.example.com/api/v3/projects?private_token=9koXpg98eAheJpvBs5tK ``` -Example of OAuth2 token as a header: +Example of a valid API request using cURL and authentication via header: ```shell -curl -H "Authorization: Bearer OAUTH-TOKEN" https://example.com/api/v3/user +curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects" ``` -Read more about [GitLab as an OAuth2 client](oauth2.md). +The API uses JSON to serialize data. You don't need to specify `.json` at the +end of an API URL. ## Status codes @@ -323,3 +335,4 @@ programming languages. Visit the [GitLab website] for a complete list. [GitLab website]: https://about.gitlab.com/applications/#api-clients "Clients using the GitLab API" [lib-api-url]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/api/api.rb +[ce-3749]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3749 -- GitLab From c46f3bcb5184f93f6424efbd4a2117caa6b6193f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 29 Apr 2016 13:11:07 +0200 Subject: [PATCH 092/714] few fixes and new integration spec -WIP --- .../import_export/project_tree_restorer.rb | 1 - lib/gitlab/import_export/repo_restorer.rb | 2 +- .../import_export/import_file_spec.rb | 22 ++++++++++++++++++ .../import_export/test_project_export.tar.gz | Bin 0 -> 353039 bytes 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 spec/features/projects/import_export/import_file_spec.rb create mode 100644 spec/features/projects/import_export/test_project_export.tar.gz diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 7b41ba0685b219..a5dc3a7c9c0fa4 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -66,7 +66,6 @@ def create_sub_relations(relation, tree_hash) end def process_sub_relation(relation_hash, relation_item, sub_relation) - sub_relation_object = nil if relation_hash.is_a?(Array) sub_relation_object = create_relation(sub_relation, relation_hash) else diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index aa90f0536808c2..aae65f6adc8b39 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -14,7 +14,7 @@ def restore FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) - untar_czf(archive: @path, dir: path_to_repo) + untar_zxf(archive: @path, dir: path_to_repo) end private diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb new file mode 100644 index 00000000000000..e40ed9a683ab28 --- /dev/null +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +feature 'project import', feature: true, js: true do + include Select2Helper + + let(:user) { create(:user) } + let!(:namespace) { create(:namespace, name: "asd", owner: user) } + background do + login_as(user) + end + + scenario 'user imports an exported project successfully' do + visit new_project_path + + select2('asd', from: '#project_namespace_id') + fill_in :project_path, with:'test-project-path', visible: true + click_link 'GitLab project' + + expect(page).to have_content('GitLab export file') + expect(URI.parse(current_url).query).to eq('namespace_id=asd&path=test-project-path') + end +end diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bc447b4a62a2094563ca643e680321ba8f99549c GIT binary patch literal 353039 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 z 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%0A=@L=>Cc>0(AY+c{d8 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 Q{r|`Q();c27(6%_0AB{bAOHXW literal 0 HcmV?d00001 -- GitLab From 7ebf22e0024f457238090c3545b8acafae0e1a6f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 29 Apr 2016 15:15:27 +0200 Subject: [PATCH 093/714] more refactoring and fixes - fixing spec as well --- .../import_export/project_tree_restorer.rb | 10 +++--- lib/gitlab/import_export/repo_bundler.rb | 1 + lib/gitlab/import_export/repo_restorer.rb | 5 +-- .../import_export/import_file_spec.rb | 35 +++++++++++++++++-- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index a5dc3a7c9c0fa4..d2834101758db6 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -1,7 +1,6 @@ module Gitlab module ImportExport class ProjectTreeRestorer - attr_reader :project def initialize(path:, user:, project_path:) @path = File.join(path, 'project.json') @@ -16,6 +15,10 @@ def restore create_relations end + def project + @project ||= create_project + end + private def members_map @@ -41,17 +44,12 @@ def default_relation_list Gitlab::ImportExport::ImportExportReader.tree.reject { |model| model.is_a?(Hash) && model[:project_members] } end - def project - @project ||= create_project - end - def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } project = Gitlab::ImportExport::ProjectFactory.create( project_params: project_params, user: @user) project.path = @project_path project.save - project.import_start project end diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index 86c9501b708697..e719ee2e9e3c8c 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -26,6 +26,7 @@ def bundle_to_disk false end + # TODO remove magic keyword and move it to a shared config def project_filename "project.bundle" end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index aae65f6adc8b39..2c67bd5a8456fb 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,9 +3,10 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project: , path:, bundler_file: ) + def initialize(project: , path: ) @project = project - @path = File.join(path, bundler_file) + # TODO remove magic keyword and move it to a shared config + @path = File.join(path, 'project.bundle') end def restore diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index e40ed9a683ab28..32e131d7040a2c 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -3,8 +3,10 @@ feature 'project import', feature: true, js: true do include Select2Helper - let(:user) { create(:user) } + let(:user) { create(:admin) } let!(:namespace) { create(:namespace, name: "asd", owner: user) } + let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') } + background do login_as(user) end @@ -12,11 +14,38 @@ scenario 'user imports an exported project successfully' do visit new_project_path - select2('asd', from: '#project_namespace_id') + select2('2', from: '#project_namespace_id') fill_in :project_path, with:'test-project-path', visible: true click_link 'GitLab project' expect(page).to have_content('GitLab export file') - expect(URI.parse(current_url).query).to eq('namespace_id=asd&path=test-project-path') + expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path') + attach_file('file', file) + + #TODO check timings + + sleep 1 + + click_on 'Continue to the next step' + + sleep 1 + + end + + def drop_in_dropzone(file_path) + # Generate a fake input selector + page.execute_script <<-JS + var fakeFileInput = window.$('').attr( + {id: 'fakeFileInput', type: 'file'} + ).appendTo('body'); + JS + # Attach the file to the fake input selector with Capybara + attach_file("fakeFileInput", file_path) + # Add the file to a fileList array and trigger the fake drop event + page.execute_script <<-JS + var fileList = [$('#fakeFileInput')[0].files[0]]; + var e = jQuery.Event('drop', { dataTransfer : { files : fileList } }); + $('.div-dropzone')[0].dropzone.listeners[0].events.drop(e); + JS end end -- GitLab From 07ab6c2e26a36734ad29ae037810c14d2be7ec8b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 2 May 2016 11:29:21 +0200 Subject: [PATCH 094/714] refactoring and fixing a bunch of stuff --- .../import/gitlab_projects_controller.rb | 8 +-- .../import/gitlab_projects/status.html.haml | 55 ------------------- lib/gitlab/import_export/command_line_util.rb | 2 +- lib/gitlab/import_export/import_service.rb | 3 +- lib/gitlab/import_export/repo_restorer.rb | 2 +- .../import_export/import_file_spec.rb | 5 +- 6 files changed, 7 insertions(+), 68 deletions(-) diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index b141b5f472afd8..f8d4bcff55a529 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -12,13 +12,7 @@ def new end def status - @repos = client.projects - @incompatible_repos = client.incompatible_projects - @already_added_projects = current_user.created_projects.where(import_type: "gitlab_project") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } end def jobs @@ -39,6 +33,8 @@ def create tmp_file: File.expand_path(file.path), namespace_id: namespace_id, project_path: path) + + redirect_to status_import_gitlab_project_path end private diff --git a/app/views/import/gitlab_projects/status.html.haml b/app/views/import/gitlab_projects/status.html.haml index 2b879f0c5954a2..e69de29bb2d1d6 100644 --- a/app/views/import/gitlab_projects/status.html.haml +++ b/app/views/import/gitlab_projects/status.html.haml @@ -1,55 +0,0 @@ -- page_title "Gitlab_project import" -- header_title "Projects", root_path -%h3.page-title - %i.icon-gitlab.icon-gitlab-big - Import Gitlab projects - -%p.light - Select projects you want to import. -%hr -%p - = button_tag class: "btn btn-import btn-success js-import-all" do - Import all projects - = icon("spinner spin", class: "loading-icon") - -.table-responsive - %table.table.import-jobs - %colgroup.import-jobs-from-col - %colgroup.import-jobs-to-col - %colgroup.import-jobs-status-col - %thead - %tr - %th From Gitlab_project.org - %th To GitLab - %th Status - %tbody - - @already_added_projects.each do |project| - %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} - %td - = link_to project.import_source, "https://gitlab_project.org/#{project.import_source}", target: "_blank" - %td - = link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] - %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - done - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - started - - else - = project.human_import_status_name - - - @repos.each do |repo| - %tr{id: "repo_#{repo.id}"} - %td - = link_to repo.full_name, "https://gitlab_project.org/#{repo.full_name}", target: "_blank" - %td.import-target - = repo.full_name - %td.import-actions.job-status - = button_tag class: "btn btn-import js-add-to-import" do - Import - = icon("spinner spin", class: "loading-icon") - -:javascript - new ImporterStatus("#{jobs_import_gitlab_project_path}", "#{import_gitlab_project_path}"); diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 9fc83afc4f7525..5ff72f5ff8d3a1 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -9,7 +9,7 @@ def untar_zxf(archive:, dir:) untar_with_options(archive: archive, dir: dir, options: 'zxf') end - def untar_czf(archive:, dir:) + def untar_xf(archive:, dir:) untar_with_options(archive: archive, dir: dir, options: 'xf') end diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 226499030afb43..227053481cd6aa 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -15,8 +15,7 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, storage_path: storage_path) - restore_project_tree - restore_repo + project_tree.project if [restore_project_tree, restore_repo].all? end private diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 2c67bd5a8456fb..994fc4bea5aae7 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -15,7 +15,7 @@ def restore FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) - untar_zxf(archive: @path, dir: path_to_repo) + untar_xf(archive: @path, dir: path_to_repo) end private diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 32e131d7040a2c..0bc2b85edb1737 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -8,6 +8,8 @@ let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') } background do + export_path = "#{Dir::tmpdir}/import_file_spec" + allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) login_as(user) end @@ -27,9 +29,6 @@ sleep 1 click_on 'Continue to the next step' - - sleep 1 - end def drop_in_dropzone(file_path) -- GitLab From b5f2a7e139f0c1803afb68c26042ce4f8cec9148 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 2 May 2016 11:58:35 +0200 Subject: [PATCH 095/714] fixed integration test --- .../import_export/import_file_spec.rb | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 0bc2b85edb1737..05f6e289841d29 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -6,14 +6,19 @@ let(:user) { create(:admin) } let!(:namespace) { create(:namespace, name: "asd", owner: user) } let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') } - + let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } background do - export_path = "#{Dir::tmpdir}/import_file_spec" allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) login_as(user) end + after(:each) do + FileUtils.rm_rf(export_path, secure: true) + 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') @@ -22,29 +27,13 @@ expect(page).to have_content('GitLab export file') expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path') - attach_file('file', file) - - #TODO check timings - sleep 1 + attach_file('file', file) - click_on 'Continue to the next step' - end + click_on 'Continue to the next step' # import starts - def drop_in_dropzone(file_path) - # Generate a fake input selector - page.execute_script <<-JS - var fakeFileInput = window.$('').attr( - {id: 'fakeFileInput', type: 'file'} - ).appendTo('body'); - JS - # Attach the file to the fake input selector with Capybara - attach_file("fakeFileInput", file_path) - # Add the file to a fileList array and trigger the fake drop event - page.execute_script <<-JS - var fileList = [$('#fakeFileInput')[0].files[0]]; - var e = jQuery.Event('drop', { dataTransfer : { files : fileList } }); - $('.div-dropzone')[0].dropzone.listeners[0].events.drop(e); - JS + expect(Project.last).not_to be_nil + expect(Project.last.issues).not_to be_empty + expect(Project.last.repo_exists?).to be true end end -- GitLab From 5a4f576359a71a57c70544568d9291cba53a2d39 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 2 May 2016 18:22:18 +0200 Subject: [PATCH 096/714] fixing issues with project members mapping. Also added some more JS magic to the import page --- app/views/projects/new.html.haml | 11 +++++++++++ lib/gitlab/import_export/import_export_reader.rb | 4 +++- lib/gitlab/import_export/project_tree_restorer.rb | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index b3d755b3790c77..f9d9216f626c55 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -131,3 +131,14 @@ var _href = $("a.import_gitlab_project").attr("href"); $(".import_gitlab_project").attr("href", _href + '?namespace_id=' + $("#project_namespace_id").val() + '&path=' + $("#project_path").val()); }); + $('.import_gitlab_project').attr('disabled',true) + $('.import_gitlab_project').attr('title', 'Project path required.'); + $('#project_path').keyup(function(){ + if($(this).val().length !=0) { + $('.import_gitlab_project').attr('disabled', false); + $('.import_gitlab_project').attr('title',''); + } else { + $('.import_gitlab_project').attr('disabled',true); + $('.import_gitlab_project').attr('title', 'Project path required.'); + } + }) diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 717d3026f9e668..4e46899ec7e4be 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -57,8 +57,10 @@ def process_current_class(hash, included_classes_hash, value) end def add_new_class(current_key, included_classes_hash, value) + only_except_hash = check_only_and_except(value) + # TODO: refactor this + value = (value.is_a?(Hash) ? value.merge(only_except_hash) : { value => only_except_hash }) if only_except_hash new_hash = { include: value } - new_hash.merge!(check_only_and_except(value)) included_classes_hash[current_key] = new_hash end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index d2834101758db6..0f2e37167794cf 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -49,6 +49,7 @@ def create_project project = Gitlab::ImportExport::ProjectFactory.create( project_params: project_params, user: @user) project.path = @project_path + project.name = @project_path project.save project end -- GitLab From 58b0b1a6615958d2ca7628a06898f81b316e6637 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 11:13:10 +0200 Subject: [PATCH 097/714] picking export stuff from the UI branch --- .../projects/import_export/export_service.rb | 3 ++- lib/gitlab/import_export/command_line_util.rb | 14 ++++++++++++++ lib/gitlab/import_export/import_export_reader.rb | 4 +++- lib/gitlab/import_export/project_tree_saver.rb | 1 + lib/gitlab/import_export/repo_bundler.rb | 1 + lib/gitlab/import_export/saver.rb | 1 + 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index ce13942c5d723f..5d5573cba5c7e0 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -1,8 +1,9 @@ module Projects module ImportExport class ExportService < BaseService + def execute(options = {}) - @shared = Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) + @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) save_project_tree bundle_repo save_all diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 7bf4b476b6c8d6..5ff72f5ff8d3a1 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -5,6 +5,14 @@ def tar_cf(archive:, dir:) tar_with_options(archive: archive, dir: dir, options: 'cf') end + def untar_zxf(archive:, dir:) + untar_with_options(archive: archive, dir: dir, options: 'zxf') + end + + def untar_xf(archive:, dir:) + untar_with_options(archive: archive, dir: dir, options: 'xf') + end + def tar_czf(archive:, dir:) tar_with_options(archive: archive, dir: dir, options: 'czf') end @@ -20,6 +28,12 @@ def tar_with_options(archive:, dir:, options:) _output, status = Gitlab::Popen.popen(cmd) status.zero? end + + def untar_with_options(archive:, dir:, options:) + cmd = %W(tar -#{options} #{archive} -C #{dir}) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end end end end diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 717d3026f9e668..4e46899ec7e4be 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -57,8 +57,10 @@ def process_current_class(hash, included_classes_hash, value) end def add_new_class(current_key, included_classes_hash, value) + only_except_hash = check_only_and_except(value) + # TODO: refactor this + value = (value.is_a?(Hash) ? value.merge(only_except_hash) : { value => only_except_hash }) if only_except_hash new_hash = { include: value } - new_hash.merge!(check_only_and_except(value)) included_classes_hash[current_key] = new_hash end diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index f6fab0fe22d7cf..394411a56c2301 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -24,6 +24,7 @@ def save_to_disk false end + # TODO remove magic keyword and move it to a shared config def project_filename "project.json" end diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index 86c9501b708697..e719ee2e9e3c8c 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -26,6 +26,7 @@ def bundle_to_disk false end + # TODO remove magic keyword and move it to a shared config def project_filename "project.bundle" end diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index f87e0fdc7ea20a..634e58e6039935 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -14,6 +14,7 @@ def initialize(storage_path:) def save if compress_and_save remove_storage_path + Rails.logger.info("Saved project export #{archive_file}") archive_file else false -- GitLab From 9d306eb132bf153a0c93dd870d3a098028f12384 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 12:41:23 +0200 Subject: [PATCH 098/714] picking stuff from ui related to import --- app/models/project.rb | 10 ++++++++ app/workers/project_impor_worker.rb | 25 +++++++++++++++++++ lib/gitlab/import_export/import_service.rb | 25 +++++++++++-------- lib/gitlab/import_export/importer.rb | 3 ++- .../import_export/project_tree_restorer.rb | 15 +++++------ lib/gitlab/import_export/repo_restorer.rb | 9 ++++--- 6 files changed, 65 insertions(+), 22 deletions(-) create mode 100644 app/workers/project_impor_worker.rb diff --git a/app/models/project.rb b/app/models/project.rb index af62e8ecd90cb5..3e782be637e94a 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -359,6 +359,16 @@ def trending(since = 1.month.ago) def visible_to_user(user) where(id: user.authorized_projects.select(:id).reorder(nil)) end + + def create_from_import_job(current_user_id:, tmp_file:, namespace_id:, project_path:) + job_id = ProjectImportWorker.perform_async(current_user_id, tmp_file, namespace_id, project_path) + + if job_id + Rails.logger.info "Import job started for export #{tmp_file} with job ID #{job_id}" + else + Rails.logger.error "Import job failed to start for #{tmp_file}" + end + end end def team diff --git a/app/workers/project_impor_worker.rb b/app/workers/project_impor_worker.rb new file mode 100644 index 00000000000000..0ef353fa441144 --- /dev/null +++ b/app/workers/project_impor_worker.rb @@ -0,0 +1,25 @@ +class ProjectImportWorker + include Sidekiq::Worker + include Gitlab::ShellAdapter + + sidekiq_options queue: :gitlab_shell, retry: false + + def perform(current_user_id, tmp_file, namespace_id, path) + current_user = User.find(current_user_id) + + project = Gitlab::ImportExport::ImportService.execute(archive_file: tmp_file, + owner: current_user, + namespace_id: namespace_id, + project_path: path) + + # TODO: Move this to import service + # if result[:status] == :error + # project.update(import_error: result[:message]) + # project.import_fail + # return + # end + + project.repository.after_import + project.import_finish + end +end \ No newline at end of file diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 978a581f57add6..227053481cd6aa 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -3,18 +3,19 @@ module ImportExport class ImportService def self.execute(*args) - new(args).execute + new(*args).execute end - def initialize(options = {}) - @archive_file = options[:archive_file] - @current_user = options[:owner] + def initialize(archive_file:, owner:, namespace_id:, project_path:) + @archive_file = archive_file + @current_user = owner + @namespace_path = Namespace.find(namespace_id).path + @project_path = project_path end def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, storage_path: storage_path) - restore_project_tree - restore_repo(project_tree.project) + project_tree.project if [restore_project_tree, restore_repo].all? end private @@ -24,15 +25,19 @@ def restore_project_tree end def project_tree - @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user) + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user, project_path: @project_path) end - def restore_repo(project) - Gitlab::ImportExport::RepoRestorer.new(path: storage_path, project: project).restore + def restore_repo + Gitlab::ImportExport::RepoRestorer.new(path: storage_path, project: project_tree.project).restore end def storage_path - @storage_path ||= Gitlab::ImportExport.export_path(relative_path: project.path_with_namespace) + @storage_path ||= Gitlab::ImportExport.export_path(relative_path: path_with_namespace) + end + + def path_with_namespace + File.join(@namespace_path, @project_path) end end end diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 9f399845437169..8f838287f97696 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -13,13 +13,14 @@ def initialize(archive_file: , storage_path:) end def import + FileUtils.mkdir_p(@storage_path) decompress_archive end private def decompress_archive - untar_czf(archive: @archive_file, dir: @storage_path) + untar_zxf(archive: @archive_file, dir: @storage_path) end end end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 4e0f555afe93fc..0f2e37167794cf 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -1,11 +1,11 @@ module Gitlab module ImportExport class ProjectTreeRestorer - attr_reader :project - def initialize(path:, user:) + def initialize(path:, user:, project_path:) @path = File.join(path, 'project.json') @user = user + @project_path = project_path end def restore @@ -15,6 +15,10 @@ def restore create_relations end + def project + @project ||= create_project + end + private def members_map @@ -40,14 +44,12 @@ def default_relation_list Gitlab::ImportExport::ImportExportReader.tree.reject { |model| model.is_a?(Hash) && model[:project_members] } end - def project - @project ||= create_project - end - def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } project = Gitlab::ImportExport::ProjectFactory.create( project_params: project_params, user: @user) + project.path = @project_path + project.name = @project_path project.save project end @@ -63,7 +65,6 @@ def create_sub_relations(relation, tree_hash) end def process_sub_relation(relation_hash, relation_item, sub_relation) - sub_relation_object = nil if relation_hash.is_a?(Array) sub_relation_object = create_relation(sub_relation, relation_hash) else diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 47be303e22ae83..315ad88ee0c5f1 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,18 +3,19 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project: , path:, bundler_file: ) + def initialize(project: , path: ) @project = project - @path = File.join(path, bundler_file) + # TODO remove magic keyword and move it to a shared config + @path = File.join(path, 'project.bundle') end def restore return false unless File.exists?(@path) - # Move repos dir to 'repositories.old' dir + # Move repos dir to 'repositories.old' dir FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) - untar_cf(archive: @path, dir: path_to_repo) + untar_xf(archive: @path, dir: path_to_repo) end private -- GitLab From 6139e1433c7f1925a7fc599106656990410a4184 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 12:46:00 +0200 Subject: [PATCH 099/714] fixing some rubucop warnings --- app/controllers/import/gitlab_project_controller.rb | 3 +-- .../{project_impor_worker.rb => project_import_worker.rb} | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) rename app/workers/{project_impor_worker.rb => project_import_worker.rb} (99%) diff --git a/app/controllers/import/gitlab_project_controller.rb b/app/controllers/import/gitlab_project_controller.rb index fa3e0c7876d2a5..ab0da196ac12ab 100644 --- a/app/controllers/import/gitlab_project_controller.rb +++ b/app/controllers/import/gitlab_project_controller.rb @@ -28,12 +28,11 @@ def jobs def create @file = params[:file] - # @project_name = repo_owner = current_user.username @target_namespace = params[:new_namespace].presence || repo_owner - namespace = get_or_create_namespace || (render and return) + # namespace = get_or_create_namespace || (render and return) @project = Gitlab::ImportExport::ImportService.execute(archive_file: file, owner: repo_owner) end diff --git a/app/workers/project_impor_worker.rb b/app/workers/project_import_worker.rb similarity index 99% rename from app/workers/project_impor_worker.rb rename to app/workers/project_import_worker.rb index 0ef353fa441144..0e8b9552442c30 100644 --- a/app/workers/project_impor_worker.rb +++ b/app/workers/project_import_worker.rb @@ -22,4 +22,4 @@ def perform(current_user_id, tmp_file, namespace_id, path) project.repository.after_import project.import_finish end -end \ No newline at end of file +end -- GitLab From 1990616a21a38e8d0496c066e753282d9a061162 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 13:06:00 +0200 Subject: [PATCH 100/714] fixed warning --- spec/lib/gitlab/import_export/project_tree_saver_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8a923dde46792d..5c1b9af2c13e98 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -21,7 +21,7 @@ labels: [label], snippets: [snippet], releases: [release] - ) + ) end let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) } let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } -- GitLab From 14964308dc4ca0d62dd12231529abbcfe940f603 Mon Sep 17 00:00:00 2001 From: Arinde Eniola Date: Tue, 3 May 2016 12:07:06 +0100 Subject: [PATCH 101/714] add gfm autocomplete for labels --- .../javascripts/gfm_auto_complete.js.coffee | 25 +++++++++++++++++++ app/controllers/projects_controller.rb | 1 + app/services/projects/autocomplete_service.rb | 4 +++ 3 files changed, 30 insertions(+) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 61e3f811e73039..6d3f4ec9753a4d 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -14,6 +14,10 @@ GitLab.GfmAutoComplete = Members: template: '

  • ${username} ${title}
  • ' + Labels: + template: '
  • ${title}
    +
  • ' + # Issues and MergeRequests Issues: template: '
  • ${id} ${title}
  • ' @@ -94,6 +98,25 @@ GitLab.GfmAutoComplete = title: sanitize(m.title) search: "#{m.iid} #{m.title}" + @input.atwho + at: '~' + alias: 'labels' + searchKey: 'search' + displayTpl: @Labels.template + insertTpl: '${atwho-at}${title}' + callbacks: + beforeSave: (merges) -> + sanitizeLabelTitle = (title)-> + if /\w+\s+\w+/g.test(title) + "\"#{sanitize(title)}\"" + else + sanitize(title) + + $.map merges, (m) -> + title: sanitizeLabelTitle(m.title) + color: m.color + search: "#{m.title}" + destroyAtWho: -> @input.atwho('destroy') @@ -109,3 +132,5 @@ GitLab.GfmAutoComplete = @input.atwho 'load', 'mergerequests', data.mergerequests # load emojis @input.atwho 'load', ':', data.emojis + # load labels + @input.atwho 'load', '~', data.labels diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3768efe142aa2a..4d7a3bfe642251 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -148,6 +148,7 @@ def autocomplete_sources emojis: AwardEmoji.urls, issues: autocomplete.issues, mergerequests: autocomplete.merge_requests, + labels: autocomplete.labels, members: participants } diff --git a/app/services/projects/autocomplete_service.rb b/app/services/projects/autocomplete_service.rb index ba50305dbd5fca..826b10899d07c0 100644 --- a/app/services/projects/autocomplete_service.rb +++ b/app/services/projects/autocomplete_service.rb @@ -7,5 +7,9 @@ def issues def merge_requests @project.merge_requests.opened.select([:iid, :title]) end + + def labels + @project.labels.select([:title, :color]) + end end end -- GitLab From 68da2ac9a0fa6f33b46f0bfbc849043605c2d878 Mon Sep 17 00:00:00 2001 From: Arinde Eniola Date: Tue, 3 May 2016 12:09:13 +0100 Subject: [PATCH 102/714] add entry to CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index b6527780bbf488..670f7fa3abdfa6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ v 8.8.0 (unreleased) - Display informative message when new milestone is created - Replace Devise Async with Devise ActiveJob integration. !3902 (Connor Shea) - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea) + - Added Gfm autocomplete for labels - Added button to toggle whitespaces changes on diff view - Backport GitLab Enterprise support from EE - Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718 -- GitLab From 315195fe56743db7f0546d3705b4c82fb3462d63 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 13:18:39 +0200 Subject: [PATCH 103/714] fix schema file --- db/schema.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 40a295ca6357dd..04aee737e4ccac 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -78,8 +78,8 @@ t.boolean "email_author_in_body", default: false t.integer "default_group_visibility" t.boolean "repository_checks_enabled", default: false - t.text "shared_runners_text" t.integer "metrics_packet_size", default: 1 + t.text "shared_runners_text" end create_table "audit_events", force: :cascade do |t| @@ -426,9 +426,9 @@ t.string "state" t.integer "iid" t.integer "updated_by_id" + t.integer "moved_to_id" t.boolean "confidential", default: false t.datetime "deleted_at" - t.integer "moved_to_id" t.date "due_date" end -- GitLab From fc329696e269044a9b366dbd5135aedca93bccd4 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 13:40:49 +0200 Subject: [PATCH 104/714] typo --- app/views/import/gitlab_projects/new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index 1158a04ea46793..d01f0190f3ff35 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -2,7 +2,7 @@ - header_title "Projects", root_path %h3.page-title %i.fa.fa-bug - Import projects from FogBugz + Import projects from Gitlab %hr = form_tag import_gitlab_project_path, class: 'form-horizontal', multipart: true do -- GitLab From b69c8c280c029781e87834610a89704210f1a5c4 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 15:07:05 +0200 Subject: [PATCH 105/714] fixing some export issues in spec --- .../import_export/test_project_export.tar.gz | Bin 353039 -> 352529 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index bc447b4a62a2094563ca643e680321ba8f99549c..0c20898086d8766d77ac9ce2216d194532abd72c 100644 GIT binary patch delta 90020 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 Bzia>i delta 90510 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μ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 D7?!-C -- GitLab From 17cfce7adcee712f7e06d8ef0badf926f8eac105 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 3 May 2016 15:09:28 +0200 Subject: [PATCH 106/714] typo --- app/views/import/gitlab_projects/new.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index d01f0190f3ff35..e8e1c02d4418d4 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -1,8 +1,8 @@ -- page_title "FogBugz Import" +- page_title "GitLab Import" - header_title "Projects", root_path %h3.page-title %i.fa.fa-bug - Import projects from Gitlab + Import projects from GitLab %hr = form_tag import_gitlab_project_path, class: 'form-horizontal', multipart: true do -- GitLab From bd2ebf37e6c5aa07f8d29f4ac8c88fc8333a2297 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 10:57:09 +0200 Subject: [PATCH 107/714] use worker in controller --- app/controllers/projects_controller.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 62f8b376c18bd2..f15f20dcf52637 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -191,8 +191,7 @@ def housekeeping end def export - #TODO: Move to worker - ::Projects::ImportExport::ExportService.new(@project, current_user).execute + @project.add_export_job(current_user_id: current_user.id) redirect_to( edit_project_path(@project), @@ -201,7 +200,11 @@ def export end def download_export - send_file export_project_path, disposition: 'attachment' + if export_project_path + send_file export_project_path, disposition: 'attachment' + else + render_404 + end end def toggle_star -- GitLab From bc8eebf04a32d893d5b536deb2e7ffc205d9fcda Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 10:59:33 +0200 Subject: [PATCH 108/714] add export worker to process project export async --- app/models/project.rb | 10 ++++++++++ app/workers/project_export_worker.rb | 13 +++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 app/workers/project_export_worker.rb diff --git a/app/models/project.rb b/app/models/project.rb index af62e8ecd90cb5..8781a3cf7a40d0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1034,4 +1034,14 @@ def runners_token def wiki @wiki ||= ProjectWiki.new(self, self.owner) end + + def add_export_job(current_user_id:) + job_id = ProjectExportWorker.perform_async(current_user_id, self.id) + + if job_id + Rails.logger.info "Export job started for project ID #{self.id} with job ID #{job_id}" + else + Rails.logger.error "Export job failed to start for project ID #{self.id}" + end + end end diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb new file mode 100644 index 00000000000000..a1add5395b7ab0 --- /dev/null +++ b/app/workers/project_export_worker.rb @@ -0,0 +1,13 @@ +class ProjectExportWorker + include Sidekiq::Worker + + # TODO: enabled retry - disabled for QA purposes + sidekiq_options queue: :gitlab_shell, retry: false + + def perform(current_user_id, project_id) + current_user = User.find(current_user_id) + project = Project.find(project_id) + ::Projects::ImportExport::ExportService.new(project, current_user).execute + # TODO : Handle errors + end +end -- GitLab From 9b21207305f7516b132211b5ead584beb37b8948 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 11:01:55 +0200 Subject: [PATCH 109/714] updated import worker --- app/workers/project_import_worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/project_import_worker.rb b/app/workers/project_import_worker.rb index 0e8b9552442c30..aaa59f79d7f901 100644 --- a/app/workers/project_import_worker.rb +++ b/app/workers/project_import_worker.rb @@ -1,7 +1,7 @@ class ProjectImportWorker include Sidekiq::Worker - include Gitlab::ShellAdapter + # TODO: enabled retry - disabled for QA purposes sidekiq_options queue: :gitlab_shell, retry: false def perform(current_user_id, tmp_file, namespace_id, path) -- GitLab From e5ee7e8692b8c9530cef61f3b4ce14f8bf278452 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 11:10:25 +0200 Subject: [PATCH 110/714] typos in export page --- app/views/import/gitlab_projects/new.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/import/gitlab_projects/new.html.haml b/app/views/import/gitlab_projects/new.html.haml index e8e1c02d4418d4..d93ae42c1bf699 100644 --- a/app/views/import/gitlab_projects/new.html.haml +++ b/app/views/import/gitlab_projects/new.html.haml @@ -1,18 +1,18 @@ - page_title "GitLab Import" - header_title "Projects", root_path %h3.page-title - %i.fa.fa-bug + %i.fa.fa-gitlab Import projects from GitLab %hr = form_tag import_gitlab_project_path, class: 'form-horizontal', multipart: true do %p - To get started you add your project export file below. + To get started add your exported project file below: .form-group = hidden_field_tag :namespace_id, @namespace_id = hidden_field_tag :path, @path = label_tag :file, class: 'control-label' do - %span GitLab export file + %span GitLab project export .col-sm-10 = file_field_tag :file, class: '' -- GitLab From 14dd2d4ad0be905385ec524a3022b9b81cb4671b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 15:05:28 +0200 Subject: [PATCH 111/714] fixed import file spec --- spec/features/projects/import_export/import_file_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 05f6e289841d29..b9173e44554518 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -25,7 +25,7 @@ fill_in :project_path, with:'test-project-path', visible: true click_link 'GitLab project' - expect(page).to have_content('GitLab export file') + expect(page).to have_content('GitLab project export') expect(URI.parse(current_url).query).to eq('namespace_id=2&path=test-project-path') attach_file('file', file) -- GitLab From 773c39cca3cc6c4f9edd9387e99d3a85924ac5af Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 15:13:44 +0200 Subject: [PATCH 112/714] fixed import export reader spec --- .../import_export/import_export_reader.rb | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 4e46899ec7e4be..14049cb1bd2fb7 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -41,7 +41,7 @@ def process_include(hash, included_classes_hash = {}) current_key = hash.keys.first value = process_current_class(hash, included_classes_hash, value) if included_classes_hash[current_key] - add_class(current_key, included_classes_hash, value) + add_to_class(current_key, included_classes_hash, value) else add_new_class(current_key, included_classes_hash, value) end @@ -58,13 +58,18 @@ def process_current_class(hash, included_classes_hash, value) def add_new_class(current_key, included_classes_hash, value) only_except_hash = check_only_and_except(value) - # TODO: refactor this - value = (value.is_a?(Hash) ? value.merge(only_except_hash) : { value => only_except_hash }) if only_except_hash - new_hash = { include: value } - included_classes_hash[current_key] = new_hash + parsed_hash = { include: value } + unless only_except_hash.empty? + if value.is_a?(Hash) + parsed_hash = { include: value.merge(only_except_hash) } + else + parsed_hash = { include: { value => only_except_hash } } + end + end + included_classes_hash[current_key] = parsed_hash end - def add_class(current_key, included_classes_hash, value) + def add_to_class(current_key, included_classes_hash, value) only_except_hash = check_only_and_except(value) value = { value => only_except_hash } unless only_except_hash.empty? old_values = included_classes_hash[current_key][:include] -- GitLab From a4d242b887f214493e73e2d44110974a417f3418 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 17:42:02 +0200 Subject: [PATCH 113/714] refactored some namespace stuff and fixed project tree restorer spec. also removing controller so that it belongs to the UI MR --- .../import/gitlab_project_controller.rb | 45 ------------------- lib/gitlab/import_export/import_service.rb | 6 +-- .../gitlab}/import_export/project.json | 0 lib/gitlab/import_export/project_factory.rb | 9 ++-- .../import_export/project_tree_restorer.rb | 10 ++--- lib/gitlab/import_export/repo_restorer.rb | 2 +- .../project_tree_restorer_spec.rb | 3 +- spec/spec_helper.rb | 4 ++ 8 files changed, 20 insertions(+), 59 deletions(-) delete mode 100644 app/controllers/import/gitlab_project_controller.rb rename {fixtures => lib/gitlab}/import_export/project.json (100%) diff --git a/app/controllers/import/gitlab_project_controller.rb b/app/controllers/import/gitlab_project_controller.rb deleted file mode 100644 index ab0da196ac12ab..00000000000000 --- a/app/controllers/import/gitlab_project_controller.rb +++ /dev/null @@ -1,45 +0,0 @@ -class Import::GitlabProjectController < Import::BaseController - before_action :verify_gitlab_project_import_enabled - before_action :gitlab_project_auth, except: :callback - - rescue_from OAuth::Error, with: :gitlab_project_unauthorized - - #TODO permissions stuff - - def callback - - redirect_to status_import_gitlab_project_url - end - - def status - @repos = client.projects - @incompatible_repos = client.incompatible_projects - - @already_added_projects = current_user.created_projects.where(import_type: "gitlab_project") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } - end - - def jobs - jobs = current_user.created_projects.where(import_type: "gitlab_project").to_json(only: [:id, :import_status]) - render json: jobs - end - - def create - @file = params[:file] - - repo_owner = current_user.username - @target_namespace = params[:new_namespace].presence || repo_owner - - # namespace = get_or_create_namespace || (render and return) - - @project = Gitlab::ImportExport::ImportService.execute(archive_file: file, owner: repo_owner) - end - - private - - def verify_gitlab_project_import_enabled - render_404 unless gitlab_project_import_enabled? - end -end diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 227053481cd6aa..97ee8a7fc90fa7 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -9,7 +9,7 @@ def self.execute(*args) def initialize(archive_file:, owner:, namespace_id:, project_path:) @archive_file = archive_file @current_user = owner - @namespace_path = Namespace.find(namespace_id).path + @namespace = Namespace.find(namespace_id) @project_path = project_path end @@ -25,7 +25,7 @@ def restore_project_tree end def project_tree - @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user, project_path: @project_path) + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user, project_path: @project_path, namespace_id: @namespace.id) end def restore_repo @@ -37,7 +37,7 @@ def storage_path end def path_with_namespace - File.join(@namespace_path, @project_path) + File.join(@namespace.path, @project_path) end end end diff --git a/fixtures/import_export/project.json b/lib/gitlab/import_export/project.json similarity index 100% rename from fixtures/import_export/project.json rename to lib/gitlab/import_export/project.json diff --git a/lib/gitlab/import_export/project_factory.rb b/lib/gitlab/import_export/project_factory.rb index c7137844a0a286..6cd4736649b6f9 100644 --- a/lib/gitlab/import_export/project_factory.rb +++ b/lib/gitlab/import_export/project_factory.rb @@ -3,17 +3,19 @@ module ImportExport module ProjectFactory extend self - def create(project_params:, user:) + def create(project_params:, user:, namespace_id:) project = Project.new(project_params.except('id')) project.creator = user - check_namespace(project_params['namespace_id'], project, user) + check_namespace(namespace_id, project, user) end def check_namespace(namespace_id, project, user) if namespace_id # Find matching namespace and check if it allowed # for current user if namespace_id passed. - unless allowed_namespace?(user, namespace_id) + if allowed_namespace?(user, namespace_id) + project.namespace_id = namespace_id + else project.namespace_id = nil deny_namespace(project) end @@ -34,7 +36,6 @@ def allowed_namespace?(user, namespace_id) def deny_namespace(project) project.errors.add(:namespace, "is not valid") end - end end end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 0f2e37167794cf..0bc23dfaa24501 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -2,10 +2,11 @@ module Gitlab module ImportExport class ProjectTreeRestorer - def initialize(path:, user:, project_path:) + def initialize(path:, user:, project_path:, namespace_id:) @path = File.join(path, 'project.json') @user = user @project_path = project_path + @namespace_id = namespace_id end def restore @@ -30,9 +31,8 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha saved = [] relation_list.each do |relation| next if !relation.is_a?(Hash) && tree_hash[relation.to_s].blank? - if relation.is_a?(Hash) - create_sub_relations(relation, tree_hash) - end + create_sub_relations(relation, tree_hash) if relation.is_a?(Hash) + relation_key = relation.is_a?(Hash) ? relation.keys.first : relation relation_hash = create_relation(relation_key, tree_hash[relation_key.to_s]) saved << project.update_attribute(relation_key, relation_hash) @@ -47,7 +47,7 @@ def default_relation_list def create_project project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) } project = Gitlab::ImportExport::ProjectFactory.create( - project_params: project_params, user: @user) + project_params: project_params, user: @user, namespace_id: @namespace_id) project.path = @project_path project.name = @project_path project.save diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 315ad88ee0c5f1..b34581deeb5e0b 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,7 +3,7 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project: , path: ) + def initialize(project:, path:) @project = project # TODO remove magic keyword and move it to a shared config @path = File.join(path, 'project.bundle') diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index f3d3a57ddd7b7e..aa8a12c4caaf31 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -4,7 +4,8 @@ describe :restore do let(:user) { create(:user) } - let(:project_tree_restorer) { Gitlab::ImportExport::ProjectTreeRestorer.new(path: "fixtures/import_export/project.json", user: user) } + let(:namespace) { create(:namespace, owner: user) } + let(:project_tree_restorer) { Gitlab::ImportExport::ProjectTreeRestorer.new(path: "lib/gitlab/import_export/", user: user, project_path: 'project', namespace_id: namespace.id) } context 'JSON' do let(:restored_project_json) do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 596d607f2a169e..b48e54b78fb0eb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -58,3 +58,7 @@ end ActiveRecord::Migration.maintain_test_schema! + +Capybara.register_driver :poltergeist do |app| + Capybara::Poltergeist::Driver.new(app, timeout: 1.minute) +end \ No newline at end of file -- GitLab From 48fcf54040bf049d7f7d959b1033ad28b3966770 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 4 May 2016 18:01:41 +0200 Subject: [PATCH 114/714] add gitlab project controller - still WIP --- .../import/gitlab_project_controller.rb | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 app/controllers/import/gitlab_project_controller.rb diff --git a/app/controllers/import/gitlab_project_controller.rb b/app/controllers/import/gitlab_project_controller.rb new file mode 100644 index 00000000000000..ab0da196ac12ab --- /dev/null +++ b/app/controllers/import/gitlab_project_controller.rb @@ -0,0 +1,45 @@ +class Import::GitlabProjectController < Import::BaseController + before_action :verify_gitlab_project_import_enabled + before_action :gitlab_project_auth, except: :callback + + rescue_from OAuth::Error, with: :gitlab_project_unauthorized + + #TODO permissions stuff + + def callback + + redirect_to status_import_gitlab_project_url + end + + def status + @repos = client.projects + @incompatible_repos = client.incompatible_projects + + @already_added_projects = current_user.created_projects.where(import_type: "gitlab_project") + already_added_projects_names = @already_added_projects.pluck(:import_source) + + @repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } + end + + def jobs + jobs = current_user.created_projects.where(import_type: "gitlab_project").to_json(only: [:id, :import_status]) + render json: jobs + end + + def create + @file = params[:file] + + repo_owner = current_user.username + @target_namespace = params[:new_namespace].presence || repo_owner + + # namespace = get_or_create_namespace || (render and return) + + @project = Gitlab::ImportExport::ImportService.execute(archive_file: file, owner: repo_owner) + end + + private + + def verify_gitlab_project_import_enabled + render_404 unless gitlab_project_import_enabled? + end +end -- GitLab From c1858da9e154d4ac0b18dc93ec13464700c1f11b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 09:35:27 +0200 Subject: [PATCH 115/714] remove spec helper conf --- spec/spec_helper.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b48e54b78fb0eb..596d607f2a169e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -58,7 +58,3 @@ end ActiveRecord::Migration.maintain_test_schema! - -Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app, timeout: 1.minute) -end \ No newline at end of file -- GitLab From a9ac9ed105a710194099a4e07a2e87712d59a59a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 10:05:42 +0200 Subject: [PATCH 116/714] fix import feature --- features/steps/dashboard/new_project.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb index a0aad66184d190..ad20201c2c59a4 100644 --- a/features/steps/dashboard/new_project.rb +++ b/features/steps/dashboard/new_project.rb @@ -19,7 +19,8 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps expect(page).to have_link('GitLab.com') expect(page).to have_link('Gitorious.org') expect(page).to have_link('Google Code') - expect(page).to have_link('Any repo by URL') + expect(page).to have_link('Repo by URL') + expect(page).to have_link('GitLab project') end step 'I click on "Import project from GitHub"' do @@ -36,7 +37,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps end end - step 'I click on "Any repo by URL"' do + step 'I click on "Repo by URL"' do first('.import_git').click end -- GitLab From e14d1051d2c04bad514d840e1eff35ce24b05922 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 11:02:22 +0200 Subject: [PATCH 117/714] fix import feature v2 --- features/dashboard/new_project.feature | 2 +- lib/gitlab/import_sources.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature index 763920683570d3..56b4a639c015f9 100644 --- a/features/dashboard/new_project.feature +++ b/features/dashboard/new_project.feature @@ -14,7 +14,7 @@ Background: @javascript Scenario: I should see instructions on how to import from Git URL Given I see "New Project" page - When I click on "Any repo by URL" + When I click on "Repo by URL" Then I see instructions on how to import from Git URL @javascript diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index 2b5658a8b64fdc..4cae819d356dcd 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -20,7 +20,7 @@ def options 'Gitorious.org' => 'gitorious', 'Google Code' => 'google_code', 'FogBugz' => 'fogbugz', - 'Any repo by URL' => 'git', + 'Repo by URL' => 'git', 'GitLab project' => 'gitlab_project' } end -- GitLab From 6612ca096a496caaa0d30724190964df8aac2f46 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 12:01:18 +0200 Subject: [PATCH 118/714] update repo and wiki repo bundler to use git bundle instead of compressing via tar --- app/services/projects/import_export/export_service.rb | 6 ++++++ lib/gitlab/import_export/repo_bundler.rb | 3 +-- lib/gitlab/import_export/wiki_repo_bundler.rb | 3 +-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 5d5573cba5c7e0..47ceff18af6248 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -4,8 +4,10 @@ class ExportService < BaseService def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) + # TODO handle errors save_project_tree bundle_repo + bundle_wiki_repo save_all end @@ -19,6 +21,10 @@ def bundle_repo Gitlab::ImportExport::RepoBundler.new(project: project, shared: @shared).bundle end + def bundle_wiki_repo + Gitlab::ImportExport::WikiRepoBundler.new(project: project, shared: @shared).bundle + end + def save_all Gitlab::ImportExport::Saver.save(storage_path: @shared.export_path) end diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index e719ee2e9e3c8c..cd871687d76381 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -20,9 +20,8 @@ def bundle def bundle_to_disk FileUtils.mkdir_p(@export_path) - tar_cf(archive: full_path, dir: path_to_repo) + git_bundle(repo_path: path_to_repo, bundle_path: @full_path) rescue - #TODO: handle error false end diff --git a/lib/gitlab/import_export/wiki_repo_bundler.rb b/lib/gitlab/import_export/wiki_repo_bundler.rb index 7821c671628094..17f1530d5a08a7 100644 --- a/lib/gitlab/import_export/wiki_repo_bundler.rb +++ b/lib/gitlab/import_export/wiki_repo_bundler.rb @@ -3,7 +3,7 @@ module ImportExport class WikiRepoBundler < RepoBundler def bundle @wiki = ProjectWiki.new(@project) - return false if !wiki? + return true if !wiki? # it's okay to have no Wiki @full_path = File.join(@export_path, project_filename) bundle_to_disk end @@ -12,7 +12,6 @@ def bundle_to_disk FileUtils.mkdir_p(@export_path) git_bundle(repo_path: path_to_repo, bundle_path: @full_path) rescue - #TODO: handle error false end -- GitLab From 92f4bde427652a33ccb42e93de1cc781289a6c8a Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 12:39:18 +0200 Subject: [PATCH 119/714] use git bundle in import and add wiki repo to import --- lib/gitlab/import_export/command_line_util.rb | 6 ++++++ lib/gitlab/import_export/import_service.rb | 16 ++++++++++++++-- lib/gitlab/import_export/repo_restorer.rb | 11 +++++------ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 5ff72f5ff8d3a1..f32e2715997965 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -23,6 +23,12 @@ def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path status.zero? end + def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) + cmd = %W(#{git_bin_path} clone --bare #{bundle_path} #{repo_path}) + _output, status = Gitlab::Popen.popen(cmd) + status.zero? + end + def tar_with_options(archive:, dir:, options:) cmd = %W(tar -#{options} #{archive} -C #{dir} .) _output, status = Gitlab::Popen.popen(cmd) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 97ee8a7fc90fa7..6878f4bbc8c66b 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -15,7 +15,7 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, storage_path: storage_path) - project_tree.project if [restore_project_tree, restore_repo].all? + project_tree.project if [restore_project_tree, restore_repo, restore_wiki_repo].all? end private @@ -29,7 +29,11 @@ def project_tree end def restore_repo - Gitlab::ImportExport::RepoRestorer.new(path: storage_path, project: project_tree.project).restore + Gitlab::ImportExport::RepoRestorer.new(path: repo_path, project: project_tree.project).restore + end + + def restore_wiki_repo + Gitlab::ImportExport::RepoRestorer.new(path: wiki_repo_path, project: project_tree.project).restore end def storage_path @@ -39,6 +43,14 @@ def storage_path def path_with_namespace File.join(@namespace.path, @project_path) end + + def repo_path + File.join('storage_path', 'project.bundle') + end + + def wiki_repo_path + File.join('storage_path', 'project.wiki.bundle') + end end end end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index b34581deeb5e0b..dc45238bf2a6ae 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,19 +3,18 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project:, path:) + def initialize(project:, path_to_bundle: ) @project = project - # TODO remove magic keyword and move it to a shared config - @path = File.join(path, 'project.bundle') + @path_to_bundle = path_to_bundle end def restore - return false unless File.exists?(@path) - # Move repos dir to 'repositories.old' dir + return true unless File.exists?(@path) FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) - untar_xf(archive: @path, dir: path_to_repo) + + git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path: path_to_repo, bundle_path: @path_to_bundle) end private -- GitLab From 7204018a36e79a4b26b954965387495f50115541 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 12:54:12 +0200 Subject: [PATCH 120/714] fix path to bundle --- lib/gitlab/import_export/import_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 6878f4bbc8c66b..a4555699ff2bf6 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -29,11 +29,11 @@ def project_tree end def restore_repo - Gitlab::ImportExport::RepoRestorer.new(path: repo_path, project: project_tree.project).restore + Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path, project: project_tree.project).restore end def restore_wiki_repo - Gitlab::ImportExport::RepoRestorer.new(path: wiki_repo_path, project: project_tree.project).restore + Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, project: project_tree.project).restore end def storage_path -- GitLab From 4b1fdfd6eb013f3549dc9198ffab46f7ef0de87c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 13:14:43 +0200 Subject: [PATCH 121/714] updated export file for testing --- .../import_export/test_project_export.tar.gz | Bin 352529 -> 338759 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 0c20898086d8766d77ac9ce2216d194532abd72c..87f118b6e230a19317e7070bf04c7ad072f0eb9c 100644 GIT binary patch delta 109939 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 delta 123803 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%0AFUT}h`Ri41z=dty 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%0Dre>xP(T9ogJJNyAk6$|+e< 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
    -F>R49+VXOtq=$&yp9zc^{bAe;2@{Ts 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 -- GitLab From 1eb802cde331fa8b3e18b45d0d3f81061661a22f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 16:25:27 +0200 Subject: [PATCH 158/714] fixed leaving comments on notes about missing authors --- lib/gitlab/import_export/import_service.rb | 7 ++++++- lib/gitlab/import_export/members_mapper.rb | 13 +++++++------ lib/gitlab/import_export/project_tree_restorer.rb | 2 +- lib/gitlab/import_export/relation_factory.rb | 9 +++++---- .../lib/gitlab/import_export/members_mapper_spec.rb | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 670f1ebece8100..0c483884fe97f0 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -16,7 +16,12 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, shared: @shared) - project_tree.project if [restore_project_tree, restore_repo, restore_wiki_repo].all? + if [restore_project_tree, restore_repo, restore_wiki_repo].all? + project_tree.project + else + project_tree.project.destroy if project_tree.project + nil + end end private diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index da8aa4756539e6..5332529a90f369 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -4,10 +4,10 @@ class MembersMapper attr_reader :map, :note_member_list - def initialize(exported_members:, user:, project_id:) + def initialize(exported_members:, user:, project:) @exported_members = exported_members @user = user - @project_id = project_id + @project = project @note_member_list = [] @project_member_map = Hash.new do |_, key| @@ -36,20 +36,21 @@ def assign_member(existing_user, member) end def member_hash(member) - member.except('id').merge(source_id: @project_id) + member.except('id').merge(source_id: @project.id) end - #TODO: If default, then we need to leave a comment 'Comment by ' on comments def default_project_member @default_project_member ||= begin + return @project.project_members.first.user.id unless @project.project_members.empty? default_member = ProjectMember.new(default_project_member_hash) - default_member.user.id if default_member.save + default_member.save! + default_member.user.id end end def default_project_member_hash - { user: @user, access_level: ProjectMember::MASTER, source_id: @project_id } + { user: @user, access_level: ProjectMember::MASTER, source_id: @project.id } end def find_project_user_query(member) diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index a840c9f94786dc..bd343d0b695f09 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -29,7 +29,7 @@ def project def members_mapper @members_mapper ||= Gitlab::ImportExport::MembersMapper.new(exported_members: @project_members, user: @user, - project_id: project.id) + project: project) end def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 0adcd0d5e6cd04..cdd4987f98020f 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -30,16 +30,17 @@ def update_user_references(relation_hash, members_map) def update_missing_author(relation_hash, members_map) old_author_id = relation_hash['author_id'] relation_hash['author_id'] = members_map.map[old_author_id] + author = relation_hash.delete('author') + return unless members_map.note_member_list.include?(old_author_id) relation_hash['note'] = ('*Blank note*') if relation_hash['note'].blank? - relation_hash['note'] += (missing_author_note(relation_hash['updated_at'], - relation_hash['author']['name'])) - relation_hash.delete('author') + relation_hash['note'] += (missing_author_note(relation_hash['updated_at'], author['name'])) end def missing_author_note(updated_at, author_name) - "\n\n *By #{author_name} on #{updated_at} (imported from GitLab project)*" + timestamp = updated_at.split('.').first + "\n\n *By #{author_name} on #{timestamp} (imported from GitLab project)*" end def update_project_references(relation_hash, klass) diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb index 78706f64fb7428..adaadbff6f8c16 100644 --- a/spec/lib/gitlab/import_export/members_mapper_spec.rb +++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb @@ -32,7 +32,7 @@ let(:members_mapper) do described_class.new( - exported_members: exported_members, user: user, project_id: project.id) + exported_members: exported_members, user: user, project: project) end it 'maps a project member' do -- GitLab From 8c508037a63ba2b82d56757bce011ac53a073ae6 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 17:03:03 +0200 Subject: [PATCH 159/714] updated controllers with permissions check --- .../import/gitlab_project_controller.rb | 45 ------------------- .../import/gitlab_projects_controller.rb | 41 ++++++++--------- app/controllers/projects_controller.rb | 2 +- 3 files changed, 19 insertions(+), 69 deletions(-) delete mode 100644 app/controllers/import/gitlab_project_controller.rb diff --git a/app/controllers/import/gitlab_project_controller.rb b/app/controllers/import/gitlab_project_controller.rb deleted file mode 100644 index ab0da196ac12ab..00000000000000 --- a/app/controllers/import/gitlab_project_controller.rb +++ /dev/null @@ -1,45 +0,0 @@ -class Import::GitlabProjectController < Import::BaseController - before_action :verify_gitlab_project_import_enabled - before_action :gitlab_project_auth, except: :callback - - rescue_from OAuth::Error, with: :gitlab_project_unauthorized - - #TODO permissions stuff - - def callback - - redirect_to status_import_gitlab_project_url - end - - def status - @repos = client.projects - @incompatible_repos = client.incompatible_projects - - @already_added_projects = current_user.created_projects.where(import_type: "gitlab_project") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } - end - - def jobs - jobs = current_user.created_projects.where(import_type: "gitlab_project").to_json(only: [:id, :import_status]) - render json: jobs - end - - def create - @file = params[:file] - - repo_owner = current_user.username - @target_namespace = params[:new_namespace].presence || repo_owner - - # namespace = get_or_create_namespace || (render and return) - - @project = Gitlab::ImportExport::ImportService.execute(archive_file: file, owner: repo_owner) - end - - private - - def verify_gitlab_project_import_enabled - render_404 unless gitlab_project_import_enabled? - end -end diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index f8d4bcff55a529..41b72c33ffe463 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -1,43 +1,38 @@ class Import::GitlabProjectsController < Import::BaseController before_action :verify_gitlab_project_import_enabled - #before_action :gitlab_project_auth, except: :callback + before_action :verify_project_and_namespace_access rescue_from OAuth::Error, with: :gitlab_project_unauthorized - #TODO permissions stuff - def new @namespace_id = project_params[:namespace_id] @path = project_params[:path] end - def status - - end + def create + @project = Project.create_from_import_job(current_user_id: current_user.id, + tmp_file: File.expand_path(params[:file].path), + namespace_id: project_params[:namespace_id], + project_path: project_params[:path]) - def jobs - jobs = current_user.created_projects.where(import_type: "gitlab_project").to_json(only: [:id, :import_status]) - render json: jobs + redirect_to dashboard_projects_path end - def create - # TODO verify access to namespace and path - file = params[:file] - namespace_id = project_params[:namespace_id] - path = project_params[:path] - - repo_owner = current_user.username - @target_namespace = params[:new_namespace].presence || repo_owner + private - @project = Project.create_from_import_job(current_user_id: current_user.id, - tmp_file: File.expand_path(file.path), - namespace_id: namespace_id, - project_path: path) + def verify_project_and_namespace_access + unless namespace_access? && project_access? + render_403 + end + end - redirect_to status_import_gitlab_project_path + def project_access? + can?(current_user, :admin_project, @project) end - private + def namespace_access? + current_user.can?(:create_projects, Namespace.find(project_params[:namespace_id])) + end def verify_gitlab_project_import_enabled render_404 unless gitlab_project_import_enabled? diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index f15f20dcf52637..980cae65f84ca4 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -7,7 +7,7 @@ class ProjectsController < Projects::ApplicationController before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists? # Authorize - before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping] + before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export] before_action :event_filter, only: [:show, :activity] layout :determine_layout -- GitLab From 89fb5df534c5b7c1ffc147e9274aee9db4f4cbc4 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 17:08:19 +0200 Subject: [PATCH 160/714] updated routes file --- config/routes.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 871997d01a2b9f..08598e36fe3694 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -160,9 +160,7 @@ end resource :gitlab_project, only: [:create, :new], controller: :gitlab_projects do - get :status post :create - get :jobs end end -- GitLab From 1ee19f04fd51322606d641ba82e6434d8d5c186f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 17:16:24 +0200 Subject: [PATCH 161/714] fixed permissions --- app/controllers/import/gitlab_projects_controller.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb index 41b72c33ffe463..a4ac55cd2a420d 100644 --- a/app/controllers/import/gitlab_projects_controller.rb +++ b/app/controllers/import/gitlab_projects_controller.rb @@ -21,15 +21,11 @@ def create private def verify_project_and_namespace_access - unless namespace_access? && project_access? + unless namespace_access? render_403 end end - def project_access? - can?(current_user, :admin_project, @project) - end - def namespace_access? current_user.can?(:create_projects, Namespace.find(project_params[:namespace_id])) end -- GitLab From 2e1decd061d679b3b8acd0a3e2178b61b59af65d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 17:17:46 +0200 Subject: [PATCH 162/714] restricted actual member mapping to admins --- lib/gitlab/import_export/members_mapper.rb | 20 +++++++++---------- .../import_export/project_tree_restorer.rb | 6 ++++-- lib/gitlab/import_export/relation_factory.rb | 17 +++++++++++----- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index 5332529a90f369..a5fdac6d93b703 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -18,6 +18,16 @@ def initialize(exported_members:, user:, project:) @map = generate_map end + def default_project_member + @default_project_member ||= + begin + return @project.project_members.first.user.id unless @project.project_members.empty? + default_member = ProjectMember.new(default_project_member_hash) + default_member.save! + default_member.user.id + end + end + private def generate_map @@ -39,16 +49,6 @@ def member_hash(member) member.except('id').merge(source_id: @project.id) end - def default_project_member - @default_project_member ||= - begin - return @project.project_members.first.user.id unless @project.project_members.empty? - default_member = ProjectMember.new(default_project_member_hash) - default_member.save! - default_member.user.id - end - end - def default_project_member_hash { user: @user, access_level: ProjectMember::MASTER, source_id: @project.id } end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index bd343d0b695f09..911ba06e7484be 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -94,8 +94,10 @@ def create_relation(relation, relation_hash_list) end def relation_from_factory(relation, relation_hash) - Gitlab::ImportExport::RelationFactory.create( - relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_mapper: members_mapper) + Gitlab::ImportExport::RelationFactory.create(relation_sym: relation.to_sym, + relation_hash: relation_hash.merge('project_id' => project.id), + members_mapper: members_mapper, + user_admin: @user.is_admin?) end end end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index cdd4987f98020f..3b27f133ecf62d 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -6,11 +6,11 @@ module RelationFactory OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status' }.freeze USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze - def create(relation_sym:, relation_hash:, members_mapper:) + def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) relation_sym = parse_relation_sym(relation_sym) klass = parse_relation(relation_hash, relation_sym) - update_missing_author(relation_hash, members_mapper) if relation_sym == :notes + update_missing_author(relation_hash, members_mapper, user_admin) if relation_sym == :notes update_user_references(relation_hash, members_mapper.map) update_project_references(relation_hash, klass) @@ -27,12 +27,19 @@ def update_user_references(relation_hash, members_map) end end - def update_missing_author(relation_hash, members_map) + def update_missing_author(relation_hash, members_map, user_admin) old_author_id = relation_hash['author_id'] - relation_hash['author_id'] = members_map.map[old_author_id] + + # Users with admin access have access to mapping of users + if user_admin + relation_hash['author_id'] = members_map.default_project_member + else + relation_hash['author_id'] = members_map.map[old_author_id] + end + author = relation_hash.delete('author') - return unless members_map.note_member_list.include?(old_author_id) + return unless user_admin && members_map.note_member_list.include?(old_author_id) relation_hash['note'] = ('*Blank note*') if relation_hash['note'].blank? relation_hash['note'] += (missing_author_note(relation_hash['updated_at'], author['name'])) -- GitLab From 2dff04f24a8446216e12d43fab6841f28f3dd406 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 17:39:03 +0200 Subject: [PATCH 163/714] fixed TODOs left --- lib/gitlab/import_export.rb | 8 ++++++++ lib/gitlab/import_export/project_tree_saver.rb | 7 +------ lib/gitlab/import_export/repo_bundler.rb | 7 +------ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 6835411ba70639..bf80ac7f09344c 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -9,5 +9,13 @@ def export_path(relative_path:) def storage_path File.join(Settings.shared['path'], 'tmp/project_exports') end + + def project_filename + "project.json" + end + + def project_bundle_filename + "project.bundle" + end end end diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index 2287524c8a56d2..c894295b0f5e19 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -6,7 +6,7 @@ class ProjectTreeSaver def initialize(project:, shared:) @project = project @shared = shared - @full_path = File.join(@shared.export_path, project_filename) + @full_path = File.join(@shared.export_path, ImportExport.project_filename) end def save @@ -20,11 +20,6 @@ def save private - # TODO remove magic keyword and move it to a shared config - def project_filename - "project.json" - end - def project_json_tree @project.to_json(Gitlab::ImportExport::ImportExportReader.new(shared: @shared).project_tree) end diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index bcf976fb624761..aff6e92be70771 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -12,7 +12,7 @@ def initialize(project: , shared: ) def bundle return false if @project.empty_repo? - @full_path = File.join(@shared.export_path, project_filename) + @full_path = File.join(@shared.export_path, ImportExport.project_bundle_filename) bundle_to_disk end @@ -26,11 +26,6 @@ def bundle_to_disk false end - # TODO remove magic keyword and move it to a shared config - def project_filename - "project.bundle" - end - def path_to_repo @project.repository.path_to_repo end -- GitLab From bf81c588fd7f34e475c0f317f7e49dc70e36366d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 19:51:07 +0200 Subject: [PATCH 164/714] fix issue with mapping members --- lib/gitlab/import_export/command_line_util.rb | 6 ------ lib/gitlab/import_export/members_mapper.rb | 4 ++++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index f53f8fba96fde4..c99b0d83b41c7b 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -19,12 +19,6 @@ def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_pa private - def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) - cmd = %W(#{git_bin_path} clone --bare #{bundle_path} #{repo_path}) - _output, status = Gitlab::Popen.popen(cmd) - status.zero? - end - def tar_with_options(archive:, dir:, options:) execute(%W(tar -#{options} #{archive} -C #{dir} .)) end diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index a5fdac6d93b703..4401fab3d23e99 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -10,6 +10,10 @@ def initialize(exported_members:, user:, project:) @project = project @note_member_list = [] + # This needs to run first, as second call would be from generate_map + # which means project members already exist. + default_project_member + @project_member_map = Hash.new do |_, key| @note_member_list << key default_project_member -- GitLab From 220e55a9806c4de9fc6839b1c676ba022b83f720 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 20:58:27 +0200 Subject: [PATCH 165/714] fix spec --- .../gitlab/import_export/project_tree_restorer_spec.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index 6464b0141f3e5a..bc7993b9d75735 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -5,9 +5,13 @@ let(:user) { create(:user) } let(:namespace) { create(:namespace, owner: user) } - let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "../../../spec/lib/gitlab/import_export/", project_path: 'path') } + let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path') } let(:project_tree_restorer) { described_class.new(user: user, shared: shared, namespace_id: namespace.id) } - let!(:restored_project_json) { project_tree_restorer.restore } + let(:restored_project_json) { project_tree_restorer.restore } + + before do + allow(shared).to receive(:export_path).and_return('spec/lib/gitlab/import_export/') + end context 'JSON' do it 'restores models based on JSON' do -- GitLab From f386d7a7b7f67ba8e77ee40ef6a3383d5206d0c1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 10:13:00 +0200 Subject: [PATCH 166/714] some changes based on MR feedback --- lib/gitlab/import_export/command_line_util.rb | 8 ++++++-- lib/gitlab/import_export/import_export_reader.rb | 1 + lib/gitlab/import_export/repo_bundler.rb | 2 +- lib/gitlab/import_export/wiki_repo_bundler.rb | 11 +++++------ .../gitlab/import_export/import_export_reader_spec.rb | 6 +++--- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index c99b0d83b41c7b..78664f076eb7ca 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -9,11 +9,11 @@ def untar_zxf(archive:, dir:) untar_with_options(archive: archive, dir: dir, options: 'zxf') end - def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) + def git_bundle(repo_path:, bundle_path:) execute(%W(#{git_bin_path} --git-dir=#{repo_path} bundle create #{bundle_path} --all)) end - def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) + def git_unbundle(repo_path:, bundle_path:) execute(%W(#{git_bin_path} clone --bare #{bundle_path} #{repo_path})) end @@ -31,6 +31,10 @@ def execute(cmd) _output, status = Gitlab::Popen.popen(cmd) status.zero? end + + def git_bin_path + Gitlab.config.git.bin_path + end end end end diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 9aac0eae79ab7f..25e13074e90ce5 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -14,6 +14,7 @@ def project_tree @attributes_parser.find_included(:project).merge(include: build_hash(@tree)) rescue => e @shared.error(e.message) + false end private diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index aff6e92be70771..f41d5af4e5374c 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -5,7 +5,7 @@ class RepoBundler attr_reader :full_path - def initialize(project: , shared: ) + def initialize(project:, shared:) @project = project @shared = shared end diff --git a/lib/gitlab/import_export/wiki_repo_bundler.rb b/lib/gitlab/import_export/wiki_repo_bundler.rb index a0000176bb59da..016c640ae1509b 100644 --- a/lib/gitlab/import_export/wiki_repo_bundler.rb +++ b/lib/gitlab/import_export/wiki_repo_bundler.rb @@ -3,14 +3,13 @@ module ImportExport class WikiRepoBundler < RepoBundler def bundle @wiki = ProjectWiki.new(@project) - return true if !wiki? # it's okay to have no Wiki - @full_path = File.join(@shared.export_path, project_filename) - bundle_to_disk + return true unless wiki_repository_exists? # it's okay to have no Wiki + bundle_to_disk(File.join(@shared.export_path, project_filename)) end - def bundle_to_disk + def bundle_to_disk(full_path) FileUtils.mkdir_p(@shared.export_path) - git_bundle(repo_path: path_to_repo, bundle_path: @full_path) + git_bundle(repo_path: path_to_repo, bundle_path: full_path) rescue => e @shared.error(e.message) false @@ -26,7 +25,7 @@ def path_to_repo @wiki.repository.path_to_repo end - def wiki? + def wiki_repository_exists? File.exists?(@wiki.repository.path_to_repo) && !@wiki.repository.empty? end end diff --git a/spec/lib/gitlab/import_export/import_export_reader_spec.rb b/spec/lib/gitlab/import_export/import_export_reader_spec.rb index 2fc9a39c68bf89..c4d03fecd5449e 100644 --- a/spec/lib/gitlab/import_export/import_export_reader_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_reader_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::ImportExport::ImportExportReader do +describe Gitlab::ImportExport::ImportExportReader, lib: true do let(:shared) { Gitlab::ImportExport::Shared.new(relative_path:'') } let(:test_config) { 'spec/support/import_export/import_export.yml' } let(:project_tree_hash) do @@ -16,7 +16,7 @@ } end - it 'should generate hash from project tree config' do - expect(described_class.new(config: test_config, shared: shared).project_tree) =~ (project_tree_hash) + it 'generates hash from project tree config' do + expect(described_class.new(config: test_config, shared: shared).project_tree).to match(project_tree_hash) end end -- GitLab From 30aa37c8127dfe10df44f7945a4722b95581ff24 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 11:24:20 +0200 Subject: [PATCH 167/714] remove spec change --- spec/spec_helper.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5b90a4b534b79e..576d16e7ea33fe 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -52,7 +52,3 @@ end ActiveRecord::Migration.maintain_test_schema! - -Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app, timeout: 1.minute) -end -- GitLab From 5777ad9a1f016f170585949059b08a4eeb7d19a9 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 12:04:31 +0200 Subject: [PATCH 168/714] adding versioning to export --- .../projects/import_export/export_service.rb | 11 +++++-- lib/gitlab/import_export.rb | 6 ++++ lib/gitlab/import_export/version_saver.rb | 29 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 lib/gitlab/import_export/version_saver.rb diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index e6eb6f915b064e..0691ca9d468602 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -4,12 +4,16 @@ class ExportService < BaseService def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) - save_all if [save_project_tree, bundle_repo, bundle_wiki_repo].all? - notify_worker if @shared.errors.any? + save_all if [save_version, save_project_tree, bundle_repo, bundle_wiki_repo].all? + cleanup_and_notify_worker if @shared.errors.any? end private + def save_version + Gitlab::ImportExport::VersionSaver.save(shared: @shared) + end + def save_project_tree Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared).save end @@ -26,7 +30,8 @@ def save_all Gitlab::ImportExport::Saver.save(shared: @shared) end - def notify_worker + def cleanup_and_notify_worker + FileUtils.rm_rf(@shared.export_path) raise Gitlab::ImportExport::Error.new(@shared.errors.join(', ')) end end diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index bf80ac7f09344c..9c7c72e2b4a011 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -2,6 +2,8 @@ module Gitlab module ImportExport extend self + VERSION = '0.1.0' + def export_path(relative_path:) File.join(storage_path, relative_path) end @@ -17,5 +19,9 @@ def project_filename def project_bundle_filename "project.bundle" end + + def version_filename + 'VERSION' + end end end diff --git a/lib/gitlab/import_export/version_saver.rb b/lib/gitlab/import_export/version_saver.rb new file mode 100644 index 00000000000000..e8be52b990fb2a --- /dev/null +++ b/lib/gitlab/import_export/version_saver.rb @@ -0,0 +1,29 @@ +module Gitlab + module ImportExport + class VersionSaver + + def self.save(*args) + new(*args).save + end + + def initialize(shared:) + @shared = shared + end + + def save + File.open(version_file, 'w') do |file| + file.write(Gitlab::ImportExport.VERSION) + end + rescue => e + @shared.error(e.message) + false + end + + private + + def version_file + File.join(@shared.export_path, Gitlab::ImportExport.version_filename) + end + end + end +end -- GitLab From 51487575bca1f4cdce4919bb4cb2bbb1ee686368 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 12:39:42 +0200 Subject: [PATCH 169/714] added version check on import --- lib/gitlab/import_export/import_service.rb | 6 +++- lib/gitlab/import_export/version_restorer.rb | 36 ++++++++++++++++++++ lib/gitlab/import_export/version_saver.rb | 2 +- 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 lib/gitlab/import_export/version_restorer.rb diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 0c483884fe97f0..b025bff29bd1a1 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -16,7 +16,7 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, shared: @shared) - if [restore_project_tree, restore_repo, restore_wiki_repo].all? + if [restore_version, restore_project_tree, restore_repo, restore_wiki_repo].all? project_tree.project else project_tree.project.destroy if project_tree.project @@ -26,6 +26,10 @@ def execute private + def restore_version + Gitlab::ImportExport::VersionRestorer.restore(shared: @shared) + end + def restore_project_tree project_tree.restore end diff --git a/lib/gitlab/import_export/version_restorer.rb b/lib/gitlab/import_export/version_restorer.rb new file mode 100644 index 00000000000000..797696511deeea --- /dev/null +++ b/lib/gitlab/import_export/version_restorer.rb @@ -0,0 +1,36 @@ +module Gitlab + module ImportExport + class VersionRestorer + + def self.restore(*args) + new(*args).restore + end + + def initialize(shared:) + @shared = shared + end + + def restore + version = File.open(version_file, &:readline) + verify_version!(version) + rescue => e + @shared.error(e) + false + end + + private + + def version_file + File.join(@shared.export_path, Gitlab::ImportExport.version_filename) + end + + def verify_version!(version) + if Gem::Version.new(version) > Gem::Version.new(Gitlab::ImportExport.VERSION) + raise Gitlab::ImportExport::Error("Import version mismatch: Required <= #{Gitlab::ImportExport.VERSION} but was #{version}") + else + true + end + end + end + end +end diff --git a/lib/gitlab/import_export/version_saver.rb b/lib/gitlab/import_export/version_saver.rb index e8be52b990fb2a..197271f35559ae 100644 --- a/lib/gitlab/import_export/version_saver.rb +++ b/lib/gitlab/import_export/version_saver.rb @@ -15,7 +15,7 @@ def save file.write(Gitlab::ImportExport.VERSION) end rescue => e - @shared.error(e.message) + @shared.error(e) false end -- GitLab From c374700390ad0e3ab8a7ad954ee1b6e311a48129 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 12:40:01 +0200 Subject: [PATCH 170/714] missing new line --- lib/gitlab/import_export/version_restorer.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/gitlab/import_export/version_restorer.rb b/lib/gitlab/import_export/version_restorer.rb index 797696511deeea..bab2fecec4920d 100644 --- a/lib/gitlab/import_export/version_restorer.rb +++ b/lib/gitlab/import_export/version_restorer.rb @@ -34,3 +34,4 @@ def verify_version!(version) end end end + -- GitLab From 360689bb5834cfe5b57c121d71a5123f27081fb0 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 13:11:49 +0200 Subject: [PATCH 171/714] fix version --- lib/gitlab/import_export/version_restorer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/version_restorer.rb b/lib/gitlab/import_export/version_restorer.rb index bab2fecec4920d..2c83bf089971cf 100644 --- a/lib/gitlab/import_export/version_restorer.rb +++ b/lib/gitlab/import_export/version_restorer.rb @@ -25,8 +25,8 @@ def version_file end def verify_version!(version) - if Gem::Version.new(version) > Gem::Version.new(Gitlab::ImportExport.VERSION) - raise Gitlab::ImportExport::Error("Import version mismatch: Required <= #{Gitlab::ImportExport.VERSION} but was #{version}") + if Gem::Version.new(version) > Gem::Version.new(Gitlab::ImportExport.version) + raise Gitlab::ImportExport::Error("Import version mismatch: Required <= #{Gitlab::ImportExport.version} but was #{version}") else true end -- GitLab From 504c186f7139df71dbea596b422d833f32348f46 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 13:28:11 +0200 Subject: [PATCH 172/714] fix version issue --- lib/gitlab/import_export.rb | 4 ++++ lib/gitlab/import_export/project_tree_saver.rb | 1 - lib/gitlab/import_export/version_saver.rb | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 9c7c72e2b4a011..65a8fcfadd0d6f 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -23,5 +23,9 @@ def project_bundle_filename def version_filename 'VERSION' end + + def version + VERSION + end end end diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index c894295b0f5e19..631746a47f183e 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -10,7 +10,6 @@ def initialize(project:, shared:) end def save - FileUtils.mkdir_p(@shared.export_path) File.write(full_path, project_json_tree) true rescue => e diff --git a/lib/gitlab/import_export/version_saver.rb b/lib/gitlab/import_export/version_saver.rb index e8be52b990fb2a..904645f273e0f6 100644 --- a/lib/gitlab/import_export/version_saver.rb +++ b/lib/gitlab/import_export/version_saver.rb @@ -11,8 +11,10 @@ def initialize(shared:) end def save + FileUtils.mkdir_p(@shared.export_path) + File.open(version_file, 'w') do |file| - file.write(Gitlab::ImportExport.VERSION) + file.write(Gitlab::ImportExport.version) end rescue => e @shared.error(e.message) -- GitLab From 7ea68d006e93f4bfe59d0513696e46c1ad5ee6a1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 16 May 2016 15:17:44 +0200 Subject: [PATCH 173/714] updated file import spec --- .../import_export/test_project_export.tar.gz | Bin 339384 -> 339482 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index aef4af6998ee729c2eea80c9d2423fc787083950..4f2ec49e9b51682a2813d3d310ea899a2ff361f3 100644 GIT binary patch delta 74261 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

    fzm7TD-`gGi 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

    w?``$89~=XC3~q|88mD*Xcaju@6uE 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�a|8&;b!u0v29rq@D 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 Date: Mon, 16 May 2016 15:29:14 +0200 Subject: [PATCH 174/714] fix issue with forked MRs --- lib/gitlab/import_export/relation_factory.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 3b27f133ecf62d..082398d1f0fc6a 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -53,11 +53,19 @@ def missing_author_note(updated_at, author_name) def update_project_references(relation_hash, klass) project_id = relation_hash.delete('project_id') + if relation_hash['source_project_id'] && relation_hash['target_project_id'] + # If source and target are the same, populate them with the new project ID. + if relation_hash['target_project_id'] == relation_hash['source_project_id'] + relation_hash['source_project_id'] = project_id + else + relation_hash['source_project_id'] = -1 + end + end + relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] + # project_id may not be part of the export, but we always need to populate it if required. relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') relation_hash['gl_project_id'] = project_id if relation_hash ['gl_project_id'] - relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] - relation_hash['source_project_id'] = -1 if relation_hash['source_project_id'] end def relation_class(relation_sym) -- GitLab From 07c642cb1342c82ff04681964754bc654450ec16 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 17 May 2016 09:39:34 +0200 Subject: [PATCH 175/714] updated routes for gitlab_project --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 08598e36fe3694..a528e0b4940a49 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -159,7 +159,7 @@ post :create_user_map, path: :user_map end - resource :gitlab_project, only: [:create, :new], controller: :gitlab_projects do + resource :gitlab_project, only: [:create, :new] do post :create end end -- GitLab From f48184cbc6d8951156ac5af6821f0a47dbc1c588 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 17 May 2016 09:40:49 +0200 Subject: [PATCH 176/714] updated routes for gitlab_projects --- config/routes.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 8ad0b4874dfb03..ad44c8f05b24fa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -159,10 +159,8 @@ post :create_user_map, path: :user_map end - resource :gitlab_project, only: [:create, :new], controller: :gitlab_projects do - get :status - get :callback - get :jobs + resource :gitlab_project, only: [:create, :new] do + post :create end end -- GitLab From 7733f56d80f84ada4c4fef8cc4a5ab9357af0dc5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 17 May 2016 16:28:27 +0200 Subject: [PATCH 177/714] fix specs --- lib/gitlab/import_export/project_tree_saver.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index 631746a47f183e..a2c5df8af25c14 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -10,6 +10,8 @@ def initialize(project:, shared:) end def save + FileUtils.mkdir_p(@shared.export_path) + File.write(full_path, project_json_tree) true rescue => e -- GitLab From bcda64c75c15e2fb1343378a9d07e4659ae4acda Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 10:39:53 +0200 Subject: [PATCH 178/714] added DB configuration --- lib/gitlab/import_export/import_export.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 66e6ae86cfe0e1..ae2bf677c90ce4 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -16,6 +16,13 @@ project_tree: - :merge_request_diff - ci_commits: - :statuses + - :builds + - :variables + - :triggers + - :deploy_keys + - :services + - :hooks + - :protected_branches # Only include the following attributes for the models specified. included_attributes: -- GitLab From ee2993040c207f70bf05a730b9389a54928e5a54 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 11:20:38 +0200 Subject: [PATCH 179/714] updated test file with DB config --- .../import_export/test_project_export.tar.gz | Bin 339482 -> 340727 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 4f2ec49e9b51682a2813d3d310ea899a2ff361f3..380696d5ab5b71539efffb0e221d5a6a80a3e435 100644 GIT binary patch delta 78539 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 Date: Wed, 18 May 2016 14:32:30 +0200 Subject: [PATCH 180/714] added commits mapper and DB config import stuff --- lib/gitlab/import_export/commit_mapper.rb | 49 ++++++++++++++ .../import_export/project_tree_restorer.rb | 14 +++- lib/gitlab/import_export/relation_factory.rb | 66 +++++++++++++------ 3 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 lib/gitlab/import_export/commit_mapper.rb diff --git a/lib/gitlab/import_export/commit_mapper.rb b/lib/gitlab/import_export/commit_mapper.rb new file mode 100644 index 00000000000000..405149d3cd8a73 --- /dev/null +++ b/lib/gitlab/import_export/commit_mapper.rb @@ -0,0 +1,49 @@ +module Gitlab + module ImportExport + class CommitMapper + def initialize(commits:, members_map:, project_id:, relation_factory: Gitlab::ImportExport::RelationFactory, user_admin:) + @commits = commits + @members_map = members_map + @project_id = project_id + @relation_factory = relation_factory + @user_admin = user_admin + end + + def ids_map + @ids_map ||= map_commits + end + + def map_commits + @id_map = Hash.new(-1) + + @commits.each do |commit_hash| + @relation_factory.update_user_references(commit_hash, @members_map) + + commit_hash['project_id'] = @project_id + @relation_factory.update_project_references(commit_hash, Ci::Commit) + create_commit_statuses(commit_hash) + create_commit(commit_hash) + end + @id_map + end + + def create_commit(commit_hash) + old_id = commit_hash.delete('id') + commit = Ci::Commit.new(commit_hash) + commit.save! + @id_map[old_id] = commit.id + end + + def create_commit_statuses(commit_hash) + commit_hash['statuses'].map! do |status_hash| + @relation_factory.create(relation_sym: :statuses, + relation_hash: status_hash.merge('project_id' => @project_id, + 'commit_id' => nil), + members_mapper: @members_map, + commits_mapper: nil, + user_admin: @user_admin) + end + end + end + end +end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 911ba06e7484be..750b69caafb11c 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -14,6 +14,7 @@ def restore json = IO.read(@path) @tree_hash = ActiveSupport::JSON.decode(json) @project_members = @tree_hash.delete('project_members') + @commits = @tree_hash.delete('ci_commits') create_relations rescue => e @shared.error(e) @@ -32,6 +33,13 @@ def members_mapper project: project) end + def commits_mapper + @commits_mapper ||= Gitlab::ImportExport::CommitMapper.new(commits: @commits, + members_map: members_mapper.map, + project_id: project.id, + user_admin: @user.is_admin?) + end + def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) saved = [] relation_list.each do |relation| @@ -47,7 +55,7 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha def default_relation_list Gitlab::ImportExport::ImportExportReader.new(shared: @shared).tree.reject do |model| - model.is_a?(Hash) && model[:project_members] + model.is_a?(Hash) && (model[:project_members] || model[:ci_commits]) end end @@ -65,9 +73,8 @@ def create_sub_relations(relation, tree_hash) relation_key = relation.keys.first.to_s tree_hash[relation_key].each do |relation_item| relation.values.flatten.each do |sub_relation| - if sub_relation.is_a?(Hash) - relation_hash = relation_item[sub_relation.keys.first.to_s] + relation_hash = relation_item[sub_relation.keys.first.to_s] sub_relation = sub_relation.keys.first else relation_hash = relation_item[sub_relation.to_s] @@ -97,6 +104,7 @@ def relation_from_factory(relation, relation_hash) Gitlab::ImportExport::RelationFactory.create(relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_mapper: members_mapper, + commits_mapper: commits_mapper, user_admin: @user.is_admin?) end end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 082398d1f0fc6a..7f0f8f8077dc73 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -3,21 +3,27 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status' }.freeze - USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze - - def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) + OVERRIDES = { snippets: :project_snippets, + ci_commits: 'Ci::Commit', + statuses: 'commit_status', + variables: 'Ci::Variable', + triggers: 'Ci::Trigger', + builds: 'Ci::Build', + hooks: 'ProjectHook' }.freeze + USER_REFERENCES = %w(author_id assignee_id updated_by_id user_id).freeze + + def create(relation_sym:, relation_hash:, members_mapper:, commits_mapper:, user_admin:) relation_sym = parse_relation_sym(relation_sym) klass = parse_relation(relation_hash, relation_sym) update_missing_author(relation_hash, members_mapper, user_admin) if relation_sym == :notes update_user_references(relation_hash, members_mapper.map) update_project_references(relation_hash, klass) + update_commit_references(relation_hash, commits_mapper.ids_map) if commits_mapper - imported_object(klass, relation_hash) + generate_imported_object(klass, relation_hash, relation_sym) end - private def update_user_references(relation_hash, members_map) USER_REFERENCES.each do |reference| @@ -27,6 +33,32 @@ def update_user_references(relation_hash, members_map) end end + def update_project_references(relation_hash, klass) + project_id = relation_hash.delete('project_id') + + if relation_hash['source_project_id'] && relation_hash['target_project_id'] + # If source and target are the same, populate them with the new project ID. + if relation_hash['target_project_id'] == relation_hash['source_project_id'] + relation_hash['source_project_id'] = project_id + else + relation_hash['source_project_id'] = -1 + end + end + relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] + + # project_id may not be part of the export, but we always need to populate it if required. + relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') + relation_hash['gl_project_id'] = project_id if relation_hash['gl_project_id'] + end + + private + + def update_commit_references(relation_hash, commit_ids_map) + return unless relation_hash['commit_id'] + old_commit_id = relation_hash['commit_id'] + relation_hash['commit_id'] = commit_ids_map[old_commit_id] + end + def update_missing_author(relation_hash, members_map, user_admin) old_author_id = relation_hash['author_id'] @@ -50,22 +82,15 @@ def missing_author_note(updated_at, author_name) "\n\n *By #{author_name} on #{timestamp} (imported from GitLab project)*" end - def update_project_references(relation_hash, klass) - project_id = relation_hash.delete('project_id') - - if relation_hash['source_project_id'] && relation_hash['target_project_id'] - # If source and target are the same, populate them with the new project ID. - if relation_hash['target_project_id'] == relation_hash['source_project_id'] - relation_hash['source_project_id'] = project_id - else - relation_hash['source_project_id'] = -1 + def generate_imported_object(klass, relation_hash, relation_sym) + if relation_sym == 'Ci::Build' # call #trace= method after assigning the other attributes + trace = relation_hash.delete('trace') + imported_object(klass, relation_hash) do |imported_object| + imported_object.trace = trace end + else + imported_object(klass, relation_hash) end - relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] - - # project_id may not be part of the export, but we always need to populate it if required. - relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') - relation_hash['gl_project_id'] = project_id if relation_hash ['gl_project_id'] end def relation_class(relation_sym) @@ -78,6 +103,7 @@ def parse_relation_sym(relation_sym) def imported_object(klass, relation_hash) imported_object = klass.new(relation_hash) + yield(imported_object) if block_given? imported_object.importing = true if imported_object.respond_to?(:importing) imported_object end -- GitLab From 0df21ac712d7afd99b0d38a52e7375b11a4fe269 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 15:15:14 +0200 Subject: [PATCH 181/714] revert changes as builds are related to statuses which are already there --- lib/gitlab/import_export/commit_mapper.rb | 49 -------------- .../import_export/project_tree_restorer.rb | 14 +--- lib/gitlab/import_export/relation_factory.rb | 66 ++++++------------- 3 files changed, 23 insertions(+), 106 deletions(-) delete mode 100644 lib/gitlab/import_export/commit_mapper.rb diff --git a/lib/gitlab/import_export/commit_mapper.rb b/lib/gitlab/import_export/commit_mapper.rb deleted file mode 100644 index 405149d3cd8a73..00000000000000 --- a/lib/gitlab/import_export/commit_mapper.rb +++ /dev/null @@ -1,49 +0,0 @@ -module Gitlab - module ImportExport - class CommitMapper - def initialize(commits:, members_map:, project_id:, relation_factory: Gitlab::ImportExport::RelationFactory, user_admin:) - @commits = commits - @members_map = members_map - @project_id = project_id - @relation_factory = relation_factory - @user_admin = user_admin - end - - def ids_map - @ids_map ||= map_commits - end - - def map_commits - @id_map = Hash.new(-1) - - @commits.each do |commit_hash| - @relation_factory.update_user_references(commit_hash, @members_map) - - commit_hash['project_id'] = @project_id - @relation_factory.update_project_references(commit_hash, Ci::Commit) - create_commit_statuses(commit_hash) - create_commit(commit_hash) - end - @id_map - end - - def create_commit(commit_hash) - old_id = commit_hash.delete('id') - commit = Ci::Commit.new(commit_hash) - commit.save! - @id_map[old_id] = commit.id - end - - def create_commit_statuses(commit_hash) - commit_hash['statuses'].map! do |status_hash| - @relation_factory.create(relation_sym: :statuses, - relation_hash: status_hash.merge('project_id' => @project_id, - 'commit_id' => nil), - members_mapper: @members_map, - commits_mapper: nil, - user_admin: @user_admin) - end - end - end - end -end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 750b69caafb11c..911ba06e7484be 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -14,7 +14,6 @@ def restore json = IO.read(@path) @tree_hash = ActiveSupport::JSON.decode(json) @project_members = @tree_hash.delete('project_members') - @commits = @tree_hash.delete('ci_commits') create_relations rescue => e @shared.error(e) @@ -33,13 +32,6 @@ def members_mapper project: project) end - def commits_mapper - @commits_mapper ||= Gitlab::ImportExport::CommitMapper.new(commits: @commits, - members_map: members_mapper.map, - project_id: project.id, - user_admin: @user.is_admin?) - end - def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) saved = [] relation_list.each do |relation| @@ -55,7 +47,7 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha def default_relation_list Gitlab::ImportExport::ImportExportReader.new(shared: @shared).tree.reject do |model| - model.is_a?(Hash) && (model[:project_members] || model[:ci_commits]) + model.is_a?(Hash) && model[:project_members] end end @@ -73,8 +65,9 @@ def create_sub_relations(relation, tree_hash) relation_key = relation.keys.first.to_s tree_hash[relation_key].each do |relation_item| relation.values.flatten.each do |sub_relation| + if sub_relation.is_a?(Hash) - relation_hash = relation_item[sub_relation.keys.first.to_s] + relation_hash = relation_item[sub_relation.keys.first.to_s] sub_relation = sub_relation.keys.first else relation_hash = relation_item[sub_relation.to_s] @@ -104,7 +97,6 @@ def relation_from_factory(relation, relation_hash) Gitlab::ImportExport::RelationFactory.create(relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_mapper: members_mapper, - commits_mapper: commits_mapper, user_admin: @user.is_admin?) end end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 7f0f8f8077dc73..082398d1f0fc6a 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -3,27 +3,21 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets, - ci_commits: 'Ci::Commit', - statuses: 'commit_status', - variables: 'Ci::Variable', - triggers: 'Ci::Trigger', - builds: 'Ci::Build', - hooks: 'ProjectHook' }.freeze - USER_REFERENCES = %w(author_id assignee_id updated_by_id user_id).freeze - - def create(relation_sym:, relation_hash:, members_mapper:, commits_mapper:, user_admin:) + OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status' }.freeze + USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze + + def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) relation_sym = parse_relation_sym(relation_sym) klass = parse_relation(relation_hash, relation_sym) update_missing_author(relation_hash, members_mapper, user_admin) if relation_sym == :notes update_user_references(relation_hash, members_mapper.map) update_project_references(relation_hash, klass) - update_commit_references(relation_hash, commits_mapper.ids_map) if commits_mapper - generate_imported_object(klass, relation_hash, relation_sym) + imported_object(klass, relation_hash) end + private def update_user_references(relation_hash, members_map) USER_REFERENCES.each do |reference| @@ -33,32 +27,6 @@ def update_user_references(relation_hash, members_map) end end - def update_project_references(relation_hash, klass) - project_id = relation_hash.delete('project_id') - - if relation_hash['source_project_id'] && relation_hash['target_project_id'] - # If source and target are the same, populate them with the new project ID. - if relation_hash['target_project_id'] == relation_hash['source_project_id'] - relation_hash['source_project_id'] = project_id - else - relation_hash['source_project_id'] = -1 - end - end - relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] - - # project_id may not be part of the export, but we always need to populate it if required. - relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') - relation_hash['gl_project_id'] = project_id if relation_hash['gl_project_id'] - end - - private - - def update_commit_references(relation_hash, commit_ids_map) - return unless relation_hash['commit_id'] - old_commit_id = relation_hash['commit_id'] - relation_hash['commit_id'] = commit_ids_map[old_commit_id] - end - def update_missing_author(relation_hash, members_map, user_admin) old_author_id = relation_hash['author_id'] @@ -82,15 +50,22 @@ def missing_author_note(updated_at, author_name) "\n\n *By #{author_name} on #{timestamp} (imported from GitLab project)*" end - def generate_imported_object(klass, relation_hash, relation_sym) - if relation_sym == 'Ci::Build' # call #trace= method after assigning the other attributes - trace = relation_hash.delete('trace') - imported_object(klass, relation_hash) do |imported_object| - imported_object.trace = trace + def update_project_references(relation_hash, klass) + project_id = relation_hash.delete('project_id') + + if relation_hash['source_project_id'] && relation_hash['target_project_id'] + # If source and target are the same, populate them with the new project ID. + if relation_hash['target_project_id'] == relation_hash['source_project_id'] + relation_hash['source_project_id'] = project_id + else + relation_hash['source_project_id'] = -1 end - else - imported_object(klass, relation_hash) end + relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] + + # project_id may not be part of the export, but we always need to populate it if required. + relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') + relation_hash['gl_project_id'] = project_id if relation_hash ['gl_project_id'] end def relation_class(relation_sym) @@ -103,7 +78,6 @@ def parse_relation_sym(relation_sym) def imported_object(klass, relation_hash) imported_object = klass.new(relation_hash) - yield(imported_object) if block_given? imported_object.importing = true if imported_object.respond_to?(:importing) imported_object end -- GitLab From 6956fb6366d78dd979fb1046bcd8b05e6dfd2bf7 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 15:22:26 +0200 Subject: [PATCH 182/714] update relation factory with new models exceptions --- lib/gitlab/import_export/relation_factory.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 082398d1f0fc6a..68319441a63427 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -3,7 +3,15 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status' }.freeze + + OVERRIDES = { snippets: :project_snippets, + ci_commits: 'Ci::Commit', + statuses: 'commit_status', + variables: 'Ci::Variable', + triggers: 'Ci::Trigger', + builds: 'Ci::Build', + hooks: 'ProjectHook' }.freeze + USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) -- GitLab From 301d64b84943f7f91588c330f2d22c172f529d52 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 15:23:32 +0200 Subject: [PATCH 183/714] updated import export conf --- lib/gitlab/import_export/import_export.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index ae2bf677c90ce4..947f3030f461ab 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -16,7 +16,6 @@ project_tree: - :merge_request_diff - ci_commits: - :statuses - - :builds - :variables - :triggers - :deploy_keys -- GitLab From a5f04ad48849b94aabeeb7450c6059e76372855c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 17:48:15 +0200 Subject: [PATCH 184/714] fixed CI commits on export --- lib/gitlab/import_export/attributes_finder.rb | 10 ++++++++-- lib/gitlab/import_export/import_export.yml | 6 +++++- lib/gitlab/import_export/import_export_reader.rb | 3 ++- .../gitlab/import_export/project_tree_saver_spec.rb | 9 +++++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/import_export/attributes_finder.rb b/lib/gitlab/import_export/attributes_finder.rb index 3439ef1006edba..d230de781d510f 100644 --- a/lib/gitlab/import_export/attributes_finder.rb +++ b/lib/gitlab/import_export/attributes_finder.rb @@ -2,9 +2,10 @@ module Gitlab module ImportExport class AttributesFinder - def initialize(included_attributes:, excluded_attributes:) + def initialize(included_attributes:, excluded_attributes:, methods:) @included_attributes = included_attributes || {} @excluded_attributes = excluded_attributes || {} + @methods = methods || {} end def find(model_object) @@ -27,10 +28,15 @@ def find_excluded(value) @excluded_attributes[key].nil? ? {} : { except: @excluded_attributes[key] } end + def find_method(value) + key = key_from_hash(value) + @methods[key].nil? ? {} : { methods: @methods[key] } + end + private def find_attributes_only(value) - find_included(value).merge(find_excluded(value)) + find_included(value).merge(find_excluded(value)).merge(find_method(value)) end def key_from_hash(value) diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 947f3030f461ab..eef4d92beee378 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -45,4 +45,8 @@ included_attributes: # Do not include the following attributes for the models specified. excluded_attributes: snippets: - - :expired_at \ No newline at end of file + - :expired_at + +methods: + statuses: + - :type \ No newline at end of file diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 25e13074e90ce5..65d27f4b7a4f80 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -7,7 +7,8 @@ def initialize(config: 'lib/gitlab/import_export/import_export.yml', shared:) config_hash = YAML.load_file(config).deep_symbolize_keys @tree = config_hash[:project_tree] @attributes_parser = Gitlab::ImportExport::AttributesFinder.new(included_attributes: config_hash[:included_attributes], - excluded_attributes: config_hash[:excluded_attributes]) + excluded_attributes: config_hash[:excluded_attributes], + methods: config_hash[:methods]) end def project_tree 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 b9cf88d3f777c8..1c55d0e33c1a37 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -84,10 +84,15 @@ it 'has author on merge requests comments' do expect(saved_project_json['merge_requests'].first['notes'].first['author']).not_to be_empty end + it 'has commit statuses' do expect(saved_project_json['ci_commits'].first['statuses']).not_to be_empty end + it 'has CI builds' do + expect(saved_project_json['ci_commits'].first['statuses'].first['type']).to eq('Ci::Build') + end + it 'has ci commits' do expect(saved_project_json['ci_commits']).not_to be_empty end @@ -99,7 +104,6 @@ def setup_project merge_request = create(:merge_request) label = create(:label) snippet = create(:project_snippet) - commit_status = create(:commit_status) release = create(:release) project = create(:project, @@ -111,7 +115,8 @@ def setup_project releases: [release] ) - create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) + ci_commit = create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch) + create(:ci_build, commit: ci_commit) create(:milestone, project: project) create(:note, noteable: issue) create(:note, noteable: merge_request) -- GitLab From 0de533ed08eb3e918f30c72a46635c256881d8c0 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 17:54:39 +0200 Subject: [PATCH 185/714] fix rubocop warning --- lib/gitlab/import_export/version_restorer.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/gitlab/import_export/version_restorer.rb b/lib/gitlab/import_export/version_restorer.rb index 2c83bf089971cf..892352f5adfabb 100644 --- a/lib/gitlab/import_export/version_restorer.rb +++ b/lib/gitlab/import_export/version_restorer.rb @@ -34,4 +34,3 @@ def verify_version!(version) end end end - -- GitLab From dac1d0d81250ef41e7a0a26edf54100229cbb22c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 18 May 2016 18:15:28 +0200 Subject: [PATCH 186/714] updated test project file --- .../import_export/test_project_export.tar.gz | Bin 340727 -> 340523 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 380696d5ab5b71539efffb0e221d5a6a80a3e435..7eed8a6306a1e3fb2c06b2eb148e765da05de12c 100644 GIT binary patch delta 78124 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 Tgk!}O#hOy;bq*Khu-+dk_E(^3cSZ}p6v4&V0A zS=e=PyB8}ns{<#4io@;wd%oDqZjW$fR&d~CaCg|T-~ZZ@i0zH7%+3y+U>|Hx``Wr7eG#OHvee2{SPY($VtKuZ}zLtI>5SJ!i|L=YTk73?U%M2w6Q2S)W4}^pCf(r z>wZpK2M$@M=yM{{_g`+C&fL_S+rucHlRRtg@3m#&<=t1;OufU~GV21fVxxn?7Y5Fj z03Y=)VhUg6syJJcoYw#Up0@4GJ=y{r~DsFC$;;?8r+>JG*wib;Z}M=PUjvyg&HYKB{`M z`E&hWH#={~6n?5ze`~(^@zZYp*x3I+mU`d0FJtoO;iDsg*y znC&~g`nwSypUL(`)qgzFe_f*Py|ww_OE=Qh)=XI6E?aj+Hh6yIcmMz8U$XsuZBt*# z*M0R$y&=}UZ^!?W)Bo+b@3_4w>}PP++TZK<{adnjdp~?oPnZ4hqW3^Rean5ykv_IxY^V;?C+m0!l?^l*9xtG2F zW!u*s_joTKllyaN*}Yxj>-WBWv{U`vlePQq`u(r`^Q+vvF8k)rYT1kTDjzO%`uC&o zvfobi>a@a@2D?Ac;NR;0;FG|ixakwukS3lWIyj#(O>^OlcTNA&(}P^ zsCvFKJ@(@-`S9BJnD(vI12wLgwq=av1j6qoxp@muHR-N)+k{}w-4_%b^0$Aev||0O>k zmVCBxcFw!nikHp1?HBgkDSUHkyMFbePtxnA$i%U9RUPrv_vWHI}hnm=ut z#pf%3oo)ZVH~CzadfuOX+upfNU$^b@KJWIqzrRe${&qX*%$@V$@rPo|AIZJy)wkXE zWmh1IK`Oo8ZZhn90UB2_%uGQ~sr^tV6ejYAUcI^Mz z|2gwl+k5KYec!CTZ%=*M*?OBD_cT}Q>@S`Jl|%ru$|?@zQgC|?Yv~qUy*;z z;Nj=T^}mko|F`u!qkQh?lkvE18KJDL{87_8h$L~+RVe;Q! z3QOm&Tfghy*7bJQ`G;1<^Y6~Rt1A0?-uG+Xt-bDZw^y|GuG@DuBJ=Rv^_82S*nT#N zNXUNo=bmJ}``gVmSChZZ{`y$*zs-Z^{BJhQD!d+-UbAA)#DC|{=hghUq`yq-`n=CS z`}Eh<+v9sk&uUhB)cXh8Ry{MZ1FXehL7kjNqR^j{nqn*-K>VGp&>1FT# zKJUiY3(cAlLGPyT|C811|6cfc&DOtq*Lk9=4hF~j?yb8g{y(Dr{S8sO*y`^a=db_m z`g`yGxP4CzFQ2Whk30FU=-Hjb~vVf5!Inww*CQ?--}w zPtmvraB$T-bIgZ zx=ueIx9|3mt7iLhj;`G=w{3~aoxcZ{>d*cE)A;z#>H77*UMFtv*=4!;z{GFWpO>Es zeOsTNZ}V*t^S>81<$HIhp4YZrJ2|4vYB{!Px?<@QKX>Nag#jTsa-$(zr zthqeD==6vB`PYlDJuyBd{>|?Hy?N>~oBmfluPytapI@(`Cmd(_f7?y}dE5TYe4hLB z`p)w*^=>~mc~_s``TWK8_f@~X>R+q96;8zu#nBuKwy*uMm-XGHUspKV{dCAKzCtXY0AX$j5-23kNHoq@FdUU<~P5sZq zbKlEtEUtPUY9|=?|J65ty~>}57suavdv$Wy{6DMLZnwOCqj>fHJHHMoa=(k%b@2zU zx}Ej@=N;w;yk6S9I+d=sYt5!_7tjCyakyJAWB=1trthN5=U(o+`GI}$v9(`b>A#Qu zc*ft{;>E%KZ}smNYz~Y6c0&B!>BVU!cm6zn?k-<%cK`R!{%dldU+g(Or&up&{jCpQ zgYQ@T>+0v&`M;?rrm`0^WbRy39{+YF)_#_VeqDo^I9u z?-xC9=g-gL=Pe$t_x9USmzUZd8-C;6-o(Rgv1Y&KOqTn(Kl}Zjr+Y8wi@v*&Q&)J( z@ntSw^}F@u?>8Q;uRI=G|6yMBeT#=j)%*5jT{-b>{@QcCHig%>hu`?VGJgHeL!GhL zIK}fmoN!)jKD*{!b$W00o3iX%$@1?CZ}gkreX^Q8e@@K>_jrD3)Aw_i%UM)#e?KI? zPwv}|$KCDrMQ6I&b>7ST{P=YDk~P)#!F)dXn^&jj6g>I)dw$L`v&w|}-`AI|EqiGgjYhm;Lbmczx-S$HMQgF4v9TR`qoKZ@GWF*{A#LF8kX2%`&2*^pEPi zq(7NAt)8FT^><@7bsfSvA`l%cD=gs`v-}>%8`LOm}{J-zo=k|QLBCggqx$k$;t@qDk z%l{o&n!Ho?)OP#LA4~o1H~g6^dgg82|7X0}cmK|JpLXA(IP&=E=j&$2edAAjUTwCs zbpDr<*K4*s%ip%^&zH^TYjUTb?W^DW;%#fToWk6FPwt-oabMp$Y4iH+JF?aaE|35E zL{Z!R^LEztPr_?+uH1GnyT9pUxcT4elZ^7Wz30!Yy6qPDPc*=Hm+)c}O#;FGv?au%A@%8IFn?A>0kNaZ$ctvns@uwYsHYUBCH#=@m^0~M5 z(Pj0|HT%~V9h_`kdcL~w@ZNt_ceIS>{rt4!tv7qh_BmC@&a4iLxoz`qd3eu{C*Q*J zetqoS-uLfo?ElDpH~w5bnI5O!V^#M%zGjcdt}n-~PHoqdn!fwb(tDP-{eM2UvDdx*ZRMkT#&Y|1?0Nas)?I)9pS7pu|1XND`?K2LEs zwqKr}xBb5)f8CV(Hs&vnB+FU;-@E_M*PUC>Y%UX8B3fTHb?edAq{!#<$hc? zeKzOH-xqwp&)#~wNxDo#?CYIv|1I^Gr`@eSxcHRw?``j^{NG=nJ@><#%fi?0)f`t} z=exG_lIZfUdyFbyUSI#l;_s2a%Wb|qdbj=l_ZyelW&Yj@{r%?Cuea^?H7BCy`|o^O zzcblv`?n`*Q`*-Teg9%Q|Hkt*kHsSoUypl!&|h!YpGzP0|CW5dUwdiutK{%|KM%*h z+47%PUUsL~uf6tj>^?3_chmMZk1cp8e0bZ=m)~3$KfCk$ynWa2cVEAnzTUg>aa{fT zKSj--_3x%_F3yW8f11AC^7Z`k^=4lezWaIpd0hVPyzlcj*4H^T$Ir&cEtA<%bEQgr&Gu(&Vy{~!oQ}S~<3m@f zeSNy;bIts-`-|@;hgbdk;C+|ZD$e+b{GSK*((6Ahp1mblP4@5Y__``nl^0#`^ymN9jPqY2=?O*oAudhE)`S|?4w`Zg8%b7jD#4We?-2&cu z8_o9a{(f+s>f6u%FBaaqG}phX`ssH2o&T4v-Cwc4=GW2d`;}`xe7N*@y3PN?R~)aO zt@^z1-RZcy8LxHYcmGkJzV=r`)rHBy`+og?8GP*DyWYUl<`QO^TkZ93R$uy7e>|uB zIcNF1?ces??c4D0{k5B~?-`XnlhTilxBI!N{7B#T{Tm+Ls<;2*|Ng9fR%_qV^YWE} zubL+RFME?U_3ZVkqronHEU{?1Ew*7Akt*Ke0ioBQk9 zmf3u_|Mhu3K6i4j;jiAU`a3>Q&D%A5=iC2X^xXc|)8^FnzF)h3xMtq_lwH5`!-VPiGc7(f#P{rYwR#=D z-2AdrcdqV>d04-)*8czbPwC+rc16c`sQ1;p`uRric>KnH{N?u^Oz@Wfw$Cnadik@t zR-b;<=G`k^?=Khe@6fJK%a5-wyP18t?`J?o#$0Cp{ePd`pKJa5a^%rJUcYUPir(zz3$tb-4FTLx0LR;uHOGLI&byYggjm5#AV`h0hrW%Ae8Vo5XPtHO{PMim zKM%I=-(NFdaJOy6d9m|T&&4LM&OWDAzi!Kqr~h|9pK^w|U-o0f@4oiAf4*MRkN zIQ`3>jc=Tu{ylumChgtX{nK{2&aS%}XguW)|MA{CZ((!~M8oD7{#tS9Y~J&C?tVW@zR#Xt`{BaX`2Ppb^ULq8`1^X^{~Rszy6dIa zcfS{x{#XBEVe&1t{kwXrznM+XtvmQ^X8Q5JQ+}^5{(MPv-L3Z%o8x90)gLV`zH^aX z?3`@bVXNDDKXoBdRdw|{$v zGx=Oy-b2OqJ!VfEitFu4d%qs9-SKP1)5F~R_t$)F@0Yp1^-}idA&fUSaVSsBjf(|JbzR!!3ip{Bs45>b2r->J;AD zaQEz-$GjK#ccmIR8!lM*ck>Qie&PJrS+gHZ+nhFQ_QQ&&+rDjE6#1_8nB1isfy;Wg z)jy6@-5ycKUHK!&XX%;BWx*vD=I1S0`!{pnbUJymFzwphXv5-|_1Q}wM6Y`uDzpCf z$=NU0ByTUB>Mgo_ukQ0HRde1=G8VVf{{FjUpY`##x1T+|n{+YpciNdX?DA)dZOz}N z-Tidv-5TTbC%2V$)>O}q+*Eb9(#PDYZ`(R%vF$rA)N47=c}L&-R-{x)RNfxMdeEVQ2U*H@?jo79us;@L7 z1-`Ynhjo?Ruk&iJS2!zhL@)Ba(2pr=Ufft8@ge4v%#7$=DbLp4%R6EcP|nT-bysvoSl z%3Y+mb$&&a}opeWF)ui}$0u6tH#MhU1W^pYEhHg>WTuyG(lDo?gcXaa|r8UwI*0NjQ)Cu=`bADyY8iA{g+nX*fmC%d}$ojA-YrmcK z+u4OmQF&*dAH6p(_)*F<&ZHA9FZ<3O6yM>)`o!@0l$}loM3ssrPm1(&N{jS%OS`q+ z^rQ~Yrj%(;M*eIcUxa;1oxb)qi!9^A>8EeA$k)gIxXGsZg}k=>a> zMM|Ag0#l;ur}={{>bR>Nx&2Y$WG)A%X^c@RKO&~Rj7YoLD`_rynJM?d>sXWDJDvD+ zG)hW$BwgFmuqHnMNMpGEq3ws z-!dcB_ZM4&-z-11_qTZ&*`}LnZ_BrNerDdD)9+GdJU?)vZ>nyE;HG3A!wt%wZa)8J zUlGxo%B89oe!y_I0q5%aNzTu6@|Hd*OuMMLGcCwkVO`Ua1iX0vv_*Z^H%ut%sx?|VGo-P&1<5O!RqSee@%WHm{(v6TPNT@0X7VD=9ADmpS!)_t?#bNi- z#)w88)h&iguZftLZe*I-c&vmO@P3py_l~qn=FV>!Ho255fs8K}tZNS%{)`oe`3kocc^PIn?yP=n@ zc;CDum6v~{*loVQ{;Nd5<;u%S&vSWhO`fRj+#@gWXNRQ^zoN<_?g#BWJ1k!8Wt4U> z3~m(p{K#eF{2%gjq?a${arQeR==_^4Pv+R1jW5Cz0xxG6vp3i8I{5B`tnBJZy0b$6 zSS-AzIMeJ(-5eoD|I2}?Hx6)$FSHX#7Cdrl&aa2wx;K)0OYWIi&iwq~d-g4{OKqnr zgOzq6a6K0*$PCr(hHIw_oM7Ljgv!>~!9esa&)|2#Fb2Yal91D45xGWC&HwRQ`FgK&W2a>G|ZjJiq@&O@3i`UzbVe!z+$s3POvgG#>i1qS>t~ zYu6MX@gIMq`p%TvY~@%o;|X`M{LF%ws%gz^fr>8${gmQ;!Y6YU?~gwnxTjBlnVW!X z!8B(+A%XS|pP>6b4#yWhT6}k7bpr3FizUjE3*LUuwv4;-;o=pJ1v6aM8mpK@)_?z9whqjz*f&ITxTfEgE7=in=E>ZcMs4v^q3dRO-G8@g<+Mw!Rj1>g?5?m= z%{=s=cAe)#u21jJ7`c0~+;&|tz2YD9@2HRU#>S;9YIUdX)n;3>;NhZ5A-}*4e|MT5 zTfgYYv#(WcwQJ%pZ)>#*shg_xeRKJo4-E2a&%T(q)11R%OP{!Fr$)!ulH4`%*+R3w zF1o^DB{7+AN|vhpJToO5CbgiBHnnL#O8=h<-aCF`D>xZXHWA*J|e>fsBl>5M;3jg&vPmOT2s%Tr~0#+A)-$$z8zer(;NA|}JY zJ<)anuL{>et`nx~1O!j-%Jj)}>I*E;HaSxMsn=QarrrnR-&DS`JUxhZzSTd#X^R(>bgwA{+<;hZy0)MK6y*@a3W8K>0U9+YOJZ4d-KYxAFZ=>W5 z`=+hBX8mdDp1|6BJg2TN+SVG}=U!~V-NmQj`0DCo(^UqK*mSeAJk-DLp0e=U?kyaA zQim6uHF3MxBf@KIy)BmeS>(cnJu3F1yk~NjB&&6ww0QA7`_{Xlwo`_el?pQEysxWF zyV$Dv;AG~XEQy@8AKI4A{=pP1nPeQ&S$>+7>p(qm10Upbc*3FhbwTv(fZT%NzgA4fc?%?+qwbs zE=eBiQ@k-Jz3k|r-=}-OJlfLoZ0fa?&t7s``hL%UR~9BF*{i$Xd~lG7#Z>-K@Il9t z$3b;JTtX+wTKum68#VdI8vW(Q+w%gpwC=jScFKk2*-K_Gd&wET?cO2n*`=4iaLk|K zQOj^YNJ&s<&GZC!r!5oL&5HZZ7Q80@bYM+FxNm4Cn4lb^NOA z+52A1U^-XvPNwsgYrQVIuCV=B=qFTv#^Xi5r0=)mvs}N=`Zq)FA^+vWA$J-NKDwT{ zqT!%-{*mK(8iEcQ2VA9J%$4*qdiv^nwr$*%FXvRgW%T}1Nt-au?$eb;w?kE)G&wF} z?hSZ4Z%> zUe0f)zx0{W!=Jo4FMR16W?7Z5wKmn>$$tzKk6z#FCH(sO7G71}net-$y&f;V7MQbp zfAkB_G!eH87T>uuG}SkTAFf;L`FX}~(TDsI{>p8}H~entvX@8wt?04KkYD`dq~b2~ z`i^ct&KNU=Ez?*&bN}9|<{UBoY{!8PPZiVLi4Au+J_ibS@5qx_{UCnZ$(c{YiXQJV zQ*>O|9Z+) zyA3&|nTbl;3mM*G6oaknql|m)GN!W*uDr)MCNqWqkKCg@q4FIeD4w zb5wcaqQ>jcTA!EQ#Q7tXx3=Mi{e1}^h9wqP>}Flut~5D+@ueyMG&ZwEvT9F^R$Jwn z_oC(RtZku378afE;mDSf-~R9L4*fG#0iPCkWqNF%Zt+fOV!Yb5y&q*?U!UcY{?|zP zko*bOh~u9lUr57q)9#}Kvm|CQX7M1FN7i=b1)imZa=i4_WvV}$@~|5d)QTr zjvbKnImW(t=edZ@KMXb)t9|yl#=phs~#(P!nfH zz+K_Vm1;&!VOC4NTQyy%pKKten!<9E*Tho)VMufAwv_KYEz9m3XNbvX?aVQfPZScF zeAra3Wo-^11f5_*eZrlibAy zN95+7Ilk$_uj5Nq#3t=D_4>5;$ONHTIcpatPH^%HoFvQo^Y5%}n_Cn=eNLIT(xF$~ z?oDO-ikcUW`nJE9+}uCIdWyM4H@UFrS88fvL1{6s8`>3qGB;vt)+1D-`6gs*iQ9c0Z;Bf3T)5GR<4odD(VG$kNUlYhMqyLU2=MUcUH2+3LyB53kI0D;6tM zd*sTZ=f*sD=P%ERpz8D0);T-(O<+6Z{bhxs*Ioyv!!uUAso2)aR#_Oe=uKwg{%Oe$ z^}hOk9S3;URJ?g^X4wP#KO;=ccWEQ9N>Tk~5mAwB< zywIH(yJ}N^uH{X$ISwz(4JRkuxlozZ_1^x;58>tY>@O7$ty&d$Mn&SL>hkL+Z+B?4 zoBs~bcyQ|VYpbh;W(R{-NP7sq4!_GPa#-k%jd9?@e=dTXlnx*7`Mp7`D6PQ8eJ=ZC zwbTF7j915tx4#WPywkO>s&aco$*B|mKi0D7t$AtrFJB@dG_6lsuwQ%jQn}?aIsZ;- z_#Sfm6fmjf?(+J{??25-HU6>lUshVzIq!;i1;@f)E9PegK04mWrI@f#Bda#u;AG?d zWr=I_Zq}diDR~-ww%Id4`!r|L;pD$fl^k22E#ym*D`I}W@Dt~%OD=z3opBCeJIKG# z@y~=^DXOVg^s|qDTW!a$IqSH>4@Hv>`IH*3+PV#YvpzKUt1aS5s#gkPR#&>#Yu)#C z_3jN%9M3rC+^|VtKJ6(X1kx7Rr>4Z4q~ye`zUWHtr;e|y4FyeSby#$Ce&C(s@i$^o z#C|E^&NB>4=Zmee6khWl+=zol9f4uD8_C&6)$N#^5bMVKG zAG_2yY^?kGMb>T4mH7>~HgINWIksp&`CJP6Zk4bme(%Tc#?x2z?oTWe>hWGDJw@zwxc_X)zi*ag31`fxZ){n( zw=_85$giuLwR`Hm1#aauIb$GnbxPp=Z+y4c&y!o1DsHw#5BaF#*3c zH$_d(m}9G`;^8LtIy_&$qxL(Ktf+C-{)L8*kBgXb*0ipOH>lg&W~un?E|;(T{s}JP zEq_<_&tF&{-@N7KQh&I?M%`-n zIq_3@$F_PDgnU?GWqSC=FIqX;7E%8n~vH}&AR5=|GF773vRD=-u_lO=oxoh{lzoAe(BnN{s;Y@&MlfV zZK>13p665F=32IF-Q_KEy=%!TIZZC9iJbALEF^-uw$1auzHfd>@{yElsw&@hf3dyP zJ6HbrBfsRX<+*ESvL7qRWcR()A*9j^G`fskUv0$!Up=GopNThz1{pFKx z(@PEYjOLkc7h2-GKJarE!>Q~2#Y|mlTwnQqZ&iEhI_*>78#7&l!!Bkbo0mOhd76BJ zEkWsO^261pTKc>PdVU?8>gFXj=|~Z%QkAqh-J>zB+Wh*f=?t?rFgVYBb>DlX?@yM* zwGJ0|u{Uk3({=yJcsMFlv+Jo`w8q1FR<`x0w(17(t?>D@;49n7#$So+9B%IFOIs6v zx-j8^L3n7Akt&#jN?GbNkxAQjy;jB&WCpp6ERFrS)%ApZ!(l zq)^SSAM+x<1jPP08d_+*jHFc?CN}Ec(_jYcuSPy z##Qx4p4{>NJ#+itIiKp5)$*r?etoUN?6FM6#6QI8SVkG=%x4$(cSO&?nu1Y=RzbY&Gi2i4r z&FwL(7tGUew+ZBa?45giWBSwdr^^?w&MX%(n%Vc|P`zHB%$_w*^qzb(ceEB2`)ZZi zKRfhc<;hJi)mOS+R9{?uVZED2Q%Pak(}}@poHv-Z95URl*|ub+SbkQfI&ZAV%@Yw` z$HcDosGgdYxm?%XO!Q*rY}pF}9=?Yi3oTE`?zwkxwXwm4z?VTsM9zO+T(PnH`C`%M z!h24gSZv40VDLbt{#Mh`AV0gd2i&D?f~DSOlM>q1mdl@hYq*V9+MHKv^`z1rJ}W0Y zuDVln%||$lm+`Xcy^EI?&D@q7d+l=DBthe@WuG^(ES`30+pNGuu1&GCUnaG$NZetj zU*c({y2Id#&wAUoWyZFeeSS+~z_(-)O`9x6ZiVpVd6*<#_#{i$D6CM9a#xaWK@EqX$( zXp6ua_rQrNvTQ3jmZ^DdTeP}uf|#tk!R0;k8qONc^Q=Ff^Ul02ZL_7}-v~4R;ty=L z>D71T3d7s7{G*#PXD(Z`{Bqc>`bjdzk2NOcEiDb4e0kZD>^*CihAK~PxM_4@*8jel zck6l1rj;fA+IVK(jmhqE{j=>-a?E6XH(lD3CdtAa3+GDgZ zU#V$#UHwkJ{vuN#clyf`{ZOyN(aug^lw&L=*-c5l&8`r8>y>MSi*w_%JzHKGC|iE`Mjtmq+;vY^$G_ZHkwCkZY@Y zc~+%Jn)<$wM=^?_<@kiYtG)nEJmy*{`+`#-B-?T5Q-JM5C0{#bh?UVLu-vGUvh z54(kA9-1_n`nQLzS|VQd>-nRU;>WL^->!`LYZUo+aa*x*Rc!x-j{4d8RdZZrq@@!b z|98vSCaTwdFWjLt?X~ijB9C0V+YhT`C#lUmJ+oM*%HkYr`-cy@+Syfd=4M$1pUO&& zzDwqrCVhXOw24J7BQ?;;EZ~ZPveu)QHlp)uPs-P}90|Y8I#HUn{_w`c>AOTTiMvQ8?AcM)Jm#&A}YqZ*7u%R;K8+_*o}Pwr9t#U!47eBFWf zA|;1~Z(KSw*FE8RL$b`zlJ}cte+}Acd12*li5kBt6EChSTI{kkcJ)>zi#(GJyLSg@ zKE8LGbD7YkDK!qxjt`jU`Lxs+ud6-i?p56lFO=s$Y~m5R;SeaWv4-j5wyWQ`yjY43*q?uSPQ=S{^PAGi?rpQ{ zeoS)BEA+gnqkFLa{)77==av3sa*F>sxb2IQ;h$R1A9v3Q9xQ+OKXUVf+1{r<*#C2` zYtPr!TrU3b|BvP!EdOM0O1|rR@%q*xN4tf;d=8d1+!XwpWO>l$Zy^8kw5GdR$?_X& zjAed`TwD9N#ITlWb=to_KUZ4%X}(Vh&NwHc{nBs!1kLm8=hs}`+_AF$a;CTrfBg#u z#}L^M7x=uA?$^BIn7`XMv+#%U@!lJi+Rw}{8OUs#^7!d?=gu3Cn*?UQpX3`?ypa9$ zqGwL&RyEtX_s*{r+^(*?y6Kk4W$n!SFCVNpethMoNrAdIFCFdCO%-VmH`cP)ziG{f zWs5#$o(+(3HN3j-O45B{_2BvbSrPS&S{5s7jMp|qP5Jot*RLrTd$v5C(U%pG=^9)S z9U7vm+chaEqb+fX@iN7TOwHUY3wSF1Lr<~H=aEhQCA*8YJ@@NjmDZGgUj#2nX>8!e-2&mc~KHJ{rB-%&wLEZy>d;ReQ!$%CjQDjZ4yv%bdkqXjd`=e zIGN)tG^%r2<{f(SD(91*)W!%-?ouw|C=hgKh;=K_1=iREr(Stakk-O zb**i()1E)9H`rr-;X*S{slSlZD%GBn>$7BD+FjZDBGj^L!#u&%m;5De0p>TfFJ~3k zHSRsuJ~^vXi?#i4RR6zbF7>IC+b4g@w9J)Uma{}Ow4~%{nF)7ISnMQG$8w)g@ls!t zOCJT6D9kBYvB*POe2v1YEg8ScCD&Z2=W&)<^MUvLbCE8Ii}ja{>p2Ckh&o>KS@=MC z!%?n+>fKu+Z}pi7SZq!8zp+Z$gZcGy2F{hU7qor}Hd(unW0C-8`odGWPv=C=N)~_i ze073H?ZKtD1SVZ!cj}sCv(TSau z&ZVyy{8ZGJ&0=Yo@S}c;kGA?3&AP+a+h^+--=ABy%b6pG;e_Yw*=&_DA&wIa{bTko zW6``6oR%ec^tHg!9Wz6!C(U}lWsPRt(e0mheoVdpm-mmsqbZg*Z=^2U@MvOls7j~g zuXv_L&P5u>KQbKW*8AEPzWdSCeyPsdgOh|NU*YKgWqSIVK-;S-(*PTzef8;X;T3aV z)LApKePZ1Z{71StMyiA3Tu{l|ybBh-vFRM1a{{Us!2`e&36U91{yCZn-rxTxPRK? zQwLT^ZaA87vnj$y@r>&PLtUPWpJjF*JRvcw%JY-0%ipNJcULDGI!>uLCU@vj&5{_4 z=o9>x7o-@iYmHtQl(sI^TtdM4(W$RRSx0|ul@ZQjOghl^Vn)|8r-fIyCrzuX%~PY#M@(Az zsV#Mhsczl*SszaE`#;;ZnD1*@!k=l}5A!#BZT|G*|GeFP&$%*%DuQ(!_?J)Nvg7(U z{~gQ0)BjR-ti4iqW5y&y7te6f+hr<}Zfj2TC0b@4-o$fxmY#+|U36KAB%{sr7jmq! z^~YB+F4mN7x^Xbum}R54VB$i4hQ+>2+l|k^&3pD-F22~<2(H!D`riRqLpUEi6W1m-q;;NJ91X?uY92AK~_ z?@##hH%>OT(r;gv@+1F()77&wC(Kq=DJx5qc=w_{wCkwT${xW>Vfqo$Pve9ycQr&> zoPT)cgA)Va25!fkjL*&YKRj~SD!pM5Z*~0D5Z}o* zX}N4%vP~w=0lQstAIvr0oAYevU9G>8>_yu5qdgC8yS4t+@og`1|K7a%zV%}5wIx?p z=t?!dkiEBOo>cuNL1Bp>XXe@!GhKdlqhfWlNSgMvIhE^-=O6hxyP`fvu!du=r8&F) z7q$rtz5f5rv{87axUqgALI6GHftT(r1J$yII(^+WK zV!d8f=GBLIID3EZU*%{bcjVEUt+$^gYuT;munX_yZ8tJ_>L&9Y{h=X!nXok=(M-vi9Qt+gkVP zcS!~Y8tu_LAk1Z@2vN4+^fHB4LvhkD!-5C%#tsOGXoZ7D$I%5 z>9IX5%jK4#?&abWb0^nX=cl|q8*_Gg&Oa8ldeig2_HMptBi(Z3XV{_X?=~+;ZOeZ= z<)c!L;CrUuPKKt7{*~tZVBCKxGo#B)X#O_qd!0S{T=@z+wZF!zMyb8k*t0ZpmX5@> zg&&(9H`p;9w@98nP4%XvYVM6EZ4S+1Q!c4a3fk+eP`-NaD#s#oL(^ZUV$=RNy-~fr z`_#KuSB=y44>n45CC!rDb1~)fv~}q!_XM~0fRm;1lGPhA4pj_7g)7a}O54J6l-nvmF?!CZN$tJg~M*jLKfg9#EG~Ts5uBopj zQp6lo*YLeoSo8ApwTf4TFE8D;Ol!K#^4-@@ialH#cX8vdSF3Hlo;e)-v|{1Dq=_B} zd=?%tjDP;&^^N&UidKAM%{XVxXZ7Vr=;RG|&VFw=X=*nt;On-t)4J^}Q

    i<9a_?QS*P9zb{2I-_@(c8=B!>*Zjp53?ktt8SvE!$ z?((^sb+gw@f1A50_4S_AnVF%RN(^Uxo zj0~P7`r^|LX3Tjf*YRfCUFOwmvfoT(nIijO?%(Mp|F4Hd-mbkbqxbsAmzUayCfBdO zlz(oYl?`LR(|aMdrtIQ0&YH~Fm0S}h`wPu5WZtt@-h765*wJIZ_Z2S?2-;lyCNEjd zUt<6BDV&Z1nwK3eOC?4%mQ7{pD?9V}ibzGoh4Oi`E(M#Iv;6asvg~{PAmdpO*FB}p zY8E^9ynL8xyX@10KS8E#Ev;UpbGPG@TCLGcJ33VIgPerrb2{ zN_MHwt&zFb?22#xH9s)DQ*&MK`=el$dHQ+{`CqN_{PQKFLgtz&^zHRdWZd#W=6s?( zpWPw;8HyYqta-HGAIx8I@lT1+XVpnwPA#$bJ12j#F4b*VYQ4NZEBv5AkKd=l8#kG| z554OB?k8R~cTV=N$!bxP%U+*JW}BNZPh~Ri%-3NK-#Pv6DXMRby;E{&=H#FxuP1I2 zZF;>ez0;ns#<;srJwBNs`Ig=MdmV&eZ1T&W7AI>S@@qb=w|sTw`EE)5 zYcjPiLBDpGUEr*L<ZibOs&&GR?dIYmS$YVFlC#nqSAx7u%z z{k`>#{G>U2^Pc>BY5(I~-QwkMZA)$hC;ptA*zBcqW?{G4`|C;LWxkzI{NfSsz;o@E?c>)j$#mn5B?$fXpexM+n|lC}Ejh)03f zOl!(cSkl=38Gc|!y zro-+Hw+^q$clHzyp0#AvhA) zusy^XFgn;rQV&k7tUR$b>%*nIUQ$4p*Ff z(6DFKvO~)zZwL(&jl0H^vT)hwRa`ptDN)A{y_%Tndo`iX$9Pk8V`=7#4Ln<>ER$rK zV0cZ(Q`2*bXa%qNv|RB9j#YgRgCDpaSdkbjwclE$2)N7rwiyp(s@ZoPtJ zRe>_AbpaD|*{-wg;FcD)dTb}2xVG_%!G#M<^BOAZ)ux-7Mr0}|EK1{L*>R*<#USbI zE-w33n;4D6S+_JDY*A21aMqA|6YJ;X@726@)fQ>4xR%DV96`)a1m8smrbHia;?(Dm zifc@to!Hr}P{`_-+uquB@Sx4RNh?IncseZaXnyEe5h)bZrJ!lW#l-tm{>BtG@2*!R zvsJVWf*k|vU3Y!p74=XQEaVRIc^JBF>Oz)^UWKI&^Ce89A~$hHbV+_U-tx*N$z#D} zmPt4HLb{z&j9+N>vO69!b6%~+v4^E-g}?PFerMNLt2IS6(ix*W%L#a;a=}`!urOICcbTr2e&lEO;2GI)ihyp zFO}PO{NSY)`9$4ApIYjDTQ8bg>D2~IT$LrTvRPEw#kncfLTsAyyTE{gBf6JaV`^mf z^<59R?4&Irl;QrME<7Rruv?PU@kg2+9nYqn+VbcclW)rnaUR}p@;96}x`pH}Vp5yc zQ)QE-zNp{a#gXx}>=TX|*<5;+Gfd`gUbSq2C)3I!+xo6v+~ZWOc7*B_Z>Dxn$RaCJ+>X1P;5HuX8LQ5i;43ey7ihL_CFA{FjmB%uv=k~!o`aw!lJy_8ye5ET{`fO z^`I70JZsYA*9MLonk+-TH5I;ww$|s$XeX|WU%+Adx;bsZ&PA&y^-Qz+Ap1tzv2!ca z=90*U`z!v+nKTQqGy?8-oA|zL?b8ciBg)d=cWkRn_S5=A z&up7nD}A&*R0KCa87I$Z1NX^1Ra)l=VbTf1R8rMr=2jJm3*gL?$Yv|uZmXQk}1|W(e|${ zKhbUdsReqhcXBpd5M0K(UHXrjsLFaqKRrXv)n?624Np0jDKN2Lbj~t4E*G@b(#@&z z#M>3CL`(z|Pc~dJPqDQ7Ds?u2>%b+3Vr9RHQfJ>duQEHXsl;dM%4Dc-&i$Nuu^a1A z?>^}ZWzVnXPuJmQb*i5q#`w@PuG==r-=H#h5=&fSp%$PTl>?HUg2Ccull# z7B(a%znHa*Tj{r(%c6w+4STw_Ht8}k`Aq%#!y@6{o}?2AcaI%AxMEL-PqH;j%i5BN z)d~usoH^nKRR^ZJocCL}x6vfwM)Q{ECI)w1LJb638&y|-nA8)YIAcYq`sw^Rk z+)WD}ADVtph<$UwM4oNGBT^)OymK*jInUN7u)%%ujlz)ByqxY04(HY-UoB+0`7`e1 z-2#78?h}Fs!lnx5gdHgHYV72>cYOQZP%Hlzc@s9jyrI9q#F4paq2KkLYm}Cs_%*3? z;&IW#X4h-{d@g9Nc_Gh#U%dCdws`&2w4E1rbRUosI`HZDw3rmXE!-&LhEY@0tYwXB*Pn`7v-kY;oA)1O z$K*?TF8$=Z_1J#H&ofNd@%>}j7Fd!sZ|ae3satFkQxv_F{;!>Gap+;jCZW|1Y6m7N z2-YVrj55~9j&!eXYr0-<|4h*L$h=h(pE3ty5MEovKLmF@@F`bt-X71GbAs0|M6VbG~Np$Zx?>N zfA!p@S<6x{K6oO!;e}<4-=<~Vzqa3tF-h@#5Nvg${+)!c3tvy-{X@5oOURop^|H!e z@#KI6f1~Lg`wFi0-iw_2+F0cd3eC)&x^>Db53Nr34mroiPk!vX<(jN`&$JREhFVJ4f{`g{H#Kffr}EVN!|RUhU4`}Nt&|0-NM)P;I4XZP$C4NkZ^yO707 z&i9q!UbUnoo)`7Yk8hDGJ9f8yuJT&7PgZV$lDmX1XRRrf2+nSnO2|3+BI)!B)4h>x z0!>;wj+-o<_-R(ekBAd}9a(aWd4XSQLwJr(GL3UEnJsunVNvPf2^|J~E?c-pwVDU~PF>p{tCG2T(&l~n?eA~8&d6!|bKf_3`qG&70c(Y} z*Z*zNJ#~-qzL()n_77~a&utj3#A9ZEuJR2G+|6_FWQxhrDZCe_$jshu92PY(HTrbJ z0^zG$R6jT6yzFXP{$g4}hh%g?eahWwxzSr3Y7SjCm}#q?@YnOgybAv{QsTePFOt$; z_3hWZkIK8=-T&_-wv*><=yHcId$WxDYk&QnS-9}ROf&DfJ9?g3_-(v@=2y+V^t8YB zfBRNDa+JR6ykx}cw%26NmigyiUtR6U^T^9En%61SXmZ#}^{(vI&Ka-cxtr<^Y**E& zXKUO!A^EC8%L*wLUCt*L=G@RwxMReAME~-YEi=0A9O9ZPx;}ZHbWkeyggSwp%zs z#>Bm-Yqm%lFaK%_gU+>?O7WZXJ$d&(xl|vzkiA}0%gbWs5*@eB7Zbb>8vM5LE$m;d z_57K3%bl>0S;p@Zr(IVIv7c&?qT|TBZAJX$Nw4`rzXm6`hRmEGVy?J*yGxJSrkukp z_kVizr5seR-pwg0FB0kRR&{H=si*wv9}0${9E%@G?_KAb8K=0lWRa7!?}`r$&mxRw zW&7%$x*0R8{&n|8I;mstg*j1t4=$-Ew_TYvXPfHulLa50j4sdmmTkF-Kj1{;%6K8kS#d`<-&qu$mUWu#9`8-gUj2s)JUJ~Dwra4m zg&s;2*y?*w-OS@rwDWllr(+>G&JSD<2I@*OKlbr7OuRblqf3coIb+9$hfMLRh9Qq; z30xI+Ua1l~xlv~FPrbSY^)=nb7mm&pjMj6UrdD#+{c-${`csMA&1!X#`}YLA`Ta}1 z?bY{Fj-g^l^}n)Kp868Xv*Gdfn(GOEb1%)ayA`m0Tkn1U@YT(h%`0?+R&QAz!hL3C z@3W513v=ue_QlAJYt>MA|5zBX%w?oS!&5y_@>MC)Nc{*Wsfbl zyotExo269ICO36YNB^PbU$ky8cs|3|p{ztx zaph7mwNjp&6Mr+zWVvv1R_2eD4;1qQ)Frdn)z!~-hI^RAnuQTX4!>`|cqU}M zq=#pL#(v@T+L?U&*5wMZCUl$>2-qKgx^S`BBW2^QbGhfm+Y3EBKdDvySD0ko>0P!J z&z@f|UB1*tn*X1Km(iKC@2?lhtl<53Lhym*&I#YM(|^}@q#I^OIqZly`ZkTh-tEw; zXKs^M&ob}*)y!14Hb?M7cSo1aJtnoFmiL!Y>{AY5u4n5Mx9HtpCchBlk-V%ShaEaWeB`y`&BG-M+pBBhY?UgYxcv&eGRX?$} zZEC|2w@C)aHpHLaxJYcx5|B)Vr>M_UurFaXk66mue$B+b-73p> zgBG3F=lXbdx=#L8#dPwH`nriS-(8+*&$E~z_K!_1Y;mAk$*M_`A$9w&JwCo5K+Vwd zR7!?gemc+90NINrmn0jvt0?L+zBDq@=c?ay*t*JX%2Gx5nJGG-G`XCcjY6w${ts9d zrE&SdvDy7?Cu*3cbS}A*Cv{5Yio?t$Q3}G%cDxKmE14U7COdrH;UY3E$=!e9m&N<` z)qhtPT&E&^GNjj!dF!k;ZO^|dEUfH%)8r-SK+3pGz_*giUghF(0Esm6m66;F}K?_9X|K815cy^HXtb za#5BPdh$Jc)-RDZ9?qaGb@xPhLr*3i^f7p|(@alzxm%#7`FO%-VuTTco^ z+cG$Na%9Lo*~e{f!uVujPl`hS{q;{R0@$AfDo2zEU0s~;boZAu%XywpnO(aoN?zCp zp1sA=;4U_q(WY+yw8w6?4eq@R7Y!q)KbW`fY1{Wpjy8fljDd33^G`gsWMV5em3usK zYRjE~sL9e>4dhIn>h07gy`Jd8;mRQWhwWL4+KvEDvqkH**klh(VtIA(YSla+&;q@M zW>*%w6+G9oJ27*6jP%ThpdB!l91Q--UHYXqVxJiKW_}Tn?Y}I||LaAS(S_shuUE~H z6nUYn!d`3Cws7{ebu*_ao+@$+kU12!r|#udbrN_^720u7CNjt6g8{%Qu#xn<=aizxOb`=zU$rf zJwN$x)Z`n693H6~{Qtj8w&I?q^d_Na$B{YlelvSnPl+G+wvy$f<)R<1=JKu=Od0D% zjIOlYcF290E5O`(g@b3V$gzlp51nQ7|0s6oCOXT^n9cm<$X?D56B1R7KmM)LJ>FgQ zA)sZJpQ0jP;v+t#8H+4}thw$R)g~}i8l4Ey;xtg&U?r5<3Chb$^xQ-gR~RpTqj_AK3TyfasRZ(PPr`}-5)OP)nY9vcyTuAy7F|^7iZraqzL}cHQ{QB z3kb?zX&QRuL4bmtCD)YcYb03}>ct){)w?ILiaYIZ{5N}%6=GZ_8yW=;h@T8lIQU?8 zE0d(DgTh`hjuaK9#$R#zla&NAtUNn=ZnQj37gH%;{i)T&x8iV0!iU<*mbQZQ=Vw?J zOlUEc6Y8|=G@m8Krt*cg_1J~iMiq&AJ5<~nWoDgK9}~o6I|Hkdk6m!GV`x!wZ;+7})>rT` z`Qpp0@ygjP$xC3eC3D^WG|l+r69US*R>HIWg1mmPCke9uso0@$Uf5SxYPb2#0vk?^ zH7ZY9F72AranLi0Wu~8^_{j^$c#PeDU$38hV@c}01ZOp&1+EVMww_6AH^h5ivSky? ze8bw%bo`Km;~W92#0vHsDSfO`e0-gnh8J7+Zirt!aUY-A64!!PXFhOcmz-)cJTW6r z)oS|3!-apdkIgf_VO{NcKrztk8Q1T>QN5~PHz?{d1s%VUcd_;D0j68Uwepq^96NW) z$lY1uk#FOnqUE`+tMzYGuezzB(q4OgAFhB6$9WtlwjVp}l;m_)VcW7a2?o)mB0u-A zx)m~qxEY&m!@Zl>JUL67uFSGZ3`m$TQHFc^L}^yVdL55TyDLgpY*_G5|F^tY2s5{l zP@|aVBp+|h*t|cw1`=DIev5t?F>&$vW%`yU`sZ-o-r90Id4s;6wPeKJHTLmqD)#Q! zcc{%O$=frtv!vw4`kZep{c#!3Hi@kJ@Mw`HpT?Jz--|32KTK|%`kI?ZzHnh9PVTh!Am zx6e)5w!z>|)sr~}@}BY#Hz+?ye#Y5&mZXi#%c`qZL5XT*-HTrW&G^ktEnvFt3f zsXp>)Qg_~`eENJLTkzrAdalCBg*_h)6W>hi7X8(oq?|0gaHUKRo1uT<;~O5%|K;jc zSSvnE;(46ty7Q>VEnYtV_P^CqPvTNl^NnA|3p%PctPJM6Jn!OZR+U2rWgYTr7RsAv z$@xt^bWY`?WLgOKJKvv^jU_8oRMyN-IJG$DK-|CEwfinDoTTciCG@kO=Xy%l;_E%h z7qj}jSF`>4pnNP|=+kXMA;~N0JvH*PeruUrtY5tJt@00xyAgIf1a1`md7$8>A@x@B zNz>w^H7_Q07XcZ3MZad%1F*rTfzrg-!ltj$o6i&Wmy~jt=J}oA0vOY9IFp z7;i0An)b4^e$h+6|4bK|v)4AuFq|uFzHfbS0(1Hj;~F3JPb+6nx0>qb`$k9W-$ef( zm01&`bEMat%f6LyD12#^*w)(OwN};_R!5lVb{;%)dY2m4wu8}|a+bJ8`ekR{3{tr) zP-1%a^rR!)v)-7TOYqw&@s5^!;#jAh&M*D z5{|A{^|wYeO^9i~7pJgGO0L1Z|H&ogmr|S+_8-;ng`|ouU%xL%ruw{HU9C<>)RLJB zrvhyQ)SurrvXBweJsNm%vi~AZ*{U^tE2EpE*>_&pcPJ(x#JBZ?aJ5d#t;E0H0bE~% z*e%bNy%3GrU*O#}yGe0+y`kxWC963uv#}gJwUP6eVU+rFR8OS*JSo@l#w&1#q_b>OrLlOoqfw&*D_x*fCErcF4Y6Y|z{lVO{< zQHR#IKQ~ynTse{TA=k@jje(BQFFwDHxG9|vAG*93x~#fF@yX;<>lw}(u6)l_UpFg9 zgVFGD$5#QphYC*^j(fh1-R%EM^pLqdueZS5V=e`5)9V`7?E5Ko^QliBUp;$3clVl^ zAC}py?D744;DSJz*vsV`cbQo6smtpWS=~6X!LW0_!0EZ(`ijpJS3dgD%<}7_Fp7*2R$Y;*njDUtid3sSqBk|)+Lbgx*ddF!=`yt-7a@t*?)A_9(_@m8r` zGS`xlEgC*6rQL|z!NlBkVM*e@RUA#8O8Tu5b978Ehbw%SQ;BOmBKQJ)GyX#WU`o0?~`Y3|nm_MCGoD^7rg9xYNM>?h)%%K8tQu$?lx5W%8!}+3o&}^(`lOW}f6>3tMu- zJAupPn@I5X8BvClSKRc_!8)_y$cDth&W z$)O;2lV#@9&aHo=zCHO&Oj7m60`;#UP1%nW9q-P#EarZ@NoeAlv%*awjw`ul$t-oc zXw}sfw4rB1XH`*RWIZ>Nn|04jsS9U6`(_%Mvl)J=oo~42yu&LC!w34DE@vn2^e?kD zPZ4aB7MyZ<*)hXeb9#6szqc`cp8jBC;u;3oI)iy4=2Igz-@LteU{U+QN*>`EZ>s99 zm_9XQ+<4Noc+(BdAWu!l_tT0W7aq9Mq6<3JMeSjY-7}$yPbJnFweP8yKjwY%{ccvl z8$EGC%`4j%E_Q5s@vADzf5q~zZZ9(b)~DqZpNaTdoq8-x+PC>^MCu0iLxo@4(=Gby z_Z-SGulgq}yT$kTUYC5n3(Oq$@7V;4cON>R){qxypfPRlp?0xF%mQkYCe69JaJ~2G znZGKRGr4+QQJY#Zbw~NB1b%P~yCdyCqOVmsf47k$ZwM0Vcq4m2jCyv^C`4m=9UJ@0u|ANrDz!zZ! z!p(BeE}U69WsTr2#|t(Sj?bCDQr5lIY0|wr9aEzf9lCF_mv$VKIkK1pkyr3zPDMhY&`s4H+7da<(-&FjN`FQapS3_Y2K^vd2(}^1o zKS&WioRj%cb(7M{q)(+*(UB*YoK&mnb-beDnmnQDplH~l4H7*U)<;h5U+QyU8`H{t zMB5^XSBWK@VX5A8$f+mg*q7LrV|Ps2P5BRtZ=R6fpnJSW z*M8-E*@){V%7qQ>lUp{_t}nQ9{YK}f?zX@Cl6(K&e-UZ!;;waHyEiu1gxCJ7@uY=J z+cHiItfsOxmoPH3{ z_+W;%&3A>ONlq*(fnxI(E!>OAuvGx&$PFc13Hou+vZ;!J*=G33H zDQosTH^GXgXBKK#C%)h~9_;IMx9HK@_PF#H|Jy{5EBzO--TALnAh7huQ{m$-YCeDD z)SN56F?5}6_vg1deCPC)GKG^3zxSLEzs-0!!nsXu<&SrITU8|-RO@Cq`I_CATkIyd z@a(!Tw;LyVZkYU`NYAt>qp*H)LgWSZuR*^{Yo?r@-=rL}SlFhi&AU?XYdh!vKR1;1 z^K5^Am{9-1=koz0ktJ-Bkes|AO5`=eY#8P*XJzETAXQ6bK#TA7W(^EP=%fvSb*a~wz*tbZg#;r;F_~Qy@^*KlOu{f#K7wyVQi~jcv(?raBzXxq43_>sq4Ce}?V_Z7%x{ zNXk#GSG-}qP{i{3jF1HNjAb)D`W?c9#BGVnR1#hE?T9k+)y3c`PM##G`ntb=+SaDbIVpnoAc> zn6~X5|JUH{oF*5XZaFQi?eO(-@>Y0o;mU()P8nYDUK;faXYAS5a%SiM@Js8`)TOJh zSM#$7zrC9A?2h&GIlt$=pX1HP`QT2;J#pvEJ&Khw`wS!(ceq4bNGz!9JIi%hGL=g+ zPH~OAj2}thvPa;Ag!@wgHhlgpRfeWosPn_;~7(tMebVA9`(K1|IrxODD`e zG)G{;7puirKa1jL+kCjla-tH9St<*{@xKd;aPh$Pv?K;tfa|? zlbRFnI!o-*DrAXd(Os{0AjSFTO@YJ3AB+x&F&Xy?xpJg!Qqr(`$LC(pA*CC6TwQ#7 zXp6zSylqmtCug6$ASC@W>@a7*-V94e&HP)-uCLfxI_10U`iO$Sz0cVE7Qe`mjGDB> zSWbTX+KZC{ZL~rI6)kzg&*=zq`*t4Bx!z-bqGE_-syLwJ|9^l#LFzwP~I71%P*F=+jsk_1?%`un;$9GzieEiI(M<3D(A0X7Vj4D z)N{o!wp=upDQ~q2coHCaQlnG(On~<#iN5KDrB{3Ok5;6_pS8Zf`TayA-FyG!Cay2c z@hk8=Ap1B%Sls(zexgUCPKL}>uh^fCE0wk_yv-u_?vt3EZkXnAV>>2c0ma!uE|+(B zGW}-x*kPV=*w|TFnyukS?b6O(6N$LP!6Lbj*z2ci7A#t@LSepfEQ{nHlgpEW@;jN` zGxZg01+SXdU;Dw9cF6Aa#yd_t)=LCV{SYoRU|4qHr=YEBaLLK$2lGUX-F8$t-T5qe zQLDMZT8_<5eiH)4J)k@vED%y5+pVOU^&%Lo{W!l?T9u%nm?HjfA%3>K?Czl0j zT?W#w9jdOl_m*s0Hy%kxn3OsG)XVj0Gud8$uEPnt_= z`d)Wiwd&Ur1>VCx6{U)t^%&cC45XHZA%6J;6P^vn)O=wbBf;UvZ_mv|@_MB$tPZY7eH&3GmvXbH;mhiHO&k z){`Oyl8>7%xrc0?q4Ql$>d2uU!)w}o*9uc5oLMBpR86~=7Y4-7;x#ose!5=iW3+)& zva0U4C8Y*e-j}&LY;yUp6!P?q@%-sAr%pyVn<1uU+`?>WTbAvy*0R3)R}SbWtRS&i2G! zNlCtjs=(LbGT#p!Ek2#j_w-p<+WEQm`A<)Oxpnw6v%g39icbxD&j~gCySXj+Lzd$~ zErt8*Znh?A{wv%*!TqNbuc_C}!dVh;#chun>}c1`zxU-q>-p-)^U?g#vetQboF|xX zmGWn{sb}9}>U`HRV*2v63VlZxFPOS3$UILXO?>k*>z4^7sWE$m4mWP#{25BrXPA`Bw_HA>(PRG=irk0_MKJ7ch%kK>#2OQ zec9oAs|;gL<^=tnHuHf^N$Q<*VfD6CO8xQ+lb25S3OfGZ!X?UU@#EgIy^9~4T{5&O zxe>9p?AF<b5U8}gYHFiRXET5I_e#`UextF=N3+WZU){A(QDf-T< zZ%fg(Ic{gu4wdHm#ay3R5$scPD-wXJIdj=l8@^_IRqbE=%e zQ{Trmf2NxJ+BW&9dC8r1SGKF?Mx`(CtxYMp#dar9sx_K3w{vTCZm0TNzy5N?)f2dS zHl9s!V3gf{ICO8N!LiBTmRz2|nJXz;U%{aKx9nt;xT>smUi#`kk6EA3+u}R-TlDGP z4YS#rH=4b=VQ-a}o^7+%cB0t|i+mx;A3G*$^zKtHa++Fbr6+GL|8wEb2(Idt*XryX zH#zs*ewc0F+Bm&z(bG8LzI$J9A2Zw^`nu%O&XCid8M$+IAH22X!j3JEb=(EBuFk5H zGL5c3Y4*S54qte&mvYj{Ro`x}{4z(NY>V3AzVi9==2x0*zVTAW)y7(OeQwigy>C^g z-HR-@2(|0_PT4E*@U&l;-RUXOOO^c;?>+Q6wL<%G#-^B4kNm^d7ft)pQFk*l_AuA7 z`Px#;<}Wm}Td3DHEA+uX(?eFeyCuw-U$2@jFYLy_BUs;6di5~-+@n@+9wt9~@$uE` zV5^u`{*oI~{&|yja4wr^diU$D`W{*FBj0bgsLF-Du9JS>&o4+n=Dto)A32z zb}gUXcgxZJiL-ueu>6z1@xh~d-`RicJ6_)io)){MYg($6YxSuubCT}OGCHHXuYcnu z_M+K|K687fM{YT|qoO`yaiMkIi*KhGlM|#btn54U$8P(z71O17?F;5MJ)X7i@lIF$ zd5dZcSFo>pEz%vg^2u$}#obbYd4fM3rzro~@g&~XFxYNi{{5MszJx!Lz9Ia7`}d>O z;n(WQ{%-vJKjWVH*Xj0uK3#j7UpqnD{=*&b^)Y<>e_q@=S^wv~Kfmpd^U?MD%fId0 zUGe8M>+@sD_J7{>mS=5lF27&(c%uBB&vWO;-~WAR>*VwE`G4=Psw?<>H2zH7z5jk+ z9^P85zHVFn-<$XCYQ7fR?|XjW^8I2dw;!{o+y6Lr{od&}yMJDoT7AF%>9v2$5B;xy z_CDTX*Yl;e+Sz{hOk}g)oi)Ed@9*ock^gVMudly?Oh)e6=@w}IcKi*k8jcS|Gr##E`O)`Xhr426H{B4_t$?epa1K&@b$W?4>$k+ z`F_8=Ds8f-+4n1FZmMf9_pfc*Z}{?W|MiY9|Dr$s&cC^A<^BJ+6$`IS->X}7ZINrY fm~PaTjEjq0yVc+<494kcr`_vVn6eyc>dK7SoDMU0paBNapzqvmBe(kw?&-Z-%CjI_i{XMDXi`;IZXJ>`p z|FbG%bPTX(j`u`UTm-D}0e_k^+v>bIvaxkbD&{1P!XlhX4U^$@n zY5#pwh6AS$3%@&ejIDyH+^Oo%{Syn12CVom%=dTxUY6FFyRmO3a`-!H>!)YCKl$Hh z`cEZ7gz0DgXMU#6jzypU%KsE^`@^fQU?9c7VD{iYU;4kFzy4SLv%ImV^=8f+o16c< z>=}bxM3{s(ZxV83JXjzhP_M@%)Ycft5tuDFVTFW<78~0kmjeM3J!fS*KM8DdJ+#)g zrNU;S+&mkWB#$Yg99l`ax;j0Z#2h;sCTJ+ID6t7|6cgPh)V%0@g9D2M)35WZJk-Pe z?HRSpcNia<#*o3f(dobgff-XfRu~B7a%#3Y9GDPb;KIV0=C z`j?Ym-M9|cPLR{{^I%fAB-M3q#R`cizS`zKaS6>dR$;el<+N6zMrDUX4iZdUf6klD zdGL6(E+fJBRkt3%5|B?F5H7CknWgKPhXih49K98^#W2o$;HyXC%tL;w%V zcBf`$jW&k=oi;)pB8|-lR@7f*6+EEmQ7@P+a*2yo&~4E{R$);=u~y{^^O_yPI1Ec< z8a+5Jz1n|SR864uFDI`H4~yf1jZGrLZ5>g~uC8kp5?F*pJefd@+$ zTfMOlOD3yhX9Q<+U;qb8)3GiMABkW3s}h(*c-UH%7i2UXY*7>t@nGR}Zg6pMkdWD{ z6C}bbz+ts@Lw)Zij>Z)o99E?qEG&G?jt38A{BRaX3dr7Ks4XZVlIzOS=%y+2Pk+@S zmN0=t?GhKk6ZX$q5jH6N#{ku|JPTy3MsT6G|;vXX|(GNSRgt}UqLA;!_Con0*4Tv zuxQ(&n+#n}oqxKu-rTog^7AN{UeaKF=`8o!w~8#kX0NUPEc1Ud@5B8$f2vi!_?sQ5 zzxm_)jQTJ0a~%F{`uKk0E&H1SKX=Rj_fz|Svh78@**{yJf0KDP{^x(h`1ka&{o#rK zPO`nxm##l2Epk>S!DRoRhfFFV5`50TlXQ7pI=H$Q)e5m5ZVmh|$nU?Sw|#=Shkyo$ zO2eVnhl@P46K8Zx72OrMiOKmwhf~MGnL=$_*pw2(4tZGAbMb8awSHE{-T%*bgoRC* zsIG8f%EVyT@2oRk%)jL#bpKAcVHQiRgVr7I8BYG3vyXm#`SkI>wEG(8(v6tAgS%3s zwmz>ow?pH!>%T+kcf3?wJP*fzn7mQ0Hmh@5<>8vh`)=PnmK^DDJ)PFZ^{wjWZQYVS&u2?tC>DLAraf(Ph`>}))0^^JeI2L$Tco-~ zfu;G{0g0sv@&6YsWM~#E;8m{J+{pQBw@r3(<=^&y8h;NR_fMHtrB>CH{G*;l>gH_T zR57(CPR6~uKmJM2c=lhQkL%{&`K>!Y*qR$ObN*MHE3)r{z1R1fkM`d<#MAaSHcDgJ zKAV?I?6vN8o&B+2aDLyBc(?A`|D0`BD%8BL7n%R^*!}3^BENQTDe)4z_1?1VXi$^u z9gdio;NaaluRbw0P2`9Pc6iHacT+9Rp#I>0qq`9Tmu~m3&;MF+Bp{7*!JB7cO;_}n zJ*+-(;z1Xq#JmIk_mA=11RrM-)QnU6c|ZHkVI6r-kHCjK#%t=| zSbE=-uiv`F?$;O2@7LCrK9YJ+{Pd!eK;mnTiHi)(Q%j99RCIO=+FLfInsr)fZ`|Oa zwlp{42(xxW#>MN$m_@B#h#z)YxOh%$bo5f?qk;}sYMl$eNA;(u>aiU1lli7NTkmRn z@uYP!<&!^WU)R3+Aw5*uMKACDrR?o;UwzH@o|y4Z=V)F1g1J-GAG=omwK8+cbiDdG zFy`yY_p=)J{9PgN`%dOBG1<#y)`xnZ3U(izUbyePs=TqzUi%hwF zY}(daI}QaMOFQ&(_L}7S&B>FWwyt#xWqNUYW%}hWYD*?{o|X7LUnnb}|LitBsigrH zXU<%V-h61CQEGY6Yxf;%l+UVb?e9stB{4rqJ2iejTkM7H1vZEG-phN@=iU3nuY9+= zK_tt(>MxNqS0DMHa5?dHWy5Xd%hwaXw{h6m`TV~9eXqmUa*Eq#gH*YG3{` zcKQBlvt?P$=|Ikd<$f0=-8OYS6&G6~KVi+OFC7^*ll(t(`Zv7Tu=1j8n%Z>ENH*On z?M|sxe;qb8F8*LWsrOTLo_wA24X)GY;-^29SsJ1L$f|70J0X^zuYD%1d+HWbSD0A& z%WSpM z@{HWmZ(N@3tf**XugEtia7nt!zdJjB+P-Cf#3wK(sy#gO$T^SThcSozkI&s(eoQit z(dUkTf7`2hlfEr6b=l3!rDJXrbXohd>JIM>=Fe4+PP>&*AGC#)w``7mme-xU3Y~p< zKDUH++A110gfGjs`}ptq!G5o^25kG(W|_S%d-r<7B#&3JcQu&>*}GO6tjQ|8E_H3s z0^5h_eUIk3-j#5Dm)9eCHNpCn))c)oV~mv?4-S7$yARJ)=SHUE}R&7saMx?IPDrsT(M zU47~I(#`2U42~t0E-^m)1aC2WKi-q%uzT8-wfFc{r1sPlc{bf*4w=KZ(y;!~eetbZ z{&dZ^zPvPJ*NKJCuHHMP+!-Ig-E2bLcb{8FVrzAFoG;(w=Ckiq$~=>@mXCiId}sdn zQ{?oQ-h9!7bv7G5Wt41{>Hg8C_I^iMcTr$>Y3IMB1FOEz7FOjxyJyY6ts!Uq%YJ)4 zQEQ*{G`{XkWZ1E}7Me4jEKS~=wy-Ar+MRk9wpl8XmWN8sjMi89?@$x-7B2a9 z7k1|VuZw=TcwNiv#A-*&$p^D@?e_gNW7^TYdHEZL`Q3Le&tds?g=t<5lUsnCsanC* zH_4^nCOzD=SLesS?BeLn+C3SvS|XyG7&jMm=Eo(3y?AuMeedq0i8Hg(ur{e#PdsdQ&5kTt8kZPlEApZcraJNErwT$seN{b>t6R674rJ@{H8#(=qR;xy*0`AdTTyfm;| z^>wjz&*E9@&lsKZGpcLXTlgLEW!UI^B3aeF=%1@lhRl)^eIGZP z&Cj>t%oD5?J?VTuqV!|^4TaN1vzhhE_WiotvGO5{E330%;jzeNS-CsU$i3(Mv@R|? zuV6_}#rp~0rH_TLzI6WnUg`40uV=1D&ban*WyUm%GkaYmY&TgPwvw;eW$|fRY53h4 z}|EZ-_^gp@2;tT&OL*} zzCt9oa8bhDS%1wd`fe?r8SwDa(YMv-*Oo+TFHTu!^0w^Xhgq7}I9Wvh=9*l8lBFx$ zII(|U|4+V?m-SPO_GwQ)ef^-~zdPQG_HpI&d(GNZF28*3*I)1IH;A8Qb$Q*&F>$yE|u89{C+Xp z1{~=;rcdz^YxyXqB#%Fp1${2#wO#> z7MmTP&R$bFez8rK-=F@Z(Y5S7fWYPP}cgxxBgD) zKRNlR+$E--)9>e9xBGuL>h!DV*rE+vA7)LdyBKtB-u{x}_!lzzwH6D%FWWvnAn;$# zp&Rzi%bio-+<3q6W-EtL%Bzp}7F{qq8Q65K?ArWq3lp^A!@X6uly>}9{Z05MxrWnBIdg% zhF|G-uUvV2?);QVVil{_i{$3DZ`yWoQ{_ajEv|IFRJd%5RaltUNqjjxmH1A_LSe`b3AiPY>& z?k{(Z)ArO>RJ^&k-PrP#yvp1cF+Xrw#Y4*jcjc*IACm=Oq18 z=6_RMmi7HxNJKFAZ`;lpvl7B@on`Bua4IM2a+dGA{Yl!Mm)KRR_UJ{H^?bfj{pwnP zn7_&7bN^YFi+}5$W}e%Unrb$U@%qtJ!-^Zc_fyU>harhKY%a9cL(=guh?TAc4iIp42(e8BjmUVr*U zN9(%NpX-EX#GUzfG1=r^$rE{R^Cw^GBPsFd_ixb&RG%)% zv+UH;+66l1I#Cmhw*QrgmQ5)7eI&WLEo!FoJEr?y`x~!qoA6ieU#<1RXM*qFt(bqc zFfMxSZ8JyiaP|E5TXC*+y1|P|8|H3Uk`%JMG5==LNtxXfzZLFJ+n={5>dg%6slq>J zT|6+o?CihR2zB*GxxV|a=*^U=kNXxs@88}ebwN9ipT4U9k6&DVGLUIeR+-h7%6Jyv z|6v=WPx!^H{_7DkS@hD$ilQ$zOW+Rw}je`S_@u+wH?aYLoZ5?|@|CHI*;n)stSSJkWU z-s~9kG?tI)uJOU$?}Nhcow+d2?_%1_?}mFI^#LRUE4+E&iFp~ zB&BRAap>#U$hf7|ijMquem%8xI{i~AmFv8jcm1lQ>}fjU_brT;Rb94CHr~8fZsz{? zJx6{&bGd8uXu^XwgNgY%>*oY>)jxQ0!-w^&z~f(co*w-Bb5B^-+;_(odikXrrLXKS~j!h>c+Wc^~OSipT1Y0dB4GL^{*ng;LHt)uX5ORlYb^8 zFST6imbCOb|DscWU;7$+8I}C9xf8Kut#XC^-NhS>D$3hhj;Yoc3(bi&Zk>BqL}|&k z>F3t>Yb>#Q_gSu_-}c_}7_OWT#=mQxrKRRaO|qVQ(Cfo&h3VhxpWHhdqp!j4%bv-( z>e~ykuz#N>9uk~3r;~Nzn+>yap61wW-1qnyYqj?3%VrBE_CN5xIGNAp`t+Dn7hm1p zkXZS4(T*+Rs`}X`{>Eo5qPKOk&KJJ(enP)*@3KkDc}?0so#$%{&we3vY=hawt<|1( zO>ZnqbC^G6*Wb~-skf2Mj5D>qjL%|P>aCcs5B!g9vk0Bjb!*?n`eY~T@Grk>Ps*-Z zz1ThCUUg7R_0Efsr{FUNB=VC&kDJa^F7hmcP)2qhQjaKl%w9?RxH`@ zqt+0nRlfr(-fgmB*>-BNsE)r@++^4NOEQ-1)^|3X{p-lO{3+$$igScpQv5$1mCcj8 zzx?Dq&63W834zx#ZJ%$bEL%TY`~KH&T(5U-?Jd(fWU>Eu?G%qvu)~Kg}0Ate}DTqYl+g0IF{3GGpl}R&V7E^$f;5*$cdpnaPjBw z=Y@oKT$-JKzrIt==Fw{IZvm^`9JwRA?_|?*gDdryFBv4Oyjk1P^0-o7))= z8JGLt3&@-ee|mj;{v<8mG~ZpjCw7HtO%~W2z}1j?`O1&jf*{LzKlj?)+-7t<=Yod1DAKjq+Wa--I zV08nAQ$H+@=vQQg--!?Sv2VJT+PBy5JGkxVTHj7r6Mwa$@Z5)plHfSkuFzvwjZU6n ztGjHU%(LuW-s5yjuV_Av)w@GheGCfx$|>;q#EiWuuk|=DuFi?|p376VY-w)(ZbdN> z(;fTYTq*asqpars|HTfQ6z$jbm0SrudE3JjwyaFkn&~zvcxgY=ho-%kK7{Pf2@hTL zIo#)$)Y~|b*}h_5_-}>S6v<82l$-l8H+@;3&(+pXD<33$zj=yBpDEfR!eRPe&HrP>BhU)>P7B*HKyexr$4yLZd_lT zHmP4^i9KVlNnzhIySa;kULQ^~nfCY8`sLckGgrL)I*&(E=Srsc{V9|0RCJx*cqitn zt8`gqPEoIYiDqri=hU^0t;b*TbUQ@c_HLDGx3M$qIaBWR()Cn+$AgP6cW?Zfsk->b z-}w&VYqk|%zWS88JAAc|ZN!Ik?qIX~%R;VSssFk#FM=)6J^tk*krU0Y9DDrNt*kCH zztt`i@yN+aX4)-f(^uE5zJIO^YLolNB`G3t^uW64HaEr1&lQr=_#Rwc5uWHT9p5QG zYf>9G`;;HsJqw@hwcRVTsPx9U{`{}`TjxrrX~v#9SnJE_R_Cb~@`Z2Btj{y&PMDf) zc-~ZO7hi9EW{$_Xh@4L^|5(gQyZ6EE*_`65n&JFX3Q2xE7bLzsdHS|_tFrrdzE_tn z9dfqgE8jjp`}6Y`SG3Lu&9N}FIIjIA+~?QMaLK89KTKyc)E3-0b8L4VXGW%-;fB9! zyq12$O-$_dmz4ocTH|Er`ju(#orL z^Ri~sE5Bw-KiE~D4 zeX``pyD5LoyMn*2XqnU+e@}?x&4qy34_Y;E$e&|5EqnjY`@AJS?>6$(&g_tQ_3!J8 z+%tz}?A`m{fA62evtBAj$MJA|Yuxj9`k&5|)9wq-zyE#yjJk{`_mkeAWUZ@@;WVFD ze>nEFCBsAs&ZQsQIOFzo+^smJw%2eEzgN+H)}vzl9C`a2e@qh=IhrBEZ#3o1J=*}~ zKdx7K@BehI(vHi1QTAe0dHZ3Ps=M`d|6ToC5^lt-5SjW&zqdCyZ@Pq9XL?nL&HIYmf+5PH^lu7-M8Ef)49Qo+9jN;P2*qkWphi~7P+l#k6o0HcQtIhUN`g8;>kQp!as_XE^0pE ze#F(q$9u^qKK0qo9L*Ay!^*EC()VqAaQ}rbUvi$uj~%jAJMO%aW?>O%;;2h$vvpMa zKclx}sql@Phw3>Vy!`Rh@~IwA?cOav^c3&bEL$bBTuG_^DRbJN?=xDJMCS)68}m+m zWVvs0Ti>_MKkt4vm}=8LvHI|N;|*tD&(LlAee_R=3dhssN26n}^d*&dbNfy;tI?A` zP`pK+G4S5x=yi*xxfUC*Wp9+4__?qts^ER!QmLC4uG#sV>RwW7T)#Q%<%Zp{IicGd z3U)uguqiA)-h$7x?SQszM|pffNwl=799n+=N zAsXr{i)}npH!qv9bk^&P^_NywZCGZ(v_?mxXL4`y^ribdr`9jvtvt4JmFO8uqs21r z_0xUMFZ=dpvR261^KYi8<5Cu zZ(4M>{avQL3cgE~;omb89?$xTA&%08N%KG^7 zOs?KDcSC>9LY_A_?)rz;t<#lYsCc*M{hM`9pX>Xn)}Ol0q5ACn>c1-wHT&`E`=)dqY&T(#DbJq3>iF-9RmJU9L4bq=&{IA?dA~E0l8~gM#ok_e$Pfg)pUbaD^Kjox*e4(l9<_Bh5*9v>t?|FIR(~pB+ zUag)}eaJkZw)^MatqeD}$gt)a>o2cdbANkwdCITfhBD_=;?}pv{oVGbUS-pkK84@A zRDM>zta|p^>rdRyJw^$!*~koW1t$ZMx<|h;qq=iXRVe!em$M5q$cw&I;iP&@HAKC@1R>EiF2;JF;!Rpdn`2JikHw_Hg`=a$RgqbojKzV<&%pI@J>Q~P{} zjOO(>CX0@pogTMAxPI1BgMU7EjxYZzFw1a4{mFIvyJF-u)tuG@f6-Wb>&DsjNt^C? z#_TmN?0$YWs?uG#`pZcZ`wi>vH%f%P$X%jkmfU!Hxw?+ZIe)3>OMfn3|FY>u$!inN z_|mHf_f@_+^jh%VBj3l{{2kQ`e@y9*SWuFj{vf^MJo_gl*?%v+Ty<^J>lF_qaZZsD zW4Y8-6LEU(_nPg-d5fH`IIX(n^6t^B9_y9PvtRVAlD#VHUUNAms&mp$v&4_A0xN_~ z1s6H~*L`rHRaStx(!ujcM$XDR2UOU8 z6sIl``Ro{a`?YCbzF*0XnQ0%c^sG;l&9Ak;cIb)Q&tL=7niQjpLgfCsgJ?8&Q1EyI(%5yOe&A} zJ~*}h^HXkycgoo(_+M@bbX?qj=t8_hf9b#U+`L8WWal+@gazHIDY+b$Yj1Jtv+maf zgVXlHr&fr3CdH?S*y|&@61(Z zc;h1Dq}|40ox;NO{lZUfyB~jVCC1}46 z$X6}S1&hiBtTOkiR@$!3X_KBGWpwK^U;L%D&JNj97R8xwvMzZRRW7-hbm-JpgIkq% zSXJcCAKamJlrwi#{f5t#xBeV759yYvwu{S<=-uIMA zo5lU6@3UWS&~WwN#h15_ytkGNUA2Vmx#`t&$M&wAV&rs&?fCsG8b{}cZwP3=75eI| z`N0G(CE3rhwv(>dmMh*DtO`>8%NA;G>YwF)T6Rjv4i4_w_y7L7SAJTxexmt2W5-v0 z`=w_2iY;pTqOvz&`IG~@jC?n$T7S0Ynf`CD3#W&{f?35zwtCa%q;ZHz)J~FpJzaMH z$L#Bm#DD586KG+a_T7BW$_0gP;)Ny0%jeG2x^&>9$V%SyH|5Qf1ItCXi?_V!77NHf z%U_%DE7-1oU0PJSuZQdh=R3cDyf{&R_R`7^rc>m7&q)L+Sa!#&Ot-txJfYq|kLOsf z-ZrL78OPMb4$U;1W(6JH=A4;PINTZx$cxEEnJM{{D?4-Ts@~ zr<|Ii@h7G|=jT2lNu7NPjj!X%)n2pJ#Q*cVdboa4{Y{DM4+DJm`98mY_L%FPsi&9Q zxe3nuWBc#e^24b;e-52oaf|0+p7xHZllNTzvv;nw#QX~yi?1Eq#d0f4;EDd*LyA{T zE*ng{^dRBJ>Zd1n7@h1_zxCQGu*j}DgW>zTm%IEg_v}8l{jAP)frZR5TBm&$^0@4B z$(VRSOZHZ#{j7P`^7YkwUFIu$6v{UIaLU?WX0Tqx?v3HEn#-myFH1hJTq1clVA9WE zM*cqimtWro2>xY1pfXp2Q8tL*c&}*H#;E7#CvTsB`tX7?|B@w2(p+_O&pbV|{AJMQ z$0wyYUw_-}8+j|rKZyCIUwZpeH``O1<9W_s?ptbAVxa0UUH$!`Gvi{ zFHSP}-#o$eKeO7dcq!+yzCtC>4JVGbpA_0$c0JMk@&2_t))n0NePhvo$IOtf>E$*5 zB8^ur-@f4j#|M6RJxITCOyG6ssny>@OPn{`zYp|n z@ZA3T=C6#i=70OTk1u{yKeaM+;T*Q>`$Q|3Nvx_{ykMzIK6K*fc=7VfVbycf%1*UOF1#tas-a}c(eHJg{#RTjV|>fj z=yE)NAFGm6TkMhR)V~BCqsp&fL$rm)pLt^DKLNU}}}j@k4Iz&8bCV>920w zz3zXmj4`>rZoP_U5R<+7GJ*YeJC^gA%xXMwzdLD^It6KdkAm_nmqD&y8g^W}eEwGdj(zmp?u%+@-5G?c|4u z0*P&_e?5A8rrIycy#6%fUH|mNFr%*e#@esDW*`61#(%(l{m=W}4{9>RPA%Lhzp7xR zNWbsL8DhQyc0&7wc5r69IIrb6wN`!Qtj!ONd6wIIzpFWu|982+wvVRF|G7!e)NaHH zt~nUBCB1h_cZ*-dgxNX|p8Y*_FiSdi)y8mn|1)b9Ppz4qRkJa5G&WtN1HnO?5~wP#!u$e5|9)u}9> zZFu6NOTfPPZQ^A#fvZm7O-AU&-GzDiH5S{S-f^q9 zTXkdGBG>tgKX15UQ53nhewo8IpKho0sn2x32CY5u?M?me>t_yzXt^6oF&?L5VYtaW|~pUIkp9u*$qd^5ImC3J(dL5Tmb&YX!IO z{k2YN_wyfhTa6!hozGpeQ738Do4(6z?e-^HCoXK6QanC_dx|?sg zvsU}OzS6UY52&|_1Ui+4%I}?b;qTj*x~`h*x%S6iQQ!4dFnDRZXN;-*ypWHt!}ct@ zysF~xl#EIC+80bNy)1Ie`}h3iT9rrjH}}5d49YnEe!|t4PtG#_`xGedTkFrddGF=| zC7Bx0t~2?@lY93oHu(iNNxgp0Y~;H4V(1jprYB0@Y*+BvmOPWz&8?jKcxUC@tM%T; z_APWyUM~Z^&{jJOAE^g4X{E!^; zx8q;kqtm}KgW~g|zdipIB6E9k`jcZ*na`K4TKW0ItG6tDzshdcdiZ}6w{=?R;$VZ`O22Nb1yubvs^?>*(z$!zbez|E9O?KGuI1k_Hz4o`{T^sBWLY)o66r} z7JF>?#y};B+e>}b;yLrqdhpFPkWKx$ivRa|pV+$hf2O8-zYvd`eUxFd@ZKQdDc^6O z3+CG@v5ko#^s}^-@Xm93a<`6IuMDe__?mrHSG#4BvDUL5*JD!+ChyV^o9+Bcz3e9U z?nnB$^{VqH*w^I;)h|1+ODOrKbm4`2A<5GUlfO>BeJ4a&dEG7HgEva6{!}edbXZs9 z{50D1Ytyk1t0(FQZ~fW#a``=vJ7Tk~P0v_`6qXwc9u=;V*|zcJi<2kbZ1%W+AUf(; z+``YQzZ&1v>rGp!D#TOgzw=ac;{|q=H~i8YZb?qxq7$#3vq;+bUmHJv{behaJrTNL za;5iOI~pj&W$ zjK{S{icC|LZSG%sUcDk;(Jq2baJ|ZjN~w-r_O~nlNHXLI*$6*VmDq4ZOUs6%y|4Xm z*pd&w%~sUe`>lN7%Fl3h{j}DrGGC0dXX)Rto~Gs1`{&X3^4Gs}dB49h4Z6Q8>-M}( zueN&0Eg_2aG2RnqtzY5G5XU83XLaD;xh+q#4{qLUs(GnXW^+T~{-i3Ve1FTje?NNnz?yvCiS_Obi|77HlYSbrwV(4_yK(BX z{P^W8(MCSU?AnfeJkC+J_o=6Om0#n++f})nE~j34A$9Zk8I2dy_y73nJnyt$&yuO? zs(V+qrf**Af6m(K=i508mSz3*KNkN=?bDLh`DL}+^6l2nytzp4((Ke(JJt*CpXv8y z+SSypkKS;<|9;vt{Ca)bvwnZpv&HjckLvBSoMY`Ee%eEGvAEQcotfqJ+S7dVpSsy4 zPQMf=^wlMx_-mev|ISML{mY)d5S5ygWOe#4cSi3E$Ka2jdiYz}ZfS-_M;Sij*v!MX zZQXMLrtsI?ntm5HpWANO$LsH9bn4$8>53;J?3>Jzwi_*LIx2jsX z*Es#XC%t#5A8R_so$_wmmB&UWCrf{?$(5;^_Q=zDv%{)89)?n`A3q)m6?17#{-=EQ z+Y?LX+_q@1{jax%m6))cuK3|v!*a2{>B)0jlM5%FU)^FJdtzH$Yks%)>B|voThlTd zm7R3HG{2iS?-~<}?z7!z&cB&0$ zf(_qXtJ~|N)$Mbuw>(b~Tzb_{vH#wt|I42mTFhVnW_sr2FS=eQJXDxf6BbkjxW=%o zQID*jVQ&!g`rnfb`vdFh+^-&a-+A!YDTew9a>f*bphr78eBR3YWy~c7?a3ed@R!+uGr+f0hf61M7cebM_`;MABmP=AyBeE60 zN`A@WeP5=zi#Kg?lUJyn{7;JyGnQ)4{rgGuSKJprwYBwvH!sNSs_Dy;7VeJKS{Ta8 zSfaf_>P!*Ws(ZGZr2mwC>$=@JKf>ACOU7#Z>ut~PtebRI|K7$gcE!`42QSFrPQUAD z+by%;wfoP|i4pdXWQzpS}pG9`l*7a{<&q^EL%SN z^r=s>?hOl`i|wdr{8qnSQfqf8!+qA5H$t{duU-`wq_X}YW5pty8CN(`y{r56Tdu@M zys%5&diqEFX0@vq0u#1~m{0nyY;NG|swn&7&!xa0+|JeO%Nch*YhlwqRXby~&-c?O zQ%`?h=Pk~D^T8f2pT7pyj<356=G+lvay|F)-xc##QzNE_H*fMAYnxtmtIwFSm9_Ju z<!^OGMWdPP5SWNwwFdHte6^k#jJ@wyg2j zU#^LLYC3lUB}HO*6L0&jyLI)-tApKY#mAHCQfg+|d#p9LY?Rc#8~**3?!qGiVedE1 z=B+8#v=`?NIcH(yw0oMC**?4f2b`ViId325oxEJ&{oIGMoo~<2jJUmi?m~If{RiJE zmlY&ebI;M*ez;ueE8n}+>s!||zN?-6TV%HZThB=+i%Vh^6X)q2;j*|TQjl1;=W^KD zFJJHPsNS-p(3^c)@V2cL7k*ZKe3Pwz%x6=3Ny@d{k2mk0wRpHiZtBI8F(;#6>CR5~ zm5(`6A0^)*y*Kdssv8ljjZN2wKFZpfbfW91m6B+L#%%HH0;hvSbRXV%z2>!I+=S(l zovG%P-|iM!XUD1^HVWPUW%}c56E=MDQdOJ@@dkbLQ-`o*a=r@0A)c{oSHPu`Taq+c;m;|5Ocmt;%&p@rBgk@?~#l zOBQfN$ojv%f8WQzBkPxF^;4}rO%>PmW`S82UavU}eYY_Dj6A&8cu{azsNbC#`bTFA z)jW9ovTOOWJKi&AYG+uq&d0A>|M{-5{8_b2)1pdW&4{kO73>?& z^?1>2g_;iYmdjrl<}a-eY}%@$__)&cxN72S)!>L%_fIcVi~R9)=|Q6)>#Mb|?F4+& zBNpZa^^2~lb>iUmzt6k=s@f8X$mK6=-`v{0ZpY8SIOTMuY|F4`6JP&Q>M@?CvvOVh zRE3$w*Z-b$zJ6xLS@w$}62`ePF%OkDa$3tJukt)-q44(6cKw>lOg5v?h4s%qiX5$Y z{ITI_W`E?(b&0#@uq5oizNU_8N5fAu+YR~U&0oyArEaa=7FgJtc=@LLjSoy-`hSA> z{FAOLoBT9SKei^Yt@riHFta;17Wyu^dR6W8!Ph?v-)LQa{723Bv&llvf3silo386S zm!%Sa?^D`tpk}XUkjGc0i^&bg z|9A`TjV%7~rYFAJag=l8JOPG^(d$DU1C^t)!)gY*7Y zu9Y^N=?`NqTi&?5Gv^n5+-&vtkH(^XHFjKApL6|umLYNC!3~!sACrC=+wGm|cKZ88 z|DJ}_dch;N*;{{4<9+VGJo21yYu-MCKL+3H?`OpQm{3u9D^4?bWwHCpH#S?!SFO7F zY0;bXH{uPNzpFDJ&Ul+%cUSDl{rd?L(t9_G@_Wo$@oq-aqr8kqCG$g5bLFhk?^Wg&0QysEc$)tQNAhbOuyPU5z}87NXZn=|C#c0_p-Y;Pw4++*lA|-%xR-+ ztMetD_hw=XizB|@HZqxeao*PZr`Z{wuM1CQ44q+iBi{1;V`eLrA0aKLm)mGQYN=D# zmJxnbyYTi?NO>GSGK{@-4wsi=n4 zJ=5v=YBYJ{WGS_1##b4>$?V+sL@mT;`0UgEc(Nw;)gJqn!jm<#zwgNx;x(#QzB~P; zYpAJX|JDeVj{D56Z67D!Y;yLDhJeCVL{8DaQ6zAb4~xU13DuLW%w_A}pM8CP-{LpRmWscP^;yaNed%VEroV6GG|lEj z`sUSDS(O{^TzKaY`|k%czNVemUHE0qd+lBc8;%#(p5INmBDinWmKDCM-}UdFw)^o) z?YXywA3JC-m{=IJV%F>PxeuDoYgHL3{c_Iyd+K1X^6SiUE7!EqfUQq4z zGX6q6-;uYozUtc8$U0c|>7_<$eCzI$<(R?oQ>Lu6>u*T>BN?vSuVy{*sx;UqmGSSL zXxqDs3EN7Z3a{TIGkZHz{K^`RX&a_){+YXfcWrE4v}A$}r_l1VUcu|{_H(ZHsEG@!NktYg9CubXs04O|x13{_I56|34O7^^m~V4R=>x7hXG;weG%s%JLUyRgWI3 zTK)F;=Gt#cx7R;RsGcoe^zg(!yRMtgod!DmJGbUZ{XDhV&TswS+HbEzzV2J%J&EJI zN_oul($>+3>Pj(fek zl==HfXz9Xx%gyJReA_C&>QwO@+t_)lgr`irWb;hZj4#Y;wdT3s(^&fw_v){;TyUgu z^5qB9E@tgJIHmS-+Jc?&zDIIC+Wwi-XcK)Xs(EXhPOkmE4R^0~w|@`**Hkgf>gdmB zWw#~=T8Y-T?R|A}=PTI*_b$g}1U)nJTIjiQlNNL8i;$SqxWpYPe-@w1Qu}hb!fj&k zg2?Nq7cQRDcdF}d(e*cPxu4Bbj?%kz&nQXc@my~62b`hnId!MrJ0r%iVBWk}Y%32g z-e11`%3Zg*ZcRgH{YhW?%U>R>uMJ+Yy_i7kKndyLx8OxK@L z)Y*DM^uR%h2lJ)3^&X3C`M&w4q~fNZJPn|Iu3>MawnjuY|8 zJvBb;HF^C-!#z%ct7Vs71K%d^fiCh5GH+|J-A8fd$jBjw|rNm56zEfbR@&34IFbDDp>bZVA8&ip)7Ed-&lBP?)yuyw-p;fA%Cj)u z&!$Ut?CQ7KOV*diwkq6NFT>xyHc7?$=GsEjhdCKreyi3A9J^_{*h9=vDmPg{=*;hw zhp#KGk}Xa%=o}QWVyS8VwOi4x&9qV@$@aWW<*#Umja3v{mZ(e!n>l z(|EtHvVRmhL0{R)chXXb~d!=K5j(gK>Jq3T9*1bEB}AK`})Dx@YG!G#AU3fPHoJqKmNt% zw93DnX8$LPLh|a)RPMSrN6_B>qJm=IT)*Q!cK`kE?a6jK;=9RRe3!a|&eK&3Bl4|p z`I|A_eU|oM*QXqhol`kzt1hRUKal-ZRcZC?M$lhxn9%7_c?G>KsN z@+BTp{WYfj%{ZSnVrBTK%Y-rBu6yG3@!?pfZxgz=w6KzCEhigmXxS%mnC>2SY| zd0RH=MVjgq)3B&3A5VUrlJ?roRygDnPmGqc*F3dfjV^X~R==1(e~#Fz`Lgq6;umbY zH}hno@ARm@JJic6e{+!x0{mS*f54e=}1k2|q3ElbR%KfpuJK?z z$0B|3<5a~O+gE4z=Erloet-7Y{z}jBikPm|!K*%8Jy_$t!$0L_$yOs-lh>zqMc(hP zjOTFqydcc?ctGFwblGOcN7jZL@9gN0S5HfS@=QHFwdT?n>+Kg`#{QXjcav+@gMitw zKK_2m-V0hi1#(0MJ7)(U6|B!ska%**b)xi^iM@$N{%^jj8F+Z*{cy{@a%S@L(D3Vx z{;|t$M82Hz=58d*sY~ZJ)pt*>-acho_ieVAJNt`ScV_!J+<9@kPIlqH6gU6deoNAy zEz4N%r?h=)y1~A;8XJ}_+ZJ^uh2`^)zbda6R~(EpnbF^uY2E%+J@V4mwAE{lMb|&A zofp^Y9`tsWljKnoNr%ok(zm-W&G>m|9pA*CCQC(M^e4&1mmP4tkm|;HHa*?G^^cZ(mNXznm)DYRu_ew8c5-&JfmM7e__yWID6{Up9f~89Y11l`G@PRgWp%*zgN3El>2#t zlyvsiX?*Hl!r={jS5BKdTl$pN`Iv4ezF#)~tG7R@(9lg(bCmKs`#jz|tmH>k)yZSa zW-NN@&(tfstp0tv>(^Z`j)j-U=~wvay7gvusXWoy*dfcJr=R>HKDAb6>-|ZZ#p-)2 zqqsi2TlBr^i=dzTf#-6*@utp?c;EfnFY)u3MB=Swr#I%_-UdOX{kfmzZg0!2PMcr8 z`M2%tv)fOW{eP()8*908oz-%!xvOQ%CYY?g8vA;UAG=V!Q=%Ee0p`ayyB_@O6jo*k z$nd!&<`zE~HzNxz@I))yTSK?)ycYN8CZ{4{`i?)22>E|);mfwjZnx0w4e5qVr$Gtb& zx0*i|UDWBzJa_-&(>?V}YUfT|>^;RlxnIIQDOttXK4$s$(m9(psh_@~p8hT~gh^9l zWy&faky`#0R=w-fm}A)%x~87WEwhh(@_TJP6SJ|ha;weJGb(FkSbOKJXvzKE=zF;I zXycE_&pXm1nTe-rp}|^ivXK;9B_4G(9aNAu*#bF+F8j#LOj=4DLU^VfxAb%yhvGd-(Wk4X;Nk zXl{PHp*`S?-?{UvPy2bEJFzm*-(&vG%Uvt;o+#!i zIj$}1x}PYo=@@PM^W4F2dqc!8RZghacb%@kU{*<8->jGeCV@L+ime}?e)`D#%Jf;> zDyBA9le`#Bq@O+3VEwC~B4i?x{Me|->@+<^aPNpC8>* z|JS=^`b@IQ3#)VTnwD2LDeYKI|3|&k%ZnoxI9&T_>i>0-uG#dfGV%-!EbMWM-`#K5 zSdpSVJ>#X;GL`A6FPEpPOjl3keOWdCF&gec?FB5cE%}^cvH@ z^-Hwnl(<$ea;cBJ?Re5Z(PsOJhj)&=xxXpn0fWZZ`bM!o_V@1oPpPqtjAG{BcKxSz z$G? ze7a)dEgCkO%sBkN+{O0aj*B}htDc5)czVTaygf9hZmP6+o8pqb{pBSolejvndiO_1 zg@qir^ZmTV@|*Q+w^1NB!lz9D^4cnbwUJu>%JUUOnRaOXgOxWm8hSM`G8Tc=#So3nM+wuP3{>z}?<)?d3N zw*T9az5wJbrP=_?N-flcz zq3Oj?W}l#SuS|ASKQ4D;+`s+X1GD-S;-)t>ny-3EGWYLSx+ec5dJ<3C_s2i)$nNlx zd3H1*KsOrxyxpZr#$jJ@g-&dZyeklH}tdq>5H~-gqu^l-Yx~r``t&3Ci zD^rtW*z@;gix+Y%nKpBd=wX93OIDs*6epkIUZW*fH*LQA*BPmQ6eA)VR~-FR_gAuj zVMe`3(B=QRX;Y-%9*m#8cjBxqwQ;k1&)u05Uw_Ahfk*3rMp*OT_-7m6^?wL_XCT0q zzdZlEp|GyMyF{+4^1nIjUwvCKk4?>uK_Ot`f|&-3dl!j2A8>lMXI;^hJ~?pX4J02s+IqLjO{lj`!- zMGChV8(p5f<&tszrQ}N*oO}9J?I7lP{%6ozZ`&(ZrMI#+$SaF#xBWCPkmL-9#5eX+R(~urc(vV#Vk@2 zLv{q{h^k3@{mWoEyt-7UY2Et=x8KEwwB0z)vEb!`7hmp+&pht4y8mVIu3vxOt(V;t zb?Wu*hp#V-?=5giy%2su$lvMO%p2wPe>iTj@2S6Qzq$PA!%tf>HoabRz{txpb7s_m zN#{iCoBzEux&L9?_QG9ju77@TW~PhTi~sRcbCWpZMH>HmFHim=bh-P#J+*jB8X zvux?4`pGl<=gprvk8S;wuUbLBZAwi~vu*L*R(fi2SMcX66I=Kf>^uQVj6 z@|>8uvd}W8ptQ8sDxX__^tjiGRi~XXSo``+I;Yo{;#F*tbEo;bcpB>m8gqKBb^asv zJ3#Z+uZ#I=+rH17HR0Xd8pByK32)jjEMvT<+#VkH$v!%2x4owD#t-)!etc)plu4EJ zWs_a0uBR&~yCLc9v*dcYjS9ti|97w-JiK6zFUOyiiCYewczJo!?d-(+3tyTjiXN~} zRbsxJ*&n!9Jp9~T<|~^X_c`Y57Ie2_F*{-ACiSA!`pvu$$N0nqmR*+jd<);Louav- zY+rriMu93>COcJ&_u8A^BpwM_;Ceo!;}nPD!uZb9Q)A`_?!KDId%s)1x?W~|$}2XX z`N3NZxf4E|_$gC;x=^Nots#s(?3L?>6NSBV+qe=NIA_)_>?xXmZSQ0mp>iLHSL>OwsPOLPSyrrBT_52c_`<=JT z{o?|eLxj6@_Cy@HJXk$yIHL=o3<)0Ca>DuzFtdi?S0d&A=z8yZPI*S?y}0t z730ai{i1dH+;0=tv+kHJcv4^btwqG&sTF^D?7wUJf@2K+2l9yYhd*PIh z>WsK+m&KRnNF3Mhb`MOGE&IGB>F&yTvj0s~jU)eVjhoT-tn9_YA6B0wKgpT)+WN=* z%3YuKI_J>#uTo*M^$|OiQ}@ohapT@M%k{3RwP9C3>zi&1-VqbGO2any@;Qrx@5}UW zhc8&4ue~p4cZG$-RfSU5=0%_SXa5LXIZJ=7#MQssZB1w2xn^$FR#UmKpy0=L#zKeb zCK<}Ns|8=IyH)6aY4t6GKl$ZzlmDt7jtbvVRG<7|PyRmhZDt9Z<#+?@L!+;mTJu!C zO!{y$sP=D87~AuL{QR$9>+kdYjj2tpzi;uQdS74vzIk?gj^wF(nOC_#;d!)Q%BD9z zciP=^zy2NIyQ$l$6&`+H=lnwdtj{@LU+4HYPc&DbWF9wb_c}eh7uzS+eJ>5Nj(PCy z$iv8I<`T;@zYCo==6!9n=!=h}X=r`aIrE>ar{Y4TBE77S+ox~IxE@e{Grea11o5l! zqE<>TL(BQySCm=$dg;B}pm@g6rTM9u;*%H2C)qhQ56@_qI90ygRy@eJbe`{|bsDlK zI(*Vamo5ER{)Me%viGGNIq!h?Uu}7Bx=uVbZF9%Exa#xTSI%ag_$gC%?m+L4yDy%+ zum5mkvH0{y=Z~p0-&>pVWYcG{{R?LCa2|fr8J@8+#(u}k?n9T)>${ll^1W~D=Js>* z%Ska!ANQ+H-yUxAqNa4m!@lVscym}M@l5)#&*CBzw}PxTzuL^Kbg^`*Kd1+m~%ZTs@Pk^&~EloxAtfPQMjx9DY4! zpK^jhX3F{PHL<=u=~Cyz7&{_3ge7jWE=Wu8U$shYPven-&jouX#3N9@XZ7cK`)FA{3^n#CVb{4KXoRN0&1 z#;2J_e@5!K91pAKSr#HCX*4NmX@&hfe(&e8510LIe0KiO+)K?~pHGVU{Fz;M-)e#9 zX2a7@G;X~JU2*mA89t*8g1#Fj+^zmw<~kwT#qQk--&`Gup!jZA+eqG@2@g^aJA}GV zW!>d6IWlq8-up#73xl@zo;&%zHBNt{Cab_guiqEFCca}juuCN4(31K+;a%E_W^ani ztF7lBogpti*Q)N_CFhfU4vH4X8GdfD-*>%>+uB+wF?&nts(KNod0To`XJ2ykSNXqs zh1Khyx%^j`UthEFd{5@||GyS}?JE1t=zd0Ft9X$W&$V^eJWF)t8kQgHul-^h!jqO-;M<>|e!>Z+{mAe}6nF$|Xd! zK5jvD`r&u^$3C*miOXp?dikj}pTP}@n1-GA6_zjLcM)7WtIb&Zf}z~wo0GI`3>#;z zFWZsQSJtwbX{|=it1{V=|6)@5+*uDlF=qeNXY{xjeOB7<=LeZ*cXWwb-HcecpXz%woYcu1ECw;FUoR8WcWhK?K!S4H%d1XGL zj!&#Y6OXSG?W*S%x_C|cn-s?lkBKL&Rxx;Oolso$mtB?Nj8LJZRC#R4`cQxNR`G^c z>i*l55_WFeSR!=puy~Lem%6<9&0||GYQ0KIap^72nYvi)9rrQyKPe&WBb@3I}6`(<@#J`3MlQYuig2*sv?%1Yv-#^ zd?jx;TK)z0&Ryy6EWN*l^?dwIg zR!DI8MjEx(mwHF}&ssRc!Nbz3x}fy$+sYfOo420YcWTY@f~<`(mfOuL6o1*C;w_QQ zjqJL!+W#N_inrgT_bz@fDx55_((KkOMfX+@hx+QWsPZ!=^_#YG#66Pxz5R4a{i!9h z&Wj#?ctrow*GEQ4QW0S<^uNo;=$l>JxK#Oi?0UNboter#uEP5|q<-06uv)t5i&4?< znW=TRHk3U%eJ$+m$`}TX*ZhmrwN@T*^eu2cR7fMV2%r@&@xYgv+%=D{on#wCO72 z^+~5ZYwp`HFSxCtUm}&ovm`}p=FRh(6HlJ{w=c~h_@blWvEZjS8+rPseK!qSY^PCD zk+OHwg^>D7RYm3;_jPx?zMkb`T%&NI=uy&6{jB$0VoxIuZNL(at*~5ve%^Pzp4EPT`x+zuZ4RDMFMYdR(A$c| z`mEJ)&sR?*?`8Vm6n0`2T~zw|&Ac_*$VC{}(A$MpZnEHaHM| zQ=^|NtjE3o?b7|#FAp42$WoiiY@Ea9R+9eUlw9q)(&=@=59ho+DYc!cB*XunKvcmK zyR$K`PVay9@WGe7!umZm^=$LAu4}fd99hEM`a1h`jOCs=>-Os{I=uVzzd3I6pI_GQ z=iKP$GxwA6#QjVg@4b8WVvgZXp-bCm@^0vOcxe9to&8=ikAD2)dskE|_H$3i=f@|e zRN22wyQumsV}H?Skxb|6eOoMlUEJPR)59ym@mlU#zw(=Z_db?XZ?P9Xs3zU#U%z3Y z?NRQN{yo2sWSrhOSMbRCxf?oIH#W!!Yq97zY0ldi|I^&{PJm}VkNB3--UGf#m-13V z9-f~!r^Z%xY5AV`w&Tm^-}vyis$k>f@1@4i&j0vmc>D9~6xZX|-#+=iVd3(}zYBl< zYHM3Qy*8)rTk6a6^Je@nR@UC>yI1G$o3xY5Z`U8b`}tvu>S?urIoI1W<_PHpPx<+B zP28;TOS6~!@z}|>OV;8+^KywM*@;}fQ+*%+^)gbael*-ZE8>YFHU>u zeDCe8-$stRm}Pp>)%aMBhIz=lE)#0hmwX_1%DG;%$yH>7P1J;lV^SY&Id;yrS7Z^q z;g*&symy6iy-C;`Q$Fve6#=1)x{fJ%mA+0VKh64lC+^W|FRt`!ErkJA*N^Ymw@2_; zxX;Dc_wHXVsXTM`WYIf)#YNdFhi`qozMkv0Xhh@hC+Y3++in_lX*zH!9$T{brs?KY zfs#Tsh4HsIz)=WNMA08@;4&OiH9iLeJJo9VYTt79Qy|^Pm zh0p)`wWkS8A-jGZyBTHky7$Y$2M=m$<5oTmp0jM?5nKMN`e!v(20y>7pu@>oC>d?& zsGsZXTW*^6X~zO_71PMWzU!5FFS$OxQL=2;3 zxy|Y1j^%vGT_RF<4#iv+tJ(5+vz^JJJ5!R=e{`=Y(=WRtv0u^Yilt^FyYk&#cJ(a0 z+x8jSP6EO|*&Bhk{#-h!e-CFKW7#NT9)YmHnOf z?gkv?nV;$*vuWiO?W@g|7oxm7*2ao1KT~48`-D;yKikqpJAauf@JY>K`<-+}OJ3G! zpXGt}0}?xT8!sx$|MfVhzUb+MPhkRc^sCP>@SffLZtjZ|{J-fBl~wT!veIJ3ZBu4RBlc-20rVL#gwY z*`{yitPuSApz%xUBF8Ad&v})T|LQ6S3kb1(VT^I{U;X2`!IDV_Ia4J{He9dY*|nTA z{xny{bQ_CCb1Bhm8|k8L5*#)<_kM2ua5uyK%$+vVFqJJkSXvG|y7pReZ<_K>IRn?0 zOAFqFeLh*LwALUftu5kpNYIq2UQ7EGgO*?Kk?>vpY_Y*i##c9vM=-l3YKhrUo2g6S$hhJxOL- z^$M4sYg>MGpWilfZiH=n)6dkB5S~uXxbu5*=I>gkIrH%M-9LmH+6pSZ1la01=NF&< z%bFKgZ+JUKJ>{g8&$okj+}~)3TnvklbuXI3?kUH7X^TqpEtgcIQvJZhhC9-Sy2`$^ zJr|yLcrJHPeYWlfg9R)t2PKY8w+da`S~j^^xo^VU{}QRTJ9d2x={$9M(G2gF{kaM8 zr}bj)b4U_CM+zTdlo(_*x*<1`!#tM z!-ff$cqTe_p6<>J?`eMghdp7|cmH46TuP>`E9Nj{WHhbXm~v=un5%r}4#QQyA{hTJ z3pM?AX3yb-3tRT^)L+o*e|6;E!+<-lU+>tHlM*vWcZy20MMn9&%Aa(TB2IP2l{aPOf3$55Y)(E`W#ka=>{Q=z#?ANq9JVc= z-fAW!MLD+Xa_y|}YF>AEuV34|g2y#BbC);U-YQbrwvlD_hvz4qGB&N~m3*y!GU{>a zZVuVD?>iEAaNX5pV)2*yZ0BmJlUX10zEG*nNUF%;R+LA^$AxnfM6PxHSR&(VzNaQ8 zX3u&i?eM~@F_)7T2CjH_ennU1{OFIXL>38z?m5A6-1WQSw|8H^pW)u4S+$$b+VRlJ zrz(hTtGymFskD2LkvF0L9 z*Ltmt+i_9nCi+-5FTDJDKli-13&S7iusnC(JoDA%idmDL+n47a*?AUQ_6- zf~=j%#`!+KLbp38T$GYMc|BO>;+1J(l}qH?EE)A}>Tjm~ZHYX&&$LHmi?l|7$@I(y zO|46+ksBg%dc=N+P1)7GDQwm;sf$TZEtlJDH(!_3=@MUARQ)|9xT9g~_EmB_?q>NM zJsN%L*p1E!8s3pp7PRJg)vAQ3A4q@q!RGz+owfHZHu!#?-7YsvXY1#uAqrN)sRj{# zde=?6G`{N2mz-6fb59arswQ;J`Jl}Hvazn z^wEXxExZSpKM|1sqc|BGa+lLOpjPo z%8cTTn`Xu^yq#wv`+Zixtqs*DowV-O?8#c>mvXV?%dz<<;#pL$KbdAOBe`w+wXI&N zs|;uE@ywSkH0Mj%c>L4+^Ov_fU3Z$(vXb$A@Xh@@^9 zSy{hhTILyZW9Pd~4|nY@OEPM!GHBXfkaGCtJnK6WVlQMkUMpHRZNDMBj{9Ko;ii&1 zOKhe2z4!|y*7(Xag{@sY?MwmJNtU@>+jRIE?0BtCEfR8xJ@+-W=$)2VUBV>JaBX8W=9aar{E0bDvUjLmHl(buN;@j54y(&e)D%+df1LpkJN=k5you#pl z_gb9W_j`A(_>?o>ZWf;UbLrudsWW|?pLk4P`}rhG*SrV*JEjM71^>Nq+(Gz;%*u$) z)`?%cGA}F;pY2tz75(sL&u`-g+g6o*6zX15vErO$&5DsMeKh z$w~!BzTNq7-KfzrO;h-t)Pm>gedi|_FB7{P#rI!pdg$(p*WRdIj_PpyWTUp~&3(@L zSoZG3;CBJvrp^_O%vn2g&%1UB&v&ahOyufkc=_J=XZw)hL~fv+?}k&BT0QB`7ddTy zADq0>W%cg*Bg+m+GChj%Y^v~XI(#(4@2h5PquG^-MzzN8s~^2qd$j(0wktkrzYzuUcPqn)b(?VI8#rFl^m|hy#GAkFsEEFvG{p^ zADi;cZAm;=y>5#aRy8OkUO9hrS=xfaZJQ)I5ArM$i}QaWYcI`z`CMRZ;yXq4pYF>F zS3JC~u-RAgd40C|pODCme@gc+#B*o2En=J(82oOFz2@!H?)+=F>&7Pi`Kev3&2ZMI z?cvo|T|RuvHnz+cZ6>?d`E>21Dr zM8ey*zhjNy?UgkO|7)KHM22ZRTdY;)yF^4+u1I=4Pw?kcokEf3X6rY~?NOhzMnK>3 z%N-HX>Yyo4S+W;hZtdN~=KM=`>8d=nqmR{p-2IZk*>limUhne5XTP*3o?M=zUbX1$ zpRkt#`W*u9rmLRZYM4}Tdum^OYuhiDb0Ts_m2;bQ%QAFke49GE;GjyR@!pk-87tL_ z=Rc~p=d}>ms8;%VrekS)wfpOjSv%r)9aA{J%l62GFvId$ zcCt{p%#s@}D^`0mI!k@^F>I?3Q#zG%HBI$!Vwss=`%-hAyS5A-GS4#ao$TZPQI!;S zTqI=vua!BHt!Ec}`LSBx*QI4%_|p|U3O$b!>s=yhtWI;py=9Z#(m#{wp9R+s#^A_= zjDophopHwsTm@>YE%Mv5w|cSvi_Wo^*}dW0`%VqfJCm=+Z(ZKaor-|ebK)W`hI<~zzUjETou@xv^4z7z3GTnlem$E| z_hVDSXP>b8X!f>;^(oaV^BorZY}&W=BxAw;3jvev_B|Evy?0-4%O=CAZwhqWPtCij z@ntXXMCJ916Btq-E_-{=udQd|h3p(gU5V>&l32zWcBWAD^fC^1z+HNBq6%t z(!w1}ydyp3mU4AI{v{SL)BM{;N0Uv>tGPuNWyKYGykIGqcl^ZL6YNW~Q!i&;;69OV z|LjoI8c7pvHIpYU`q57E|LSL!my1cPXMemrQSs=}?-8BmFLU`cOLS@`d|wc$w_u6P z1J*@t@uy7Yzk4tv{!M$qj@UB387besd~R7P`2X;9)*kN?>0Tv&yROJjEzc}0Zf3k( z@s)YTt1q4_w)m^f?&^>9uF8ED@GnZEB=rC3H4~v4{ zkCNE=L2HrNnzLs<_I1ZTX}VSWF`?qI%yyR#kC&=G+cEnZquF$^H14Oq)tocLo|=|5 zy0N^fO0NGRa$6-~F7qj8yP$v1&Yvhc8a8)nkA&wY9X;M{EYG`hcQsBj`O1BbQPs{i ziTTbaxoZ(Ic5my>-u6!MJ^1k8j91go{pl8pD-)h;J6%z3=X+T}$*k4wrP`5ePn!tO z5&E^2_ulj?T2~Lq-~K&m`CpzAH?<{pGO1T`wl8%({#obaxB7UcH6a(O(5jfl{#0%nl~#y6*JN{BiZ{m}l$BjfX>5<&*|o~)j=boW-V;~AHv0-s23 zsQ0`muYa6NFR8wIlMBnqFHR{ha`;Z#f31K2`R?~-m#a_QLrYy*w^i&hRJXs^{4GuB z`}Lx~9vy%FNvNNwI2LoSUL!`uadp)HgeBcC)@&6!?L70+{Fhx1*ne0=GOT9#esmF^ z@ZO)f0xvw?^v|4f{M@cIYw^mwBh$7yPW$s>#+FBiJ9e*JALD&>@*IbvLjT*m#m_yw zUY1PKn%!v8rfvMr`t<{cX}NRe=5Y`*N+TXkCW+e5>@+(r#ImN6Z5E=$oo8d{a& z>>()GW&CLGX{QadPFiFXtv2I4ac`4bG}DIqKrzK@=jME{URLFp%r*Pf{)#ETj)u$Z zoY8ss`-I%XGFHh||6Tj+Z^el5&3yLY&7zbuXI6e)ynV?x;RjM3IjSBt>(00|9Sd<; zaBRhiIh?n)=gw7UulIdc80XupqnC2vDgl-z+a~tf=Sx^zzvq@rHZbsuw;v z_ri0{{0^C#3Q2JR{;yp6p(l+*H?BK;bEoSSyP~qmukH5#pJ4aIuGROz%JXM=zfQAR zJav-ST;u1{>-hVm_8yZy)at?DJ?#p+l2Pw9=I&J$IVCLqm-K6eOL7mbV^FG}S>rur zN7ad3Rv)vwoR*spFr>6Bs{h|KasJC1o3oYj3VWUk_U778aX*(9z2vd_%m~fkj2ypA zC5A{bkMd~a4tKwG*Om#Fu`hbR(#nxDbX%u~^SP^RS)F`kzFYIIJ8qdWS=!Dk%R_BJ z%2vr4h7ASRe!KU{HWVwpe70j=uX@C;8?S#RNh-@bMZWBwRoVNC;alz1?!EPz(aX+H zWBuvH8_VVDRkgf(;zsF-`w!mTbFx|TrMITm_GR0r&);Rp`bOJK%OYhir)ISB+$;96 z3B|6?f5k)>u6P=f*EElB%}wJEsokz$D^`7e^(fh-W@cs8t{qyBA8=ayFi+#jI@$B8 z^zS{ksaZ$cY$X5Zt|*;6WxJfDwR>0hh5D`wSuf7HCThKWw&s&$gXjNG^IrO&E{=_S zQBl=-ZOP?dIqc6u+?Q;QRbTGA{J2o;nK}3K8*<#8bC@rkT_0Pd{&bz9()Y!e3VlzO z&R(l#YP$KIliiiChn;?VJ^c~5o$J!_v<$8HXXL_GZPz;TdX87l0o7}N7MU$O{LoF} zW`AL?e*Kf{ftuo8i@VzwRCIp!{#GN#QS@N_^n)^f%|*`^&0A;loA39FCmUm>zq{@_ z*KK{}uG>X(zTTHm9FxL#@D(pPtUy!TpX%)P&yZPEFt6Z=yCdd1!B z$ZD9alqx=R&wGXsx{*dLy`H}Ud^B@8vsNZ`J7;>c2Oi3=U$9O+RZ4cvC?zI8;3U!PH z^e5`|wcof@#hls@6*R|VrF7tib+uRCUGgz7W)5qb{prCDqlUF=MzfzBwtrQ&IcHIK zTk7K3y&Bh=jT+uhFXdCvBMdl4tYD z*TG3qZx!1=?qReI()s(w^ujF8gC*A%s4tkJ;8A3sb$jBQsb=yTvlj3xeyhJ2qQ3Bu zn}MfG{9B&9opr&deXeX;dsT&f+RGQuo|IbeTu>L2o3?=YFn9g-(47pLYW-Jlq?SGM zESG&Y$L)uM?ey%->$#`aU9ho<*;BAWulC7omd3e@=x&6$)Nty6s5EaLN)dJ)~rn$usTs($R8(zxPb$a0(Li!T;Ng?Q^& z?pVE0;^--Mh3wOLPs?`I+s4)P?bD65%iqY|TrDZ`Pe!2o$DgNb^d}0bzOmbLd?k~A zlH{M4O8bs4o^rKg>YP@Vy|Z*gGD0&#Pcb~^@eE^sy|n(^(o;Ml+C{qmUxaJfEqfuc zNxQ0kis*xyn_g;Ri~ssL6u+qKi&!Mrd&aUalRVOwPSrZP&Oh|pjy^WGOVdQ==pSV|(ll+$ zf#dHOxE7u1ZoF=KZc$@{z)#&r0`j(*Pn?CWJd%BP|4jX^JKMDv1%{t#Fwna8{9A~` zv86kh^e)7u?B2Lx?yHc_!gA@#82fR)*UoTDuGbND5}R`9PC&nF>A^oYv$rRF*snb|s$?}koVWGHi3J=v*M$8WKYmsonekGhyl(ULGV zD?`OO?XxQaId5BuC9oOE`^x1jrJcE+AF8_d-$9P{$NPWiy6bp)SnyN^Jd`fWe9gZ} ztjsVlrjh;W@&re}kQ3M6I2;J*2zq+%Nj6t|LYK^^c>Hv!C2ncwG22%VK7YOv=363G+9vRSy5=?$!5M`1y@hL60;dZLZLAWt4{Jx3U_|j|5@tT+N0kW$1OgbFYsw) z{q8wu*02Bao~KnpsrwX@&Z`St*10YwQu#fCrrh`0J~TVB5BYi{>ZgRGk>TB&FIZm)zg!88TLUpLfCA zXx8zyWiAIQd%xP4_l7-)xw7G_Y>BtB!%vrtRlDm$Jed9|Upjd3;+JPBWtX$#`FY$6 zyXWq--^nVR=zQ=_u~b|48^)lnnghbUB`U_>Dl0=@b^{CE_b_{XO$l!#~wiC-bfT)_EhsUQ<-^_~{A0 z-vV@5t9E~1{m}i7P2JzDE7KMyFI$~9|M#}wf9tn9&p7bh;hdm7v!7z=jh_Xcsp93O ztwwxzrMBPMtK9zCvSm@z+avYu$sc@Hu)dm7*Dus`K1HzQ!_u$`-Thsc*^4q4huz=& zg2i1**{hc8!=!aDrfm`T(BCxsJkOVP{j*NzNgrTyc=_a$?`aXc7xvX2pN}^8Ec<#$ zNbTw&{rl55X(b&A->CVSBmJ__9UGClgHicLYYmw@!Z)>Mulp=wAUn18k&aF5v-*U< zl9zFzua^f;vk(zUI3vC##?8R^f~(5!xhA|nq*WPMybOEpIXSytSyI%ywm#vZo#3H+ zNiI{prmy3uIe1!j`|^XOoC1^XE_+fY*YsIUt5k>cU!2?1oi1}WhyQem-BPufFG2Njpi8o+L4sR==S64w{nQt1nsqm|3X>)yMQrXAtr+qG+U}e7braF%4rfl2Vr$^mO%Ek9CJIw#9?heaT&HHa(2u*q1 z=)V6{N7(8sWp6XW6!&SjG^q1eec|%<3g2wiJ?m4=`InP;x9d!in8xx&V&w~OKk;*{ z+M;#8)`_|%&-wO-)wg(ZUGJyXWlIB{*9dPrt9dirXXms%G4+3Lsc24&OQ>eKV*TJ?^XK_)tbas18xnuF#v&%Rfas`U6?k;@(C9aC|__dm({pT&V zmQQ#Z>ukB(T;R%-EAh)qoYr?u-olu@2zy=>*2htI^lP^zKs`u;!RfF4GHyvrv5XY zo|O*MlGvr2UElcg)3QQgpK$GoEswue3jEgpJmcyzH{;umUuD+yE%mx)wIzP#T&A^# zn(DkRO01R3wd=}KoT;km3_8>uRWfc3L zk56LjW9L0qG`(K-h}C9)0Rux=XYZbMwN`ZvRrzs=v!;Fa&0ffQRbM`B&-?eUX1ecg zeOJSEajKZ=H^2UJfkaXN)Q30XW8O%JQ4M6}3*ALtp+aw4c8-;3ezh z8~PRfuY%^i+s+-9&pRiODQ{I#%;K*>=DR)m3ue%%G{-{e`jzxy$YXSSK8&k z8?bE3<(K=O=hdWtFRnkJ$$LOzgV1xEEzGMKs~X%cls{>=?%I@661)HSi3bhEjTzGR zKLbkz9{yX&=xi`O$YKr8mh%kBRu|V+%uZ;tjJ^}Yv8JQ(nA4{jWm}Ie)ec)^z`W+N zq`OEM+tZmxOV`BRmgbwVjQQD_)>^(fvZ;rbhJIW%dGW_cGqs|{l3j&G^$&hrc=$ak z{Z`4ztJ6-l7BKcdpWO9ifxJpz-7n?Mu_f_a7(X8{s+}wLcm2V>BRSb;8#nYC#XVbl z>EhoD6?d!u`hHc|zsPfY)xo5HvdL4_9(ujJTE15{>ll|v$jQcMnR7lFaF%Gs_#Nfmu*sb@>}SmDy0eVWSZ!}9Rx0mmcq$gE z!LJ*7!)9rS#*!_?Ppi}FyJvpc==LbP@pJjnM&@+2_Q^YUPPV<0P_ryK&D~$Uxxaqt z2FChZ-yXeKCB-^*S99^1wO+Tc9xuuWbdf{-WF5;_?R!{TlC3GZ+CRZu28?_vGM_n$-{cHrRZ z*KfXYo$KAjy=2X_%J}b|yXBhZ?%GqB7aegVZAbe7XDjq^_ghr4*ZST4zXi4^R&3_x`)So-|BCW zS$@!d`IoHu3%AsL)~&Wb%^p~maOGotd|T(_BfGCnWlvWBSyQ*~-?NVmYZ~j{FY!!$ zv-6s|zO}{kX3yozr*zC}{vvev#(&FX+24}6#qHtuw7K?v`w&{&v3TXjgGS2UPHwI2 zWxFnyFS0KcpXIgpL|f!k-MNcA-OR+j?>cYUep-5j#Q`E?@bk^hV{ww)A<2pKvI|%#&i5uH&$}r*((% z#pSzulUH{!W@@Rs-TNA`#AVK$$Db<2e?(PwraI&VXr*t`kegw1PX0js-|W41&esdL zZcBI9JKwnyX`%MRVn?i)euiDwT&`1JI@EQePP5KS>D*AIc9VbgVWxl1mwQ_|POndV zmf>;8cj2wh@*6fv9Xi?%vKSb%^Zk~8^_x9G;Xt!PpZOoN(4Efjs}q*hE9#v6weA0o z>unyhiW!|GemdV;T{>Onv0_b5+`V_ZrMX{R+%!#iOIH0_ZYODmO|u!Mdq?`RZ(Ym$ zsqC`$HlACjqrF1c#Xoo4c_>bN?yAP9(5+d2m+oJ^C~kULP2#gVo9FAUt~ByVJH>u+ z)`cA=Ht$v$22A<*J!NNb-kcLH&oyUB#$U_b%$s>WY;)4S@7~)xmK2J;+3EN$fIEAu z;f%AlH*9oQJ(birSF=7v+FyZ&b+n>#Yw(Qzm(FyqjyGw!r$H`SaD& zmVWq{6u#E_)QW)FQB&O&1bJ&ddOy;1Vf@Ir&u_}UD_M_acg6>4vo-e~s()j5Kifs& zn9a@7t!H|Z*tC)weDi*qoRIXIWy0aUF|ga+-@2#z(l_%tr(*l#lQ-ohWVCWrGw06# z#LjSj>VL5y*J6KXOXTh)65B{c?274I6v33pGlj?Zo1C(i!u8zzC@cv>y!7J=657rslE1u zD_qK~=hFoshIPdi+;V=31Z4#-U9V1HEXeQBPW z(f@6CV!W;>&3M!rzRA@4s`=p#{RQ_-lE0}`ST8-tcv))ytCPNe7cG9+I`46F%0s56 z2lZ=$e=Xwl{Uwcio?-k$UELC#77OF~4t5F>jvOGhN{+ zX(uL!AKS$gdiKfe1;@7asLD)L<}W;Dx%V=cmz2TxrO|#_v*t%#36xlVE$!ll!TPvZp^62?ztue)37iYvXKC^SKuD^J3tDBK)vXWf>0hyJV5$^t% zTz>Vo*sR(W)u-_5;z`rZiaZh(*;_W36$kxz@Su^^+(OHtb=$gyk~PNWd0U#-8XpRK zz1S%Ah6wk$$x>FcL~^^$^ZlCIy2ORJ{9KkP>9@ose~?)GRd3z3%eQ@e;M9-hCp^~Tww8c#jt7W12F=iL1*S=Xa0)5RKi!0BNE zbAjkFojXfjJ2FK*@amOK)ykYWr84V<>&%bF*C%h=ta0@3vJ#%o`mHaXzkK|>yxp3) z=*~ImR~5`gZ(aJKSy*-NN+RD!-~XXIG(|Qf zxI}Vqm>Ro%&&Bej^-;@Y892@ri7h{P)9k{PXzVr zkD%Vl-ZibBmtXmJT|CQl(5xz&Lw-rk%J|${!pf|3_e|yW4nKTN$k*oDmi3R$EfCxp z-p}By8P0QU<(vs${vSMQ?V5gw_5Hkq(zmzeO3U7Ubz@uZZNKB&)|zk2Eq$|O@#neq zk;du&jL+{|v335c+pE5=?%sQ{tHU>C^wJo`3fRf9fYW{C{6BJzMWi_2wDr>vnamIV@&ebAPFt zk$?7sCWph5YD0B@3;c6Qnq|qKFTJWa`Ro?1XP4ueUI%GgNGwSC^X>YzcMJOXw%%9$ zP$O@6jQz)h7xTZ~T=8PZHtRiR=@-m*1jKFmc&k5n@7rGoKJ{B#B<`zzbSq*0?88TX znx`CL;WwG`wB52kUwn_(f}QyR#eAB{E9QTF{!>Eow~c0x(`BQXGBqu$WmAtBFj{;6 z&F==W$zh z=X8hU$2Yc29`}#)eb8;H;k+=pM}wtv^9L^1{(%2Bv$EySw%og>TmNitQ#o&diuK4W6DYWb||Hh1J6E^Q6r);9=z*B&)-#l2?Op`b&dC-6Pv!1OFD<&;U^_94O;5dIN`%yRcrTuqh z4Ge1)H*EVlXOG5@jTbtupV61ItT$6?n*T_BMKbe@uIH}5{X~*xcm1EC*mJAk!ZJ4Q z3t?%HRYllsr@RJPUy$JYfq z%L15XQnznd!gOq!xyfwnyC&klXL2G zr~X*2wuUp)CW@ib&wI!B3q9^%xt z_Mkr(EyvyS%dNuS8qknyXjUUVkg&?Vp!l#J;c|3|vunVcol#*~`sR z_aE)KQ|#GZ8FyuxNu}?kM*iPhJhXZkHpCq0XVYGtA$w7&Rba{fJx?cJ4fC)un|tHj z;hA&)a{oJ86CalvDJPvidz(^w$nj^s(za7sf{WrbqBhMI&sN_$@o(9kuP0yqv^q5V zpGn-LPg&WA>X+8knyQ7KK5aCM&)nQ2@ciN@UHeX)={=I?_I1Nuj?=dGtM?z>wvK6w zMr*{Ce@BAi8!v8FKRO}pSgGN(*osS+|GO^Pe(faF+3#OXcggE+bopX*f_MAp#fjq9 zdmi^)SG;m!%JU0pk6#@+qA*e z@yyG$o~D<7xh?HnE!4L8g51Z4bNq@{*t^=4njB`kr>)}>=c~3juh7FU%E7s&M`5kv zYxk3v1#+)$f4E6xxtMi`=h>Y1^??@gvFS}$6t!n|%)GF(|Fp%bw=d@<{ht2LwfK41 zGCxxowt%yKbV#HEtBJ+)EULwrx%v>g?#r3H<7r1LU!i$Q+8(@ym&YLOg-h3 z6KC>oUAjSpbmvT~&AW?5HeCx4TOqHPw|A@EOC@=YPlDgWvNd*my>{}_1<4ojlMHUI zE6b2O?>bY0(Rt?7s|2>ZV_O#FD{+``a z9gpPvFaEs3;aNflN4cAp#9iB6ydI)G57zMO=!HGpqiPkgYgR>M;h#V7w&HKf1Wx~-Qx&idH(HI5U+q>mpxxZ!gCI#Ip5R(~YdYTVMa{`@$i zWp=`+S@+w{GS^>x##mRpS3zIt)HUzaPc^HGAFq&el&?*1n)hV)G<&I@#ep)ltAib8 zr}?b8HZx@Uqt@0Xe5dzM-XjujbbNB!ourWYLV>1?OO0mzn(F**vD8xU`tsTB+uZ(~ z$>FUsb#!_3;S;R$;q{p0C z$)>hG$y?+@-!4gB(MfK%=BAo0&yr(5K4Y6-ux6KC;KTN41FM67k`zt;HE~X}pLTQC zuk|Yh_Ek#H-hW_{<%WBY<~=sINm;vV=2@Ba!}|Y?^ZgqiddvL1Znei-NX}r2f@u8} z{wF6|^Pee39yqk@gJ}-S+h00!g%6sXiQn_iX18echoq8hpQ@7I@q(r+CrhrmYoOvS z`AXZ+(W1G^t}}V*_w&rlzbAb67P;hF->bSiNW6Ad0%y-hxfAz1Om?RJ=GR`z%jGm_ zs&4q|DYpUzmxoJC+L+V$ZOO|OI$KUKt~(z4xxVwo39ry|m!z9D)}D%;(GlsYqMN

    ho&fUOio4aec4s5NMrs+$HCSAOkFWkto`HAoK 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 Date: Wed, 18 May 2016 18:17:16 +0200 Subject: [PATCH 187/714] fixed issue exporting builds --- lib/gitlab/import_export/relation_factory.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 68319441a63427..d4e49ae17f0bd4 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -22,7 +22,7 @@ def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) update_user_references(relation_hash, members_mapper.map) update_project_references(relation_hash, klass) - imported_object(klass, relation_hash) + generate_imported_object(klass, relation_hash, relation_sym) end private @@ -58,6 +58,18 @@ def missing_author_note(updated_at, author_name) "\n\n *By #{author_name} on #{timestamp} (imported from GitLab project)*" end + def generate_imported_object(klass, relation_hash, relation_sym) + if relation_sym == 'commit_status' # call #trace= method after assigning the other attributes + trace = relation_hash.delete('trace') + imported_object(klass, relation_hash) do |imported_object| + imported_object.trace = trace + imported_object.commit_id = nil + end + else + imported_object(klass, relation_hash) + end + end + def update_project_references(relation_hash, klass) project_id = relation_hash.delete('project_id') @@ -86,6 +98,7 @@ def parse_relation_sym(relation_sym) def imported_object(klass, relation_hash) imported_object = klass.new(relation_hash) + yield(imported_object) if block_given? imported_object.importing = true if imported_object.respond_to?(:importing) imported_object end -- GitLab From 30f4dcd4c906a71db98833075c76eb59922f5b98 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 13:02:57 +0200 Subject: [PATCH 188/714] uploads export --- .../projects/import_export/export_service.rb | 6 +++- lib/gitlab/import_export/uploads_saver.rb | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 lib/gitlab/import_export/uploads_saver.rb diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 0691ca9d468602..1a23a4ede97c0b 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -4,7 +4,7 @@ class ExportService < BaseService def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) - save_all if [save_version, save_project_tree, bundle_repo, bundle_wiki_repo].all? + save_all if [save_version, save_project_tree, save_uploads, bundle_repo, bundle_wiki_repo].all? cleanup_and_notify_worker if @shared.errors.any? end @@ -18,6 +18,10 @@ def save_project_tree Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared).save end + def save_uploads + Gitlab::ImportExport::UploadsSaver.save(project: project, shared: @shared) + end + def bundle_repo Gitlab::ImportExport::RepoBundler.new(project: project, shared: @shared).bundle end diff --git a/lib/gitlab/import_export/uploads_saver.rb b/lib/gitlab/import_export/uploads_saver.rb new file mode 100644 index 00000000000000..3420d2ea4cbc53 --- /dev/null +++ b/lib/gitlab/import_export/uploads_saver.rb @@ -0,0 +1,35 @@ +module Gitlab + module ImportExport + class UploadsSaver + + def self.save(*args) + new(*args).save + end + + def initialize(project:, shared:) + @project = project + @shared = shared + end + + def save + return true unless File.directory?(uploads_path) + + FileUtils.copy_entry(uploads_path, uploads_export_path) + true + rescue => e + @shared.error(e.message) + false + end + + private + + def uploads_export_path + File.join(@shared.export_path, 'uploads') + end + + def uploads_path + File.join(Rails.root.join('public/uploads'), project.path_with_namespace) + end + end + end +end -- GitLab From bac27df16c35abb2f8115d9c94edcc4ecbace1a7 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 13:10:41 +0200 Subject: [PATCH 189/714] Squashed commit of the following: commit 92de6309e1c918a4ae023641dc42b196b3fb25ea Merge: 6c082ed 30f4dcd Author: James Lopez Date: Thu May 19 13:06:34 2016 +0200 Merge branches 'feature/project-export' and 'feature/project-import' of gitlab.com:gitlab-org/gitlab-ce into feature/project-import commit 30f4dcd4c906a71db98833075c76eb59922f5b98 Author: James Lopez Date: Thu May 19 13:02:57 2016 +0200 uploads export --- .../projects/import_export/export_service.rb | 6 +++- lib/gitlab/import_export/uploads_saver.rb | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 lib/gitlab/import_export/uploads_saver.rb diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 0691ca9d468602..1a23a4ede97c0b 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -4,7 +4,7 @@ class ExportService < BaseService def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) - save_all if [save_version, save_project_tree, bundle_repo, bundle_wiki_repo].all? + save_all if [save_version, save_project_tree, save_uploads, bundle_repo, bundle_wiki_repo].all? cleanup_and_notify_worker if @shared.errors.any? end @@ -18,6 +18,10 @@ def save_project_tree Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared).save end + def save_uploads + Gitlab::ImportExport::UploadsSaver.save(project: project, shared: @shared) + end + def bundle_repo Gitlab::ImportExport::RepoBundler.new(project: project, shared: @shared).bundle end diff --git a/lib/gitlab/import_export/uploads_saver.rb b/lib/gitlab/import_export/uploads_saver.rb new file mode 100644 index 00000000000000..3420d2ea4cbc53 --- /dev/null +++ b/lib/gitlab/import_export/uploads_saver.rb @@ -0,0 +1,35 @@ +module Gitlab + module ImportExport + class UploadsSaver + + def self.save(*args) + new(*args).save + end + + def initialize(project:, shared:) + @project = project + @shared = shared + end + + def save + return true unless File.directory?(uploads_path) + + FileUtils.copy_entry(uploads_path, uploads_export_path) + true + rescue => e + @shared.error(e.message) + false + end + + private + + def uploads_export_path + File.join(@shared.export_path, 'uploads') + end + + def uploads_path + File.join(Rails.root.join('public/uploads'), project.path_with_namespace) + end + end + end +end -- GitLab From 816dfcb1c54277ce5e3e3da1a0c1028b4c2cdb3c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 13:21:56 +0200 Subject: [PATCH 190/714] fix path --- lib/gitlab/import_export/uploads_saver.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/import_export/uploads_saver.rb b/lib/gitlab/import_export/uploads_saver.rb index 3420d2ea4cbc53..7bce4ddd4e5f68 100644 --- a/lib/gitlab/import_export/uploads_saver.rb +++ b/lib/gitlab/import_export/uploads_saver.rb @@ -28,7 +28,7 @@ def uploads_export_path end def uploads_path - File.join(Rails.root.join('public/uploads'), project.path_with_namespace) + File.join(Rails.root.join('public/uploads'), @project.path_with_namespace) end end end -- GitLab From 1466997755f704b1f8af49ced136e91827a0892c Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 15:36:20 +0200 Subject: [PATCH 191/714] import uploads. Fixed a few things to do with members, triggers, etc... --- app/models/member.rb | 9 +++++---- lib/gitlab/import_export.rb | 4 ++++ lib/gitlab/import_export/import_service.rb | 6 +++++- lib/gitlab/import_export/members_mapper.rb | 4 ++-- lib/gitlab/import_export/relation_factory.rb | 10 +++++++++- lib/gitlab/import_export/uploads_restorer.rb | 19 +++++++++++++++++++ lib/gitlab/import_export/uploads_saver.rb | 13 +++++++++---- 7 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 lib/gitlab/import_export/uploads_restorer.rb diff --git a/app/models/member.rb b/app/models/member.rb index cca82da89f1879..bef0b545c707af 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -22,6 +22,7 @@ class Member < ActiveRecord::Base include Gitlab::Access attr_accessor :raw_invite_token + attr_accessor :importing belongs_to :created_by, class_name: "User" belongs_to :user @@ -54,10 +55,10 @@ class Member < ActiveRecord::Base scope :owners, -> { where(access_level: OWNER) } before_validation :generate_invite_token, on: :create, if: -> (member) { member.invite_email.present? } - after_create :send_invite, if: :invite? - after_create :create_notification_setting, unless: :invite? - after_create :post_create_hook, unless: :invite? - after_update :post_update_hook, unless: :invite? + after_create :send_invite, if: :invite?, unless: :importing + after_create :create_notification_setting, unless: [:invite?, :importing] + after_create :post_create_hook, unless: [:invite?, :importing] + after_update :post_update_hook, unless: [:invite?, :importing] after_destroy :post_destroy_hook, unless: :invite? delegate :name, :username, :email, to: :user, prefix: true diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 65a8fcfadd0d6f..9c04a3d6995656 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -27,5 +27,9 @@ def version_filename def version VERSION end + + def reset_tokens? + true + end end end diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index b025bff29bd1a1..acd734f0890503 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -16,7 +16,7 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, shared: @shared) - if [restore_version, restore_project_tree, restore_repo, restore_wiki_repo].all? + if [restore_version, restore_project_tree, restore_repo, restore_wiki_repo, restore_uploads].all? project_tree.project else project_tree.project.destroy if project_tree.project @@ -52,6 +52,10 @@ def restore_wiki_repo project: ProjectWiki.new(project_tree.project)).restore end + def restore_uploads + Gitlab::ImportExport::UploadsRestorer.restore(project: project_tree.project, shared: @shared) + end + def path_with_namespace(project_path) File.join(@namespace.path, project_path) end diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index 4401fab3d23e99..28e57867158e2d 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -50,11 +50,11 @@ def assign_member(existing_user, member) end def member_hash(member) - member.except('id').merge(source_id: @project.id) + member.except('id').merge(source_id: @project.id, importing: true) end def default_project_member_hash - { user: @user, access_level: ProjectMember::MASTER, source_id: @project.id } + { user: @user, access_level: ProjectMember::MASTER, source_id: @project.id, importing: true } end def find_project_user_query(member) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index d4e49ae17f0bd4..566777e8fc95c2 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -12,7 +12,7 @@ module RelationFactory builds: 'Ci::Build', hooks: 'ProjectHook' }.freeze - USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze + USER_REFERENCES = %w(author_id assignee_id updated_by_id user_id).freeze def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) relation_sym = parse_relation_sym(relation_sym) @@ -21,6 +21,7 @@ def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) update_missing_author(relation_hash, members_mapper, user_admin) if relation_sym == :notes update_user_references(relation_hash, members_mapper.map) update_project_references(relation_hash, klass) + reset_tokens(relation_hash) if relation_sym == 'Ci::Trigger' generate_imported_object(klass, relation_hash, relation_sym) end @@ -88,6 +89,13 @@ def update_project_references(relation_hash, klass) relation_hash['gl_project_id'] = project_id if relation_hash ['gl_project_id'] end + def reset_tokens(relation_hash) + return unless Gitlab::ImportExport.reset_tokens? + + # If we import/export a project to the same instance, tokens will have to be reseated. + relation_hash['token'] = nil + end + def relation_class(relation_sym) relation_sym.to_s.classify.constantize end diff --git a/lib/gitlab/import_export/uploads_restorer.rb b/lib/gitlab/import_export/uploads_restorer.rb new file mode 100644 index 00000000000000..fdcbc48eb1b1f3 --- /dev/null +++ b/lib/gitlab/import_export/uploads_restorer.rb @@ -0,0 +1,19 @@ +module Gitlab + module ImportExport + class UploadsRestorer < UploadsSaver + + class << self + alias_method :restore, :save + end + + def save + return true unless File.directory?(uploads_export_path) + + copy_files(uploads_export_path, uploads_path) + rescue => e + @shared.error(e) + false + end + end + end +end diff --git a/lib/gitlab/import_export/uploads_saver.rb b/lib/gitlab/import_export/uploads_saver.rb index 3420d2ea4cbc53..93bc626b3636b9 100644 --- a/lib/gitlab/import_export/uploads_saver.rb +++ b/lib/gitlab/import_export/uploads_saver.rb @@ -14,21 +14,26 @@ def initialize(project:, shared:) def save return true unless File.directory?(uploads_path) - FileUtils.copy_entry(uploads_path, uploads_export_path) - true + copy_files(uploads_path, uploads_export_path) rescue => e - @shared.error(e.message) + @shared.error(e) false end private + def copy_files(source, destination) + FileUtils.mkdir_p(destination) + FileUtils.copy_entry(source, destination) + true + end + def uploads_export_path File.join(@shared.export_path, 'uploads') end def uploads_path - File.join(Rails.root.join('public/uploads'), project.path_with_namespace) + File.join(Rails.root.join('public/uploads'), @project.path_with_namespace) end end end -- GitLab From 7df495fb7702f3635d6746cb9b0d79d00eafed80 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 15:37:21 +0200 Subject: [PATCH 192/714] updated uploads saver --- lib/gitlab/import_export/uploads_saver.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/import_export/uploads_saver.rb b/lib/gitlab/import_export/uploads_saver.rb index 7bce4ddd4e5f68..93bc626b3636b9 100644 --- a/lib/gitlab/import_export/uploads_saver.rb +++ b/lib/gitlab/import_export/uploads_saver.rb @@ -14,15 +14,20 @@ def initialize(project:, shared:) def save return true unless File.directory?(uploads_path) - FileUtils.copy_entry(uploads_path, uploads_export_path) - true + copy_files(uploads_path, uploads_export_path) rescue => e - @shared.error(e.message) + @shared.error(e) false end private + def copy_files(source, destination) + FileUtils.mkdir_p(destination) + FileUtils.copy_entry(source, destination) + true + end + def uploads_export_path File.join(@shared.export_path, 'uploads') end -- GitLab From becd9bfdc6142779e3874ba0558af29d9ef96588 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 16:42:41 +0200 Subject: [PATCH 193/714] updated spec file --- .../import_export/test_project_export.tar.gz | Bin 340523 -> 672360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 7eed8a6306a1e3fb2c06b2eb148e765da05de12c..b85055070d821808e0ca0e52254bee72520637db 100644 GIT binary patch delta 185822 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 z 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 S@?89}{|vIfeQX&Tco+b3A`8<1 delta 97287 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 Date: Thu, 19 May 2016 17:02:49 +0200 Subject: [PATCH 194/714] fixed small issue mapping members --- lib/gitlab/import_export/members_mapper.rb | 1 - lib/gitlab/import_export/relation_factory.rb | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index 28e57867158e2d..cd1e174f180070 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -25,7 +25,6 @@ def initialize(exported_members:, user:, project:) def default_project_member @default_project_member ||= begin - return @project.project_members.first.user.id unless @project.project_members.empty? default_member = ProjectMember.new(default_project_member_hash) default_member.save! default_member.user.id diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 566777e8fc95c2..d5b80beb312143 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -39,11 +39,11 @@ def update_user_references(relation_hash, members_map) def update_missing_author(relation_hash, members_map, user_admin) old_author_id = relation_hash['author_id'] - # Users with admin access have access to mapping of users + # Users with admin access can map users if user_admin - relation_hash['author_id'] = members_map.default_project_member - else relation_hash['author_id'] = members_map.map[old_author_id] + else + relation_hash['author_id'] = members_map.default_project_member end author = relation_hash.delete('author') -- GitLab From 6782cd3cf6bd298c0c26538db35704bf13fcabb3 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 19 May 2016 17:05:35 +0200 Subject: [PATCH 195/714] fix extra space --- lib/gitlab/import_export/relation_factory.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index d5b80beb312143..0fdf208cfa08e5 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -3,7 +3,6 @@ module ImportExport module RelationFactory extend self - OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status', -- GitLab From fa1884698db9d462ebff3301d42cbc7d43d62c49 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 20 May 2016 10:57:10 +0200 Subject: [PATCH 196/714] a few nice to have and updated changelog --- CHANGELOG | 1 + app/helpers/todos_helper.rb | 10 ++++++++-- app/models/project.rb | 2 ++ app/models/todo.rb | 5 +++++ app/views/projects/edit.html.haml | 2 +- lib/gitlab/import_export/import_service.rb | 13 +++++++++++++ 6 files changed, 30 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 822fa4be56586b..992f782f803535 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -33,6 +33,7 @@ v 8.8.0 (unreleased) - Fix Gravatar hint in user profile when Gravatar is disabled. !3988 (Artem Sidorenko) - Expire repository exists? and has_visible_content? caches after a push if necessary - Fix unintentional filtering bug in issues sorted by milestone due (Takuya Noguchi) + - GitLab project import and export functionality v 8.7.4 - Fix always showing build notification message when switching between merge requests diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 2f066682180e7e..5317b55520b256 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -9,8 +9,12 @@ def todos_done_count def todo_action_name(todo) case todo.action - when Todo::ASSIGNED then 'assigned you' - when Todo::MENTIONED then 'mentioned you on' + when Todo::ASSIGNED then + 'assigned you' + when Todo::MENTIONED then + 'mentioned you on' + when Todo::IMPORTED then + 'imported successfully' end end @@ -27,6 +31,8 @@ def todo_target_path(todo) if todo.for_commit? namespace_project_commit_path(todo.project.namespace.becomes(Namespace), todo.project, todo.target, anchor: anchor) + elsif todo.for_project? + namespace_project_path(todo.project.namespace, todo.project) else polymorphic_path([todo.project.namespace.becomes(Namespace), todo.project, todo.target], anchor: anchor) diff --git a/app/models/project.rb b/app/models/project.rb index 5003324f8f87b1..3bd5d048e10470 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -94,6 +94,8 @@ def update_forks_visibility_level attr_accessor :new_default_branch attr_accessor :old_path_with_namespace + alias_attribute :title, :name + # Relations belongs_to :creator, foreign_key: 'creator_id', class_name: 'User' belongs_to :group, -> { where(type: Group) }, foreign_key: 'namespace_id' diff --git a/app/models/todo.rb b/app/models/todo.rb index d85f7bfdf57219..3333e56912a8a6 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -19,6 +19,7 @@ class Todo < ActiveRecord::Base ASSIGNED = 1 MENTIONED = 2 + IMPORTED = 3 belongs_to :author, class_name: "User" belongs_to :note @@ -58,6 +59,10 @@ def for_commit? target_type == "Commit" end + def for_project? + target_type == "Project" + end + # override to return commits, which are not active record def target if for_commit? diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 251fba474afa9f..dcb46ad9d19885 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -144,7 +144,7 @@ = link_to 'Generate new export', export_namespace_project_path(@project.namespace, @project), method: :post, class: "btn btn-default" - = link_to 'Download export', download_export_namespace_project_path(@project.namespace, @project), + = link_to 'Download latest export', download_export_namespace_project_path(@project.namespace, @project), method: :post, class: "btn btn-default" diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index acd734f0890503..79794a4c34f38f 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -17,6 +17,7 @@ def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, shared: @shared) if [restore_version, restore_project_tree, restore_repo, restore_wiki_repo, restore_uploads].all? + Todo.create(attributes_for_todo) project_tree.project else project_tree.project.destroy if project_tree.project @@ -67,6 +68,18 @@ def repo_path def wiki_repo_path File.join(@shared.export_path, 'project.wiki.bundle') end + + def attributes_for_todo + { user_id: @current_user.id, + project_id: project_tree.project.id, + target_type: 'Project', + target: project_tree.project, + action: Todo::IMPORTED, + author_id: @current_user.id, + state: :pending, + target_id: project_tree.project.id + } + end end end end -- GitLab From f70c000924c82bc579310fe784a6df159d15618b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 20 May 2016 11:56:02 +0200 Subject: [PATCH 197/714] fix indentation --- app/helpers/todos_helper.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 5317b55520b256..25b812877e6a09 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -9,12 +9,12 @@ def todos_done_count def todo_action_name(todo) case todo.action - when Todo::ASSIGNED then - 'assigned you' - when Todo::MENTIONED then - 'mentioned you on' - when Todo::IMPORTED then - 'imported successfully' + when Todo::ASSIGNED then + 'assigned you' + when Todo::MENTIONED then + 'mentioned you on' + when Todo::IMPORTED then + 'imported successfully' end end -- GitLab From 05b319b0b45288cbbe0bce15bf7bed7f58f6cf76 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 1 Jun 2016 14:04:38 +0530 Subject: [PATCH 198/714] Perform private token and personal access token authentication in the same `before_action`. - So that the check for valid personal access tokens happens only if private token auth fails. --- app/controllers/application_controller.rb | 38 ++++---- .../application_controller_spec.rb | 92 ++++++++++--------- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b26afb42e74e52..9dbaba00ff5741 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,8 +7,7 @@ class ApplicationController < ActionController::Base include GitlabRoutingHelper include PageLayoutHelper - before_action :authenticate_user_from_private_token! - before_action :authenticate_user_from_personal_access_token! + before_action :authenticate_user_from_token! before_action :authenticate_user! before_action :validate_user_service_ticket! before_action :reject_blocked! @@ -64,26 +63,8 @@ def sentry_program_context end end - # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example - # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 - def authenticate_user_from_private_token! - user_token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence - user = user_token && User.find_by_authentication_token(user_token.to_s) - - if user - # Notice we are passing store false, so the user is not - # actually stored in the session and a token is needed - # for every request. If you want the token to work as a - # sign in token, you can simply remove store: false. - sign_in user, store: false - end - end - - def authenticate_user_from_personal_access_token! - token_string = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence - personal_access_token = PersonalAccessToken.active.find_by_token(token_string) - user = personal_access_token && personal_access_token.user - + def authenticate_user_from_token! + user = get_user_from_private_token || get_user_from_personal_access_token if user # Notice we are passing store false, so the user is not # actually stored in the session and a token is needed @@ -383,4 +364,17 @@ def is_a_listing_page_for?(page_type) (controller_name == 'groups' && action_name == page_type) || (controller_name == 'dashboard' && action_name == page_type) end + + # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example + # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 + def get_user_from_private_token + user_token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence + User.find_by_authentication_token(user_token.to_s) if user_token + end + + def get_user_from_personal_access_token + token_string = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence + personal_access_token = PersonalAccessToken.active.find_by_token(token_string) + personal_access_token.user if personal_access_token + end end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index d7835dc6e2bccb..90dbd1183ebdc5 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -31,63 +31,65 @@ end end - describe "#authenticate_user_from_private_token!" do - controller(ApplicationController) do - def index - render text: "authenticated" + describe "#authenticate_user_from_token!" do + describe "authenticating a user from a private token" do + controller(ApplicationController) do + def index + render text: "authenticated" + end end - end - let(:user) { create(:user) } + let(:user) { create(:user) } - it "logs the user in when the 'private_token' param is populated with the private token" do - get :index, private_token: user.private_token - expect(response.status).to eq(200) - expect(response.body).to eq("authenticated") - end + it "logs the user in when the 'private_token' param is populated with the private token" do + get :index, private_token: user.private_token + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end - it "logs the user in when the 'PRIVATE-TOKEN' header is populated with the private token" do - @request.headers['PRIVATE-TOKEN'] = user.private_token - get :index - expect(response.status).to eq(200) - expect(response.body).to eq("authenticated") - end + it "logs the user in when the 'PRIVATE-TOKEN' header is populated with the private token" do + @request.headers['PRIVATE-TOKEN'] = user.private_token + get :index + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end - it "doesn't log the user in otherwise" do - @request.headers['PRIVATE-TOKEN'] = "token" - get :index, private_token: "token", authenticity_token: "token" - expect(response.status).to_not eq(200) - expect(response.body).to_not eq("authenticated") + it "doesn't log the user in otherwise" do + @request.headers['PRIVATE-TOKEN'] = "token" + get :index, private_token: "token", authenticity_token: "token" + expect(response.status).to_not eq(200) + expect(response.body).to_not eq("authenticated") + end end - end - describe "#authenticate_user_from_personal_access_token!" do - controller(ApplicationController) do - def index - render text: 'authenticated' + describe "authenticating a user from a personal access token" do + controller(ApplicationController) do + def index + render text: 'authenticated' + end end - end - let(:user) { create(:user) } - let(:personal_access_token) { create(:personal_access_token, user: user) } + let(:user) { create(:user) } + let(:personal_access_token) { create(:personal_access_token, user: user) } - it "logs the user in when the 'personal_access_token' param is populated with the personal access token" do - get :index, private_token: personal_access_token.token - expect(response.status).to eq(200) - expect(response.body).to eq('authenticated') - end + it "logs the user in when the 'personal_access_token' param is populated with the personal access token" do + get :index, private_token: personal_access_token.token + expect(response.status).to eq(200) + expect(response.body).to eq('authenticated') + end - it "logs the user in when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do - @request.headers["PRIVATE-TOKEN"] = personal_access_token.token - get :index - expect(response.status).to eq(200) - expect(response.body).to eq('authenticated') - end + it "logs the user in when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do + @request.headers["PRIVATE-TOKEN"] = personal_access_token.token + get :index + expect(response.status).to eq(200) + expect(response.body).to eq('authenticated') + end - it "doesn't log the user in otherwise" do - get :index, private_token: "token" - expect(response.status).to_not eq(200) - expect(response.body).to_not eq('authenticated') + it "doesn't log the user in otherwise" do + get :index, private_token: "token" + expect(response.status).to_not eq(200) + expect(response.body).to_not eq('authenticated') + end end end end -- GitLab From 6d444331764fec1910d15b300d89b6246a1f83ea Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 1 Jun 2016 14:09:17 +0530 Subject: [PATCH 199/714] Don't look for personal access tokens in the DB when the parameter/header is not passed. --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9dbaba00ff5741..17bd980b4547d0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -374,7 +374,7 @@ def get_user_from_private_token def get_user_from_personal_access_token token_string = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence - personal_access_token = PersonalAccessToken.active.find_by_token(token_string) + personal_access_token = PersonalAccessToken.active.find_by_token(token_string) if token_string personal_access_token.user if personal_access_token end end -- GitLab From c75aea5e4dc6f4420e7576a5c367a9e035f63646 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 1 Jun 2016 14:31:16 +0530 Subject: [PATCH 200/714] Fix minor issues with the personal access tokens implementation. - Use the `:personal_access_token` param root instead of `personal_access_token_params`, because we aren't using the `personal_access_token` param for authentication anymore (we're using `private_token` instead). - Use `build` to instantiate a `PersonalAccessToken` - Use better-formatted dates --- .../profiles/personal_access_tokens_controller.rb | 6 ++---- .../profiles/personal_access_tokens/index.html.haml | 12 ++++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index af6def25e7f72c..1ad1c11b73fbb2 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -2,7 +2,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def index @active_personal_access_tokens = current_user.personal_access_tokens.active.order(:expires_at) @inactive_personal_access_tokens = current_user.personal_access_tokens.inactive - @personal_access_token = PersonalAccessToken.new(user: @user) + @personal_access_token = current_user.personal_access_tokens.build end def create @@ -28,8 +28,6 @@ def revoke private def personal_access_token_params - # We aren't using `personal_access_token` as the root param because the authentication - # system expects to find a token string there - it's off-limits to us. - params.require(:personal_access_token_params).permit(:name, :expires_at) + params.require(:personal_access_token).permit(:name, :expires_at) end end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 0f51e8cd8bef6a..b4468dd9839af1 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -12,7 +12,7 @@ Add a Personal Access Token %p.profile-settings-content Pick a name for the application, and we'll give you a unique token. - = form_for [:profile, @personal_access_token], as: "personal_access_token_params", + = form_for [:profile, @personal_access_token], method: :post, html: { class: 'js-requires-input' } do |f| .form-group @@ -29,7 +29,7 @@ %hr - %h5= "Active Personal Access Tokens (#{@active_personal_access_tokens.length})" + %h5 Active Personal Access Tokens (#{@active_personal_access_tokens.length}) - if @active_personal_access_tokens.present? .table-responsive @@ -50,9 +50,9 @@ %div.input-group-btn %button.btn.btn-default{ type: "button", data: { clipboard_text: token.token } } %i.fa.fa-clipboard - %td= token.created_at.to_date + %td= token.created_at.to_date.to_s(:medium) - if token.expires_at.present? - %td= token.expires_at.to_date + %td= token.expires_at.to_date.to_s(:medium) - else %td %span.personal-access-tokens-never-expires-label Never @@ -63,7 +63,7 @@ %hr - %h5= "Inactive Personal Access Tokens (#{@inactive_personal_access_tokens.length})" + %h5 Inactive Personal Access Tokens (#{@inactive_personal_access_tokens.length}) - if @inactive_personal_access_tokens.present? .table-responsive @@ -82,7 +82,7 @@ %div.input-group-btn %button.btn.btn-default{ type: "button", data: { clipboard_text: token.token } } %i.fa.fa-clipboard - %td= token.created_at.to_date + %td= token.created_at.to_date.to_s(:medium) - else %span No inactive tokens. -- GitLab From 7c8359b7441c2631ceec3bd3783a9761646a9f99 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 1 Jun 2016 18:03:51 +0200 Subject: [PATCH 201/714] started refactoring some stuff based on MR feedback --- app/models/concerns/importable.rb | 6 ++++ app/models/member.rb | 10 +++--- app/models/merge_request.rb | 7 ++-- app/models/merge_request_diff.rb | 5 ++- db/schema.rb | 16 ++++----- lib/gitlab/import_export/members_mapper.rb | 34 +++++++++++-------- .../import_export/project_tree_restorer.rb | 34 ++++++------------- lib/gitlab/import_export/relation_factory.rb | 17 ++++------ lib/gitlab/import_export/repo_restorer.rb | 1 - 9 files changed, 61 insertions(+), 69 deletions(-) create mode 100644 app/models/concerns/importable.rb diff --git a/app/models/concerns/importable.rb b/app/models/concerns/importable.rb new file mode 100644 index 00000000000000..019ef7558494d2 --- /dev/null +++ b/app/models/concerns/importable.rb @@ -0,0 +1,6 @@ +module Importable + extend ActiveSupport::Concern + + attr_accessor :importing + alias_method :importing?, :importing +end diff --git a/app/models/member.rb b/app/models/member.rb index bef0b545c707af..9a56d3d218180d 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -19,10 +19,10 @@ class Member < ActiveRecord::Base include Sortable + include Importable include Gitlab::Access attr_accessor :raw_invite_token - attr_accessor :importing belongs_to :created_by, class_name: "User" belongs_to :user @@ -55,10 +55,10 @@ class Member < ActiveRecord::Base scope :owners, -> { where(access_level: OWNER) } before_validation :generate_invite_token, on: :create, if: -> (member) { member.invite_email.present? } - after_create :send_invite, if: :invite?, unless: :importing - after_create :create_notification_setting, unless: [:invite?, :importing] - after_create :post_create_hook, unless: [:invite?, :importing] - after_update :post_update_hook, unless: [:invite?, :importing] + after_create :send_invite, if: :invite?, unless: :importing? + after_create :create_notification_setting, unless: [:invite?, :importing?] + after_create :post_create_hook, unless: [:invite?, :importing?] + after_update :post_update_hook, unless: [:invite?, :importing?] after_destroy :post_destroy_hook, unless: :invite? delegate :name, :username, :email, to: :user, prefix: true diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 916329e04d6227..c771968627c639 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -34,6 +34,7 @@ class MergeRequest < ActiveRecord::Base include Referable include Sortable include Taskable + include Importable belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project" belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project" @@ -48,8 +49,6 @@ class MergeRequest < ActiveRecord::Base delegate :commits, :diffs, :real_size, to: :merge_request_diff, prefix: nil - attr_accessor :importing - # When this attribute is true some MR validation is ignored # It allows us to close or modify broken merge requests attr_accessor :allow_broken @@ -123,12 +122,12 @@ class MergeRequest < ActiveRecord::Base end end - validates :source_project, presence: true, unless: [:allow_broken, :importing] + validates :source_project, presence: true, unless: [:allow_broken, :importing?] validates :source_branch, presence: true validates :target_project, presence: true validates :target_branch, presence: true validates :merge_user, presence: true, if: :merge_when_build_succeeds? - validate :validate_branches, unless: [:allow_broken, :importing] + validate :validate_branches, unless: [:allow_broken, :importing?] validate :validate_fork scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) } diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 4278c7daa4137a..2c9eaf3849f896 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -15,6 +15,7 @@ class MergeRequestDiff < ActiveRecord::Base include Sortable + include Importable # Prevent store of diff if commits amount more then 500 COMMITS_SAFE_SIZE = 100 @@ -37,9 +38,7 @@ class MergeRequestDiff < ActiveRecord::Base serialize :st_commits serialize :st_diffs - after_create :reload_content, unless: :importing - - attr_accessor :importing + after_create :reload_content, unless: :importing? def reload_content reload_commits diff --git a/db/schema.rb b/db/schema.rb index 71d953afe30ab9..89dba1318fa971 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -70,11 +70,11 @@ t.string "recaptcha_site_key" t.string "recaptcha_private_key" t.integer "metrics_port", default: 8089 - t.boolean "akismet_enabled", default: false - t.string "akismet_api_key" t.integer "metrics_sample_interval", default: 15 t.boolean "sentry_enabled", default: false t.string "sentry_dsn" + t.boolean "akismet_enabled", default: false + t.string "akismet_api_key" t.boolean "email_author_in_body", default: false t.integer "default_group_visibility" t.boolean "repository_checks_enabled", default: false @@ -428,8 +428,8 @@ t.integer "updated_by_id" t.boolean "confidential", default: false t.datetime "deleted_at" - t.date "due_date" t.integer "moved_to_id" + t.date "due_date" end add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree @@ -716,8 +716,8 @@ t.integer "project_id" t.text "data" t.text "encrypted_credentials" - t.string "encrypted_credentials_iv" - t.string "encrypted_credentials_salt" + t.text "encrypted_credentials_iv" + t.text "encrypted_credentials_salt" end create_table "projects", force: :cascade do |t| @@ -815,9 +815,9 @@ t.string "type" t.string "title" t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "active", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "active", null: false t.text "properties" t.boolean "template", default: false t.boolean "push_events", default: true diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index cd1e174f180070..9c47216eb8d03a 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -2,7 +2,7 @@ module Gitlab module ImportExport class MembersMapper - attr_reader :map, :note_member_list + attr_reader :note_member_list def initialize(exported_members:, user:, project:) @exported_members = exported_members @@ -19,33 +19,37 @@ def initialize(exported_members:, user:, project:) default_project_member end - @map = generate_map end def default_project_member @default_project_member ||= begin default_member = ProjectMember.new(default_project_member_hash) - default_member.save! + default_member.create! default_member.user.id end end - private - - def generate_map - @exported_members.each do |member| - existing_user = User.where(find_project_user_query(member)).first - assign_member(existing_user, member) if existing_user - end - @project_member_map + def map + @map ||= + begin + @exported_members.inject(@project_member_map) do |hash, member| + existing_user = User.where(find_project_user_query(member)).first + if existing_user + old_user_id = member['user']['id'] + add_user_as_team_member(existing_user, member) + hash[old_user_id] = existing_user.id + end + hash + end + end end - def assign_member(existing_user, member) - old_user_id = member['user']['id'] + private + + def add_user_as_team_member(existing_user, member) member['user'] = existing_user - project_member = ProjectMember.new(member_hash(member)) - @project_member_map[old_user_id] = project_member.user.id if project_member.save + ProjectMember.create!(member_hash(member)) end def member_hash(member) diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 911ba06e7484be..e8f5fb88382c87 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -32,14 +32,15 @@ def members_mapper project: project) end - def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) + def create_relations saved = [] - relation_list.each do |relation| - next if !relation.is_a?(Hash) && tree_hash[relation.to_s].blank? - create_sub_relations(relation, tree_hash) if relation.is_a?(Hash) + default_relation_list.each do |relation| + next unless relation.is_a?(Hash) || @tree_hash[relation.to_s].present? + + create_sub_relations(relation, @tree_hash) if relation.is_a?(Hash) relation_key = relation.is_a?(Hash) ? relation.keys.first : relation - relation_hash = create_relation(relation_key, tree_hash[relation_key.to_s]) + relation_hash = create_relation(relation_key, @tree_hash[relation_key.to_s]) saved << project.update_attribute(relation_key, relation_hash) end saved.all? @@ -73,32 +74,19 @@ def create_sub_relations(relation, tree_hash) relation_hash = relation_item[sub_relation.to_s] end - process_sub_relation(relation_hash, relation_item, sub_relation) unless relation_hash.blank? + relation_item[sub_relation.to_s] = create_relation(sub_relation, relation_hash) unless relation_hash.blank? end end end - def process_sub_relation(relation_hash, relation_item, sub_relation) - if relation_hash.is_a?(Array) - sub_relation_object = create_relation(sub_relation, relation_hash) - else - sub_relation_object = relation_from_factory(sub_relation, relation_hash) - end - relation_item[sub_relation.to_s] = sub_relation_object - end - def create_relation(relation, relation_hash_list) [relation_hash_list].flatten.map do |relation_hash| - relation_from_factory(relation, relation_hash) + Gitlab::ImportExport::RelationFactory.create(relation_sym: relation.to_sym, + relation_hash: relation_hash.merge('project_id' => project.id), + members_mapper: members_mapper, + user_admin: @user.is_admin?) end end - - def relation_from_factory(relation, relation_hash) - Gitlab::ImportExport::RelationFactory.create(relation_sym: relation.to_sym, - relation_hash: relation_hash.merge('project_id' => project.id), - members_mapper: members_mapper, - user_admin: @user.is_admin?) - end end end end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 0fdf208cfa08e5..2794eafe4b6339 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -11,11 +11,14 @@ module RelationFactory builds: 'Ci::Build', hooks: 'ProjectHook' }.freeze - USER_REFERENCES = %w(author_id assignee_id updated_by_id user_id).freeze + USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id].freeze + # Guesses a model and saves it to the DB given its name `relation_sym` def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) relation_sym = parse_relation_sym(relation_sym) - klass = parse_relation(relation_hash, relation_sym) + + klass = relation_class(relation_sym) + relation_hash.delete('id') update_missing_author(relation_hash, members_mapper, user_admin) if relation_sym == :notes update_user_references(relation_hash, members_mapper.map) @@ -49,8 +52,8 @@ def update_missing_author(relation_hash, members_map, user_admin) return unless user_admin && members_map.note_member_list.include?(old_author_id) - relation_hash['note'] = ('*Blank note*') if relation_hash['note'].blank? - relation_hash['note'] += (missing_author_note(relation_hash['updated_at'], author['name'])) + relation_hash['note'] = '*Blank note*' if relation_hash['note'].blank? + relation_hash['note'] += missing_author_note(relation_hash['updated_at'], author['name']) end def missing_author_note(updated_at, author_name) @@ -109,12 +112,6 @@ def imported_object(klass, relation_hash) imported_object.importing = true if imported_object.respond_to?(:importing) imported_object end - - def parse_relation(relation_hash, relation_sym) - klass = relation_class(relation_sym) - relation_hash.delete('id') - klass - end end end end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 36094b95aa4445..9fac58e2242601 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -12,7 +12,6 @@ def initialize(project:, shared:, path_to_bundle:) def restore return true unless File.exists?(@path_to_bundle) - FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) git_unbundle(repo_path: path_to_repo, bundle_path: @path_to_bundle) -- GitLab From 4d50d8a6e3b8ae1521617df32af4cad18385fb9f Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Thu, 2 Jun 2016 08:27:47 +0530 Subject: [PATCH 202/714] Only show a personal access token right after its creation. --- app/assets/stylesheets/pages/profile.scss | 8 +++++ .../personal_access_tokens_controller.rb | 3 +- .../personal_access_tokens/index.html.haml | 26 +++++++-------- .../profiles/personal_access_tokens_spec.rb | 32 ++++++++++++------- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 53f16c13eca25b..69bc74228e8cf1 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -218,6 +218,14 @@ max-width: 500px } +.created-personal-access-token { + margin: 15px 15px 0 0; + pre { + max-width: 400px; + display: inline; + } +} + .user-profile { @media (max-width: $screen-xs-max) { .cover-block { diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 1ad1c11b73fbb2..81f2390a566e1e 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -9,7 +9,8 @@ def create @personal_access_token = current_user.personal_access_tokens.generate(personal_access_token_params) if @personal_access_token.save - redirect_to profile_personal_access_tokens_path, notice: "Created personal access token!" + flash[:personal_access_token] = @personal_access_token.token + redirect_to profile_personal_access_tokens_path else render :index end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index b4468dd9839af1..503f88efb43933 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -8,6 +8,16 @@ %p You can generate a personal access token for each application you use that needs access to GitLab. .col-lg-9 + + - if flash[:personal_access_token] + .panel.panel-success + .panel-heading Success! + .panel-body + Your new personal access token has been created. Make sure to save it - you can't see it again on this page. + .created-personal-access-token + %pre= flash[:personal_access_token] + = clipboard_button(clipboard_text: flash[:personal_access_token]) + %h5.prepend-top-0 Add a Personal Access Token %p.profile-settings-content @@ -37,7 +47,6 @@ %thead %tr %th Name - %th Token %th Created %th Expires %th Actions @@ -45,11 +54,6 @@ - @active_personal_access_tokens.each do |token| %tr %td= token.name - %td.input-group.personal-access-tokens-token-column - %input.form-control{ type: "text", value: token.token, readonly: true } - %div.input-group-btn - %button.btn.btn-default{ type: "button", data: { clipboard_text: token.token } } - %i.fa.fa-clipboard %td= token.created_at.to_date.to_s(:medium) - if token.expires_at.present? %td= token.expires_at.to_date.to_s(:medium) @@ -71,17 +75,11 @@ %thead %tr %th Name - %th Token %th Created %tbody - @inactive_personal_access_tokens.each do |token| %tr %td= token.name - %td.input-group.personal-access-tokens-token-column - %input.form-control{ type: "text", value: token.token, readonly: true } - %div.input-group-btn - %button.btn.btn-default{ type: "button", data: { clipboard_text: token.token } } - %i.fa.fa-clipboard %td= token.created_at.to_date.to_s(:medium) - else @@ -91,5 +89,5 @@ :javascript $(".datepicker").datepicker({ dateFormat: "yy-mm-dd", - onSelect: function(dateText, inst) { $("#personal_access_token_params_expires_at").val(dateText) } - }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#personal_access_token_params_expires_at').val())); + onSelect: function(dateText, inst) { $("#personal_access_token_expires_at").val(dateText) } + }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#personal_access_token_expires_at').val())); diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index e9fbeefae75c7a..095c7d60e29e11 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -3,21 +3,35 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do let(:user) { create(:user) } + def active_personal_access_tokens + find(".table.active-personal-access-tokens").native['innerHTML'] + end + + def inactive_personal_access_tokens + find(".table.inactive-personal-access-tokens").native['innerHTML'] + end + + def created_personal_access_token + find(".created-personal-access-token pre").native['innerHTML'] + end + before do login_as(user) end describe "token creation" do - it "allows creation of a token with an optional expiry date" do + it "allows creation of a token" do visit profile_personal_access_tokens_path fill_in "Name", with: FFaker::Product.brand - expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) - active_personal_access_tokens = find(".table.active-personal-access-tokens").native['innerHTML'] + expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) + expect(created_personal_access_token).to eq(PersonalAccessToken.last.token) expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) expect(active_personal_access_tokens).to match("Never") - expect(active_personal_access_tokens).to match(PersonalAccessToken.last.token) + end + it "allows creation of a token with an expiry date" do + visit profile_personal_access_tokens_path fill_in "Name", with: FFaker::Product.brand # Set date to 1st of next month @@ -25,11 +39,9 @@ click_on "1" expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) - - active_personal_access_tokens = find(".table.active-personal-access-tokens").native['innerHTML'] + expect(created_personal_access_token).to eq(PersonalAccessToken.last.token) expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) - expect(active_personal_access_tokens).to match(Date.today.next_month.at_beginning_of_month.to_s) - expect(active_personal_access_tokens).to match(PersonalAccessToken.last.token) + expect(active_personal_access_tokens).to match(Date.today.next_month.at_beginning_of_month.to_s(:medium)) end end @@ -39,18 +51,14 @@ visit profile_personal_access_tokens_path click_on "Revoke" - inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native['innerHTML'] expect(inactive_personal_access_tokens).to match(personal_access_token.name) - expect(inactive_personal_access_tokens).to match(personal_access_token.token) end it "moves expired tokens to the 'inactive' section" do personal_access_token = create(:personal_access_token, expires_at: 5.days.ago, user: user) visit profile_personal_access_tokens_path - inactive_personal_access_tokens = find(".table.inactive-personal-access-tokens").native['innerHTML'] expect(inactive_personal_access_tokens).to match(personal_access_token.name) - expect(inactive_personal_access_tokens).to match(personal_access_token.token) end end end -- GitLab From 102074c80152a0d9b808f3eea78a195234ef80bb Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 2 Jun 2016 10:59:54 +0200 Subject: [PATCH 203/714] more and more refactoring --- lib/gitlab/import_export/import_service.rb | 22 ++++----- lib/gitlab/import_export/members_mapper.rb | 49 ++++++++++--------- .../import_export/project_tree_restorer.rb | 4 +- lib/gitlab/import_export/relation_factory.rb | 2 +- lib/gitlab/import_export/uploads_saver.rb | 4 -- ...version_restorer.rb => version_checker.rb} | 6 +-- 6 files changed, 41 insertions(+), 46 deletions(-) rename lib/gitlab/import_export/{version_restorer.rb => version_checker.rb} (91%) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index acd734f0890503..96cb8f4b174789 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -16,7 +16,7 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, shared: @shared) - if [restore_version, restore_project_tree, restore_repo, restore_wiki_repo, restore_uploads].all? + if check_version! && [project_tree, repo_restorer, wiki_restorer, uploads_restorer].all?(&:restore) project_tree.project else project_tree.project.destroy if project_tree.project @@ -26,12 +26,8 @@ def execute private - def restore_version - Gitlab::ImportExport::VersionRestorer.restore(shared: @shared) - end - - def restore_project_tree - project_tree.restore + def check_version! + Gitlab::ImportExport::VersionChecker.check!(shared: @shared) end def project_tree @@ -40,20 +36,20 @@ def project_tree namespace_id: @namespace.id) end - def restore_repo + def repo_restorer Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path, shared: @shared, - project: project_tree.project).restore + project: project_tree.project) end - def restore_wiki_repo + def wiki_restorer Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, shared: @shared, - project: ProjectWiki.new(project_tree.project)).restore + project: ProjectWiki.new(project_tree.project)) end - def restore_uploads - Gitlab::ImportExport::UploadsRestorer.restore(project: project_tree.project, shared: @shared) + def uploads_restorer + Gitlab::ImportExport::UploadsRestorer.new(project: project_tree.project, shared: @shared) end def path_with_namespace(project_path) diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index 9c47216eb8d03a..13fe68d540822c 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -12,32 +12,27 @@ def initialize(exported_members:, user:, project:) # This needs to run first, as second call would be from generate_map # which means project members already exist. - default_project_member - - @project_member_map = Hash.new do |_, key| - @note_member_list << key - default_project_member - end + ensure_default_member! + end + def map + @map ||= generate_map end - def default_project_member - @default_project_member ||= - begin - default_member = ProjectMember.new(default_project_member_hash) - default_member.create! - default_member.user.id - end + def default_user_id + @user.id end - def map + private + + + def generate_map @map ||= begin - @exported_members.inject(@project_member_map) do |hash, member| + @exported_members.inject(missing_keys_tracking_hash) do |hash, member| existing_user = User.where(find_project_user_query(member)).first - if existing_user - old_user_id = member['user']['id'] - add_user_as_team_member(existing_user, member) + old_user_id = member['user']['id'] + if existing_user && add_user_as_team_member(existing_user, member).persisted? hash[old_user_id] = existing_user.id end hash @@ -45,21 +40,27 @@ def map end end - private + def missing_keys_tracking_hash + Hash.new do |_, key| + @note_member_list << key + @user.id + end + end + + def ensure_default_member! + ProjectMember.create!(user: @user, access_level: ProjectMember::MASTER, source_id: @project.id, importing: true) + end def add_user_as_team_member(existing_user, member) member['user'] = existing_user - ProjectMember.create!(member_hash(member)) + + ProjectMember.create(member_hash(member)) end def member_hash(member) member.except('id').merge(source_id: @project.id, importing: true) end - def default_project_member_hash - { user: @user, access_level: ProjectMember::MASTER, source_id: @project.id, importing: true } - end - def find_project_user_query(member) user_arel[:username].eq(member['user']['username']).or(user_arel[:email].eq(member['user']['email'])) end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index e8f5fb88382c87..8d3a016ad7132d 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -80,12 +80,14 @@ def create_sub_relations(relation, tree_hash) end def create_relation(relation, relation_hash_list) - [relation_hash_list].flatten.map do |relation_hash| + relation_array = [relation_hash_list].flatten.map do |relation_hash| Gitlab::ImportExport::RelationFactory.create(relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_mapper: members_mapper, user_admin: @user.is_admin?) end + + relation_hash_list.is_a?(Array) ? relation_array : relation_array.first end end end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 2794eafe4b6339..cecb4747822d85 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -45,7 +45,7 @@ def update_missing_author(relation_hash, members_map, user_admin) if user_admin relation_hash['author_id'] = members_map.map[old_author_id] else - relation_hash['author_id'] = members_map.default_project_member + relation_hash['author_id'] = members_map.default_user_id end author = relation_hash.delete('author') diff --git a/lib/gitlab/import_export/uploads_saver.rb b/lib/gitlab/import_export/uploads_saver.rb index 93bc626b3636b9..7292e9d9712bb8 100644 --- a/lib/gitlab/import_export/uploads_saver.rb +++ b/lib/gitlab/import_export/uploads_saver.rb @@ -2,10 +2,6 @@ module Gitlab module ImportExport class UploadsSaver - def self.save(*args) - new(*args).save - end - def initialize(project:, shared:) @project = project @shared = shared diff --git a/lib/gitlab/import_export/version_restorer.rb b/lib/gitlab/import_export/version_checker.rb similarity index 91% rename from lib/gitlab/import_export/version_restorer.rb rename to lib/gitlab/import_export/version_checker.rb index 892352f5adfabb..4f4677608623d5 100644 --- a/lib/gitlab/import_export/version_restorer.rb +++ b/lib/gitlab/import_export/version_checker.rb @@ -1,16 +1,16 @@ module Gitlab module ImportExport - class VersionRestorer + class VersionChecker def self.restore(*args) - new(*args).restore + new(*args).check end def initialize(shared:) @shared = shared end - def restore + def check! version = File.open(version_file, &:readline) verify_version!(version) rescue => e -- GitLab From a9fdf62b5797220b7736859a2bc0f34f96a7ed43 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 2 Jun 2016 14:07:09 +0200 Subject: [PATCH 204/714] refactoring relation factory, changed from module to class --- .../import_export/project_tree_restorer.rb | 5 + lib/gitlab/import_export/relation_factory.rb | 125 ++++++++++-------- 2 files changed, 72 insertions(+), 58 deletions(-) diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 8d3a016ad7132d..dc1e477a82ff51 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -32,6 +32,11 @@ def members_mapper project: project) end + # Loops through the tree of models defined in import_export.yml and + # finds them in the imported JSON so they can be instantiated and saved + # in the DB. The structure and relationships between models are guessed from + # the configuration yaml file too. + # Finally, it updates each attribute in the newly imported project. def create_relations saved = [] default_relation_list.each do |relation| diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index cecb4747822d85..3738dbaebd318b 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -1,7 +1,6 @@ module Gitlab module ImportExport - module RelationFactory - extend self + class RelationFactory OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', @@ -13,47 +12,54 @@ module RelationFactory USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id].freeze - # Guesses a model and saves it to the DB given its name `relation_sym` - def create(relation_sym:, relation_hash:, members_mapper:, user_admin:) - relation_sym = parse_relation_sym(relation_sym) + def self.create(*args) + new(*args).create + end - klass = relation_class(relation_sym) - relation_hash.delete('id') + def initialize(relation_sym:, relation_hash:, members_mapper:, user_admin:) + @relation_name = OVERRIDES[relation_sym] || relation_sym + @relation_hash = relation_hash.except('id') + @members_mapper = members_mapper + @user_admin = user_admin + end - update_missing_author(relation_hash, members_mapper, user_admin) if relation_sym == :notes - update_user_references(relation_hash, members_mapper.map) - update_project_references(relation_hash, klass) - reset_tokens(relation_hash) if relation_sym == 'Ci::Trigger' + # Creates an object from an actual model with name "relation_sym" with params from + # the relation_hash, updating references with new object IDs, mapping users using + # the "members_mapper" object, also updating notes if required. + def create + set_note_author if @relation_name == :notes + update_user_references + update_project_references + reset_tokens if @relation_name == 'Ci::Trigger' - generate_imported_object(klass, relation_hash, relation_sym) + generate_imported_object end private - def update_user_references(relation_hash, members_map) + def update_user_references USER_REFERENCES.each do |reference| - if relation_hash[reference] - relation_hash[reference] = members_map[relation_hash[reference]] + if @relation_hash[reference] + @relation_hash[reference] = @members_mapper.map[@relation_hash[reference]] end end end - def update_missing_author(relation_hash, members_map, user_admin) - old_author_id = relation_hash['author_id'] + # Sets the author for a note. If the user importing the project + # has admin access, an actual mapping with new project members + # will be used. Otherwise, a note stating the original author name + # is left. + def set_note_author + old_author_id = @relation_hash['author_id'] # Users with admin access can map users - if user_admin - relation_hash['author_id'] = members_map.map[old_author_id] - else - relation_hash['author_id'] = members_map.default_user_id - end + @relation_hash['author_id'] = admin_user? ? @members_mapper.map[old_author_id] : @members_mapper.default_user_id - author = relation_hash.delete('author') + author = @relation_hash.delete('author') - return unless user_admin && members_map.note_member_list.include?(old_author_id) - - relation_hash['note'] = '*Blank note*' if relation_hash['note'].blank? - relation_hash['note'] += missing_author_note(relation_hash['updated_at'], author['name']) + if admin_user? && @members_mapper.note_member_list.include?(old_author_id) + update_note_for_missing_author(author['name']) + end end def missing_author_note(updated_at, author_name) @@ -61,57 +67,60 @@ def missing_author_note(updated_at, author_name) "\n\n *By #{author_name} on #{timestamp} (imported from GitLab project)*" end - def generate_imported_object(klass, relation_hash, relation_sym) - if relation_sym == 'commit_status' # call #trace= method after assigning the other attributes - trace = relation_hash.delete('trace') - imported_object(klass, relation_hash) do |imported_object| - imported_object.trace = trace - imported_object.commit_id = nil + def generate_imported_object + if @relation_sym == 'commit_status' # call #trace= method after assigning the other attributes + trace = @relation_hash.delete('trace') + imported_object do |object| + object.trace = trace + object.commit_id = nil end else - imported_object(klass, relation_hash) + imported_object end end - def update_project_references(relation_hash, klass) - project_id = relation_hash.delete('project_id') - - if relation_hash['source_project_id'] && relation_hash['target_project_id'] - # If source and target are the same, populate them with the new project ID. - if relation_hash['target_project_id'] == relation_hash['source_project_id'] - relation_hash['source_project_id'] = project_id - else - relation_hash['source_project_id'] = -1 - end - end - relation_hash['target_project_id'] = project_id if relation_hash['target_project_id'] + def update_project_references + project_id = @relation_hash.delete('project_id') # project_id may not be part of the export, but we always need to populate it if required. - relation_hash['project_id'] = project_id if klass.column_names.include?('project_id') - relation_hash['gl_project_id'] = project_id if relation_hash ['gl_project_id'] + @relation_hash['project_id'] = project_id if relation_class.column_names.include?('project_id') + @relation_hash['gl_project_id'] = project_id if @relation_hash['gl_project_id'] + @relation_hash['target_project_id'] = project_id if @relation_hash['target_project_id'] + @relation_hash['source_project_id'] = -1 if @relation_hash['source_project_id'] + + # If source and target are the same, populate them with the new project ID. + if @relation_hash['source_project_id'] && @relation_hash['target_project_id'] && + @relation_hash['target_project_id'] == @relation_hash['source_project_id'] + @relation_hash['source_project_id'] = project_id + end end - def reset_tokens(relation_hash) + def reset_tokens return unless Gitlab::ImportExport.reset_tokens? # If we import/export a project to the same instance, tokens will have to be reseated. - relation_hash['token'] = nil - end - - def relation_class(relation_sym) - relation_sym.to_s.classify.constantize + @relation_hash['token'] = nil end - def parse_relation_sym(relation_sym) - OVERRIDES[relation_sym] || relation_sym + def relation_class + @relation_class ||= @relation_name.to_s.classify.constantize end - def imported_object(klass, relation_hash) - imported_object = klass.new(relation_hash) + def imported_object + imported_object = relation_class.new(@relation_hash) yield(imported_object) if block_given? imported_object.importing = true if imported_object.respond_to?(:importing) imported_object end + + def update_note_for_missing_author(author_name) + @relation_hash['note'] = '*Blank note*' if @relation_hash['note'].blank? + @relation_hash['note'] += missing_author_note(@relation_hash['updated_at'], author_name) + end + + def admin_user? + @user_admin + end end end end -- GitLab From 41c06c311b9c5642f6056d0b34030980ebf507b3 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 2 Jun 2016 14:44:59 +0200 Subject: [PATCH 205/714] refactoring more things based on MR feedback --- lib/gitlab/import_export/import_service.rb | 3 ++- lib/gitlab/import_export/relation_factory.rb | 6 +++--- lib/gitlab/import_export/repo_restorer.rb | 9 +++++++-- lib/gitlab/import_export/shared.rb | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 96cb8f4b174789..db71f72efec02f 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -45,7 +45,8 @@ def repo_restorer def wiki_restorer Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, shared: @shared, - project: ProjectWiki.new(project_tree.project)) + project: ProjectWiki.new(project_tree.project), + wiki: true) end def uploads_restorer diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 3738dbaebd318b..dc86862c2d3260 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -30,7 +30,7 @@ def create set_note_author if @relation_name == :notes update_user_references update_project_references - reset_tokens if @relation_name == 'Ci::Trigger' + reset_ci_tokens if @relation_name == 'Ci::Trigger' generate_imported_object end @@ -95,10 +95,10 @@ def update_project_references end end - def reset_tokens + def reset_ci_tokens return unless Gitlab::ImportExport.reset_tokens? - # If we import/export a project to the same instance, tokens will have to be reseated. + # If we import/export a project to the same instance, tokens will have to be reset. @relation_hash['token'] = nil end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 9fac58e2242601..d6dcf5dc11681e 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,14 +3,15 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project:, shared:, path_to_bundle:) + def initialize(project:, shared:, path_to_bundle:, wiki: false) @project = project @path_to_bundle = path_to_bundle @shared = shared + @wiki = wiki end def restore - return true unless File.exists?(@path_to_bundle) + return false unless File.exists?(@path_to_bundle) || wiki? FileUtils.mkdir_p(path_to_repo) @@ -29,6 +30,10 @@ def repos_path def path_to_repo @project.repository.path_to_repo end + + def wiki? + @wiki + end end end end diff --git a/lib/gitlab/import_export/shared.rb b/lib/gitlab/import_export/shared.rb index 01ac332981b472..6aff05b886a011 100644 --- a/lib/gitlab/import_export/shared.rb +++ b/lib/gitlab/import_export/shared.rb @@ -10,7 +10,7 @@ def initialize(opts) end def export_path - @export_path ||= Gitlab::ImportExport.export_path(relative_path: @opts[:relative_path]) + @export_path ||= Gitlab::ImportExport.export_path(relative_path: opts[:relative_path]) end def error(error) -- GitLab From a1295d8ebef223eb0a87bc9e1660efcb9147599c Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 08:58:15 +0530 Subject: [PATCH 206/714] Don't use `natve['innerHTML']` in the feature spec. - The `have_text` matcher works fine. --- .../profiles/personal_access_tokens_spec.rb | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 095c7d60e29e11..14f2a7c9a254e8 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -4,15 +4,15 @@ let(:user) { create(:user) } def active_personal_access_tokens - find(".table.active-personal-access-tokens").native['innerHTML'] + find(".table.active-personal-access-tokens") end def inactive_personal_access_tokens - find(".table.inactive-personal-access-tokens").native['innerHTML'] + find(".table.inactive-personal-access-tokens") end def created_personal_access_token - find(".created-personal-access-token pre").native['innerHTML'] + find(".created-personal-access-token pre") end before do @@ -25,9 +25,9 @@ def created_personal_access_token fill_in "Name", with: FFaker::Product.brand expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) - expect(created_personal_access_token).to eq(PersonalAccessToken.last.token) - expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) - expect(active_personal_access_tokens).to match("Never") + expect(created_personal_access_token).to have_text(PersonalAccessToken.last.token) + expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.name) + expect(active_personal_access_tokens).to have_text("Never") end it "allows creation of a token with an expiry date" do @@ -39,9 +39,9 @@ def created_personal_access_token click_on "1" expect {click_on "Add Personal Access Token"}.to change { PersonalAccessToken.count }.by(1) - expect(created_personal_access_token).to eq(PersonalAccessToken.last.token) - expect(active_personal_access_tokens).to match(PersonalAccessToken.last.name) - expect(active_personal_access_tokens).to match(Date.today.next_month.at_beginning_of_month.to_s(:medium)) + expect(created_personal_access_token).to have_text(PersonalAccessToken.last.token) + expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.name) + expect(active_personal_access_tokens).to have_text(Date.today.next_month.at_beginning_of_month.to_s(:medium)) end end @@ -51,14 +51,14 @@ def created_personal_access_token visit profile_personal_access_tokens_path click_on "Revoke" - expect(inactive_personal_access_tokens).to match(personal_access_token.name) + expect(inactive_personal_access_tokens).to have_text(personal_access_token.name) end it "moves expired tokens to the 'inactive' section" do personal_access_token = create(:personal_access_token, expires_at: 5.days.ago, user: user) visit profile_personal_access_tokens_path - expect(inactive_personal_access_tokens).to match(personal_access_token.name) + expect(inactive_personal_access_tokens).to have_text(personal_access_token.name) end end end -- GitLab From b4b024857783e1fc39424fdf631b722ee1dfd195 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 09:00:39 +0530 Subject: [PATCH 207/714] Parts of spec names with "when" should be contexts. --- .../application_controller_spec.rb | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 90dbd1183ebdc5..ff596e7c2ad79b 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -41,17 +41,22 @@ def index let(:user) { create(:user) } - it "logs the user in when the 'private_token' param is populated with the private token" do - get :index, private_token: user.private_token - expect(response.status).to eq(200) - expect(response.body).to eq("authenticated") + context "when the 'private_token' param is populated with the private token" do + it "logs the user in" do + get :index, private_token: user.private_token + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end end - it "logs the user in when the 'PRIVATE-TOKEN' header is populated with the private token" do - @request.headers['PRIVATE-TOKEN'] = user.private_token - get :index - expect(response.status).to eq(200) - expect(response.body).to eq("authenticated") + + context "when the 'PRIVATE-TOKEN' header is populated with the private token" do + it "logs the user in" do + @request.headers['PRIVATE-TOKEN'] = user.private_token + get :index + expect(response.status).to eq(200) + expect(response.body).to eq("authenticated") + end end it "doesn't log the user in otherwise" do @@ -72,17 +77,21 @@ def index let(:user) { create(:user) } let(:personal_access_token) { create(:personal_access_token, user: user) } - it "logs the user in when the 'personal_access_token' param is populated with the personal access token" do - get :index, private_token: personal_access_token.token - expect(response.status).to eq(200) - expect(response.body).to eq('authenticated') + context "when the 'personal_access_token' param is populated with the personal access token" do + it "logs the user in" do + get :index, private_token: personal_access_token.token + expect(response.status).to eq(200) + expect(response.body).to eq('authenticated') + end end - it "logs the user in when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do - @request.headers["PRIVATE-TOKEN"] = personal_access_token.token - get :index - expect(response.status).to eq(200) - expect(response.body).to eq('authenticated') + context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do + it "logs the user in" do + @request.headers["PRIVATE-TOKEN"] = personal_access_token.token + get :index + expect(response.status).to eq(200) + expect(response.body).to eq('authenticated') + end end it "doesn't log the user in otherwise" do -- GitLab From 399a633061577b8a2ca95c29ce1cfe0abeac4779 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 09:07:37 +0530 Subject: [PATCH 208/714] Fix minor styling issues. - No "Actions" label necessary - `%td` can be moved out of `if/else` - Page header should be "Profile Settings", not "Personal Access Tokens" - "You don't have any tokens" message should be styled consistently --- .../personal_access_tokens/index.html.haml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 503f88efb43933..68f2813bc1a08b 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -1,12 +1,11 @@ - page_title "Personal Access Tokens" -- header_title page_title, profile_personal_access_tokens_path .row.prepend-top-default .col-lg-3.profile-settings-sidebar %h4.prepend-top-0 = page_title %p - You can generate a personal access token for each application you use that needs access to GitLab. + You can generate a personal access token for each application you use that needs access to the GitLab API. .col-lg-9 - if flash[:personal_access_token] @@ -49,21 +48,22 @@ %th Name %th Created %th Expires - %th Actions + %th %tbody - @active_personal_access_tokens.each do |token| %tr %td= token.name %td= token.created_at.to_date.to_s(:medium) - - if token.expires_at.present? - %td= token.expires_at.to_date.to_s(:medium) - - else - %td + %td + - if token.expires_at.present? + = token.expires_at.to_date.to_s(:medium) + - else %span.personal-access-tokens-never-expires-label Never %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: { confirm: "Are you sure? This cannot be undone." } - else - %span You don't have any active tokens yet. + .settings-message.text-center + You don't have any active tokens yet. %hr @@ -83,7 +83,8 @@ %td= token.created_at.to_date.to_s(:medium) - else - %span No inactive tokens. + .settings-message.text-center + There are no inactive tokens. :javascript -- GitLab From ffe111c1e22b0cce827c297fea62dfb0bd91326a Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 09:23:16 +0530 Subject: [PATCH 209/714] Display appropriate errors when personal access token creation/revocation fails. --- .../profiles/personal_access_tokens_controller.rb | 12 +++++++++--- .../profiles/personal_access_tokens/index.html.haml | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index 81f2390a566e1e..a1545a5dd003e5 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -1,7 +1,7 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController + before_action :load_personal_access_tokens, only: :index + def index - @active_personal_access_tokens = current_user.personal_access_tokens.active.order(:expires_at) - @inactive_personal_access_tokens = current_user.personal_access_tokens.inactive @personal_access_token = current_user.personal_access_tokens.build end @@ -12,6 +12,7 @@ def create flash[:personal_access_token] = @personal_access_token.token redirect_to profile_personal_access_tokens_path else + load_personal_access_tokens render :index end end @@ -22,7 +23,7 @@ def revoke if @personal_access_token.revoke! redirect_to profile_personal_access_tokens_path, notice: "Revoked personal access token #{@personal_access_token.name}!" else - render :index + redirect_to profile_personal_access_tokens_path, alert: "Could not revoke personal access token #{@personal_access_token.name}." end end @@ -31,4 +32,9 @@ def revoke def personal_access_token_params params.require(:personal_access_token).permit(:name, :expires_at) end + + def load_personal_access_tokens + @active_personal_access_tokens = current_user.personal_access_tokens.active.order(:expires_at) + @inactive_personal_access_tokens = current_user.personal_access_tokens.inactive + end end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 68f2813bc1a08b..64e632b20e5495 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -24,6 +24,8 @@ = form_for [:profile, @personal_access_token], method: :post, html: { class: 'js-requires-input' } do |f| + = form_errors(@personal_access_token) + .form-group = f.label :name, class: 'label-light' = f.text_field :name, class: "form-control", required: true -- GitLab From 1a416720a2261f453ec4ce539fa61c1c32769aea Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 09:31:56 +0530 Subject: [PATCH 210/714] Update CHANGELOG. --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 547921a0777628..57a006869cfff9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,7 @@ v 8.9.0 (unreleased) - Link to blank group icon doesn't throw a 404 anymore - Remove 'main language' feature - Pipelines can be canceled only when there are running builds + - Allow authentication using personal access tokens - Use downcased path to container repository as this is expected path by Docker - Projects pending deletion will render a 404 page - Measure queue duration between gitlab-workhorse and Rails @@ -92,7 +93,6 @@ v 8.8.0 - GitAccess#protected_tag? no longer loads all tags just to check if a single one exists - Reduce delay in destroying a project from 1-minute to immediately - Make build status canceled if any of the jobs was canceled and none failed - - Allow authentication using personal access tokens - Upgrade Sidekiq to 4.1.2 - Added /health_check endpoint for checking service status - Make 'upcoming' filter for milestones work better across projects -- GitLab From 3adf125a155fd04fbba4f0882c739eae1cc73e15 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 09:53:49 +0530 Subject: [PATCH 211/714] Add tests for errors while creating/revoking personal access tokens. --- .../profiles/personal_access_tokens_spec.rb | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 14f2a7c9a254e8..5bba08d005c53b 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -15,6 +15,12 @@ def created_personal_access_token find(".created-personal-access-token pre") end + def disallow_personal_access_token_saves! + allow_any_instance_of(PersonalAccessToken).to receive(:save).and_return(false) + errors = ActiveModel::Errors.new(PersonalAccessToken.new).tap { |e| e.add(:name, "cannot be nil") } + allow_any_instance_of(PersonalAccessToken).to receive(:errors).and_return(errors) + end + before do login_as(user) end @@ -43,11 +49,23 @@ def created_personal_access_token expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.name) expect(active_personal_access_tokens).to have_text(Date.today.next_month.at_beginning_of_month.to_s(:medium)) end + + context "when creation fails" do + it "displays an error message" do + disallow_personal_access_token_saves! + visit profile_personal_access_tokens_path + fill_in "Name", with: FFaker::Product.brand + + expect { click_on "Add Personal Access Token" }.not_to change { PersonalAccessToken.count } + expect(page).to have_content("Name cannot be nil") + end + end end describe "inactive tokens" do + let!(:personal_access_token) { create(:personal_access_token, user: user) } + it "allows revocation of an active token" do - personal_access_token = create(:personal_access_token, user: user) visit profile_personal_access_tokens_path click_on "Revoke" @@ -55,10 +73,21 @@ def created_personal_access_token end it "moves expired tokens to the 'inactive' section" do - personal_access_token = create(:personal_access_token, expires_at: 5.days.ago, user: user) + personal_access_token.update(expires_at: 5.days.ago) visit profile_personal_access_tokens_path expect(inactive_personal_access_tokens).to have_text(personal_access_token.name) end + + context "when revocation fails" do + it "displays an error message" do + disallow_personal_access_token_saves! + visit profile_personal_access_tokens_path + + expect { click_on "Revoke" }.not_to change { PersonalAccessToken.inactive.count } + expect(active_personal_access_tokens).to have_text(personal_access_token.name) + expect(page).to have_content("Could not revoke") + end + end end end -- GitLab From 0dff6fd7148957fa94d2626e3912cd929ba150d3 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 3 Jun 2016 10:10:58 +0530 Subject: [PATCH 212/714] Fix rubocop spec. --- app/controllers/application_controller.rb | 2 +- spec/controllers/application_controller_spec.rb | 8 ++++---- spec/models/personal_access_token_spec.rb | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c8baea2579be70..23a0e16ca43350 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -368,7 +368,7 @@ def is_a_listing_page_for?(page_type) # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 def get_user_from_private_token - user_token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence + user_token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence User.find_by_authentication_token(user_token.to_s) if user_token end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index ff596e7c2ad79b..ff5b3916273a74 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -62,8 +62,8 @@ def index it "doesn't log the user in otherwise" do @request.headers['PRIVATE-TOKEN'] = "token" get :index, private_token: "token", authenticity_token: "token" - expect(response.status).to_not eq(200) - expect(response.body).to_not eq("authenticated") + expect(response.status).not_to eq(200) + expect(response.body).not_to eq("authenticated") end end @@ -96,8 +96,8 @@ def index it "doesn't log the user in otherwise" do get :index, private_token: "token" - expect(response.status).to_not eq(200) - expect(response.body).to_not eq('authenticated') + expect(response.status).not_to eq(200) + expect(response.body).not_to eq('authenticated') end end end diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb index 3e80a48175a7b3..46eb71cef145bd 100644 --- a/spec/models/personal_access_token_spec.rb +++ b/spec/models/personal_access_token_spec.rb @@ -9,7 +9,7 @@ it "doesn't save the record" do personal_access_token = PersonalAccessToken.generate({}) - expect(personal_access_token).to_not be_persisted + expect(personal_access_token).not_to be_persisted end end end -- GitLab From 3e99123095b26988de67a94b0e7a5207c1ef5ae2 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 3 Jun 2016 10:57:46 +0200 Subject: [PATCH 213/714] Fix merge conflicts - squashed commit # Conflicts: # app/models/project.rb --- .gitignore | 78 +-- .rubocop.yml | 273 ++++++--- ...t_discussion.html.haml => .vagrant_enabled | 0 CHANGELOG | 154 ++++- CONTRIBUTING.md | 6 +- GITLAB_SHELL_VERSION | 2 +- GITLAB_WORKHORSE_VERSION | 2 +- Gemfile | 39 +- Gemfile.lock | 212 ++----- README.md | 6 +- VERSION | 2 +- app/assets/images/ci/arch.jpg | Bin 25222 -> 0 bytes app/assets/images/ci/favicon.ico | Bin 5430 -> 0 bytes app/assets/images/ci/loader.gif | Bin 4405 -> 0 bytes app/assets/images/ci/no_avatar.png | Bin 1337 -> 0 bytes app/assets/images/ci/rails.png | Bin 6646 -> 0 bytes app/assets/images/ci/service_sample.png | Bin 76024 -> 0 bytes .../images/mailers/gitlab_header_logo.png | Bin 0 -> 7096 bytes .../images/mailers/gitlab_tanuki_2x.png | Bin 0 -> 2545 bytes app/assets/javascripts/api.js.coffee | 35 +- app/assets/javascripts/application.js.coffee | 43 +- .../blob/blob_gitignore_selector.js.coffee | 58 ++ .../javascripts/blob/edit_blob.js.coffee | 1 + app/assets/javascripts/calendar.js.coffee | 34 -- .../javascripts/ci/application.js.coffee | 28 - app/assets/javascripts/ci/build.coffee | 24 +- app/assets/javascripts/dispatcher.js.coffee | 3 +- .../javascripts/due_date_select.js.coffee | 35 +- .../javascripts/gfm_auto_complete.js.coffee | 19 + app/assets/javascripts/gl_dropdown.js.coffee | 82 ++- .../javascripts/graphs/application.js.coffee | 7 + .../{ => graphs}/stat_graph.js.coffee | 0 .../stat_graph_contributors.js.coffee | 1 - .../stat_graph_contributors_graph.js.coffee | 2 - .../stat_graph_contributors_util.js.coffee | 0 app/assets/javascripts/issuable.js.coffee | 48 +- .../javascripts/issuable_form.js.coffee | 26 + app/assets/javascripts/issues.js.coffee | 38 -- app/assets/javascripts/layout_nav.js.coffee | 14 + .../javascripts/lib/type_utility.js.coffee | 9 + .../javascripts/lib/url_utility.js.coffee | 11 +- .../javascripts/merge_request_tabs.js.coffee | 3 + .../merge_request_widget.js.coffee | 15 +- app/assets/javascripts/notes.js.coffee | 12 +- .../javascripts/right_sidebar.js.coffee | 36 +- .../javascripts/search_autocomplete.js.coffee | 22 +- .../shortcuts_dashboard_navigation.js.coffee | 8 +- .../javascripts/shortcuts_issuable.coffee | 4 + app/assets/javascripts/sidebar.js.coffee | 2 +- app/assets/javascripts/user_tabs.js.coffee | 9 +- .../javascripts/users/application.js.coffee | 8 + .../javascripts/users/calendar.js.coffee | 198 +++++++ app/assets/javascripts/users_select.js.coffee | 12 +- app/assets/stylesheets/application.scss | 2 - app/assets/stylesheets/framework.scss | 1 + .../stylesheets/framework/animations.scss | 72 +++ app/assets/stylesheets/framework/avatar.scss | 1 + app/assets/stylesheets/framework/blocks.scss | 11 +- app/assets/stylesheets/framework/buttons.scss | 18 +- .../stylesheets/framework/calendar.scss | 72 +-- app/assets/stylesheets/framework/common.scss | 2 +- .../stylesheets/framework/dropdowns.scss | 6 +- app/assets/stylesheets/framework/files.scss | 31 +- app/assets/stylesheets/framework/forms.scss | 8 +- .../stylesheets/framework/gitlab-theme.scss | 17 +- app/assets/stylesheets/framework/header.scss | 58 +- app/assets/stylesheets/framework/mobile.scss | 4 - app/assets/stylesheets/framework/nav.scss | 122 +++- app/assets/stylesheets/framework/sidebar.scss | 52 +- .../stylesheets/framework/typography.scss | 8 + .../stylesheets/framework/variables.scss | 15 +- app/assets/stylesheets/framework/zen.scss | 2 +- app/assets/stylesheets/mailers/devise.scss | 134 +++++ .../mailers/repository_push_email.scss | 43 ++ app/assets/stylesheets/pages/commit.scss | 24 +- app/assets/stylesheets/pages/detail_page.scss | 2 - app/assets/stylesheets/pages/editor.scss | 21 +- app/assets/stylesheets/pages/issuable.scss | 6 +- app/assets/stylesheets/pages/issues.scss | 10 - .../stylesheets/pages/merge_requests.scss | 31 +- app/assets/stylesheets/pages/notes.scss | 3 +- app/assets/stylesheets/pages/pipelines.scss | 24 + app/assets/stylesheets/pages/profile.scss | 16 +- app/assets/stylesheets/pages/projects.scss | 170 ++++-- app/assets/stylesheets/pages/search.scss | 4 +- app/assets/stylesheets/pages/settings.scss | 8 + app/assets/stylesheets/pages/snippets.scss | 44 +- app/assets/stylesheets/pages/todos.scss | 14 +- app/assets/stylesheets/pages/tree.scss | 13 +- .../admin/abuse_reports_controller.rb | 2 +- .../admin/application_settings_controller.rb | 17 +- .../admin/broadcast_messages_controller.rb | 2 +- .../admin/health_check_controller.rb | 5 + app/controllers/admin/keys_controller.rb | 2 +- app/controllers/admin/runners_controller.rb | 37 +- app/controllers/admin/spam_logs_controller.rb | 2 +- app/controllers/admin/users_controller.rb | 3 +- app/controllers/application_controller.rb | 6 +- app/controllers/autocomplete_controller.rb | 18 + app/controllers/concerns/creates_commit.rb | 2 +- .../concerns/toggle_subscription_action.rb | 2 +- .../dashboard/labels_controller.rb | 2 +- .../dashboard/projects_controller.rb | 2 +- app/controllers/dashboard/todos_controller.rb | 4 +- app/controllers/dashboard_controller.rb | 2 +- .../groups/group_members_controller.rb | 2 +- app/controllers/health_check_controller.rb | 22 + app/controllers/jwt_controller.rb | 87 +++ .../omniauth_callbacks_controller.rb | 2 +- app/controllers/profiles/emails_controller.rb | 2 +- app/controllers/profiles/keys_controller.rb | 2 +- .../projects/application_controller.rb | 2 +- .../projects/branches_controller.rb | 2 +- app/controllers/projects/builds_controller.rb | 8 + app/controllers/projects/commit_controller.rb | 12 +- .../projects/compare_controller.rb | 3 +- .../projects/container_registry_controller.rb | 34 ++ .../projects/find_file_controller.rb | 52 +- app/controllers/projects/hooks_controller.rb | 9 +- .../projects/imports_controller.rb | 1 + .../projects/merge_requests_controller.rb | 16 +- .../projects/milestones_controller.rb | 2 +- app/controllers/projects/notes_controller.rb | 10 +- .../projects/pipelines_controller.rb | 59 ++ .../projects/project_members_controller.rb | 4 +- .../projects/protected_branches_controller.rb | 2 +- .../projects/runners_controller.rb | 4 +- .../projects/variables_controller.rb | 30 +- app/controllers/projects/wikis_controller.rb | 4 +- app/controllers/projects_controller.rb | 16 +- app/controllers/registrations_controller.rb | 4 +- app/controllers/sessions_controller.rb | 2 + app/controllers/snippets_controller.rb | 2 +- app/controllers/users_controller.rb | 24 +- app/finders/group_projects_finder.rb | 2 +- app/finders/issuable_finder.rb | 10 +- app/finders/notes_finder.rb | 2 +- app/finders/pipelines_finder.rb | 38 ++ app/finders/todos_finder.rb | 2 +- app/helpers/application_helper.rb | 20 +- app/helpers/application_settings_helper.rb | 14 + app/helpers/auth_helper.rb | 10 + app/helpers/blob_helper.rb | 10 + app/helpers/button_helper.rb | 2 +- app/helpers/ci_status_helper.rb | 29 +- app/helpers/commits_helper.rb | 19 +- app/helpers/diff_helper.rb | 30 +- app/helpers/emails_helper.rb | 6 - app/helpers/events_helper.rb | 92 +-- app/helpers/gitlab_markdown_helper.rb | 2 +- app/helpers/gitlab_routing_helper.rb | 4 + app/helpers/groups_helper.rb | 2 +- app/helpers/issuables_helper.rb | 10 +- app/helpers/issues_helper.rb | 21 +- app/helpers/javascript_helper.rb | 7 + app/helpers/nav_helper.rb | 8 + app/helpers/notes_helper.rb | 29 +- app/helpers/projects_helper.rb | 21 +- app/helpers/search_helper.rb | 2 +- app/helpers/selects_helper.rb | 2 +- app/helpers/tab_helper.rb | 6 +- app/helpers/todos_helper.rb | 28 +- app/mailers/devise_mailer.rb | 2 + app/mailers/emails/projects.rb | 8 +- app/mailers/notify.rb | 2 + app/models/ability.rb | 54 +- app/models/abuse_report.rb | 12 - app/models/appearance.rb | 13 - app/models/application_setting.rb | 80 +-- app/models/audit_event.rb | 14 - app/models/broadcast_message.rb | 14 - app/models/ci/build.rb | 57 +- app/models/ci/commit.rb | 50 +- app/models/ci/runner.rb | 39 +- app/models/ci/runner_project.rb | 12 - app/models/ci/trigger.rb | 13 - app/models/ci/trigger_request.rb | 12 - app/models/ci/variable.rb | 19 +- app/models/commit.rb | 23 +- app/models/commit_range.rb | 2 +- app/models/commit_status.rb | 54 +- app/models/concerns/issuable.rb | 57 +- app/models/concerns/mentionable.rb | 19 +- app/models/concerns/participable.rb | 94 +-- app/models/concerns/subscribable.rb | 6 + app/models/deploy_key.rb | 15 - app/models/deploy_keys_project.rb | 11 - app/models/email.rb | 11 - app/models/event.rb | 51 +- app/models/forked_project_link.rb | 11 - app/models/generic_commit_status.rb | 37 -- app/models/group.rb | 17 - app/models/hooks/project_hook.rb | 22 - app/models/hooks/service_hook.rb | 22 - app/models/hooks/system_hook.rb | 22 - app/models/hooks/web_hook.rb | 24 +- app/models/identity.rb | 12 - app/models/issue.rb | 47 +- app/models/key.rb | 17 +- app/models/label.rb | 18 +- app/models/label_link.rb | 12 - app/models/legacy_diff_note.rb | 157 +++++ app/models/lfs_object.rb | 12 - app/models/lfs_objects_project.rb | 11 - app/models/member.rb | 19 - app/models/members/group_member.rb | 19 - app/models/members/project_member.rb | 26 +- app/models/merge_request.rb | 59 +- app/models/merge_request_diff.rb | 45 +- app/models/milestone.rb | 91 ++- app/models/namespace.rb | 25 +- app/models/network/graph.rb | 35 +- app/models/note.rb | 269 ++------- app/models/notification_setting.rb | 13 - app/models/oauth_access_token.rb | 15 - app/models/personal_snippet.rb | 16 - app/models/project.rb | 161 +++--- app/models/project_group_link.rb | 12 - app/models/project_import_data.rb | 15 +- app/models/project_services/asana_service.rb | 24 - .../project_services/assembla_service.rb | 24 - app/models/project_services/bamboo_service.rb | 24 - .../project_services/buildkite_service.rb | 24 - .../project_services/builds_email_service.rb | 24 - .../project_services/campfire_service.rb | 24 - app/models/project_services/ci_service.rb | 24 - .../custom_issue_tracker_service.rb | 24 - .../project_services/drone_ci_service.rb | 24 - .../emails_on_push_service.rb | 24 - .../project_services/external_wiki_service.rb | 26 +- .../project_services/flowdock_service.rb | 24 - .../project_services/gemnasium_service.rb | 24 - .../project_services/gitlab_ci_service.rb | 24 - .../gitlab_issue_tracker_service.rb | 24 - .../project_services/hipchat_service.rb | 24 - app/models/project_services/irker_service.rb | 26 +- .../project_services/issue_tracker_service.rb | 24 - app/models/project_services/jira_service.rb | 24 - .../pivotaltracker_service.rb | 24 - .../project_services/pushover_service.rb | 24 - .../project_services/redmine_service.rb | 24 - app/models/project_services/slack_service.rb | 24 - .../slack_service/build_message.rb | 4 +- .../slack_service/issue_message.rb | 19 +- .../project_services/teamcity_service.rb | 24 - app/models/project_snippet.rb | 19 +- app/models/project_wiki.rb | 18 +- app/models/protected_branch.rb | 12 - app/models/release.rb | 12 - app/models/repository.rb | 56 +- app/models/security_event.rb | 14 - app/models/sent_notification.rb | 14 - app/models/service.rb | 24 - app/models/snippet.rb | 23 +- app/models/spam_log.rb | 17 - app/models/subscription.rb | 13 - app/models/todo.rb | 27 +- app/models/user.rb | 110 ++-- app/models/users_star_project.rb | 11 - ...ntainer_registry_authentication_service.rb | 87 +++ app/services/ci/create_pipeline_service.rb | 50 ++ app/services/create_commit_builds_service.rb | 17 +- app/services/git_push_service.rb | 17 - app/services/git_tag_push_service.rb | 2 +- app/services/issues/update_service.rb | 10 + .../add_todo_when_build_fails_service.rb | 17 + app/services/merge_requests/base_service.rb | 25 + app/services/merge_requests/build_service.rb | 2 +- app/services/merge_requests/create_service.rb | 7 +- app/services/merge_requests/merge_service.rb | 8 +- .../merge_when_build_succeeds_service.rb | 23 +- .../merge_requests/refresh_service.rb | 7 + app/services/merge_requests/update_service.rb | 2 + app/services/notes/create_service.rb | 11 - app/services/projects/autocomplete_service.rb | 4 + app/services/projects/create_service.rb | 43 +- app/services/projects/destroy_service.rb | 12 +- app/services/projects/fork_service.rb | 14 +- app/services/projects/housekeeping_service.rb | 2 +- app/services/projects/import_service.rb | 2 +- app/services/projects/transfer_service.rb | 5 + app/services/system_hooks_service.rb | 2 +- app/services/system_note_service.rb | 25 +- app/services/todo_service.rb | 30 + app/services/wiki_pages/base_service.rb | 5 +- .../abuse_reports/_abuse_report.html.haml | 2 +- .../application_settings/_form.html.haml | 21 + app/views/admin/builds/index.html.haml | 3 +- app/views/admin/health_check/show.html.haml | 49 ++ app/views/admin/runners/_runner.html.haml | 12 +- app/views/admin/runners/show.html.haml | 24 +- app/views/dashboard/issues.atom.builder | 5 +- .../dashboard/projects/index.atom.builder | 4 +- app/views/dashboard/todos/_todo.html.haml | 14 +- .../mailer/confirmation_instructions.html.erb | 9 - .../confirmation_instructions.html.haml | 16 + .../mailer/confirmation_instructions.text.erb | 9 + app/views/devise/sessions/new.html.haml | 2 +- .../devise/sessions/two_factor.html.haml | 1 + .../devise/shared/_omniauth_box.html.haml | 2 +- .../doorkeeper/authorizations/new.html.haml | 2 +- app/views/events/_commit.html.haml | 2 +- app/views/events/_event.atom.builder | 20 + app/views/events/_event_issue.atom.haml | 2 +- .../events/_event_merge_request.atom.haml | 2 +- app/views/events/_event_note.atom.haml | 2 +- app/views/events/_event_push.atom.haml | 2 +- app/views/events/event/_common.html.haml | 2 +- app/views/events/event/_push.html.haml | 2 +- app/views/groups/_activities.html.haml | 2 +- app/views/groups/issues.atom.builder | 13 +- app/views/groups/show.atom.builder | 4 +- app/views/import/gitlab/status.html.haml | 2 +- app/views/issues/_issue.atom.builder | 14 + .../kaminari/gitlab/_first_page.html.haml | 2 +- app/views/kaminari/gitlab/_gap.html.haml | 2 +- .../kaminari/gitlab/_last_page.html.haml | 2 +- .../kaminari/gitlab/_next_page.html.haml | 2 +- app/views/kaminari/gitlab/_page.html.haml | 2 +- .../kaminari/gitlab/_paginator.html.haml | 6 +- .../kaminari/gitlab/_prev_page.html.haml | 2 +- app/views/layouts/_head.html.haml | 3 + app/views/layouts/_page.html.haml | 4 +- app/views/layouts/_search.html.haml | 7 +- app/views/layouts/devise_mailer.html.haml | 34 ++ app/views/layouts/header/_default.html.haml | 10 +- app/views/layouts/nav/_admin.html.haml | 5 + app/views/layouts/nav/_dashboard.html.haml | 14 +- app/views/layouts/nav/_group.html.haml | 75 +-- .../layouts/nav/_group_settings.html.haml | 2 +- app/views/layouts/nav/_profile.html.haml | 4 +- app/views/layouts/nav/_project.html.haml | 250 ++++---- .../layouts/nav/_project_settings.html.haml | 102 ++-- app/views/layouts/notify.html.haml | 1 + app/views/layouts/project.html.haml | 2 +- app/views/layouts/project_settings.html.haml | 3 +- app/views/notify/_note_message.html.haml | 2 +- app/views/notify/new_issue_email.html.haml | 2 +- .../notify/new_merge_request_email.html.haml | 2 +- .../notify/note_merge_request_email.html.haml | 4 +- .../notify/repository_push_email.html.haml | 59 +- .../notify/repository_push_email.text.haml | 38 +- app/views/profiles/accounts/show.html.haml | 4 +- app/views/profiles/preferences/show.html.haml | 2 +- app/views/projects/_builds_settings.html.haml | 119 ++-- app/views/projects/_home_panel.html.haml | 86 +-- app/views/projects/_md_preview.html.haml | 2 +- app/views/projects/_zen.html.haml | 2 +- app/views/projects/activity.html.haml | 1 - app/views/projects/artifacts/browse.html.haml | 1 - app/views/projects/badges/index.html.haml | 1 - app/views/projects/blame/show.html.haml | 1 - app/views/projects/blob/_editor.html.haml | 3 + .../projects/blob/_header_title.html.haml | 1 - app/views/projects/blob/edit.html.haml | 1 - app/views/projects/blob/new.html.haml | 1 - app/views/projects/blob/show.html.haml | 1 - app/views/projects/branches/destroy.js.haml | 1 - app/views/projects/branches/index.html.haml | 1 - app/views/projects/branches/new.html.haml | 1 - .../projects/builds/_header_title.html.haml | 1 - app/views/projects/builds/index.html.haml | 5 +- app/views/projects/builds/show.html.haml | 8 +- .../projects/buttons/_dropdown.html.haml | 2 +- app/views/projects/buttons/_fork.html.haml | 5 +- .../projects/buttons/_notifications.html.haml | 6 +- app/views/projects/ci/builds/_build.html.haml | 10 +- .../projects/ci/commits/_commit.html.haml | 71 +++ app/views/projects/commit/_builds.html.haml | 2 +- .../projects/commit/_ci_commit.html.haml | 63 +- app/views/projects/commit/_ci_stage.html.haml | 15 + .../projects/commit/_commit_box.html.haml | 78 +-- app/views/projects/commit/builds.html.haml | 4 +- app/views/projects/commit/show.html.haml | 2 - .../projects/commits/_commit.atom.builder | 14 + app/views/projects/commits/_commit.html.haml | 4 +- app/views/projects/commits/_commits.html.haml | 2 +- app/views/projects/commits/_head.html.haml | 8 +- .../projects/commits/_header_title.html.haml | 1 - app/views/projects/commits/show.atom.builder | 15 +- app/views/projects/commits/show.html.haml | 1 - app/views/projects/compare/index.html.haml | 1 - app/views/projects/compare/show.html.haml | 1 - .../container_registry/_tag.html.haml | 21 + .../container_registry/index.html.haml | 39 ++ .../projects/deploy_keys/index.html.haml | 4 +- app/views/projects/diffs/_file.html.haml | 8 +- app/views/projects/diffs/_line.html.haml | 2 +- .../projects/diffs/_parallel_view.html.haml | 14 +- app/views/projects/diffs/_text_file.html.haml | 9 +- app/views/projects/edit.html.haml | 445 +++++++------- app/views/projects/empty.html.haml | 10 +- app/views/projects/find_file/show.html.haml | 1 - .../_generic_commit_status.html.haml | 15 +- app/views/projects/graphs/_head.html.haml | 1 + .../projects/graphs/_header_title.html.haml | 1 - app/views/projects/graphs/ci.html.haml | 1 - app/views/projects/graphs/commits.html.haml | 1 - app/views/projects/graphs/languages.html.haml | 1 - app/views/projects/graphs/show.html.haml | 3 +- .../projects/hooks/_project_hook.html.haml | 2 +- app/views/projects/hooks/index.html.haml | 9 +- .../projects/issues/_header_title.html.haml | 1 - app/views/projects/issues/_issue.html.haml | 16 +- .../projects/issues/_merge_requests.html.haml | 7 +- .../issues/_related_branches.html.haml | 2 +- app/views/projects/issues/edit.html.haml | 1 - app/views/projects/issues/index.atom.builder | 4 +- app/views/projects/issues/index.html.haml | 1 - app/views/projects/issues/new.html.haml | 1 - app/views/projects/issues/show.html.haml | 5 +- .../projects/labels/_header_title.html.haml | 1 - app/views/projects/labels/edit.html.haml | 1 - app/views/projects/labels/index.html.haml | 3 +- app/views/projects/labels/new.html.haml | 1 - .../merge_requests/_header_title.html.haml | 1 - .../merge_requests/_merge_request.html.haml | 18 +- .../projects/merge_requests/_show.html.haml | 1 - .../dropdowns/_branch.html.haml | 2 +- .../projects/merge_requests/edit.html.haml | 1 - .../projects/merge_requests/index.html.haml | 1 - .../projects/merge_requests/invalid.html.haml | 1 - .../projects/merge_requests/new.html.haml | 1 - .../merge_requests/show/_mr_box.html.haml | 4 +- .../merge_requests/widget/_open.html.haml | 2 +- .../merge_requests/widget/_show.html.haml | 8 +- .../widget/open/_accept.html.haml | 5 +- .../open/_merge_when_build_succeeds.html.haml | 5 +- .../widget/open/_not_allowed.html.haml | 4 +- .../milestones/_header_title.html.haml | 1 - app/views/projects/milestones/edit.html.haml | 1 - app/views/projects/milestones/index.html.haml | 2 - app/views/projects/milestones/new.html.haml | 1 - app/views/projects/milestones/show.html.haml | 2 - app/views/projects/network/show.html.haml | 1 - app/views/projects/new.html.haml | 2 +- .../notes/_diff_notes_with_reply.html.haml | 18 +- .../_diff_notes_with_reply_parallel.html.haml | 20 +- .../projects/notes/_discussion.html.haml | 47 +- app/views/projects/notes/_form.html.haml | 1 + app/views/projects/notes/_note.html.haml | 11 +- app/views/projects/notes/_notes.html.haml | 9 +- .../notes/discussions/_active.html.haml | 16 - .../notes/discussions/_commit.html.haml | 25 - .../notes/discussions/_diff.html.haml | 28 - .../discussions/_diff_with_notes.html.haml | 30 + .../notes/discussions/_notes.html.haml | 7 + .../notes/discussions/_outdated.html.haml | 14 - app/views/projects/pipelines/_head.html.haml | 14 + app/views/projects/pipelines/_info.html.haml | 37 ++ app/views/projects/pipelines/index.html.haml | 58 ++ app/views/projects/pipelines/new.html.haml | 21 + app/views/projects/pipelines/show.html.haml | 8 + .../project_members/_header_title.html.haml | 1 - .../projects/project_members/import.html.haml | 1 - .../projects/project_members/index.html.haml | 1 - .../_branches_list.html.haml | 2 +- app/views/projects/releases/edit.html.haml | 1 - .../projects/repositories/_feed.html.haml | 2 +- app/views/projects/runners/_form.html.haml | 32 + app/views/projects/runners/_runner.html.haml | 2 +- .../runners/_specific_runners.html.haml | 2 +- app/views/projects/runners/edit.html.haml | 27 +- app/views/projects/runners/show.html.haml | 51 +- app/views/projects/services/_form.html.haml | 32 +- app/views/projects/services/index.html.haml | 52 +- app/views/projects/show.atom.builder | 4 +- app/views/projects/show.html.haml | 78 +-- .../projects/snippets/_actions.html.haml | 38 +- .../projects/snippets/_header_title.html.haml | 1 - app/views/projects/snippets/edit.html.haml | 1 - app/views/projects/snippets/index.html.haml | 1 - app/views/projects/snippets/new.html.haml | 1 - app/views/projects/snippets/show.html.haml | 9 +- app/views/projects/tags/destroy.js.haml | 1 - app/views/projects/tags/index.html.haml | 1 - app/views/projects/tags/new.html.haml | 3 +- app/views/projects/tags/show.html.haml | 9 +- app/views/projects/tree/show.html.haml | 2 +- app/views/projects/triggers/index.html.haml | 22 +- .../projects/variables/_content.html.haml | 8 + app/views/projects/variables/_form.html.haml | 10 + app/views/projects/variables/_table.html.haml | 25 + app/views/projects/variables/index.html.haml | 17 + app/views/projects/variables/show.html.haml | 41 +- .../projects/wikis/_header_title.html.haml | 1 - app/views/projects/wikis/edit.html.haml | 1 - app/views/projects/wikis/empty.html.haml | 1 - app/views/projects/wikis/git_access.html.haml | 1 - app/views/projects/wikis/history.html.haml | 1 - app/views/projects/wikis/pages.html.haml | 1 - app/views/projects/wikis/show.html.haml | 1 - app/views/search/results/_issue.html.haml | 2 +- .../search/results/_merge_request.html.haml | 2 +- app/views/search/results/_note.html.haml | 2 +- app/views/shared/_clone_panel.html.haml | 2 +- app/views/shared/_event_filter.html.haml | 4 +- app/views/shared/_sort_dropdown.html.haml | 2 +- app/views/shared/groups/_list.html.haml | 2 +- app/views/shared/issuable/_filter.html.haml | 6 +- app/views/shared/issuable/_form.html.haml | 93 +-- .../shared/issuable/_search_form.html.haml | 6 - app/views/shared/issuable/_sidebar.html.haml | 24 +- .../milestones/_participants_tab.html.haml | 2 +- app/views/shared/projects/_project.html.haml | 5 +- app/views/shared/snippets/_header.html.haml | 23 +- app/views/snippets/_actions.html.haml | 38 +- app/views/snippets/show.html.haml | 7 +- app/views/users/calendar.html.haml | 19 +- app/views/users/calendar_activities.html.haml | 42 +- app/views/users/show.atom.builder | 4 +- app/views/users/show.html.haml | 14 +- app/workers/emails_on_push_worker.rb | 44 +- app/workers/repository_fork_worker.rb | 6 +- app/workers/repository_import_worker.rb | 3 +- config/application.rb | 32 +- config/boot.rb | 2 +- config/environments/development.rb | 1 + config/environments/test.rb | 2 +- config/gitlab.yml.example | 10 + config/initializers/1_settings.rb | 46 +- config/initializers/5_backend.rb | 6 +- config/initializers/carrierwave.rb | 4 +- config/initializers/devise.rb | 2 +- config/initializers/devise_async.rb | 1 - config/initializers/doorkeeper.rb | 4 +- config/initializers/health_check.rb | 3 + config/initializers/metrics.rb | 3 + config/initializers/monkey_patch.rb | 48 -- config/initializers/omniauth.rb | 2 +- config/initializers/premailer.rb | 2 +- config/initializers/session_store.rb | 2 +- config/routes.rb | 63 +- ...8_remove_wrong_import_url_from_projects.rb | 4 +- ...roup_visibility_to_application_settings.rb | 4 +- ...07120251_add_images_enabled_for_project.rb | 5 + ...sign_in_sources_to_application_settings.rb | 5 + ...504112519_add_run_untagged_to_ci_runner.rb | 13 + .../20160508215820_add_type_to_notes.rb | 5 + ...508221410_set_type_on_legacy_diff_notes.rb | 5 + ...ck_access_token_to_application_settings.rb | 5 + ...firmation_email_to_application_settings.rb | 12 + ...5328_remove_main_language_from_projects.rb | 21 + ...ification_settings_for_deleted_projects.rb | 13 + .../20160528043124_add_users_state_index.rb | 9 + ...en_expire_delay_to_application_settings.rb | 9 + db/schema.rb | 55 +- doc/README.md | 3 + doc/administration/container_registry.md | 375 ++++++++++++ doc/administration/environment_variables.md | 2 +- .../high_availability/README.md | 4 + .../high_availability/load_balancer.md | 2 +- doc/administration/high_availability/nfs.md | 6 +- doc/administration/high_availability/redis.md | 2 +- .../active-active-diagram.png | Bin 0 -> 29607 bytes .../active-passive-diagram.png | Bin 0 -> 24246 bytes doc/administration/repository_checks.md | 4 +- doc/administration/troubleshooting/sidekiq.md | 8 + doc/api/README.md | 2 +- doc/api/build_triggers.md | 12 +- doc/api/groups.md | 2 - doc/api/issues.md | 15 +- doc/api/labels.md | 72 ++- doc/api/merge_requests.md | 22 +- doc/api/notes.md | 10 +- doc/api/projects.md | 3 + doc/api/runners.md | 4 +- doc/api/services.md | 8 +- doc/api/settings.md | 7 +- doc/ci/{ => examples}/deployment/README.md | 0 doc/ci/quick_start/README.md | 4 +- doc/ci/runners/README.md | 8 +- doc/ci/triggers/README.md | 2 +- doc/ci/yaml/README.md | 4 +- doc/container_registry/README.md | 113 ++++ .../img/container_registry.png | Bin 0 -> 354050 bytes .../img/project_feature.png | Bin 0 -> 392842 bytes doc/development/doc_styleguide.md | 4 +- doc/development/instrumentation.md | 129 ++++- doc/development/migration_style_guide.md | 48 +- doc/development/testing.md | 2 +- doc/development/ui_guide.md | 48 ++ doc/gitlab-basics/create-issue.md | 2 +- doc/gitlab-basics/create-project.md | 2 +- doc/hooks/custom_hooks.md | 2 +- doc/install/installation.md | 8 +- doc/install/relative_url.md | 2 +- doc/install/requirements.md | 3 +- doc/integration/README.md | 2 +- doc/integration/cas.md | 19 +- doc/integration/google.md | 4 +- .../img/enabled-oauth-sign-in-sources.png | Bin 0 -> 49081 bytes doc/integration/omniauth.md | 15 + doc/intro/README.md | 2 +- doc/logs/logs.md | 8 +- doc/markdown/markdown.md | 49 +- doc/migrate_ci_to_ce/README.md | 2 +- doc/monitoring/health_check.md | 66 +++ doc/monitoring/img/health_check_token.png | Bin 0 -> 10884 bytes doc/operations/moving_repositories.md | 8 +- doc/permissions/permissions.md | 3 + doc/raketasks/README.md | 2 +- doc/security/README.md | 1 + doc/security/user_email_confirmation.md | 7 + doc/update/8.6-to-8.7.md | 8 + doc/update/8.7-to-8.8.md | 162 ++++++ doc/update/README.md | 6 +- doc/update/patch_versions.md | 4 +- doc/web_hooks/web_hooks.md | 68 +++ doc/workflow/gitlab_flow.md | 4 +- doc/workflow/groups.md | 2 +- .../importing/import_projects_from_github.md | 2 +- .../import_projects_from_gitlab_com.md | 2 +- .../lfs/manage_large_binaries_with_git_lfs.md | 6 +- doc/workflow/notifications.md | 2 +- features/project/active_tab.feature | 55 +- features/project/builds/summary.feature | 1 + features/project/commits/tags.feature | 46 -- features/project/create.feature | 16 +- features/project/project.feature | 9 - features/project/shortcuts.feature | 8 +- features/steps/admin/active_tab.rb | 10 +- features/steps/admin/users.rb | 2 +- features/steps/dashboard/active_tab.rb | 6 +- features/steps/dashboard/dashboard.rb | 2 +- features/steps/dashboard/issues.rb | 2 +- features/steps/dashboard/merge_requests.rb | 2 +- features/steps/dashboard/shortcuts.rb | 3 +- features/steps/dashboard/todos.rb | 4 +- features/steps/profile/active_tab.rb | 4 - features/steps/profile/profile.rb | 2 +- features/steps/project/active_tab.rb | 32 +- features/steps/project/builds/summary.rb | 4 + features/steps/project/commits/commits.rb | 6 +- features/steps/project/commits/tags.rb | 90 --- features/steps/project/create.rb | 26 +- features/steps/project/fork.rb | 2 +- features/steps/project/hooks.rb | 2 +- features/steps/project/issues/award_emoji.rb | 4 +- features/steps/project/issues/issues.rb | 6 +- features/steps/project/issues/labels.rb | 4 +- features/steps/project/merge_requests.rb | 10 +- features/steps/project/project.rb | 12 +- features/steps/project/project_find_file.rb | 4 +- features/steps/project/project_milestone.rb | 2 +- features/steps/project/project_shortcuts.rb | 1 + features/steps/project/snippets.rb | 4 +- features/steps/project/source/browse_files.rb | 16 +- features/steps/project/team_management.rb | 2 +- features/steps/shared/active_tab.rb | 28 +- features/steps/shared/diff_note.rb | 12 +- features/steps/shared/issuable.rb | 8 +- features/steps/shared/note.rb | 2 +- features/steps/shared/project.rb | 2 +- features/steps/shared/project_tab.rb | 20 +- features/steps/shared/shortcuts.rb | 2 +- features/steps/shared/sidebar_active_tab.rb | 35 ++ features/steps/snippets/snippets.rb | 4 +- features/steps/user.rb | 2 +- .../migration/create_table_migration.rb | 35 ++ .../active_record/migration/migration.rb | 55 ++ lib/api/api.rb | 71 +-- lib/api/api_guard.rb | 270 ++++----- lib/api/commit_statuses.rb | 2 +- lib/api/commits.rb | 2 + lib/api/entities.rb | 27 +- lib/api/gitignores.rb | 29 + lib/api/groups.rb | 3 +- lib/api/helpers.rb | 15 +- lib/api/issues.rb | 39 +- lib/api/labels.rb | 6 +- lib/api/licenses.rb | 14 +- lib/api/merge_requests.rb | 36 -- lib/api/notes.rb | 47 +- lib/api/projects.rb | 7 +- lib/api/runners.rb | 2 +- lib/api/subscriptions.rb | 60 ++ lib/api/users.rb | 2 +- lib/backup/manager.rb | 17 +- lib/backup/registry.rb | 13 + .../filter/abstract_reference_filter.rb | 12 +- .../filter/commit_range_reference_filter.rb | 20 +- lib/banzai/filter/commit_reference_filter.rb | 20 +- .../filter/external_issue_reference_filter.rb | 14 +- lib/banzai/filter/inline_diff_filter.rb | 26 + lib/banzai/filter/issue_reference_filter.rb | 7 +- lib/banzai/filter/label_reference_filter.rb | 2 + .../filter/merge_request_reference_filter.rb | 2 + .../filter/milestone_reference_filter.rb | 46 +- lib/banzai/filter/redactor_filter.rb | 31 +- lib/banzai/filter/reference_filter.rb | 24 +- .../filter/reference_gatherer_filter.rb | 65 --- lib/banzai/filter/sanitization_filter.rb | 2 +- lib/banzai/filter/snippet_reference_filter.rb | 2 + lib/banzai/filter/upload_link_filter.rb | 8 +- lib/banzai/filter/user_reference_filter.rb | 44 +- lib/banzai/filter/wiki_link_filter.rb | 11 +- lib/banzai/lazy_reference.rb | 25 - lib/banzai/pipeline/gfm_pipeline.rb | 3 +- .../pipeline/reference_extraction_pipeline.rb | 11 - lib/banzai/reference_extractor.rb | 48 +- lib/banzai/reference_parser.rb | 14 + lib/banzai/reference_parser/base_parser.rb | 204 +++++++ lib/banzai/reference_parser/commit_parser.rb | 34 ++ .../reference_parser/commit_range_parser.rb | 38 ++ .../reference_parser/external_issue_parser.rb | 25 + lib/banzai/reference_parser/issue_parser.rb | 40 ++ lib/banzai/reference_parser/label_parser.rb | 11 + .../reference_parser/merge_request_parser.rb | 11 + .../reference_parser/milestone_parser.rb | 11 + lib/banzai/reference_parser/snippet_parser.rb | 11 + lib/banzai/reference_parser/user_parser.rb | 92 +++ lib/ci/ansi2html.rb | 87 ++- lib/ci/api/api.rb | 10 +- lib/ci/api/runners.rb | 18 +- lib/ci/charts.rb | 3 +- lib/ci/gitlab_ci_yaml_processor.rb | 4 +- lib/container_registry/blob.rb | 48 ++ lib/container_registry/client.rb | 61 ++ lib/container_registry/config.rb | 16 + lib/container_registry/registry.rb | 21 + lib/container_registry/repository.rb | 48 ++ lib/container_registry/tag.rb | 77 +++ lib/event_filter.rb | 2 +- lib/gitlab.rb | 2 +- lib/gitlab/backend/shell.rb | 2 +- lib/gitlab/bitbucket_import/client.rb | 2 +- .../bitbucket_import/project_creator.rb | 7 +- lib/gitlab/ci/build/artifacts/metadata.rb | 2 +- lib/gitlab/contributions_calendar.rb | 2 +- lib/gitlab/current_settings.rb | 23 +- lib/gitlab/database.rb | 4 +- lib/gitlab/database/migration_helpers.rb | 142 +++++ lib/gitlab/diff/inline_diff_marker.rb | 36 +- lib/gitlab/diff/parser.rb | 16 +- lib/gitlab/email/message/repository_push.rb | 11 +- lib/gitlab/email/reply_parser.rb | 2 +- lib/gitlab/fogbugz_import/project_creator.rb | 9 +- lib/gitlab/github_import/branch_formatter.rb | 29 + lib/gitlab/github_import/importer.rb | 76 ++- .../github_import/pull_request_formatter.rb | 54 +- lib/gitlab/gitignore.rb | 56 ++ lib/gitlab/gitlab_import/importer.rb | 8 +- .../google_code_import/project_creator.rb | 9 +- lib/gitlab/lazy.rb | 34 ++ lib/gitlab/markup_helper.rb | 2 +- lib/gitlab/metrics/instrumentation.rb | 2 - lib/gitlab/metrics/subscribers/rails_cache.rb | 12 +- lib/gitlab/middleware/go.rb | 2 +- lib/gitlab/middleware/rails_queue_duration.rb | 24 + lib/gitlab/project_search_results.rb | 2 +- lib/gitlab/redis.rb | 8 +- lib/gitlab/reference_extractor.rb | 19 +- lib/gitlab/regex.rb | 4 + lib/gitlab/sanitizers/svg.rb | 8 +- lib/gitlab/sanitizers/svg/whitelist.rb | 170 +++--- lib/gitlab/url_builder.rb | 2 +- .../{import_url.rb => url_sanitizer.rb} | 17 +- lib/gitlab/visibility_level.rb | 7 + lib/json_web_token/rsa_token.rb | 42 ++ lib/json_web_token/token.rb | 46 ++ lib/support/nginx/registry-ssl | 53 ++ lib/tasks/auto_annotate_models.rake | 44 -- lib/tasks/gitlab/backup.rake | 29 + lib/tasks/gitlab/check.rake | 2 +- lib/tasks/gitlab/db.rake | 14 +- lib/tasks/gitlab/update_gitignore.rake | 46 ++ lib/tasks/rubocop.rake | 1 + public/robots.txt | 1 + shared/registry/.gitkeep | 0 spec/config/mail_room_spec.rb | 2 +- .../admin/projects_controller_spec.rb | 2 +- .../admin/users_controller_spec.rb | 76 +++ .../health_check_controller_spec.rb | 105 ++++ .../projects/branches_controller_spec.rb | 4 - .../projects/compare_controller_spec.rb | 4 +- .../projects/group_links_controller_spec.rb | 4 +- .../projects/issues_controller_spec.rb | 2 +- .../merge_requests_controller_spec.rb | 2 +- .../notification_settings_controller_spec.rb | 14 + .../project_members_controller_spec.rb | 2 +- .../projects/raw_controller_spec.rb | 2 +- spec/controllers/projects_controller_spec.rb | 45 ++ .../registrations_controller_spec.rb | 33 ++ spec/controllers/sessions_controller_spec.rb | 29 +- spec/controllers/users_controller_spec.rb | 22 + spec/factories/abuse_reports.rb | 12 - spec/factories/broadcast_messages.rb | 14 - spec/factories/forked_project_links.rb | 11 - spec/factories/label_links.rb | 12 - spec/factories/labels.rb | 13 - spec/factories/lfs_objects.rb | 12 - spec/factories/lfs_objects_projects.rb | 11 - spec/factories/merge_requests.rb | 29 - spec/factories/notes.rb | 45 +- spec/factories/oauth_access_tokens.rb | 15 - spec/factories/projects.rb | 49 +- spec/factories/releases.rb | 12 - spec/factories/todos.rb | 22 +- spec/factories_spec.rb | 4 +- spec/features/admin/admin_builds_spec.rb | 1 + .../features/admin/admin_health_check_spec.rb | 55 ++ spec/features/admin/admin_runners_spec.rb | 2 +- spec/features/admin/admin_users_spec.rb | 5 +- spec/features/builds_spec.rb | 4 +- spec/features/commits_spec.rb | 10 +- spec/features/container_registry_spec.rb | 44 ++ spec/features/issues/filter_issues_spec.rb | 176 ++++++ spec/features/issues/move_spec.rb | 16 +- spec/features/issues/note_polling_spec.rb | 5 +- spec/features/issues/update_issues_spec.rb | 2 +- spec/features/issues_spec.rb | 99 +++- spec/features/login_spec.rb | 10 +- spec/features/markdown_spec.rb | 4 + .../merge_requests/created_from_fork_spec.rb | 58 ++ .../user_lists_merge_requests_spec.rb | 161 ++++++ spec/features/notes_on_merge_requests_spec.rb | 12 +- .../participants_autocomplete_spec.rb | 6 +- spec/features/pipelines_spec.rb | 189 ++++++ spec/features/projects/badges/list_spec.rb | 5 +- ...r_views_empty_project_instructions_spec.rb | 63 ++ .../projects/files/gitignore_dropdown_spec.rb | 30 + ...project_owner_creates_license_file_spec.rb | 8 +- ...eate_license_file_in_empty_project_spec.rb | 4 +- .../{project => projects}/shortcuts_spec.rb | 4 +- spec/features/runners_spec.rb | 37 +- spec/features/signup_spec.rb | 45 +- spec/features/tags/master_creates_tag_spec.rb | 62 ++ spec/features/tags/master_deletes_tag_spec.rb | 41 ++ spec/features/tags/master_updates_tag_spec.rb | 42 ++ spec/features/tags/master_views_tags_spec.rb | 73 +++ spec/features/task_lists_spec.rb | 5 +- spec/features/todos/target_state_spec.rb | 65 +++ spec/features/todos/todos_spec.rb | 21 + spec/features/variables_spec.rb | 61 +- spec/finders/issues_finder_spec.rb | 180 +++--- .../container_registry/config_blob.json | 1 + .../container_registry/tag_manifest.json | 1 + spec/fixtures/markdown.md.erb | 23 +- spec/helpers/auth_helper_spec.rb | 47 +- spec/helpers/diff_helper_spec.rb | 4 +- spec/helpers/events_helper_spec.rb | 95 +-- spec/helpers/merge_requests_helper_spec.rb | 2 +- spec/helpers/projects_helper_spec.rb | 10 +- .../fixtures/right_sidebar.html.haml | 13 + .../stat_graph_contributors_graph_spec.js | 2 +- .../stat_graph_contributors_util_spec.js | 2 +- .../{ => graphs}/stat_graph_spec.js | 2 +- spec/javascripts/project_title_spec.js.coffee | 1 + spec/javascripts/right_sidebar_spec.js.coffee | 69 +++ spec/lib/award_emoji_spec.rb | 2 +- .../commit_range_reference_filter_spec.rb | 15 - .../filter/commit_reference_filter_spec.rb | 15 - .../banzai/filter/inline_diff_filter_spec.rb | 68 +++ .../filter/issue_reference_filter_spec.rb | 25 - .../filter/label_reference_filter_spec.rb | 10 - .../merge_request_reference_filter_spec.rb | 15 - .../filter/milestone_reference_filter_spec.rb | 145 ++++- .../lib/banzai/filter/redactor_filter_spec.rb | 38 +- .../filter/reference_gatherer_filter_spec.rb | 87 --- .../banzai/filter/sanitization_filter_spec.rb | 6 + .../filter/snippet_reference_filter_spec.rb | 15 - .../banzai/filter/upload_link_filter_spec.rb | 18 + .../filter/user_reference_filter_spec.rb | 35 +- .../banzai/filter/wiki_link_filter_spec.rb | 85 +++ .../reference_parser/base_parser_spec.rb | 237 ++++++++ .../reference_parser/commit_parser_spec.rb | 113 ++++ .../commit_range_parser_spec.rb | 120 ++++ .../external_issue_parser_spec.rb | 62 ++ .../reference_parser/issue_parser_spec.rb | 79 +++ .../reference_parser/label_parser_spec.rb | 31 + .../merge_request_parser_spec.rb | 30 + .../reference_parser/milestone_parser_spec.rb | 31 + .../reference_parser/snippet_parser_spec.rb | 31 + .../reference_parser/user_parser_spec.rb | 189 ++++++ spec/lib/ci/ansi2html_spec.rb | 120 ++-- spec/lib/ci/charts_spec.rb | 7 + spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 10 +- spec/lib/container_registry/blob_spec.rb | 61 ++ spec/lib/container_registry/registry_spec.rb | 28 + .../lib/container_registry/repository_spec.rb | 65 +++ spec/lib/container_registry/tag_spec.rb | 89 +++ spec/lib/gitlab/akismet_helper_spec.rb | 4 +- .../gitlab/bitbucket_import/client_spec.rb | 2 +- .../ci/build/artifacts/metadata/entry_spec.rb | 6 +- .../gitlab/database/migration_helpers_spec.rb | 128 ++++ .../email/message/repository_push_spec.rb | 4 +- .../lib/gitlab/gfm/reference_rewriter_spec.rb | 4 +- spec/lib/gitlab/gfm/uploads_rewriter_spec.rb | 8 +- .../github_import/branch_formatter_spec.rb | 71 +++ .../pull_request_formatter_spec.rb | 46 +- spec/lib/gitlab/gitignore_spec.rb | 40 ++ spec/lib/gitlab/import_url_spec.rb | 21 - spec/lib/gitlab/lazy_spec.rb | 37 ++ spec/lib/gitlab/lfs/lfs_router_spec.rb | 8 +- .../gitlab/metrics/instrumentation_spec.rb | 14 +- spec/lib/gitlab/metrics/sampler_spec.rb | 2 +- .../metrics/subscribers/active_record_spec.rb | 2 +- .../metrics/subscribers/rails_cache_spec.rb | 16 +- .../middleware/rails_queue_duration_spec.rb | 31 + spec/lib/gitlab/note_data_builder_spec.rb | 71 ++- spec/lib/gitlab/sherlock/collection_spec.rb | 6 +- spec/lib/gitlab/sherlock/query_spec.rb | 2 +- spec/lib/gitlab/sherlock/transaction_spec.rb | 4 +- spec/lib/gitlab/url_sanitizer_spec.rb | 68 +++ spec/lib/json_web_token/rsa_token_spec.rb | 43 ++ spec/lib/json_web_token/token_spec.rb | 18 + spec/mailers/notify_spec.rb | 54 +- .../mailers/previews/devise_mailer_preview.rb | 11 + spec/mailers/shared/notify.rb | 4 +- spec/models/ability_spec.rb | 117 ++++ spec/models/abuse_report_spec.rb | 12 - spec/models/application_setting_spec.rb | 55 +- spec/models/broadcast_message_spec.rb | 14 - spec/models/build_spec.rb | 98 ++-- spec/models/ci/commit_spec.rb | 21 +- spec/models/ci/runner_project_spec.rb | 17 - spec/models/ci/runner_spec.rb | 51 +- spec/models/ci/trigger_spec.rb | 13 - spec/models/ci/variable_spec.rb | 16 +- spec/models/commit_range_spec.rb | 34 ++ spec/models/commit_spec.rb | 40 +- spec/models/commit_status_spec.rb | 34 -- spec/models/concerns/issuable_spec.rb | 54 +- spec/models/concerns/participable_spec.rb | 83 +++ spec/models/concerns/subscribable_spec.rb | 10 + .../concerns/token_authenticatable_spec.rb | 6 +- spec/models/deploy_key_spec.rb | 15 - spec/models/deploy_keys_project_spec.rb | 11 - spec/models/email_spec.rb | 11 - spec/models/event_spec.rb | 16 - spec/models/forked_project_link_spec.rb | 11 - spec/models/generic_commit_status_spec.rb | 38 +- spec/models/group_spec.rb | 15 - spec/models/hooks/service_hook_spec.rb | 4 +- spec/models/hooks/system_hook_spec.rb | 20 +- spec/models/hooks/web_hook_spec.rb | 4 +- spec/models/identity_spec.rb | 12 - spec/models/issue_spec.rb | 77 ++- spec/models/key_spec.rb | 15 - spec/models/label_link_spec.rb | 12 - spec/models/label_spec.rb | 21 +- spec/models/legacy_diff_note_spec.rb | 76 +++ spec/models/member_spec.rb | 19 - spec/models/members/project_member_spec.rb | 42 ++ spec/models/merge_request_spec.rb | 99 ++-- spec/models/milestone_spec.rb | 56 +- spec/models/namespace_spec.rb | 29 +- spec/models/note_spec.rb | 187 +++--- .../project_services/hipchat_service_spec.rb | 151 +++-- .../slack_service/build_message_spec.rb | 23 +- .../slack_service/issue_message_spec.rb | 11 +- .../slack_service/note_message_spec.rb | 4 +- .../project_services/slack_service_spec.rb | 68 ++- spec/models/project_snippet_spec.rb | 16 - spec/models/project_spec.rb | 132 +++-- spec/models/project_wiki_spec.rb | 16 +- spec/models/protected_branch_spec.rb | 12 - spec/models/release_spec.rb | 12 - spec/models/repository_spec.rb | 46 +- spec/models/service_spec.rb | 21 - spec/models/snippet_spec.rb | 43 +- spec/models/todo_spec.rb | 18 - spec/models/user_spec.rb | 89 +-- spec/requests/api/builds_spec.rb | 4 +- ...status_spec.rb => commit_statuses_spec.rb} | 2 +- spec/requests/api/gitignores_spec.rb | 29 + spec/requests/api/group_members_spec.rb | 10 +- spec/requests/api/groups_spec.rb | 21 +- spec/requests/api/issues_spec.rb | 33 ++ spec/requests/api/labels_spec.rb | 82 +++ spec/requests/api/licenses_spec.rb | 12 +- spec/requests/api/merge_requests_spec.rb | 28 + spec/requests/api/notes_spec.rb | 71 ++- spec/requests/api/project_members_spec.rb | 2 +- spec/requests/api/projects_spec.rb | 21 +- spec/requests/api/runners_spec.rb | 15 +- spec/requests/api/system_hooks_spec.rb | 2 +- spec/requests/api/users_spec.rb | 2 +- spec/requests/ci/api/builds_spec.rb | 40 +- spec/requests/ci/api/runners_spec.rb | 83 ++- spec/requests/jwt_controller_spec.rb | 72 +++ spec/routing/admin_routing_spec.rb | 7 + spec/routing/routing_spec.rb | 51 +- ...er_registry_authentication_service_spec.rb | 242 ++++++++ .../create_commit_builds_service_spec.rb | 2 +- spec/services/git_push_service_spec.rb | 43 -- spec/services/groups/create_service_spec.rb | 4 +- .../issues/bulk_update_service_spec.rb | 9 +- spec/services/issues/create_service_spec.rb | 6 +- spec/services/issues/move_service_spec.rb | 6 +- spec/services/issues/update_service_spec.rb | 24 +- .../add_todo_when_build_fails_service_spec.rb | 81 +++ .../merge_requests/create_service_spec.rb | 4 +- .../merge_requests/merge_service_spec.rb | 15 + .../merge_when_build_succeeds_service_spec.rb | 16 +- .../merge_requests/refresh_service_spec.rb | 28 + .../merge_requests/update_service_spec.rb | 8 +- spec/services/notification_service_spec.rb | 30 + spec/services/projects/create_service_spec.rb | 4 +- .../services/projects/destroy_service_spec.rb | 31 +- spec/services/projects/fork_service_spec.rb | 27 + spec/services/projects/import_service_spec.rb | 2 +- .../projects/transfer_service_spec.rb | 11 + spec/services/system_note_service_spec.rb | 26 +- spec/services/todo_service_spec.rb | 38 ++ spec/support/filter_spec_helper.rb | 3 +- spec/support/jira_service_helper.rb | 10 +- spec/support/login_helpers.rb | 6 +- spec/support/markdown_feature.rb | 6 +- spec/support/matchers/markdown_matchers.rb | 12 +- spec/support/reference_parser_helpers.rb | 5 + spec/support/stub_gitlab_calls.rb | 37 +- spec/tasks/gitlab/backup_rake_spec.rb | 32 +- spec/tasks/gitlab/db_rake_spec.rb | 62 ++ spec/teaspoon_env.rb | 50 +- spec/workers/emails_on_push_worker_spec.rb | 65 ++- spec/workers/post_receive_spec.rb | 16 + spec/workers/repository_import_worker_spec.rb | 26 +- vendor/assets/javascripts/jquery.scrollTo.js | 210 +++++++ vendor/assets/stylesheets/animate.css | 11 - vendor/gitignore/Actionscript.gitignore | 19 + vendor/gitignore/Ada.gitignore | 5 + vendor/gitignore/Agda.gitignore | 1 + vendor/gitignore/Android.gitignore | 39 ++ vendor/gitignore/AppEngine.gitignore | 2 + .../gitignore/AppceleratorTitanium.gitignore | 3 + vendor/gitignore/ArchLinuxPackages.gitignore | 13 + vendor/gitignore/Autotools.gitignore | 18 + vendor/gitignore/C++.gitignore | 28 + vendor/gitignore/C.gitignore | 33 ++ vendor/gitignore/CFWheels.gitignore | 12 + vendor/gitignore/CMake.gitignore | 6 + vendor/gitignore/CUDA.gitignore | 6 + vendor/gitignore/CakePHP.gitignore | 25 + vendor/gitignore/ChefCookbook.gitignore | 9 + vendor/gitignore/Clojure.gitignore | 1 + vendor/gitignore/CodeIgniter.gitignore | 6 + vendor/gitignore/CommonLisp.gitignore | 3 + vendor/gitignore/Composer.gitignore | 6 + vendor/gitignore/Concrete5.gitignore | 4 + vendor/gitignore/Coq.gitignore | 3 + vendor/gitignore/CraftCMS.gitignore | 3 + vendor/gitignore/D.gitignore | 20 + vendor/gitignore/DM.gitignore | 5 + vendor/gitignore/Dart.gitignore | 27 + vendor/gitignore/Delphi.gitignore | 66 +++ vendor/gitignore/Drupal.gitignore | 36 ++ vendor/gitignore/EPiServer.gitignore | 4 + vendor/gitignore/Eagle.gitignore | 44 ++ vendor/gitignore/Elisp.gitignore | 5 + vendor/gitignore/Elixir.gitignore | 5 + vendor/gitignore/Elm.gitignore | 4 + vendor/gitignore/Erlang.gitignore | 10 + vendor/gitignore/ExpressionEngine.gitignore | 19 + vendor/gitignore/ExtJs.gitignore | 4 + vendor/gitignore/Fancy.gitignore | 2 + vendor/gitignore/Finale.gitignore | 13 + vendor/gitignore/ForceDotCom.gitignore | 4 + vendor/gitignore/Fortran.gitignore | 1 + vendor/gitignore/FuelPHP.gitignore | 21 + vendor/gitignore/GWT.gitignore | 28 + vendor/gitignore/Gcov.gitignore | 5 + vendor/gitignore/GitBook.gitignore | 16 + vendor/gitignore/Global/Anjuta.gitignore | 3 + vendor/gitignore/Global/Archives.gitignore | 27 + vendor/gitignore/Global/BricxCC.gitignore | 4 + vendor/gitignore/Global/CVS.gitignore | 4 + vendor/gitignore/Global/Calabash.gitignore | 10 + vendor/gitignore/Global/Cloud9.gitignore | 3 + vendor/gitignore/Global/CodeKit.gitignore | 3 + vendor/gitignore/Global/DartEditor.gitignore | 2 + vendor/gitignore/Global/Dreamweaver.gitignore | 7 + vendor/gitignore/Global/Dropbox.gitignore | 4 + vendor/gitignore/Global/Eclipse.gitignore | 51 ++ .../gitignore/Global/EiffelStudio.gitignore | 2 + vendor/gitignore/Global/Emacs.gitignore | 42 ++ vendor/gitignore/Global/Ensime.gitignore | 4 + vendor/gitignore/Global/Espresso.gitignore | 1 + vendor/gitignore/Global/FlexBuilder.gitignore | 3 + vendor/gitignore/Global/GPG.gitignore | 2 + .../Global/IPythonNotebook.gitignore | 2 + vendor/gitignore/Global/JDeveloper.gitignore | 13 + vendor/gitignore/Global/JetBrains.gitignore | 44 ++ vendor/gitignore/Global/KDevelop4.gitignore | 2 + vendor/gitignore/Global/Kate.gitignore | 3 + vendor/gitignore/Global/Lazarus.gitignore | 30 + vendor/gitignore/Global/LibreOffice.gitignore | 2 + vendor/gitignore/Global/Linux.gitignore | 10 + vendor/gitignore/Global/LyX.gitignore | 4 + vendor/gitignore/Global/Matlab.gitignore | 19 + vendor/gitignore/Global/Mercurial.gitignore | 6 + .../Global/MicrosoftOffice.gitignore | 16 + vendor/gitignore/Global/ModelSim.gitignore | 23 + vendor/gitignore/Global/Momentics.gitignore | 8 + vendor/gitignore/Global/MonoDevelop.gitignore | 8 + vendor/gitignore/Global/NetBeans.gitignore | 7 + vendor/gitignore/Global/Ninja.gitignore | 2 + vendor/gitignore/Global/NotepadPP.gitignore | 2 + vendor/gitignore/Global/OSX.gitignore | 24 + vendor/gitignore/Global/Otto.gitignore | 1 + vendor/gitignore/Global/Redcar.gitignore | 1 + vendor/gitignore/Global/Redis.gitignore | 3 + vendor/gitignore/Global/SBT.gitignore | 9 + vendor/gitignore/Global/SVN.gitignore | 1 + vendor/gitignore/Global/SlickEdit.gitignore | 11 + vendor/gitignore/Global/SublimeText.gitignore | 14 + vendor/gitignore/Global/SynopsysVCS.gitignore | 36 ++ vendor/gitignore/Global/Tags.gitignore | 16 + vendor/gitignore/Global/TextMate.gitignore | 3 + vendor/gitignore/Global/TortoiseGit.gitignore | 2 + vendor/gitignore/Global/Vagrant.gitignore | 1 + vendor/gitignore/Global/Vim.gitignore | 10 + vendor/gitignore/Global/VirtualEnv.gitignore | 12 + .../Global/VisualStudioCode.gitignore | 2 + vendor/gitignore/Global/WebMethods.gitignore | 14 + vendor/gitignore/Global/Windows.gitignore | 18 + vendor/gitignore/Global/Xcode.gitignore | 23 + vendor/gitignore/Global/XilinxISE.gitignore | 67 +++ vendor/gitignore/Go.gitignore | 24 + vendor/gitignore/Gradle.gitignore | 14 + vendor/gitignore/Grails.gitignore | 33 ++ vendor/gitignore/Haskell.gitignore | 18 + vendor/gitignore/IGORPro.gitignore | 5 + vendor/gitignore/Idris.gitignore | 2 + vendor/gitignore/Java.gitignore | 12 + vendor/gitignore/Jboss.gitignore | 19 + vendor/gitignore/Jekyll.gitignore | 3 + vendor/gitignore/Joomla.gitignore | 546 ++++++++++++++++++ vendor/gitignore/KiCad.gitignore | 20 + vendor/gitignore/Kohana.gitignore | 2 + vendor/gitignore/LabVIEW.gitignore | 16 + vendor/gitignore/Laravel.gitignore | 16 + vendor/gitignore/Leiningen.gitignore | 12 + vendor/gitignore/LemonStand.gitignore | 21 + vendor/gitignore/Lilypond.gitignore | 6 + vendor/gitignore/Lithium.gitignore | 2 + vendor/gitignore/Lua.gitignore | 41 ++ vendor/gitignore/Magento.gitignore | 104 ++++ vendor/gitignore/Maven.gitignore | 9 + vendor/gitignore/Mercury.gitignore | 13 + .../gitignore/MetaProgrammingSystem.gitignore | 16 + vendor/gitignore/Nanoc.gitignore | 10 + vendor/gitignore/Nim.gitignore | 1 + vendor/gitignore/Node.gitignore | 37 ++ vendor/gitignore/OCaml.gitignore | 20 + vendor/gitignore/Objective-C.gitignore | 51 ++ vendor/gitignore/Opa.gitignore | 13 + vendor/gitignore/OpenCart.gitignore | 13 + vendor/gitignore/OracleForms.gitignore | 8 + vendor/gitignore/Packer.gitignore | 5 + vendor/gitignore/Perl.gitignore | 20 + vendor/gitignore/Phalcon.gitignore | 2 + vendor/gitignore/PlayFramework.gitignore | 15 + vendor/gitignore/Plone.gitignore | 18 + vendor/gitignore/Prestashop.gitignore | 32 + vendor/gitignore/Processing.gitignore | 7 + vendor/gitignore/Python.gitignore | 89 +++ vendor/gitignore/Qooxdoo.gitignore | 5 + vendor/gitignore/Qt.gitignore | 38 ++ vendor/gitignore/R.gitignore | 33 ++ vendor/gitignore/README.md | 14 + vendor/gitignore/ROS.gitignore | 47 ++ vendor/gitignore/Rails.gitignore | 38 ++ vendor/gitignore/RhodesRhomobile.gitignore | 9 + vendor/gitignore/Ruby.gitignore | 50 ++ vendor/gitignore/Rust.gitignore | 7 + vendor/gitignore/SCons.gitignore | 2 + vendor/gitignore/Sass.gitignore | 2 + vendor/gitignore/Scala.gitignore | 17 + vendor/gitignore/Scheme.gitignore | 7 + vendor/gitignore/Scrivener.gitignore | 7 + vendor/gitignore/Sdcc.gitignore | 8 + vendor/gitignore/SeamGen.gitignore | 26 + vendor/gitignore/SketchUp.gitignore | 1 + vendor/gitignore/Smalltalk.gitignore | 18 + vendor/gitignore/Stella.gitignore | 12 + vendor/gitignore/SugarCRM.gitignore | 25 + vendor/gitignore/Swift.gitignore | 63 ++ vendor/gitignore/Symfony.gitignore | 48 ++ vendor/gitignore/SymphonyCMS.gitignore | 6 + vendor/gitignore/TeX.gitignore | 180 ++++++ vendor/gitignore/Terraform.gitignore | 3 + vendor/gitignore/Textpattern.gitignore | 11 + vendor/gitignore/TurboGears2.gitignore | 20 + vendor/gitignore/Typo3.gitignore | 20 + vendor/gitignore/Umbraco.gitignore | 19 + vendor/gitignore/Unity.gitignore | 30 + vendor/gitignore/UnrealEngine.gitignore | 62 ++ vendor/gitignore/VVVV.gitignore | 6 + vendor/gitignore/VisualStudio.gitignore | 252 ++++++++ vendor/gitignore/Waf.gitignore | 4 + vendor/gitignore/WordPress.gitignore | 18 + vendor/gitignore/Xojo.gitignore | 11 + vendor/gitignore/Yeoman.gitignore | 6 + vendor/gitignore/Yii.gitignore | 6 + vendor/gitignore/ZendFramework.gitignore | 25 + vendor/gitignore/Zephir.gitignore | 26 + 1198 files changed, 20290 insertions(+), 8262 deletions(-) rename app/views/projects/notes/_commit_discussion.html.haml => .vagrant_enabled (100%) delete mode 100644 app/assets/images/ci/arch.jpg delete mode 100644 app/assets/images/ci/favicon.ico delete mode 100644 app/assets/images/ci/loader.gif delete mode 100644 app/assets/images/ci/no_avatar.png delete mode 100644 app/assets/images/ci/rails.png delete mode 100644 app/assets/images/ci/service_sample.png create mode 100644 app/assets/images/mailers/gitlab_header_logo.png create mode 100644 app/assets/images/mailers/gitlab_tanuki_2x.png create mode 100644 app/assets/javascripts/blob/blob_gitignore_selector.js.coffee delete mode 100644 app/assets/javascripts/calendar.js.coffee create mode 100644 app/assets/javascripts/graphs/application.js.coffee rename app/assets/javascripts/{ => graphs}/stat_graph.js.coffee (100%) rename app/assets/javascripts/{ => graphs}/stat_graph_contributors.js.coffee (98%) rename app/assets/javascripts/{ => graphs}/stat_graph_contributors_graph.js.coffee (99%) rename app/assets/javascripts/{ => graphs}/stat_graph_contributors_util.js.coffee (100%) delete mode 100644 app/assets/javascripts/issues.js.coffee create mode 100644 app/assets/javascripts/layout_nav.js.coffee create mode 100644 app/assets/javascripts/lib/type_utility.js.coffee create mode 100644 app/assets/javascripts/users/application.js.coffee create mode 100644 app/assets/javascripts/users/calendar.js.coffee create mode 100644 app/assets/stylesheets/framework/animations.scss create mode 100644 app/assets/stylesheets/mailers/devise.scss create mode 100644 app/assets/stylesheets/mailers/repository_push_email.scss create mode 100644 app/assets/stylesheets/pages/pipelines.scss create mode 100644 app/controllers/admin/health_check_controller.rb create mode 100644 app/controllers/health_check_controller.rb create mode 100644 app/controllers/jwt_controller.rb create mode 100644 app/controllers/projects/container_registry_controller.rb create mode 100644 app/controllers/projects/pipelines_controller.rb create mode 100644 app/finders/pipelines_finder.rb create mode 100644 app/helpers/javascript_helper.rb create mode 100644 app/models/legacy_diff_note.rb create mode 100644 app/services/auth/container_registry_authentication_service.rb create mode 100644 app/services/ci/create_pipeline_service.rb create mode 100644 app/services/merge_requests/add_todo_when_build_fails_service.rb create mode 100644 app/views/admin/health_check/show.html.haml delete mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.haml create mode 100644 app/views/devise/mailer/confirmation_instructions.text.erb create mode 100644 app/views/events/_event.atom.builder create mode 100644 app/views/issues/_issue.atom.builder create mode 100644 app/views/layouts/devise_mailer.html.haml delete mode 100644 app/views/projects/blob/_header_title.html.haml delete mode 100644 app/views/projects/branches/destroy.js.haml delete mode 100644 app/views/projects/builds/_header_title.html.haml create mode 100644 app/views/projects/ci/commits/_commit.html.haml create mode 100644 app/views/projects/commit/_ci_stage.html.haml create mode 100644 app/views/projects/commits/_commit.atom.builder delete mode 100644 app/views/projects/commits/_header_title.html.haml create mode 100644 app/views/projects/container_registry/_tag.html.haml create mode 100644 app/views/projects/container_registry/index.html.haml delete mode 100644 app/views/projects/graphs/_header_title.html.haml delete mode 100644 app/views/projects/issues/_header_title.html.haml delete mode 100644 app/views/projects/labels/_header_title.html.haml delete mode 100644 app/views/projects/merge_requests/_header_title.html.haml delete mode 100644 app/views/projects/milestones/_header_title.html.haml delete mode 100644 app/views/projects/notes/discussions/_active.html.haml delete mode 100644 app/views/projects/notes/discussions/_commit.html.haml delete mode 100644 app/views/projects/notes/discussions/_diff.html.haml create mode 100644 app/views/projects/notes/discussions/_diff_with_notes.html.haml create mode 100644 app/views/projects/notes/discussions/_notes.html.haml delete mode 100644 app/views/projects/notes/discussions/_outdated.html.haml create mode 100644 app/views/projects/pipelines/_head.html.haml create mode 100644 app/views/projects/pipelines/_info.html.haml create mode 100644 app/views/projects/pipelines/index.html.haml create mode 100644 app/views/projects/pipelines/new.html.haml create mode 100644 app/views/projects/pipelines/show.html.haml delete mode 100644 app/views/projects/project_members/_header_title.html.haml create mode 100644 app/views/projects/runners/_form.html.haml delete mode 100644 app/views/projects/snippets/_header_title.html.haml create mode 100644 app/views/projects/variables/_content.html.haml create mode 100644 app/views/projects/variables/_form.html.haml create mode 100644 app/views/projects/variables/_table.html.haml create mode 100644 app/views/projects/variables/index.html.haml delete mode 100644 app/views/projects/wikis/_header_title.html.haml delete mode 100644 config/initializers/devise_async.rb create mode 100644 config/initializers/health_check.rb delete mode 100644 config/initializers/monkey_patch.rb create mode 100644 db/migrate/20160407120251_add_images_enabled_for_project.rb create mode 100644 db/migrate/20160504091942_add_disabled_oauth_sign_in_sources_to_application_settings.rb create mode 100644 db/migrate/20160504112519_add_run_untagged_to_ci_runner.rb create mode 100644 db/migrate/20160508215820_add_type_to_notes.rb create mode 100644 db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb create mode 100644 db/migrate/20160509201028_add_health_check_access_token_to_application_settings.rb create mode 100644 db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb create mode 100644 db/migrate/20160525205328_remove_main_language_from_projects.rb create mode 100644 db/migrate/20160527020117_remove_notification_settings_for_deleted_projects.rb create mode 100644 db/migrate/20160528043124_add_users_state_index.rb create mode 100644 db/migrate/20160530150109_add_container_registry_token_expire_delay_to_application_settings.rb create mode 100644 doc/administration/container_registry.md create mode 100644 doc/administration/img/high_availability/active-active-diagram.png create mode 100644 doc/administration/img/high_availability/active-passive-diagram.png rename doc/ci/{ => examples}/deployment/README.md (100%) create mode 100644 doc/container_registry/README.md create mode 100644 doc/container_registry/img/container_registry.png create mode 100644 doc/container_registry/img/project_feature.png create mode 100644 doc/integration/img/enabled-oauth-sign-in-sources.png create mode 100644 doc/monitoring/health_check.md create mode 100644 doc/monitoring/img/health_check_token.png create mode 100644 doc/security/user_email_confirmation.md create mode 100644 doc/update/8.7-to-8.8.md delete mode 100644 features/project/commits/tags.feature delete mode 100644 features/steps/project/commits/tags.rb create mode 100644 features/steps/shared/sidebar_active_tab.rb create mode 100644 generator_templates/active_record/migration/create_table_migration.rb create mode 100644 generator_templates/active_record/migration/migration.rb create mode 100644 lib/api/gitignores.rb create mode 100644 lib/api/subscriptions.rb create mode 100644 lib/backup/registry.rb create mode 100644 lib/banzai/filter/inline_diff_filter.rb delete mode 100644 lib/banzai/filter/reference_gatherer_filter.rb delete mode 100644 lib/banzai/lazy_reference.rb delete mode 100644 lib/banzai/pipeline/reference_extraction_pipeline.rb create mode 100644 lib/banzai/reference_parser.rb create mode 100644 lib/banzai/reference_parser/base_parser.rb create mode 100644 lib/banzai/reference_parser/commit_parser.rb create mode 100644 lib/banzai/reference_parser/commit_range_parser.rb create mode 100644 lib/banzai/reference_parser/external_issue_parser.rb create mode 100644 lib/banzai/reference_parser/issue_parser.rb create mode 100644 lib/banzai/reference_parser/label_parser.rb create mode 100644 lib/banzai/reference_parser/merge_request_parser.rb create mode 100644 lib/banzai/reference_parser/milestone_parser.rb create mode 100644 lib/banzai/reference_parser/snippet_parser.rb create mode 100644 lib/banzai/reference_parser/user_parser.rb create mode 100644 lib/container_registry/blob.rb create mode 100644 lib/container_registry/client.rb create mode 100644 lib/container_registry/config.rb create mode 100644 lib/container_registry/registry.rb create mode 100644 lib/container_registry/repository.rb create mode 100644 lib/container_registry/tag.rb create mode 100644 lib/gitlab/database/migration_helpers.rb create mode 100644 lib/gitlab/github_import/branch_formatter.rb create mode 100644 lib/gitlab/gitignore.rb create mode 100644 lib/gitlab/lazy.rb create mode 100644 lib/gitlab/middleware/rails_queue_duration.rb rename lib/gitlab/{import_url.rb => url_sanitizer.rb} (66%) create mode 100644 lib/json_web_token/rsa_token.rb create mode 100644 lib/json_web_token/token.rb create mode 100644 lib/support/nginx/registry-ssl delete mode 100644 lib/tasks/auto_annotate_models.rake create mode 100644 lib/tasks/gitlab/update_gitignore.rake create mode 100644 shared/registry/.gitkeep create mode 100644 spec/controllers/health_check_controller_spec.rb create mode 100644 spec/controllers/registrations_controller_spec.rb create mode 100644 spec/features/admin/admin_health_check_spec.rb create mode 100644 spec/features/container_registry_spec.rb create mode 100644 spec/features/merge_requests/created_from_fork_spec.rb create mode 100644 spec/features/merge_requests/user_lists_merge_requests_spec.rb create mode 100644 spec/features/pipelines_spec.rb create mode 100644 spec/features/projects/developer_views_empty_project_instructions_spec.rb create mode 100644 spec/features/projects/files/gitignore_dropdown_spec.rb rename spec/features/{project => projects}/shortcuts_spec.rb (79%) create mode 100644 spec/features/tags/master_creates_tag_spec.rb create mode 100644 spec/features/tags/master_deletes_tag_spec.rb create mode 100644 spec/features/tags/master_updates_tag_spec.rb create mode 100644 spec/features/tags/master_views_tags_spec.rb create mode 100644 spec/features/todos/target_state_spec.rb create mode 100644 spec/fixtures/container_registry/config_blob.json create mode 100644 spec/fixtures/container_registry/tag_manifest.json create mode 100644 spec/javascripts/fixtures/right_sidebar.html.haml rename spec/javascripts/{ => graphs}/stat_graph_contributors_graph_spec.js (98%) rename spec/javascripts/{ => graphs}/stat_graph_contributors_util_spec.js (99%) rename spec/javascripts/{ => graphs}/stat_graph_spec.js (92%) create mode 100644 spec/javascripts/right_sidebar_spec.js.coffee create mode 100644 spec/lib/banzai/filter/inline_diff_filter_spec.rb delete mode 100644 spec/lib/banzai/filter/reference_gatherer_filter_spec.rb create mode 100644 spec/lib/banzai/filter/wiki_link_filter_spec.rb create mode 100644 spec/lib/banzai/reference_parser/base_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/commit_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/commit_range_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/external_issue_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/issue_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/label_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/merge_request_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/milestone_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/snippet_parser_spec.rb create mode 100644 spec/lib/banzai/reference_parser/user_parser_spec.rb create mode 100644 spec/lib/container_registry/blob_spec.rb create mode 100644 spec/lib/container_registry/registry_spec.rb create mode 100644 spec/lib/container_registry/repository_spec.rb create mode 100644 spec/lib/container_registry/tag_spec.rb create mode 100644 spec/lib/gitlab/database/migration_helpers_spec.rb create mode 100644 spec/lib/gitlab/github_import/branch_formatter_spec.rb create mode 100644 spec/lib/gitlab/gitignore_spec.rb delete mode 100644 spec/lib/gitlab/import_url_spec.rb create mode 100644 spec/lib/gitlab/lazy_spec.rb create mode 100644 spec/lib/gitlab/middleware/rails_queue_duration_spec.rb create mode 100644 spec/lib/gitlab/url_sanitizer_spec.rb create mode 100644 spec/lib/json_web_token/rsa_token_spec.rb create mode 100644 spec/lib/json_web_token/token_spec.rb create mode 100644 spec/mailers/previews/devise_mailer_preview.rb create mode 100644 spec/models/ability_spec.rb delete mode 100644 spec/models/ci/runner_project_spec.rb create mode 100644 spec/models/concerns/participable_spec.rb create mode 100644 spec/models/legacy_diff_note_spec.rb rename spec/requests/api/{commit_status_spec.rb => commit_statuses_spec.rb} (99%) create mode 100644 spec/requests/api/gitignores_spec.rb create mode 100644 spec/requests/jwt_controller_spec.rb create mode 100644 spec/services/auth/container_registry_authentication_service_spec.rb create mode 100644 spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb create mode 100644 spec/support/reference_parser_helpers.rb create mode 100644 spec/tasks/gitlab/db_rake_spec.rb create mode 100755 vendor/assets/javascripts/jquery.scrollTo.js delete mode 100644 vendor/assets/stylesheets/animate.css create mode 100644 vendor/gitignore/Actionscript.gitignore create mode 100644 vendor/gitignore/Ada.gitignore create mode 100644 vendor/gitignore/Agda.gitignore create mode 100644 vendor/gitignore/Android.gitignore create mode 100644 vendor/gitignore/AppEngine.gitignore create mode 100644 vendor/gitignore/AppceleratorTitanium.gitignore create mode 100644 vendor/gitignore/ArchLinuxPackages.gitignore create mode 100644 vendor/gitignore/Autotools.gitignore create mode 100644 vendor/gitignore/C++.gitignore create mode 100644 vendor/gitignore/C.gitignore create mode 100644 vendor/gitignore/CFWheels.gitignore create mode 100644 vendor/gitignore/CMake.gitignore create mode 100644 vendor/gitignore/CUDA.gitignore create mode 100644 vendor/gitignore/CakePHP.gitignore create mode 100644 vendor/gitignore/ChefCookbook.gitignore create mode 120000 vendor/gitignore/Clojure.gitignore create mode 100644 vendor/gitignore/CodeIgniter.gitignore create mode 100644 vendor/gitignore/CommonLisp.gitignore create mode 100644 vendor/gitignore/Composer.gitignore create mode 100644 vendor/gitignore/Concrete5.gitignore create mode 100644 vendor/gitignore/Coq.gitignore create mode 100644 vendor/gitignore/CraftCMS.gitignore create mode 100644 vendor/gitignore/D.gitignore create mode 100644 vendor/gitignore/DM.gitignore create mode 100644 vendor/gitignore/Dart.gitignore create mode 100644 vendor/gitignore/Delphi.gitignore create mode 100644 vendor/gitignore/Drupal.gitignore create mode 100644 vendor/gitignore/EPiServer.gitignore create mode 100644 vendor/gitignore/Eagle.gitignore create mode 100644 vendor/gitignore/Elisp.gitignore create mode 100644 vendor/gitignore/Elixir.gitignore create mode 100644 vendor/gitignore/Elm.gitignore create mode 100644 vendor/gitignore/Erlang.gitignore create mode 100644 vendor/gitignore/ExpressionEngine.gitignore create mode 100644 vendor/gitignore/ExtJs.gitignore create mode 100644 vendor/gitignore/Fancy.gitignore create mode 100644 vendor/gitignore/Finale.gitignore create mode 100644 vendor/gitignore/ForceDotCom.gitignore create mode 120000 vendor/gitignore/Fortran.gitignore create mode 100644 vendor/gitignore/FuelPHP.gitignore create mode 100644 vendor/gitignore/GWT.gitignore create mode 100644 vendor/gitignore/Gcov.gitignore create mode 100644 vendor/gitignore/GitBook.gitignore create mode 100644 vendor/gitignore/Global/Anjuta.gitignore create mode 100644 vendor/gitignore/Global/Archives.gitignore create mode 100644 vendor/gitignore/Global/BricxCC.gitignore create mode 100644 vendor/gitignore/Global/CVS.gitignore create mode 100644 vendor/gitignore/Global/Calabash.gitignore create mode 100644 vendor/gitignore/Global/Cloud9.gitignore create mode 100644 vendor/gitignore/Global/CodeKit.gitignore create mode 100644 vendor/gitignore/Global/DartEditor.gitignore create mode 100644 vendor/gitignore/Global/Dreamweaver.gitignore create mode 100644 vendor/gitignore/Global/Dropbox.gitignore create mode 100644 vendor/gitignore/Global/Eclipse.gitignore create mode 100644 vendor/gitignore/Global/EiffelStudio.gitignore create mode 100644 vendor/gitignore/Global/Emacs.gitignore create mode 100644 vendor/gitignore/Global/Ensime.gitignore create mode 100644 vendor/gitignore/Global/Espresso.gitignore create mode 100644 vendor/gitignore/Global/FlexBuilder.gitignore create mode 100644 vendor/gitignore/Global/GPG.gitignore create mode 100644 vendor/gitignore/Global/IPythonNotebook.gitignore create mode 100644 vendor/gitignore/Global/JDeveloper.gitignore create mode 100644 vendor/gitignore/Global/JetBrains.gitignore create mode 100644 vendor/gitignore/Global/KDevelop4.gitignore create mode 100644 vendor/gitignore/Global/Kate.gitignore create mode 100644 vendor/gitignore/Global/Lazarus.gitignore create mode 100644 vendor/gitignore/Global/LibreOffice.gitignore create mode 100644 vendor/gitignore/Global/Linux.gitignore create mode 100644 vendor/gitignore/Global/LyX.gitignore create mode 100644 vendor/gitignore/Global/Matlab.gitignore create mode 100644 vendor/gitignore/Global/Mercurial.gitignore create mode 100644 vendor/gitignore/Global/MicrosoftOffice.gitignore create mode 100644 vendor/gitignore/Global/ModelSim.gitignore create mode 100644 vendor/gitignore/Global/Momentics.gitignore create mode 100644 vendor/gitignore/Global/MonoDevelop.gitignore create mode 100644 vendor/gitignore/Global/NetBeans.gitignore create mode 100644 vendor/gitignore/Global/Ninja.gitignore create mode 100644 vendor/gitignore/Global/NotepadPP.gitignore create mode 100644 vendor/gitignore/Global/OSX.gitignore create mode 100644 vendor/gitignore/Global/Otto.gitignore create mode 100644 vendor/gitignore/Global/Redcar.gitignore create mode 100644 vendor/gitignore/Global/Redis.gitignore create mode 100644 vendor/gitignore/Global/SBT.gitignore create mode 100644 vendor/gitignore/Global/SVN.gitignore create mode 100644 vendor/gitignore/Global/SlickEdit.gitignore create mode 100644 vendor/gitignore/Global/SublimeText.gitignore create mode 100644 vendor/gitignore/Global/SynopsysVCS.gitignore create mode 100644 vendor/gitignore/Global/Tags.gitignore create mode 100644 vendor/gitignore/Global/TextMate.gitignore create mode 100644 vendor/gitignore/Global/TortoiseGit.gitignore create mode 100644 vendor/gitignore/Global/Vagrant.gitignore create mode 100644 vendor/gitignore/Global/Vim.gitignore create mode 100644 vendor/gitignore/Global/VirtualEnv.gitignore create mode 100644 vendor/gitignore/Global/VisualStudioCode.gitignore create mode 100644 vendor/gitignore/Global/WebMethods.gitignore create mode 100644 vendor/gitignore/Global/Windows.gitignore create mode 100644 vendor/gitignore/Global/Xcode.gitignore create mode 100644 vendor/gitignore/Global/XilinxISE.gitignore create mode 100644 vendor/gitignore/Go.gitignore create mode 100644 vendor/gitignore/Gradle.gitignore create mode 100644 vendor/gitignore/Grails.gitignore create mode 100644 vendor/gitignore/Haskell.gitignore create mode 100644 vendor/gitignore/IGORPro.gitignore create mode 100644 vendor/gitignore/Idris.gitignore create mode 100644 vendor/gitignore/Java.gitignore create mode 100644 vendor/gitignore/Jboss.gitignore create mode 100644 vendor/gitignore/Jekyll.gitignore create mode 100644 vendor/gitignore/Joomla.gitignore create mode 100644 vendor/gitignore/KiCad.gitignore create mode 100644 vendor/gitignore/Kohana.gitignore create mode 100644 vendor/gitignore/LabVIEW.gitignore create mode 100644 vendor/gitignore/Laravel.gitignore create mode 100644 vendor/gitignore/Leiningen.gitignore create mode 100644 vendor/gitignore/LemonStand.gitignore create mode 100644 vendor/gitignore/Lilypond.gitignore create mode 100644 vendor/gitignore/Lithium.gitignore create mode 100644 vendor/gitignore/Lua.gitignore create mode 100644 vendor/gitignore/Magento.gitignore create mode 100644 vendor/gitignore/Maven.gitignore create mode 100644 vendor/gitignore/Mercury.gitignore create mode 100644 vendor/gitignore/MetaProgrammingSystem.gitignore create mode 100644 vendor/gitignore/Nanoc.gitignore create mode 100644 vendor/gitignore/Nim.gitignore create mode 100644 vendor/gitignore/Node.gitignore create mode 100644 vendor/gitignore/OCaml.gitignore create mode 100644 vendor/gitignore/Objective-C.gitignore create mode 100644 vendor/gitignore/Opa.gitignore create mode 100644 vendor/gitignore/OpenCart.gitignore create mode 100644 vendor/gitignore/OracleForms.gitignore create mode 100644 vendor/gitignore/Packer.gitignore create mode 100644 vendor/gitignore/Perl.gitignore create mode 100644 vendor/gitignore/Phalcon.gitignore create mode 100644 vendor/gitignore/PlayFramework.gitignore create mode 100644 vendor/gitignore/Plone.gitignore create mode 100644 vendor/gitignore/Prestashop.gitignore create mode 100644 vendor/gitignore/Processing.gitignore create mode 100644 vendor/gitignore/Python.gitignore create mode 100644 vendor/gitignore/Qooxdoo.gitignore create mode 100644 vendor/gitignore/Qt.gitignore create mode 100644 vendor/gitignore/R.gitignore create mode 100644 vendor/gitignore/README.md create mode 100644 vendor/gitignore/ROS.gitignore create mode 100644 vendor/gitignore/Rails.gitignore create mode 100644 vendor/gitignore/RhodesRhomobile.gitignore create mode 100644 vendor/gitignore/Ruby.gitignore create mode 100644 vendor/gitignore/Rust.gitignore create mode 100644 vendor/gitignore/SCons.gitignore create mode 100644 vendor/gitignore/Sass.gitignore create mode 100644 vendor/gitignore/Scala.gitignore create mode 100644 vendor/gitignore/Scheme.gitignore create mode 100644 vendor/gitignore/Scrivener.gitignore create mode 100644 vendor/gitignore/Sdcc.gitignore create mode 100644 vendor/gitignore/SeamGen.gitignore create mode 100644 vendor/gitignore/SketchUp.gitignore create mode 100644 vendor/gitignore/Smalltalk.gitignore create mode 100644 vendor/gitignore/Stella.gitignore create mode 100644 vendor/gitignore/SugarCRM.gitignore create mode 100644 vendor/gitignore/Swift.gitignore create mode 100644 vendor/gitignore/Symfony.gitignore create mode 100644 vendor/gitignore/SymphonyCMS.gitignore create mode 100644 vendor/gitignore/TeX.gitignore create mode 100644 vendor/gitignore/Terraform.gitignore create mode 100644 vendor/gitignore/Textpattern.gitignore create mode 100644 vendor/gitignore/TurboGears2.gitignore create mode 100644 vendor/gitignore/Typo3.gitignore create mode 100644 vendor/gitignore/Umbraco.gitignore create mode 100644 vendor/gitignore/Unity.gitignore create mode 100644 vendor/gitignore/UnrealEngine.gitignore create mode 100644 vendor/gitignore/VVVV.gitignore create mode 100644 vendor/gitignore/VisualStudio.gitignore create mode 100644 vendor/gitignore/Waf.gitignore create mode 100644 vendor/gitignore/WordPress.gitignore create mode 100644 vendor/gitignore/Xojo.gitignore create mode 100644 vendor/gitignore/Yeoman.gitignore create mode 100644 vendor/gitignore/Yii.gitignore create mode 100644 vendor/gitignore/ZendFramework.gitignore create mode 100644 vendor/gitignore/Zephir.gitignore diff --git a/.gitignore b/.gitignore index 8f861d76a373b7..ce6a363fe35fe4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,46 +4,46 @@ .bundle .chef .directory -.envrc -.gitlab_shell_secret +/.envrc +/.gitlab_shell_secret .idea -.rbenv-version +/.rbenv-version .rbx/ -.ruby-gemset -.ruby-version -.rvmrc +/.ruby-gemset +/.ruby-version +/.rvmrc .sass-cache/ -.secret -.vagrant -.byebug_history -Vagrantfile -backups/* -config/aws.yml -config/database.yml -config/gitlab.yml -config/gitlab_ci.yml -config/initializers/rack_attack.rb -config/initializers/smtp_settings.rb -config/initializers/relative_url.rb -config/resque.yml -config/unicorn.rb -config/secrets.yml -config/sidekiq.yml -coverage/* -db/*.sqlite3 -db/*.sqlite3-journal -db/data.yml -doc/code/* -dump.rdb -log/*.log* -nohup.out -public/assets/ -public/uploads.* -public/uploads/ -shared/artifacts/ -rails_best_practices_output.html +/.secret +/.vagrant +/.byebug_history +/Vagrantfile +/backups/* +/config/aws.yml +/config/database.yml +/config/gitlab.yml +/config/gitlab_ci.yml +/config/initializers/rack_attack.rb +/config/initializers/smtp_settings.rb +/config/initializers/relative_url.rb +/config/resque.yml +/config/unicorn.rb +/config/secrets.yml +/config/sidekiq.yml +/coverage/* +/db/*.sqlite3 +/db/*.sqlite3-journal +/db/data.yml +/doc/code/* +/dump.rdb +/log/*.log* +/nohup.out +/public/assets/ +/public/uploads.* +/public/uploads/ +/shared/artifacts/ +/rails_best_practices_output.html /tags -tmp/ -vendor/bundle/* -builds/* -shared/* +/tmp/* +/vendor/bundle/* +/builds/* +/shared/* diff --git a/.rubocop.yml b/.rubocop.yml index 9f179efa3ce0ba..84a8015b410026 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,5 @@ +require: rubocop-rspec + AllCops: TargetRubyVersion: 2.1 # Cop names are not displayed in offense messages by default. Change behavior @@ -21,6 +23,7 @@ AllCops: - 'lib/email_validator.rb' - 'lib/gitlab/upgrader.rb' - 'lib/gitlab/seeder.rb' + - 'generator_templates/**/*' ##################### Style ################################## @@ -56,7 +59,7 @@ Style/AndOr: # Use `Array#join` instead of `Array#*`. Style/ArrayJoin: - Enabled: false + Enabled: true # Use only ascii symbols in comments. Style/AsciiComments: @@ -68,7 +71,7 @@ Style/AsciiIdentifiers: # Checks for uses of Module#attr. Style/Attr: - Enabled: false + Enabled: true # Avoid the use of BEGIN blocks. Style/BeginBlock: @@ -80,7 +83,7 @@ Style/BarePercentLiterals: # Do not use block comments. Style/BlockComments: - Enabled: false + Enabled: true # Put end statement of multiline block on its own line. Style/BlockEndNewline: @@ -121,7 +124,7 @@ Style/ClassCheck: # Use self when defining module/class methods. Style/ClassMethods: - Enabled: false + Enabled: true # Avoid the use of class variables. Style/ClassVars: @@ -151,7 +154,7 @@ Style/ConstantName: # Use def with parentheses when there are arguments. Style/DefWithParentheses: - Enabled: false + Enabled: true # Checks for use of deprecated Hash methods. Style/DeprecatedHashMethods: @@ -215,15 +218,15 @@ Style/EmptyLiteral: # Avoid the use of END blocks. Style/EndBlock: - Enabled: false + Enabled: true # Use Unix-style line endings. Style/EndOfLine: - Enabled: false + Enabled: true # Favor the use of Fixnum#even? && Fixnum#odd? Style/EvenOdd: - Enabled: false + Enabled: true # Do not use unnecessary spacing. Style/ExtraSpacing: @@ -231,15 +234,20 @@ Style/ExtraSpacing: # Use snake_case for source file names. Style/FileName: - Enabled: false + Enabled: true + +# Checks for a line break before the first parameter in a multi-line method +# parameter definition. +Style/FirstMethodParameterLineBreak: + Enabled: true # Checks for flip flops. Style/FlipFlop: - Enabled: false + Enabled: true # Checks use of for or each in multiline loops. Style/For: - Enabled: false + Enabled: true # Enforce the use of Kernel#sprintf, Kernel#format or String#%. Style/FormatString: @@ -247,7 +255,7 @@ Style/FormatString: # Do not introduce global variables. Style/GlobalVars: - Enabled: false + Enabled: true # Check for conditionals that can be replaced with guard clauses. Style/GuardClause: @@ -268,7 +276,7 @@ Style/IfUnlessModifier: # Do not use if x; .... Use the ternary operator instead. Style/IfWithSemicolon: - Enabled: false + 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. @@ -276,9 +284,9 @@ Style/IdenticalConditionalBranches: Enabled: false # Checks the indentation of the first line of the right-hand-side of a -# multi-line assignment. +# multi-line assignment. Style/IndentAssignment: - Enabled: false + Enabled: true # Keep indentation straight. Style/IndentationConsistency: @@ -298,7 +306,7 @@ Style/IndentHash: # Use Kernel#loop for infinite loops. Style/InfiniteLoop: - Enabled: false + Enabled: true # Use the new lambda literal syntax for single-line blocks. Style/Lambda: @@ -306,11 +314,11 @@ Style/Lambda: # Use lambda.call(...) instead of lambda.(...). Style/LambdaCall: - Enabled: false + Enabled: true # Comments should start with a space. Style/LeadingCommentSpace: - Enabled: false + Enabled: true # Use \ instead of + or << to concatenate two string literals at line end. Style/LineEndConcatenation: @@ -322,16 +330,22 @@ Style/MethodCallParentheses: # Checks if the method definitions have or don't have parentheses. Style/MethodDefParentheses: - Enabled: false + Enabled: true # Use the configured style when naming methods. Style/MethodName: - Enabled: false + Enabled: true # Checks for usage of `extend self` in modules. Style/ModuleFunction: Enabled: false +# 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 + EnforcedStyle: symmetrical + # Avoid multi-line chains of blocks. Style/MultilineBlockChain: Enabled: false @@ -340,15 +354,32 @@ Style/MultilineBlockChain: Style/MultilineBlockLayout: Enabled: true +# 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 + EnforcedStyle: symmetrical + # Do not use then for multi-line if/unless. Style/MultilineIfThen: + Enabled: true + +# Checks that the closing brace in a method call is either on the same line as +# the last method argument, or a new line. +Style/MultilineMethodCallBraceLayout: Enabled: false + EnforcedStyle: symmetrical # Checks indentation of method calls with the dot operator that span more than # one line. Style/MultilineMethodCallIndentation: Enabled: false +# Checks that the closing brace in a method definition is symmetrical with +# respect to the opening brace and the method parameters. +Style/MultilineMethodDefinitionBraceLayout: + Enabled: false + # Checks indentation of binary operations that span more than one line. Style/MultilineOperationIndentation: Enabled: false @@ -363,7 +394,7 @@ Style/MutableConstant: # Favor unless over if for negative conditions (or control flow or). Style/NegatedIf: - Enabled: false + Enabled: true # Favor until over while for negative conditions. Style/NegatedWhile: @@ -371,7 +402,7 @@ Style/NegatedWhile: # Avoid using nested modifiers. Style/NestedModifier: - Enabled: false + Enabled: true # Parenthesize method calls which are nested inside the argument list of # another parenthesized method call. @@ -408,7 +439,7 @@ Style/OneLineConditional: # When defining binary operators, name the argument other. Style/OpMethod: - Enabled: false + Enabled: true # Check for simple usages of parallel assignment. It will only warn when # the number of variables matches on both sides of the assignment. @@ -455,10 +486,9 @@ Style/RedundantException: Style/RedundantFreeze: Enabled: false -# TODO: Enable RedundantParentheses Cop. # Checks for parentheses that seem not to serve any purpose. Style/RedundantParentheses: - Enabled: false + Enabled: true # Don't use return where it's not required. Style/RedundantReturn: @@ -484,11 +514,12 @@ Style/SelfAssignment: # Don't use semicolons to terminate expressions. Style/Semicolon: - Enabled: false + Enabled: true # Checks for proper usage of fail and raise. Style/SignalException: - Enabled: false + EnforcedStyle: only_raise + Enabled: true # Enforces the names of some block params. Style/SingleLineBlockParams: @@ -509,29 +540,28 @@ Style/SpaceAfterComma: # Do not put a space between a method name and the opening parenthesis in a # method definition. Style/SpaceAfterMethodName: - Enabled: false + Enabled: true # Tracks redundant space after the ! operator. Style/SpaceAfterNot: - Enabled: false + Enabled: true # Use spaces after semicolons. Style/SpaceAfterSemicolon: - Enabled: false + Enabled: true # Checks that the equals signs in parameter default assignments have or don't # have surrounding space depending on configuration. Style/SpaceAroundEqualsInParameterDefault: Enabled: false -# TODO: Enable SpaceAroundKeyword Cop. # Use a space around keywords if appropriate. Style/SpaceAroundKeyword: - Enabled: false + Enabled: true # Use a single space around operators. Style/SpaceAroundOperators: - Enabled: false + Enabled: true # Checks that the left block brace has or doesn't have space before it. Style/SpaceBeforeBlockBraces: @@ -539,11 +569,11 @@ Style/SpaceBeforeBlockBraces: # No spaces before commas. Style/SpaceBeforeComma: - Enabled: false + Enabled: true # Checks for missing space between code and a comment on the same line. Style/SpaceBeforeComment: - Enabled: false + Enabled: true # Checks that exactly one space is used between a method name and the first # argument for method calls without parentheses. @@ -552,7 +582,7 @@ Style/SpaceBeforeFirstArg: # No spaces before semicolons. Style/SpaceBeforeSemicolon: - Enabled: false + Enabled: true # Checks that block braces have or don't have surrounding space. # For blocks taking parameters, checks that the left brace has or doesn't @@ -574,11 +604,12 @@ Style/SpaceInsideParens: # No spaces inside range literals. Style/SpaceInsideRangeLiteral: - Enabled: false + Enabled: true # Checks for padding/surrounding spaces inside string interpolation. Style/SpaceInsideStringInterpolation: - Enabled: false + EnforcedStyle: no_space + Enabled: true # Avoid Perl-style global variables. Style/SpecialGlobalVars: @@ -586,7 +617,8 @@ Style/SpecialGlobalVars: # Check for the usage of parentheses around stabby lambda arguments. Style/StabbyLambdaParentheses: - Enabled: false + EnforcedStyle: require_parentheses + Enabled: true # Checks if uses of quotes match the configured preference. Style/StringLiterals: @@ -599,7 +631,9 @@ Style/StringLiteralsInInterpolation: # Checks if configured preferred methods are used over non-preferred. Style/StringMethods: - Enabled: false + PreferredMethods: + intern: to_sym + Enabled: true # Use %i or %I for arrays of symbols. Style/SymbolArray: @@ -657,23 +691,24 @@ Style/UnneededPercentQ: # Don't interpolate global, instance and class variables directly in strings. Style/VariableInterpolation: - Enabled: false + Enabled: true # Use the configured style when naming variables. Style/VariableName: - Enabled: false + EnforcedStyle: snake_case + Enabled: true # Use when x then ... for one-line cases. Style/WhenThen: - Enabled: false + Enabled: true # Checks for redundant do after while or until. Style/WhileUntilDo: - Enabled: false + Enabled: true # Favor modifier while/until usage when you have a single-line body. Style/WhileUntilModifier: - Enabled: false + Enabled: true # Use %w or %W for arrays of words. Style/WordArray: @@ -749,28 +784,28 @@ Lint/AssignmentInCondition: # Align block ends correctly. Lint/BlockAlignment: - Enabled: false + Enabled: true # Default values in optional keyword arguments and optional ordinal arguments # should not refer back to the name of the argument. Lint/CircularArgumentReference: - Enabled: false + Enabled: true # Checks for condition placed in a confusing position relative to the keyword. Lint/ConditionPosition: - Enabled: false + Enabled: true # Check for debugger calls. Lint/Debugger: - Enabled: false + Enabled: true # Align ends corresponding to defs correctly. Lint/DefEndAlignment: - Enabled: false + Enabled: true # Check for deprecated class method calls. Lint/DeprecatedClassMethods: - Enabled: false + Enabled: true # Check for duplicate method definitions. Lint/DuplicateMethods: @@ -782,15 +817,15 @@ Lint/DuplicatedKey: # Check for immutable argument given to each_with_object. Lint/EachWithObjectArgument: - Enabled: false + Enabled: true # Check for odd code arrangement in an else block. Lint/ElseLayout: - Enabled: false + Enabled: true # Checks for empty ensure block. Lint/EmptyEnsure: - Enabled: false + Enabled: true # Checks for empty string interpolation. Lint/EmptyInterpolation: @@ -798,37 +833,36 @@ Lint/EmptyInterpolation: # Align ends correctly. Lint/EndAlignment: - Enabled: false + Enabled: true # END blocks should not be placed inside method definitions. Lint/EndInMethod: - Enabled: false + Enabled: true # Do not use return in an ensure block. Lint/EnsureReturn: - Enabled: false + Enabled: true # The use of eval represents a serious security risk. Lint/Eval: - Enabled: false + Enabled: true # Catches floating-point literals too large or small for Ruby to represent. Lint/FloatOutOfRange: - Enabled: false + Enabled: true # The number of parameters to format/sprint must match the fields. Lint/FormatParameterMismatch: - Enabled: false + Enabled: true # Don't suppress exception. Lint/HandleExceptions: Enabled: false -# TODO: Enable ImplicitStringConcatenation Cop. # Checks for adjacent string literals on the same line, which could better be # represented as a single string literal. Lint/ImplicitStringConcatenation: - Enabled: false + Enabled: true # TODO: Enable IneffectiveAccessModifier Cop. # Checks for attempts to use `private` or `protected` to set the visibility @@ -839,15 +873,15 @@ Lint/IneffectiveAccessModifier: # Checks for invalid character literals with a non-escaped whitespace # character. Lint/InvalidCharacterLiteral: - Enabled: false + Enabled: true # Checks of literals used in conditions. Lint/LiteralInCondition: - Enabled: false + Enabled: true # Checks for literals used in interpolation. Lint/LiteralInInterpolation: - Enabled: false + Enabled: true # Use Kernel#loop with break rather than begin/end/until or begin/end/while # for post-loop tests. @@ -856,11 +890,11 @@ Lint/Loop: # Do not use nested method definitions. Lint/NestedMethodDefinition: - Enabled: false + Enabled: true # Do not omit the accumulator when calling `next` in a `reduce`/`inject` block. Lint/NextWithoutAccumulator: - Enabled: false + Enabled: true # Checks for method calls with a space before the opening parenthesis. Lint/ParenthesesAsGroupedExpression: @@ -869,11 +903,11 @@ Lint/ParenthesesAsGroupedExpression: # Checks for `rand(1)` calls. Such calls always return `0` and most likely # a mistake. Lint/RandOne: - Enabled: false + Enabled: true # Use parentheses in the method call to avoid confusion about precedence. Lint/RequireParentheses: - Enabled: false + Enabled: true # Avoid rescuing the Exception class. Lint/RescueException: @@ -908,7 +942,7 @@ Lint/UnusedMethodArgument: # Unreachable code. Lint/UnreachableCode: - Enabled: false + Enabled: true # Checks for useless access modifiers. Lint/UselessAccessModifier: @@ -920,33 +954,31 @@ Lint/UselessAssignment: # Checks for comparison of something with itself. Lint/UselessComparison: - Enabled: false + Enabled: true # Checks for useless `else` in `begin..end` without `rescue`. Lint/UselessElseWithoutRescue: - Enabled: false + Enabled: true # Checks for useless setter call to a local variable. Lint/UselessSetterCall: - Enabled: false + Enabled: true # Possible use of operator/literal/variable in void context. Lint/Void: - Enabled: false + Enabled: true ##################### Performance ############################ -# TODO: Enable Casecmp Cop. # Use `casecmp` rather than `downcase ==`. Performance/Casecmp: - Enabled: false + Enabled: true -# TODO: Enable DoubleStartEndWith Cop. # Use `str.{start,end}_with?(x, ..., y, ...)` instead of # `str.{start,end}_with?(x, ...) || str.{start,end}_with?(y, ...)`. Performance/DoubleStartEndWith: - Enabled: false + Enabled: true # TODO: Enable EndWith Cop. # Use `end_with?` instead of a regex match anchored to the end of a string. @@ -957,10 +989,9 @@ Performance/EndWith: Performance/LstripRstrip: Enabled: true -# TODO: Enable RangeInclude Cop. # Use `Range#cover?` instead of `Range#include?`. Performance/RangeInclude: - Enabled: false + Enabled: true # TODO: Enable RedundantBlockCall Cop. # Use `yield` instead of `block.call`. @@ -980,26 +1011,24 @@ Performance/RedundantMerge: MaxKeyValuePairs: 2 Enabled: false -# TODO: Enable RedundantSortBy Cop. # Use `sort` instead of `sort_by { |x| x }`. Performance/RedundantSortBy: - Enabled: false + Enabled: true -# TODO: Enable StartWith Cop. # Use `start_with?` instead of a regex match anchored to the beginning of a # string. Performance/StartWith: - Enabled: false + Enabled: true + # Use `tr` instead of `gsub` when you are replacing the same number of # characters. Use `delete` instead of `gsub` when you are deleting # characters. Performance/StringReplacement: - Enabled: false + Enabled: true -# TODO: Enable TimesMap Cop. # Checks for `.times.map` calls. Performance/TimesMap: - Enabled: false + Enabled: true ##################### Rails ################################## @@ -1024,11 +1053,11 @@ Rails/Delegate: # Prefer `find_by` over `where.first`. Rails/FindBy: - Enabled: false + Enabled: true # Prefer `all.find_each` over `all.find`. Rails/FindEach: - Enabled: false + Enabled: true # Prefer has_many :through to has_and_belongs_to_many. Rails/HasAndBelongsToMany: @@ -1040,7 +1069,7 @@ Rails/Output: # Checks for incorrect grammar when using methods like `3.day.ago`. Rails/PluralizationGrammar: - Enabled: false + Enabled: true # Checks for `read_attribute(:attr)` and `write_attribute(:attr, val)`. Rails/ReadWriteAttribute: @@ -1048,7 +1077,7 @@ Rails/ReadWriteAttribute: # Checks the arguments of ActiveRecord scopes. Rails/ScopeArgs: - Enabled: false + Enabled: true # Checks the correct usage of time zone aware methods. # http://danilenko.org/2012/7/6/rails_timezones @@ -1058,3 +1087,65 @@ Rails/TimeZone: # Use validates :attribute, hash of validations. Rails/Validation: Enabled: false + +##################### RSpec ################################## + +# Check that instances are not being stubbed globally. +RSpec/AnyInstance: + Enabled: false + +# Check that the first argument to the top level describe is the tested class or +# module. +RSpec/DescribeClass: + Enabled: false + +# Use `described_class` for tested class / module. +RSpec/DescribeMethod: + Enabled: false + +# Checks that the second argument to top level describe is the tested method +# name. +RSpec/DescribedClass: + Enabled: false + +# Checks for long example. +RSpec/ExampleLength: + Enabled: false + Max: 5 + +# Do not use should when describing your tests. +RSpec/ExampleWording: + Enabled: false + CustomTransform: + be: is + have: has + not: does not + IgnoredWords: [] + +# Checks the file and folder naming of the spec file. +RSpec/FilePath: + Enabled: false + CustomTransform: + RuboCop: rubocop + RSpec: rspec + +# Checks if there are focused specs. +RSpec/Focus: + Enabled: true + +# Checks for the usage of instance variables. +RSpec/InstanceVariable: + Enabled: false + +# Checks for multiple top-level describes. +RSpec/MultipleDescribes: + Enabled: false + +# Enforces the usage of the same method on all negative message expectations. +RSpec/NotToNot: + EnforcedStyle: not_to + Enabled: true + +# Prefer using verifying doubles over normal doubles. +RSpec/VerifiedDoubles: + Enabled: false diff --git a/app/views/projects/notes/_commit_discussion.html.haml b/.vagrant_enabled similarity index 100% rename from app/views/projects/notes/_commit_discussion.html.haml rename to .vagrant_enabled diff --git a/CHANGELOG b/CHANGELOG index 822fa4be56586b..ec026b8f39827f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,47 +1,180 @@ Please view this file on the master branch, on stable branches it's out of date. -v 8.8.0 (unreleased) +v 8.9.0 (unreleased) + - Allow enabling wiki page events from Webhook management UI + - Make EmailsOnPushWorker use Sidekiq mailers queue + - Fix wiki page events' webhook to point to the wiki repository + - Fix issue todo not remove when leave project !4150 (Long Nguyen) + - Allow forking projects with restricted visibility level + - Improve note validation to prevent errors when creating invalid note via API + - Reduce number of fog gem dependencies + - Remove project notification settings associated with deleted projects + - Fix 404 page when viewing TODOs that contain milestones or labels in different projects + - Redesign navigation for project pages + - Fix groups API to list only user's accessible projects + - Redesign account and email confirmation emails + - Use gitlab-shell v3.0.0 + - Add DB index on users.state + - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database + - Changed the Slack build message to use the singular duration if necessary (Aran Koning) + - Fix issues filter when ordering by milestone + - Todos will display target state if issuable target is 'Closed' or 'Merged' + - Fix bug when sorting issues by milestone due date and filtering by two or more labels + - Link to blank group icon doesn't throw a 404 anymore + - Remove 'main language' feature + - Pipelines can be canceled only when there are running builds + - Use downcased path to container repository as this is expected path by Docker + - Projects pending deletion will render a 404 page + - Measure queue duration between gitlab-workhorse and Rails + - Make authentication service for Container Registry to be compatible with < Docker 1.11 + - Add Application Setting to configure Container Registry token expire delay (default 5min) + - Cache assigned issue and merge request counts in sidebar nav + - Cache project build count in sidebar nav + - Reduce number of queries needed to render issue labels in the sidebar + - Improve error handling importing projects + - Put project Files and Commits tabs under Code tab + +v 8.8.3 + - Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312 + - Fixed JS error when trying to remove discussion form. !4303 + - Fixed issue with button color when no CI enabled. !4287 + - Fixed potential issue with 2 CI status polling events happening. !3869 + - Improve design of Pipeline view. !4230 + - Fix gitlab importer failing to import new projects due to missing credentials. !4301 + - Fix import URL migration not rescuing with the correct Error. !4321 + - Fix health check access token changing due to old application settings being used. !4332 + - Make authentication service for Container Registry to be compatible with Docker versions before 1.11. !4363 + - Add Application Setting to configure Container Registry token expire delay (default 5 min). !4364 + - Pass the "Remember me" value to the 2FA token form. !4369 + - Fix incorrect links on pipeline page when merge request created from fork. !4376 + - Use downcased path to container repository as this is expected path by Docker. !4420 + - Fix wiki project clone address error (chujinjin). !4429 + - Fix serious performance bug with rendering Markdown with InlineDiffFilter. !4392 + - Fix missing number on generated ordered list element. !4437 + - Prevent disclosure of notes on confidential issues in search results. + +v 8.8.2 + - Added remove due date button. !4209 + - Fix Error 500 when accessing application settings due to nil disabled OAuth sign-in sources. !4242 + - Fix Error 500 in CI charts by gracefully handling commits with no durations. !4245 + - Fix table UI on CI builds page. !4249 + - Fix backups if registry is disabled. !4263 + - Fixed issue with merge button color. !4211 + - Fixed issue with enter key selecting wrong option in dropdown. !4210 + - When creating a .gitignore file a dropdown with templates will be provided. !4075 + - Fix concurrent request when updating build log in browser. !4183 + +v 8.8.1 + - Add documentation for the "Health Check" feature + - Allow anonymous users to access a public project's pipelines !4233 + - Fix MySQL compatibility in zero downtime migrations helpers + - Fix the CI login to Container Registry (the gitlab-ci-token user) + +v 8.8.0 + - Implement GFM references for milestones (Alejandro Rodríguez) + - Snippets tab under user profile. !4001 (Long Nguyen) + - Fix error when using link to uploads in global snippets + - Fix Error 500 when attempting to retrieve project license when HEAD points to non-existent ref - Assign labels and milestone to target project when moving issue. !3934 (Long Nguyen) + - Use a case-insensitive comparison in sanitizing URI schemes + - Toggle sign-up confirmation emails in application settings + - Make it possible to prevent tagged runner from picking untagged jobs + - Added `InlineDiffFilter` to the markdown parser. (Adam Butler) + - Added inline diff styling for `change_title` system notes. (Adam Butler) - Project#open_branches has been cleaned up and no longer loads entire records into memory. - Escape HTML in commit titles in system note messages + - Improve design of Pipeline View + - Fix scope used when accessing container registry + - Fix creation of Ci::Commit object which can lead to pending, failed in some scenarios - Improve multiple branch push performance by memoizing permission checking - Log to application.log when an admin starts and stops impersonating a user + - Changing the confidentiality of an issue now creates a new system note (Alex Moore-Niemi) - Updated gitlab_git to 10.1.0 - GitAccess#protected_tag? no longer loads all tags just to check if a single one exists - Reduce delay in destroying a project from 1-minute to immediately - Make build status canceled if any of the jobs was canceled and none failed - Upgrade Sidekiq to 4.1.2 + - Added /health_check endpoint for checking service status + - Make 'upcoming' filter for milestones work better across projects - Sanitize repo paths in new project error message - Bump mail_room to 0.7.0 to fix stuck IDLE connections - Remove future dates from contribution calendar graph. - Support e-mail notifications for comments on project snippets + - Fix API leak of notes of unauthorized issues, snippets and merge requests - Use ActionDispatch Remote IP for Akismet checking - Fix error when visiting commit builds page before build was updated - Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project - Update SVG sanitizer to conform to SVG 1.1 + - Speed up push emails with multiple recipients by only generating the email once - Updated search UI + - Added authentication service for Container Registry - Display informative message when new milestone is created + - Sanitize milestones and labels titles + - Support multi-line tag messages. !3833 (Calin Seciu) + - Force users to reset their password after an admin changes it - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea) - Added button to toggle whitespaces changes on diff view - Backport GitHub Enterprise import support from EE - Create tags using Rugged for performance reasons. !3745 + - Allow guests to set notification level in projects + - API: Expose Issue#user_notes_count. !3126 (Anton Popov) + - Don't show forks button when user can't view forks + - Fix atom feed links and rendering - Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718 - Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes) + - Add eager load paths to help prevent dependency load issues in Sidekiq workers. !3724 - Added multiple colors for labels in dropdowns when dups happen. + - Show commits in the same order as `git log` - Improve description for the Two-factor Authentication sign-in screen. (Connor Shea) - API support for the 'since' and 'until' operators on commit requests (Paco Guzman) - Fix Gravatar hint in user profile when Gravatar is disabled. !3988 (Artem Sidorenko) - Expire repository exists? and has_visible_content? caches after a push if necessary - - Fix unintentional filtering bug in issues sorted by milestone due (Takuya Noguchi) + - Fix unintentional filtering bug in Issue/MR sorted by milestone due (Takuya Noguchi) + - Fix adding a todo for private group members (Ahmad Sherif) + - Bump ace-rails-ap gem version from 2.0.1 to 4.0.2 which upgrades Ace Editor from 1.1.2 to 1.2.3 + - Total method execution timings are no longer tracked + - Allow Admins to remove the Login with buttons for OAuth services and still be able to import !4034. (Andrei Gliga) + - Add API endpoints for un/subscribing from/to a label. !4051 (Ahmad Sherif) + - Hide left sidebar on phone screens to give more space for content + - Redesign navigation for profile and group pages + - Add counter metrics for rails cache + - Import pull requests from GitHub where the source or target branches were removed + - All Grape API helpers are now instrumented + - Improve Issue formatting for the Slack Service (Jeroen van Baarsen) + - Fixed advice on invalid permissions on upload path !2948 (Ludovic Perrine) + - Allows MR authors to have the source branch removed when merging the MR. !2801 (Jeroen Jacobs) + - When creating a .gitignore file a dropdown with templates will be provided + +v 8.7.7 + - Fix import by `Any Git URL` broken if the URL contains a space + +v 8.7.6 + - Fix links on wiki pages for relative url setups. !4131 (Artem Sidorenko) + - Fix import from GitLab.com to a private instance failure. !4181 + - Fix external imports not finding the import data. !4106 + - Fix notification delay when changing status of an issue + +v 8.7.5 + - Fix relative links in wiki pages. !4050 + - Fix always showing build notification message when switching between merge requests !4086 + - Fix an issue when filtering merge requests with more than one label. !3886 + - Fix short note for the default scope on build page (Takuya Noguchi) v 8.7.4 - - Fix always showing build notification message when switching between merge requests + - Links for Redmine issue references are generated correctly again !4048 (Benedikt Huss) + - Fix setting trusted proxies !3970 + - Fix BitBucket importer bug when throwing exceptions !3941 + - Use sign out path only if not empty !3989 + - Running rake gitlab:db:drop_tables now drops tables with cascade !4020 + - Running rake gitlab:db:drop_tables uses "IF EXISTS" as a precaution !4100 + - Use a case-insensitive comparison in sanitizing URI schemes v 8.7.3 - Emails, Gitlab::Email::Message, Gitlab::Diff, and Premailer::Adapter::Nokogiri are now instrumented - Merge request widget displays TeamCity build state and code coverage correctly again. - Fix the line code when importing PR review comments from GitHub. !4010 - Wikis are now initialized on legacy projects when checking repositories + - Remove animate.css in favor of a smaller subset of animations. !3937 (Connor Shea) v 8.7.2 - The "New Branch" button is now loaded asynchronously @@ -850,7 +983,7 @@ v 8.1.3 - Use issue editor as cross reference comment author when issue is edited with a new mention - Add Facebook authentication -v 8.1.2 +v 8.1.1 - Fix cloning Wiki repositories via HTTP (Stan Hu) - Add migration to remove satellites directory - Fix specific runners visibility @@ -1475,20 +1608,17 @@ v 7.10.0 - Fix stuck Merge Request merging events from old installations (Ben Bodenmiller) - Fix merge request comments on files with multiple commits - Fix Resource Owner Password Authentication Flow - -v 7.9.4 - - Security: Fix project import URL regex to prevent arbitary local repos from being imported - - Fixed issue where only 25 commits would load in file listings - - Fix LDAP identities after config update - -v 7.9.3 - - Contains no changes - Add icons to Add dropdown items. - Allow admin to create public deploy keys that are accessible to any project. - Warn when gitlab-shell version doesn't match requirement. - Skip email confirmation when set by admin or via LDAP. - Only allow users to reference groups, projects, issues, MRs, commits they have access to. +v 7.9.4 + - Security: Fix project import URL regex to prevent arbitary local repos from being imported + - Fixed issue where only 25 commits would load in file listings + - Fix LDAP identities after config update + v 7.9.3 - Contains no changes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9fe4cf7b0f6d8f..a15f8c4fec74bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -311,13 +311,11 @@ request is as follows: 1. Create a feature branch 1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code 1. Add your changes to the [CHANGELOG](CHANGELOG) -1. If you are changing the README, some documentation or other things which - have no effect on the tests, add `[ci skip]` somewhere in the commit message - and make sure to read the [documentation styleguide][doc-styleguide] +1. If you are writing documentation, make sure to read the [documentation styleguide][doc-styleguide] 1. If you have multiple commits please combine them into one commit by [squashing them][git-squash] 1. Push the commit(s) to your fork -1. Submit a merge request (MR) to the master branch +1. Submit a merge request (MR) to the `master` branch 1. The MR title should describe the change you want to make 1. The MR description should give a motive for your change and the method you used to achieve it, see the [merge request description format] diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 37c2961c2430f3..4a36342fcab700 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -2.7.2 +3.0.0 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index 39e898a4f952d3..0a1ffad4b4df76 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -0.7.1 +0.7.4 diff --git a/Gemfile b/Gemfile index 1137ef4d72b6cc..d9429de786f863 100644 --- a/Gemfile +++ b/Gemfile @@ -18,9 +18,8 @@ gem "mysql2", '~> 0.3.16', group: :mysql gem "pg", '~> 0.18.2', group: :postgres # Authentication libraries -gem 'devise', '~> 3.5.4' +gem 'devise', '~> 4.0' gem 'doorkeeper', '~> 3.1' -gem 'devise-async', '~> 0.9.0' gem 'omniauth', '~> 1.3.1' gem 'omniauth-auth0', '~> 1.4.1' gem 'omniauth-azure-oauth2', '~> 0.0.6' @@ -36,15 +35,16 @@ gem 'omniauth-shibboleth', '~> 1.2.0' gem 'omniauth-twitter', '~> 1.2.0' gem 'omniauth_crowd', '~> 2.2.0' gem 'rack-oauth2', '~> 1.2.1' +gem 'jwt' # Spam and anti-bot protection gem 'recaptcha', require: 'recaptcha/rails' gem 'akismet', '~> 2.0' # Two-factor authentication -gem 'devise-two-factor', '~> 2.0.0' +gem 'devise-two-factor', '~> 3.0.0' gem 'rqrcode-rails3', '~> 0.1.7' -gem 'attr_encrypted', '~> 1.3.4' +gem 'attr_encrypted', '~> 3.0.0' # Browser detection gem "browser", '~> 1.0.0' @@ -72,7 +72,7 @@ gem 'grape-entity', '~> 0.4.2' gem 'rack-cors', '~> 0.4.0', require: 'rack/cors' # Pagination -gem "kaminari", "~> 0.16.3" +gem "kaminari", "~> 0.17.0" # HAML gem "haml-rails", '~> 0.9.0' @@ -83,8 +83,14 @@ gem "carrierwave", '~> 0.10.0' # Drag and Drop UI gem 'dropzonejs-rails', '~> 0.7.1' +# for backups +gem 'fog-aws', '~> 0.9' +gem 'fog-core', '~> 1.40' +gem 'fog-local', '~> 0.3' +gem 'fog-google', '~> 0.3' +gem 'fog-openstack', '~> 0.1' + # for aws storage -gem "fog", "~> 1.36.0" gem "unf", '~> 0.1.4' # Authorization @@ -120,7 +126,7 @@ group :unicorn do end # State machine -gem "state_machines-activerecord", '~> 0.3.0' +gem "state_machines-activerecord", '~> 0.4.0' # Run events after state machine commits gem 'after_commit_queue' @@ -177,9 +183,6 @@ gem 'ruby-fogbugz', '~> 0.2.1' # d3 gem 'd3_rails', '~> 3.5.0' -#cal-heatmap -gem 'cal-heatmap-rails', '~> 3.6.0' - # underscore-rails gem "underscore-rails", "~> 1.8.0" @@ -197,7 +200,7 @@ gem 'licensee', '~> 8.0.0' gem "rack-attack", '~> 4.3.1' # Ace editor -gem 'ace-rails-ap', '~> 2.0.1' +gem 'ace-rails-ap', '~> 4.0.2' # Keyboard shortcuts gem 'mousetrap-rails', '~> 1.4.6' @@ -218,13 +221,13 @@ gem 'gitlab_emoji', '~> 0.3.0' gem 'gon', '~> 6.0.1' gem 'jquery-atwho-rails', '~> 1.3.2' gem 'jquery-rails', '~> 4.1.0' -gem 'jquery-scrollto-rails', '~> 1.4.3' gem 'jquery-ui-rails', '~> 5.0.0' gem 'raphael-rails', '~> 2.1.2' gem 'request_store', '~> 1.3.0' gem 'select2-rails', '~> 3.5.9' gem 'virtus', '~> 1.0.1' gem 'net-ssh', '~> 3.0.1' +gem 'base32', '~> 0.3.0' # Sentry integration gem 'sentry-raven', '~> 0.15' @@ -242,7 +245,6 @@ group :development do gem "foreman" gem 'brakeman', '~> 3.2.0', require: false - gem "annotate", "~> 2.7.0" gem 'letter_opener_web', '~> 1.3.0' gem 'quiet_assets', '~> 1.0.2' gem 'rerun', '~> 0.11.0' @@ -293,9 +295,10 @@ group :development, :test do gem 'spring-commands-spinach', '~> 1.1.0' gem 'spring-commands-teaspoon', '~> 0.0.2' - gem 'rubocop', '~> 0.38.0', require: false + gem 'rubocop', '~> 0.40.0', require: false + gem 'rubocop-rspec', '~> 1.5.0', require: false gem 'scss_lint', '~> 0.47.0', require: false - gem 'coveralls', '~> 0.8.2', require: false + gem 'coveralls', '~> 0.8.2', require: false gem 'simplecov', '~> 0.11.0', require: false gem 'flog', require: false gem 'flay', require: false @@ -325,8 +328,7 @@ gem "mail_room", "~> 0.7" gem 'email_reply_parser', '~> 0.5.8' ## CI -gem 'activerecord-deprecated_finders', '~> 1.0.3' -gem 'activerecord-session_store', '~> 0.1.0' +gem 'activerecord-session_store', '~> 1.0.0' gem "nested_form", '~> 0.3.2' # OAuth @@ -334,3 +336,6 @@ gem 'oauth2', '~> 1.0.0' # Soft deletion gem "paranoia", "~> 2.0" + +# Health check +gem 'health_check', '~> 1.5.1' diff --git a/Gemfile.lock b/Gemfile.lock index fe083c2b56681f..8ae25269e65fe2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,8 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (2.3.2) RedCloth (4.2.9) - ace-rails-ap (2.0.1) + ace-rails-ap (4.0.2) actionmailer (4.2.6) actionpack (= 4.2.6) actionview (= 4.2.6) @@ -33,11 +32,12 @@ GEM activemodel (= 4.2.6) activesupport (= 4.2.6) arel (~> 6.0) - activerecord-deprecated_finders (1.0.4) - activerecord-session_store (0.1.2) - actionpack (>= 4.0.0, < 5) - activerecord (>= 4.0.0, < 5) - railties (>= 4.0.0, < 5) + activerecord-session_store (1.0.0) + actionpack (>= 4.0, < 5.1) + activerecord (>= 4.0, < 5.1) + multi_json (~> 1.11, >= 1.11.2) + rack (>= 1.5.2, < 3) + railties (>= 4.0, < 5.1) activesupport (4.2.6) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) @@ -51,9 +51,6 @@ GEM activerecord (>= 3.0) akismet (2.0.0) allocations (1.0.4) - annotate (2.7.0) - activerecord (>= 3.2, < 6.0) - rake (~> 10.4) arel (6.0.3) asana (0.4.0) faraday (~> 0.9) @@ -62,8 +59,8 @@ GEM oauth2 (~> 1.0) asciidoctor (1.5.3) ast (2.2.0) - attr_encrypted (1.3.4) - encryptor (>= 1.3.0) + attr_encrypted (3.0.1) + encryptor (~> 3.0.0) attr_required (1.0.0) autoprefixer-rails (6.2.3) execjs @@ -74,7 +71,8 @@ GEM ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) babosa (1.0.2) - bcrypt (3.1.10) + base32 (0.3.2) + bcrypt (3.1.11) benchmark-ips (2.3.0) better_errors (1.0.1) coderay (>= 1.0.0) @@ -103,7 +101,6 @@ GEM bundler (~> 1.2) thor (~> 0.18) byebug (8.2.1) - cal-heatmap-rails (3.6.0) capybara (2.6.2) addressable mime-types (>= 1.16) @@ -157,21 +154,18 @@ GEM activerecord (>= 3.2.0, < 5.0) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - devise (3.5.4) + devise (4.1.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 3.2.6, < 5) + railties (>= 4.1.0, < 5.1) responders - thread_safe (~> 0.1) warden (~> 1.2.3) - devise-async (0.9.0) - devise (~> 3.2) - devise-two-factor (2.0.1) + devise-two-factor (3.0.0) activesupport - attr_encrypted (~> 1.3.2) - devise (~> 3.5.0) + attr_encrypted (>= 1.3, < 4, != 2) + devise (~> 4.0) railties - rotp (~> 2) + rotp (~> 2.0) diff-lcs (1.2.5) diffy (3.0.7) docile (1.1.5) @@ -183,12 +177,12 @@ GEM email_spec (1.6.0) launchy (~> 2.1) mail (~> 2.2) - encryptor (1.3.0) + encryptor (3.0.0) equalizer (0.0.11) erubis (2.7.0) escape_utils (1.1.1) eventmachine (1.0.8) - excon (0.45.4) + excon (0.49.0) execjs (2.6.0) expression_parser (0.9.0) factory_girl (4.5.0) @@ -205,8 +199,6 @@ GEM multi_json ffaker (2.0.0) ffi (1.9.10) - fission (0.5.0) - CFPropertyList (~> 2.2) flay (2.6.1) ruby_parser (~> 3.0) sexp_processor (~> 4.0) @@ -216,109 +208,28 @@ GEM flowdock (0.7.1) httparty (~> 0.7) multi_json - fog (1.36.0) - fog-aliyun (>= 0.1.0) - fog-atmos - fog-aws (>= 0.6.0) - fog-brightbox (~> 0.4) - fog-core (~> 1.32) - fog-dynect (~> 0.0.2) - fog-ecloud (~> 0.1) - fog-google (<= 0.1.0) - fog-json - fog-local - fog-powerdns (>= 0.1.1) - fog-profitbricks - fog-radosgw (>= 0.0.2) - fog-riakcs - fog-sakuracloud (>= 0.0.4) - fog-serverlove - fog-softlayer - fog-storm_on_demand - fog-terremark - fog-vmfusion - fog-voxel - fog-xenserver - fog-xml (~> 0.1.1) - ipaddress (~> 0.5) - nokogiri (~> 1.5, >= 1.5.11) - fog-aliyun (0.1.0) - fog-core (~> 1.27) - fog-json (~> 1.0) - ipaddress (~> 0.8) - xml-simple (~> 1.1) - fog-atmos (0.1.0) - fog-core - fog-xml - fog-aws (0.8.1) + fog-aws (0.9.2) fog-core (~> 1.27) fog-json (~> 1.0) fog-xml (~> 0.1) ipaddress (~> 0.8) - fog-brightbox (0.10.1) - fog-core (~> 1.22) - fog-json - inflecto (~> 0.0.2) - fog-core (1.35.0) + fog-core (1.40.0) builder - excon (~> 0.45) + excon (~> 0.49) formatador (~> 0.2) - fog-dynect (0.0.2) - fog-core - fog-json - fog-xml - fog-ecloud (0.3.0) - fog-core - fog-xml - fog-google (0.1.0) + fog-google (0.3.2) fog-core fog-json fog-xml fog-json (1.0.2) fog-core (~> 1.0) multi_json (~> 1.10) - fog-local (0.2.1) - fog-core (~> 1.27) - fog-powerdns (0.1.1) + fog-local (0.3.0) fog-core (~> 1.27) - fog-json (~> 1.0) - fog-xml (~> 0.1) - fog-profitbricks (0.0.5) - fog-core - fog-xml - nokogiri - fog-radosgw (0.0.5) - fog-core (>= 1.21.0) - fog-json - fog-xml (>= 0.0.1) - fog-riakcs (0.1.0) - fog-core - fog-json - fog-xml - fog-sakuracloud (1.7.5) - fog-core - fog-json - fog-serverlove (0.1.2) - fog-core - fog-json - fog-softlayer (1.0.3) - fog-core - fog-json - fog-storm_on_demand (0.1.1) - fog-core - fog-json - fog-terremark (0.1.0) - fog-core - fog-xml - fog-vmfusion (0.1.0) - fission - fog-core - fog-voxel (0.1.0) - fog-core - fog-xml - fog-xenserver (0.2.2) - fog-core - fog-xml + fog-openstack (0.1.6) + fog-core (>= 1.39) + fog-json (>= 1.0) + ipaddress (>= 0.8) fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) @@ -405,6 +316,8 @@ GEM html2haml (>= 1.0.1) railties (>= 4.0.1) hashie (3.4.3) + health_check (1.5.1) + rails (>= 2.3.0) highline (1.7.8) hipchat (1.5.2) httparty @@ -425,18 +338,15 @@ GEM httpclient (2.7.0.1) i18n (0.7.0) ice_nine (0.11.1) - inflecto (0.0.2) influxdb (0.2.3) cause json - ipaddress (0.8.2) + ipaddress (0.8.3) jquery-atwho-rails (1.3.2) jquery-rails (4.1.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jquery-scrollto-rails (1.4.3) - railties (> 3.1, < 5.0) jquery-turbolinks (2.1.0) railties (>= 3.1.0) turbolinks @@ -444,7 +354,7 @@ GEM railties (>= 3.2.16) json (1.8.3) jwt (1.5.2) - kaminari (0.16.3) + kaminari (0.17.0) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.10.0) @@ -552,7 +462,7 @@ GEM orm_adapter (0.5.0) paranoia (2.1.4) activerecord (~> 4.0) - parser (2.3.0.6) + parser (2.3.1.0) ast (~> 2.2) pg (0.18.4) poltergeist (1.9.0) @@ -658,7 +568,7 @@ GEM responders (2.1.1) railties (>= 4.2.0, < 5.1) rinku (1.7.3) - rotp (2.1.1) + rotp (2.1.2) rouge (1.10.1) rqrcode (0.7.0) chunky_png @@ -687,15 +597,17 @@ GEM rspec-retry (0.4.5) rspec-core rspec-support (3.4.1) - rubocop (0.38.0) - parser (>= 2.3.0.6, < 3.0) + rubocop (0.40.0) + parser (>= 2.3.1.0, < 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.5.0) + rubocop (>= 0.40.0) ruby-fogbugz (0.2.1) crack (~> 0.4) - ruby-progressbar (1.7.5) + ruby-progressbar (1.8.1) ruby-saml (1.1.2) nokogiri (>= 1.5.10) uuid (~> 2.3) @@ -789,11 +701,11 @@ GEM activesupport (>= 4.0) sprockets (>= 3.0.0) state_machines (0.4.0) - state_machines-activemodel (0.3.0) - activemodel (~> 4.1) + state_machines-activemodel (0.4.0) + activemodel (>= 4.1, < 5.1) state_machines (>= 0.4.0) - state_machines-activerecord (0.3.0) - activerecord (~> 4.1) + state_machines-activerecord (0.4.0) + activerecord (>= 4.1, < 5.1) state_machines-activemodel (>= 0.3.0) stringex (2.5.2) systemu (2.6.5) @@ -842,7 +754,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) - unicode-display_width (1.0.2) + unicode-display_width (1.0.5) unicorn (4.9.0) kgio (~> 2.6) rack @@ -859,7 +771,7 @@ GEM coercible (~> 1.0) descendants_tracker (~> 0.0, >= 0.0.3) equalizer (~> 0.0, >= 0.0.9) - warden (1.2.4) + warden (1.2.6) rack (>= 1.0) web-console (2.3.0) activemodel (>= 4.0) @@ -876,7 +788,6 @@ GEM builder expression_parser rinku - xml-simple (1.1.5) xpath (2.0.0) nokogiri (~> 1.3) @@ -885,20 +796,19 @@ PLATFORMS DEPENDENCIES RedCloth (~> 4.2.9) - ace-rails-ap (~> 2.0.1) - activerecord-deprecated_finders (~> 1.0.3) - activerecord-session_store (~> 0.1.0) + ace-rails-ap (~> 4.0.2) + activerecord-session_store (~> 1.0.0) acts-as-taggable-on (~> 3.4) addressable (~> 2.3.8) after_commit_queue akismet (~> 2.0) allocations (~> 1.0) - annotate (~> 2.7.0) asana (~> 0.4.0) asciidoctor (~> 1.5.2) - attr_encrypted (~> 1.3.4) + attr_encrypted (~> 3.0.0) awesome_print (~> 1.2.0) babosa (~> 1.0.2) + base32 (~> 0.3.0) benchmark-ips better_errors (~> 1.0.1) binding_of_caller (~> 0.7.2) @@ -908,7 +818,6 @@ DEPENDENCIES bullet bundler-audit byebug - cal-heatmap-rails (~> 3.6.0) capybara (~> 2.6.2) capybara-screenshot (~> 1.0.0) carrierwave (~> 0.10.0) @@ -921,9 +830,8 @@ DEPENDENCIES d3_rails (~> 3.5.0) database_cleaner (~> 1.4.0) default_value_for (~> 3.0.0) - devise (~> 3.5.4) - devise-async (~> 0.9.0) - devise-two-factor (~> 2.0.0) + devise (~> 4.0) + devise-two-factor (~> 3.0.0) diffy (~> 3.0.3) doorkeeper (~> 3.1) dropzonejs-rails (~> 0.7.1) @@ -933,7 +841,11 @@ DEPENDENCIES ffaker (~> 2.0.0) flay flog - fog (~> 1.36.0) + fog-aws (~> 0.9) + fog-core (~> 1.40) + fog-google (~> 0.3) + fog-local (~> 0.3) + fog-openstack (~> 0.1) font-awesome-rails (~> 4.2) foreman fuubar (~> 2.0.0) @@ -951,16 +863,17 @@ DEPENDENCIES grape (~> 0.13.0) grape-entity (~> 0.4.2) haml-rails (~> 0.9.0) + health_check (~> 1.5.1) hipchat (~> 1.5.0) html-pipeline (~> 1.11.0) httparty (~> 0.13.3) influxdb (~> 0.2) jquery-atwho-rails (~> 1.3.2) jquery-rails (~> 4.1.0) - jquery-scrollto-rails (~> 1.4.3) jquery-turbolinks (~> 2.1.0) jquery-ui-rails (~> 5.0.0) - kaminari (~> 0.16.3) + jwt + kaminari (~> 0.17.0) letter_opener_web (~> 1.3.0) licensee (~> 8.0.0) loofah (~> 2.0.3) @@ -1016,7 +929,8 @@ DEPENDENCIES rqrcode-rails3 (~> 0.1.7) rspec-rails (~> 3.4.0) rspec-retry - rubocop (~> 0.38.0) + rubocop (~> 0.40.0) + rubocop-rspec (~> 1.5.0) ruby-fogbugz (~> 0.2.1) sanitize (~> 2.0) sass-rails (~> 5.0.0) @@ -1041,7 +955,7 @@ DEPENDENCIES spring-commands-spinach (~> 1.1.0) spring-commands-teaspoon (~> 0.0.2) sprockets (~> 3.6.0) - state_machines-activerecord (~> 0.3.0) + state_machines-activerecord (~> 0.4.0) task_list (~> 1.0.2) teaspoon (~> 1.1.0) teaspoon-jasmine (~> 2.2.0) @@ -1061,4 +975,4 @@ DEPENDENCIES wikicloth (= 0.8.1) BUNDLED WITH - 1.12.1 + 1.12.4 diff --git a/README.md b/README.md index 5e41665a6ba8f6..fee93d5f9c304c 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # GitLab [![build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master) -[![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq) [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq) -[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.svg?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) ## Canonical source @@ -35,11 +33,11 @@ There are two editions of GitLab: On [about.gitlab.com](https://about.gitlab.com/) you can find more information about: -- [Subscriptions](https://about.gitlab.com/subscription/) +- [Subscriptions](https://about.gitlab.com/pricing/) - [Consultancy](https://about.gitlab.com/consultancy/) - [Community](https://about.gitlab.com/community/) - [Hosted GitLab.com](https://about.gitlab.com/gitlab-com/) use GitLab as a free service -- [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee/) with additional features aimed at larger organizations. +- [GitLab Enterprise Edition](https://about.gitlab.com/features/#enterprise) with additional features aimed at larger organizations. - [GitLab CI](https://about.gitlab.com/gitlab-ci/) a continuous integration (CI) server that is easy to integrate with GitLab. ## Requirements diff --git a/VERSION b/VERSION index d5a967c3933268..6c07f65628533d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.8.0-pre +8.9.0-pre diff --git a/app/assets/images/ci/arch.jpg b/app/assets/images/ci/arch.jpg deleted file mode 100644 index 0e05674e840c6946d5a40f340790289af2dc25f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25222 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 N%zVfG-~9UjHv!tiqgwy~ diff --git a/app/assets/images/ci/favicon.ico b/app/assets/images/ci/favicon.ico deleted file mode 100644 index 9663d4d00b9ceee236ba324738d5d4a253a81ed8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5430 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 A!~g&Q diff --git a/app/assets/images/ci/rails.png b/app/assets/images/ci/rails.png deleted file mode 100644 index d5edc04e65f555e3ba4dcdaad39dc352e75b575e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6646 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 diff --git a/app/assets/images/ci/service_sample.png b/app/assets/images/ci/service_sample.png deleted file mode 100644 index 65d29e3fd891b7b8deba8670cb7d74b03056e3d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76024 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�T< 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 OFnGH9xvXvMo61A}zEr;B4q#hkZyt4l(z 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 literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index dd1bbb37551e80..3f61ea1eaf4320 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -1,14 +1,15 @@ @Api = - groups_path: "/api/:version/groups.json" - group_path: "/api/:version/groups/:id.json" - namespaces_path: "/api/:version/namespaces.json" - group_projects_path: "/api/:version/groups/:id/projects.json" - projects_path: "/api/:version/projects.json" - labels_path: "/api/:version/projects/:id/labels" - license_path: "/api/:version/licenses/:key" + groupsPath: "/api/:version/groups.json" + groupPath: "/api/:version/groups/:id.json" + namespacesPath: "/api/:version/namespaces.json" + groupProjectsPath: "/api/:version/groups/:id/projects.json" + projectsPath: "/api/:version/projects.json" + labelsPath: "/api/:version/projects/:id/labels" + licensePath: "/api/:version/licenses/:key" + gitignorePath: "/api/:version/gitignores/:key" group: (group_id, callback) -> - url = Api.buildUrl(Api.group_path) + url = Api.buildUrl(Api.groupPath) url = url.replace(':id', group_id) $.ajax( @@ -22,7 +23,7 @@ # Return groups list. Filtered by query # Only active groups retrieved groups: (query, skip_ldap, callback) -> - url = Api.buildUrl(Api.groups_path) + url = Api.buildUrl(Api.groupsPath) $.ajax( url: url @@ -36,7 +37,7 @@ # Return namespaces list. Filtered by query namespaces: (query, callback) -> - url = Api.buildUrl(Api.namespaces_path) + url = Api.buildUrl(Api.namespacesPath) $.ajax( url: url @@ -50,7 +51,7 @@ # Return projects list. Filtered by query projects: (query, order, callback) -> - url = Api.buildUrl(Api.projects_path) + url = Api.buildUrl(Api.projectsPath) $.ajax( url: url @@ -64,7 +65,7 @@ callback(projects) newLabel: (project_id, data, callback) -> - url = Api.buildUrl(Api.labels_path) + url = Api.buildUrl(Api.labelsPath) url = url.replace(':id', project_id) data.private_token = gon.api_token @@ -80,7 +81,7 @@ # Return group projects list. Filtered by query groupProjects: (group_id, query, callback) -> - url = Api.buildUrl(Api.group_projects_path) + url = Api.buildUrl(Api.groupProjectsPath) url = url.replace(':id', group_id) $.ajax( @@ -95,7 +96,7 @@ # Return text for a specific license licenseText: (key, data, callback) -> - url = Api.buildUrl(Api.license_path).replace(':key', key) + url = Api.buildUrl(Api.licensePath).replace(':key', key) $.ajax( url: url @@ -103,6 +104,12 @@ ).done (license) -> callback(license) + gitignoreText: (key, callback) -> + url = Api.buildUrl(Api.gitignorePath).replace(':key', key) + + $.get url, (gitignore) -> + callback(gitignore) + buildUrl: (url) -> url = gon.relative_url_root + url if gon.relative_url_root? return url.replace(':version', gon.api_version) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 5bac8eef1cb61e..18c1aa0d4e282c 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -18,8 +18,6 @@ #= require jquery.atwho #= require jquery.scrollTo #= require jquery.turbolinks -#= require d3 -#= require cal-heatmap #= require turbolinks #= require autosave #= require bootstrap/affix @@ -52,7 +50,13 @@ #= require shortcuts_network #= require jquery.nicescroll #= require date.format -#= require_tree . +#= require_directory ./behaviors +#= require_directory ./blob +#= require_directory ./ci +#= require_directory ./commit +#= require_directory ./extensions +#= require_directory ./lib +#= require_directory . #= require fuzzaldrin-plus #= require cropper @@ -204,6 +208,7 @@ $ -> $('.header-content .title').toggle() $('.header-content .navbar-collapse').toggle() $('.navbar-toggle').toggleClass('active') + $('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left") # Show/hide comments on diff $("body").on "click", ".js-toggle-diff-comments", (e) -> @@ -245,38 +250,6 @@ $ -> if $navIcon.hasClass('fa-angle-left') $navIconToggle.trigger('click') - $(document) - .off 'click', '.js-sidebar-toggle' - .on 'click', '.js-sidebar-toggle', (e, triggered) -> - e.preventDefault() - $this = $(this) - $thisIcon = $this.find 'i' - $allGutterToggleIcons = $('.js-sidebar-toggle i') - if $thisIcon.hasClass('fa-angle-double-right') - $allGutterToggleIcons - .removeClass('fa-angle-double-right') - .addClass('fa-angle-double-left') - $('aside.right-sidebar') - .removeClass('right-sidebar-expanded') - .addClass('right-sidebar-collapsed') - $('.page-with-sidebar') - .removeClass('right-sidebar-expanded') - .addClass('right-sidebar-collapsed') - else - $allGutterToggleIcons - .removeClass('fa-angle-double-left') - .addClass('fa-angle-double-right') - $('aside.right-sidebar') - .removeClass('right-sidebar-collapsed') - .addClass('right-sidebar-expanded') - $('.page-with-sidebar') - .removeClass('right-sidebar-collapsed') - .addClass('right-sidebar-expanded') - if not triggered - $.cookie("collapsed_gutter", - $('.right-sidebar') - .hasClass('right-sidebar-collapsed'), { path: '/' }) - fitSidebarForSize = -> oldBootstrapBreakpoint = bootstrapBreakpoint bootstrapBreakpoint = bp.getBreakpointSize() diff --git a/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee b/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee new file mode 100644 index 00000000000000..cc8a497d081537 --- /dev/null +++ b/app/assets/javascripts/blob/blob_gitignore_selector.js.coffee @@ -0,0 +1,58 @@ +class @BlobGitignoreSelector + constructor: (opts) -> + { + @dropdown + @editor + @$wrapper = @dropdown.closest('.gitignore-selector') + @$filenameInput = $('#file_name') + @data = @dropdown.data('filenames') + } = opts + + @dropdown.glDropdown( + data: @data, + filterable: true, + selectable: true, + search: + fields: ['name'] + clicked: @onClick + text: (gitignore) -> + gitignore.name + ) + + @toggleGitignoreSelector() + @bindEvents() + + bindEvents: -> + @$filenameInput + .on 'keyup blur', (e) => + @toggleGitignoreSelector() + + toggleGitignoreSelector: -> + filename = @$filenameInput.val() or $('.editor-file-name').text().trim() + @$wrapper.toggleClass 'hidden', filename isnt '.gitignore' + + onClick: (item, el, e) => + e.preventDefault() + @requestIgnoreFile(item.name) + + requestIgnoreFile: (name) -> + Api.gitignoreText name, @requestIgnoreFileSuccess.bind(@) + + requestIgnoreFileSuccess: (gitignore) -> + @editor.setValue(gitignore.content, 1) + @editor.focus() + +class @BlobGitignoreSelectors + constructor: (opts) -> + { + @$dropdowns = $('.js-gitignore-selector') + @editor + } = opts + + @$dropdowns.each (i, dropdown) => + $dropdown = $(dropdown) + + new BlobGitignoreSelector( + dropdown: $dropdown, + editor: @editor + ) diff --git a/app/assets/javascripts/blob/edit_blob.js.coffee b/app/assets/javascripts/blob/edit_blob.js.coffee index eea9aa972ee337..79141e768b8464 100644 --- a/app/assets/javascripts/blob/edit_blob.js.coffee +++ b/app/assets/javascripts/blob/edit_blob.js.coffee @@ -13,6 +13,7 @@ class @EditBlob @initModePanesAndLinks() new BlobLicenseSelector(@editor) + new BlobGitignoreSelectors(editor: @editor) initModePanesAndLinks: -> @$editModePanes = $(".js-edit-mode-pane") diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee deleted file mode 100644 index d80e0e716cec7e..00000000000000 --- a/app/assets/javascripts/calendar.js.coffee +++ /dev/null @@ -1,34 +0,0 @@ -class @Calendar - constructor: (timestamps, starting_year, starting_month, calendar_activities_path) -> - cal = new CalHeatMap() - cal.init - itemName: ["contribution"] - data: timestamps - start: new Date(starting_year, starting_month) - domainLabelFormat: "%b" - id: "cal-heatmap" - domain: "month" - subDomain: "day" - range: 12 - tooltip: true - label: - position: "top" - legend: [ - 0 - 10 - 20 - 30 - ] - legendCellPadding: 3 - cellSize: $('.user-calendar').width() / 73 - onClick: (date, count) -> - formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() - $.ajax - url: calendar_activities_path - data: - date: formated_date - cache: false - dataType: "html" - success: (data) -> - $(".user-calendar-activities").html data - diff --git a/app/assets/javascripts/ci/application.js.coffee b/app/assets/javascripts/ci/application.js.coffee index 05aa0f366bb11c..ca24c1d759f879 100644 --- a/app/assets/javascripts/ci/application.js.coffee +++ b/app/assets/javascripts/ci/application.js.coffee @@ -1,34 +1,6 @@ -# This is a manifest file that'll be compiled into application.js, which will include all the files -# listed below. -# -# Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -# or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. -# -# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -# the compiled file. -# -# WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD -# GO AFTER THE REQUIRES BELOW. -# #= require pager #= require jquery_nested_form #= require_tree . -# -$(document).on 'click', '.edit-runner-link', (event) -> - event.preventDefault() - - descr = $(this).closest('.runner-description').first() - descr.addClass('hide') - form = descr.next('.runner-description-form') - descrInput = form.find('input.description') - originalValue = descrInput.val() - form.removeClass('hide') - form.find('.cancel').on 'click', (event) -> - event.preventDefault() - - form.addClass('hide') - descrInput.val(originalValue) - descr.removeClass('hide') $(document).on 'click', '.assign-all-runner', -> $(this).replaceWith(' Assign in progress..') diff --git a/app/assets/javascripts/ci/build.coffee b/app/assets/javascripts/ci/build.coffee index 7afe8bf79e2614..98d05e41273697 100644 --- a/app/assets/javascripts/ci/build.coffee +++ b/app/assets/javascripts/ci/build.coffee @@ -1,9 +1,12 @@ class CiBuild @interval: null + @state: null - constructor: (build_url, build_status) -> + constructor: (build_url, build_status, build_state) -> clearInterval(CiBuild.interval) + @state = build_state + @initScrollButtonAffix() if build_status == "running" || build_status == "pending" @@ -25,15 +28,22 @@ class CiBuild # CiBuild.interval = setInterval => if window.location.href.split("#").first() is build_url + last_state = @state $.ajax - url: build_url + url: build_url + "/trace.json?state=" + encodeURIComponent(@state) dataType: "json" - success: (build) => - if build.status == "running" - $('#build-trace code').html build.trace_html - $('#build-trace code').append '' + success: (log) => + return unless last_state is @state + + if log.state and log.status is "running" + @state = log.state + if log.append + $('.fa-refresh').before log.html + else + $('#build-trace code').html log.html + $('#build-trace code').append '' @checkAutoscroll() - else if build.status != build_status + else if log.status isnt build_status Turbolinks.visit build_url , 4000 diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index f91aa3c5ad7c85..a3185f876408aa 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -16,7 +16,6 @@ class Dispatcher shortcut_handler = null switch page when 'projects:issues:index' - Issues.init() Issuable.init() shortcut_handler = new ShortcutsNavigation() when 'projects:issues:show' @@ -119,7 +118,7 @@ class Dispatcher new UsersSelect() when 'projects' new NamespaceSelect() - when 'dashboard' + when 'dashboard', 'root' shortcut_handler = new ShortcutsDashboardNavigation() when 'profiles' new Profile() diff --git a/app/assets/javascripts/due_date_select.js.coffee b/app/assets/javascripts/due_date_select.js.coffee index a4304786cbb6de..3cc70185178b07 100644 --- a/app/assets/javascripts/due_date_select.js.coffee +++ b/app/assets/javascripts/due_date_select.js.coffee @@ -11,6 +11,7 @@ class @DueDateSelect $block = $dropdown.closest('.block') $selectbox = $dropdown.closest('.selectbox') $value = $block.find('.value') + $valueContent = $block.find('.value-content') $sidebarValue = $('.js-due-date-sidebar-value', $block) fieldName = $dropdown.data('field-name') @@ -23,11 +24,15 @@ class @DueDateSelect $value.removeAttr('style') ) - addDueDate = -> + addDueDate = (isDropdown) -> # Create the post date value = $("input[name='#{fieldName}']").val() - date = new Date value.replace(new RegExp('-', 'g'), ',') - mediumDate = $.datepicker.formatDate 'M d, yy', date + + if value isnt '' + date = new Date value.replace(new RegExp('-', 'g'), ',') + mediumDate = $.datepicker.formatDate 'M d, yy', date + else + mediumDate = 'None' data = {} data[abilityName] = {} @@ -39,23 +44,35 @@ class @DueDateSelect data: data beforeSend: -> $loading.fadeIn() - $dropdown.trigger('loading.gl.dropdown') - $selectbox.hide() + if isDropdown + $dropdown.trigger('loading.gl.dropdown') + $selectbox.hide() $value.removeAttr('style') - $value.html(mediumDate) + $valueContent.html(mediumDate) $sidebarValue.html(mediumDate) + + if value isnt '' + $('.js-remove-due-date-holder').removeClass 'hidden' + else + $('.js-remove-due-date-holder').addClass 'hidden' ).done (data) -> - $dropdown.trigger('loaded.gl.dropdown') - $dropdown.dropdown('toggle') + if isDropdown + $dropdown.trigger('loaded.gl.dropdown') + $dropdown.dropdown('toggle') $loading.fadeOut() + $block.on 'click', '.js-remove-due-date', (e) -> + e.preventDefault() + $("input[name='#{fieldName}']").val '' + addDueDate(false) + $datePicker.datepicker( dateFormat: 'yy-mm-dd', defaultDate: $("input[name='#{fieldName}']").val() altField: "input[name='#{fieldName}']" onSelect: -> - addDueDate() + addDueDate(true) ) $(document) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 61e3f811e73039..41dba342107fb3 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -18,6 +18,10 @@ GitLab.GfmAutoComplete = Issues: template: '

  • ${id} ${title}
  • ' + # Milestones + Milestones: + template: '
  • ${title}
  • ' + # Add GFM auto-completion to all input fields, that accept GFM input. setup: (wrap) -> @input = $('.js-gfm-input') @@ -81,6 +85,19 @@ GitLab.GfmAutoComplete = title: sanitize(i.title) search: "#{i.iid} #{i.title}" + @input.atwho + at: '%' + alias: 'milestones' + searchKey: 'search' + displayTpl: @Milestones.template + insertTpl: '${atwho-at}"${title}"' + callbacks: + beforeSave: (milestones) -> + $.map milestones, (m) -> + id: m.iid + title: sanitize(m.title) + search: "#{m.title}" + @input.atwho at: '!' alias: 'mergerequests' @@ -105,6 +122,8 @@ GitLab.GfmAutoComplete = @input.atwho 'load', '@', data.members # load issues @input.atwho 'load', 'issues', data.issues + # load milestones + @input.atwho 'load', 'milestones', data.milestones # load merge requests @input.atwho 'load', 'mergerequests', data.mergerequests # load emojis diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 1d1bfeb2e7746f..b3f1dc969b8db6 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -60,9 +60,36 @@ class GitLabDropdownFilter results = data if search_text isnt '' - results = fuzzaldrinPlus.filter(data, search_text, - key: @options.keys - ) + # When data is an array of objects therefore [object Array] e.g. + # [ + # { prop: 'foo' }, + # { prop: 'baz' } + # ] + if _.isArray(data) + results = fuzzaldrinPlus.filter(data, search_text, + key: @options.keys + ) + else + # If data is grouped therefore an [object Object]. e.g. + # { + # groupName1: [ + # { prop: 'foo' }, + # { prop: 'baz' } + # ], + # groupName2: [ + # { prop: 'abc' }, + # { prop: 'def' } + # ] + # } + if gl.utils.isObject data + results = {} + for key, group of data + tmp = fuzzaldrinPlus.filter(group, search_text, + key: @options.keys + ) + + if tmp.length + results[key] = tmp.map (item) -> item @options.callback results else @@ -141,8 +168,9 @@ class GitLabDropdown searchFields = if @options.search then @options.search.fields else []; if @options.data - # If data is an array - if _.isArray @options.data + # If we provided data + # data could be an array of objects or a group of arrays + if _.isObject(@options.data) and not _.isFunction(@options.data) @fullData = @options.data @parseData @options.data else @@ -230,19 +258,33 @@ class GitLabDropdown parseData: (data) -> @renderedData = data - # Render each row - html = $.map data, (obj) => - return @renderItem(obj) - if @options.filterable and data.length is 0 # render no matching results html = [@noResults()] + else + # Handle array groups + if gl.utils.isObject data + html = [] + for name, groupData of data + # Add header for each group + html.push(@renderItem(header: name, name)) + + @renderData(groupData, name) + .map (item) -> + html.push item + else + # Render each row + html = @renderData(data) # Render the full menu full_html = @renderMenu(html.join("")) @appendMenu(full_html) + renderData: (data, group = false) -> + data.map (obj, index) => + return @renderItem(obj, group, index) + shouldPropagate: (e) => if @options.multiSelect $target = $(e.target) @@ -299,11 +341,10 @@ class GitLabDropdown selector = '.dropdown-content' if @dropdown.find(".dropdown-toggle-page").length selector = ".dropdown-page-one .dropdown-content" - $(selector, @dropdown).html html # Render the row - renderItem: (data) -> + renderItem: (data, group = false, index = false) -> html = "" # Divider @@ -346,8 +387,13 @@ class GitLabDropdown if @highlight text = @highlightTextMatches(text, @filterInput.val()) + if group + groupAttrs = "data-group='#{group}' data-index='#{index}'" + else + groupAttrs = '' + html = "
  • - + #{text}
  • " @@ -377,9 +423,15 @@ class GitLabDropdown rowClicked: (el) -> fieldName = @options.fieldName - selectedIndex = el.parent().index() if @renderedData - selectedObject = @renderedData[selectedIndex] + groupName = el.data('group') + if groupName + selectedIndex = el.data('index') + selectedObject = @renderedData[groupName][selectedIndex] + else + selectedIndex = el.closest('li').index() + selectedObject = @renderedData[selectedIndex] + value = if @options.id then @options.id(selectedObject, el) else selectedObject.id field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") if el.hasClass(ACTIVE_CLASS) @@ -460,7 +512,7 @@ class GitLabDropdown return false if currentKeyCode is 13 - @selectRowAtIndex currentIndex + @selectRowAtIndex if currentIndex < 0 then 0 else currentIndex removeArrayKeyEvent: -> $('body').off 'keydown' diff --git a/app/assets/javascripts/graphs/application.js.coffee b/app/assets/javascripts/graphs/application.js.coffee new file mode 100644 index 00000000000000..e0f681acf0b533 --- /dev/null +++ b/app/assets/javascripts/graphs/application.js.coffee @@ -0,0 +1,7 @@ +# This is a manifest file that'll be compiled into including all the files listed below. +# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically +# be included in the compiled file accessible from http://example.com/assets/application.js +# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +# the compiled file. +# +#= require_tree . diff --git a/app/assets/javascripts/stat_graph.js.coffee b/app/assets/javascripts/graphs/stat_graph.js.coffee similarity index 100% rename from app/assets/javascripts/stat_graph.js.coffee rename to app/assets/javascripts/graphs/stat_graph.js.coffee diff --git a/app/assets/javascripts/stat_graph_contributors.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors.js.coffee similarity index 98% rename from app/assets/javascripts/stat_graph_contributors.js.coffee rename to app/assets/javascripts/graphs/stat_graph_contributors.js.coffee index 3be14cb43dd504..1d9fae7cf79d81 100644 --- a/app/assets/javascripts/stat_graph_contributors.js.coffee +++ b/app/assets/javascripts/graphs/stat_graph_contributors.js.coffee @@ -1,5 +1,4 @@ #= require d3 -#= require stat_graph_contributors_util class @ContributorsStatGraph init: (log) -> diff --git a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee similarity index 99% rename from app/assets/javascripts/stat_graph_contributors_graph.js.coffee rename to app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee index b7a0e073766ac0..584d281a510e06 100644 --- a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee +++ b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee @@ -1,6 +1,4 @@ #= require d3 -#= require jquery -#= require underscore class @ContributorsGraph MARGIN: diff --git a/app/assets/javascripts/stat_graph_contributors_util.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors_util.js.coffee similarity index 100% rename from app/assets/javascripts/stat_graph_contributors_util.js.coffee rename to app/assets/javascripts/graphs/stat_graph_contributors_util.js.coffee diff --git a/app/assets/javascripts/issuable.js.coffee b/app/assets/javascripts/issuable.js.coffee index afffed63ac57ec..6504e48110281f 100644 --- a/app/assets/javascripts/issuable.js.coffee +++ b/app/assets/javascripts/issuable.js.coffee @@ -1,7 +1,11 @@ +issuable_created = false @Issuable = init: -> - Issuable.initTemplates() - Issuable.initSearch() + unless issuable_created + issuable_created = true + Issuable.initTemplates() + Issuable.initSearch() + Issuable.initChecks() initTemplates: -> Issuable.labelRow = _.template( @@ -19,7 +23,16 @@ .on 'keyup', -> clearTimeout(@timer) @timer = setTimeout( -> - Issuable.filterResults $('#issue_search_form') + $search = $('#issue_search') + $form = $('.js-filter-form') + $input = $("input[name='#{$search.attr('name')}']", $form) + + if $input.length is 0 + $form.append "" + else + $input.val $search.val() + + Issuable.filterResults $form , 500) toggleLabelFilters: -> @@ -59,15 +72,22 @@ dataType: "json" reload: -> - if Issues.created - Issues.initChecks() + if Issuable.created + Issuable.initChecks() $('#filter_issue_search').val($('#issue_search').val()) + initChecks: -> + $('.check_all_issues').on 'click', -> + $('.selected_issue').prop('checked', @checked) + Issuable.checkChanged() + + $('.selected_issue').on 'change', Issuable.checkChanged + updateStateFilters: -> - stateFilters = $('.issues-state-filters') + stateFilters = $('.issues-state-filters, .dropdown-menu-sort') newParams = {} - paramKeys = ['author_id', 'milestone_title', 'assignee_id', 'issue_search'] + paramKeys = ['author_id', 'milestone_title', 'assignee_id', 'issue_search', 'issue_search'] for paramKey in paramKeys newParams[paramKey] = gl.utils.getParameterValues(paramKey)[0] or '' @@ -82,3 +102,17 @@ else newUrl = gl.utils.mergeUrlParams(newParams, initialUrl) $(this).attr 'href', newUrl + + checkChanged: -> + checked_issues = $('.selected_issue:checked') + if checked_issues.length > 0 + ids = $.map checked_issues, (value) -> + $(value).data('id') + + $('#update_issues_ids').val ids + $('.issues-other-filters').hide() + $('.issues_bulk_update').show() + else + $('#update_issues_ids').val [] + $('.issues_bulk_update').hide() + $('.issues-other-filters').show() diff --git a/app/assets/javascripts/issuable_form.js.coffee b/app/assets/javascripts/issuable_form.js.coffee index 7a788f761b7ac8..898506fde3221a 100644 --- a/app/assets/javascripts/issuable_form.js.coffee +++ b/app/assets/javascripts/issuable_form.js.coffee @@ -19,6 +19,16 @@ class @IssuableForm @form.on "click", ".btn-cancel", @resetAutosave @initWip() + @initMoveDropdown() + + $issuableDueDate = $('#issuable-due-date') + + if $issuableDueDate.length + $('.datepicker').datepicker( + dateFormat: 'yy-mm-dd', + onSelect: (dateText, inst) -> + $issuableDueDate.val dateText + ).datepicker 'setDate', $.datepicker.parseDate('yy-mm-dd', $issuableDueDate.val()) initAutosave: -> new Autosave @titleField, [ @@ -80,3 +90,19 @@ class @IssuableForm addWip: -> @titleField.val "WIP: #{@titleField.val()}" + + initMoveDropdown: -> + $moveDropdown = $('.js-move-dropdown') + + if $moveDropdown.length + $('.js-move-dropdown').select2 + ajax: + url: $moveDropdown.data('projects-url') + results: (data) -> + return { + results: data + } + formatResult: (project) -> + project.name_with_namespace + formatSelection: (project) -> + project.name_with_namespace diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee deleted file mode 100644 index 3330e6c68aded1..00000000000000 --- a/app/assets/javascripts/issues.js.coffee +++ /dev/null @@ -1,38 +0,0 @@ -@Issues = - init: -> - Issues.created = true - Issues.initChecks() - - $("body").on "ajax:success", ".close_issue, .reopen_issue", -> - t = $(this) - totalIssues = undefined - reopen = t.hasClass("reopen_issue") - $(".issue_counter").each -> - issue = $(this) - totalIssues = parseInt($(this).html(), 10) - if reopen and issue.closest(".main_menu").length - $(this).html totalIssues + 1 - else - $(this).html totalIssues - 1 - - initChecks: -> - $(".check_all_issues").click -> - $(".selected_issue").prop("checked", @checked) - Issues.checkChanged() - - $(".selected_issue").bind "change", Issues.checkChanged - - checkChanged: -> - checked_issues = $(".selected_issue:checked") - if checked_issues.length > 0 - ids = [] - $.each checked_issues, (index, value) -> - ids.push $(value).attr("data-id") - - $("#update_issues_ids").val ids - $(".issues-other-filters").hide() - $(".issues_bulk_update").show() - else - $("#update_issues_ids").val [] - $(".issues_bulk_update").hide() - $(".issues-other-filters").show() diff --git a/app/assets/javascripts/layout_nav.js.coffee b/app/assets/javascripts/layout_nav.js.coffee new file mode 100644 index 00000000000000..6adac6dac97ba1 --- /dev/null +++ b/app/assets/javascripts/layout_nav.js.coffee @@ -0,0 +1,14 @@ +class @LayoutNav + $ -> + $('.fade-left').addClass('end-scroll') + $('.scrolling-tabs').on 'scroll', (event) -> + $this = $(this) + $el = $(event.target) + currentPosition = $this.scrollLeft() + size = bp.getBreakpointSize() + controlBtnWidth = $('.controls').width() + maxPosition = $this.get(0).scrollWidth - $this.parent().width() + maxPosition += controlBtnWidth if size isnt 'xs' and $('.nav-control').length + + $el.find('.fade-left').toggleClass('end-scroll', currentPosition is 0) + $el.find('.fade-right').toggleClass('end-scroll', currentPosition is maxPosition) diff --git a/app/assets/javascripts/lib/type_utility.js.coffee b/app/assets/javascripts/lib/type_utility.js.coffee new file mode 100644 index 00000000000000..957f0d86b36ec7 --- /dev/null +++ b/app/assets/javascripts/lib/type_utility.js.coffee @@ -0,0 +1,9 @@ +((w) -> + + w.gl ?= {} + w.gl.utils ?= {} + + w.gl.utils.isObject = (obj) -> + obj? and (obj.constructor is Object) + +) window diff --git a/app/assets/javascripts/lib/url_utility.js.coffee b/app/assets/javascripts/lib/url_utility.js.coffee index 6a00932c028ff2..e8085e1c2e45b4 100644 --- a/app/assets/javascripts/lib/url_utility.js.coffee +++ b/app/assets/javascripts/lib/url_utility.js.coffee @@ -26,10 +26,19 @@ newUrl = decodeURIComponent(url) for paramName, paramValue of params pattern = new RegExp "\\b(#{paramName}=).*?(&|$)" - if url.search(pattern) >= 0 + if not paramValue? + newUrl = newUrl.replace pattern, '' + else if url.search(pattern) isnt -1 newUrl = newUrl.replace pattern, "$1#{paramValue}$2" else newUrl = "#{newUrl}#{(if newUrl.indexOf('?') > 0 then '&' else '?')}#{paramName}=#{paramValue}" + + # Remove a trailing ampersand + lastChar = newUrl[newUrl.length - 1] + + if lastChar is '&' + newUrl = newUrl.slice 0, -1 + newUrl # removes parameter query string from url. returns the modified url diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee index 372732d0aac27a..49a4727205a6e9 100644 --- a/app/assets/javascripts/merge_request_tabs.js.coffee +++ b/app/assets/javascripts/merge_request_tabs.js.coffee @@ -75,6 +75,9 @@ class @MergeRequestTabs @loadDiff($target.attr('href')) if bp? and bp.getBreakpointSize() isnt 'lg' @shrinkView() + + navBarHeight = $('.navbar-gitlab').outerHeight() + $.scrollTo(".merge-request-details .merge-request-tabs", offset: -navBarHeight) else if action == 'builds' @loadBuilds($target.attr('href')) @expandView() diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee index f58647988a2265..779f536d9f0745 100644 --- a/app/assets/javascripts/merge_request_widget.js.coffee +++ b/app/assets/javascripts/merge_request_widget.js.coffee @@ -10,6 +10,7 @@ class @MergeRequestWidget $('#modal_merge_info').modal(show: false) @firstCICheck = true @readyForCICheck = false + @cancel = false clearInterval @fetchBuildStatusInterval @clearEventListeners() @@ -21,10 +22,16 @@ class @MergeRequestWidget clearEventListeners: -> $(document).off 'page:change.merge_request' + cancelPolling: -> + @cancel = true + addEventListeners: -> + allowedPages = ['show', 'commits', 'builds', 'changes'] $(document).on 'page:change.merge_request', => - if $('body').data('page') isnt 'projects:merge_requests:show' + page = $('body').data('page').split(':').last() + if allowedPages.indexOf(page) < 0 clearInterval @fetchBuildStatusInterval + @cancelPolling() @clearEventListeners() mergeInProgress: (deleteSourceBranch = false)-> @@ -67,6 +74,7 @@ class @MergeRequestWidget $('.ci-widget-fetching').show() $.getJSON @opts.ci_status_url, (data) => + return if @cancel @readyForCICheck = true if data.status is '' @@ -106,6 +114,7 @@ class @MergeRequestWidget @firstCICheck = false showCIStatus: (state) -> + return if not state? $('.ci_widget').hide() allowed_states = ["failed", "canceled", "running", "pending", "success", "skipped", "not_found"] if state in allowed_states @@ -113,7 +122,7 @@ class @MergeRequestWidget switch state when "failed", "canceled", "not_found" @setMergeButtonClass('btn-danger') - when "running", "pending" + when "running" @setMergeButtonClass('btn-warning') when "success" @setMergeButtonClass('btn-create') @@ -126,6 +135,6 @@ class @MergeRequestWidget $('.ci_widget:visible .ci-coverage').text(text) setMergeButtonClass: (css_class) -> - $('.accept_merge_request') + $('.js-merge-button,.accept-action .dropdown-toggle') .removeClass('btn-danger btn-warning btn-create') .addClass(css_class) diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index efb3e8e219817a..f8151963fa7930 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -114,9 +114,9 @@ class @Notes @refresh() , @pollingInterval - refresh: -> + refresh: => return if @refreshing is true - refreshing = true + @refreshing = true if not document.hidden and document.URL.indexOf(@noteable_url) is 0 @getContent() @@ -134,8 +134,8 @@ class @Notes @renderDiscussionNote(note) else @renderNote(note) - always: => - @refreshing = false + .always () => + @refreshing = false ### Increase @pollingInterval up to 120 seconds on every function call, @@ -285,6 +285,7 @@ class @Notes form.addClass "js-main-target-form" form.find("#note_line_code").remove() + form.find("#note_type").remove() ### General note form setup. @@ -328,7 +329,7 @@ class @Notes @renderDiscussionNote(note) # cleanup after successfully creating a diff/discussion note - @removeDiscussionNoteForm($("#new-discussion-note-form-#{note.discussion_id}")) + @removeDiscussionNoteForm($(xhr.target)) ### Called in response to the edit note form being submitted @@ -472,6 +473,7 @@ class @Notes setupDiscussionNoteForm: (dataHolder, form) => # setup note target form.attr 'id', "new-discussion-note-form-#{dataHolder.data("discussionId")}" + form.find("#note_type").val dataHolder.data("noteType") form.find("#line_type").val dataHolder.data("lineType") form.find("#note_commit_id").val dataHolder.data("commitId") form.find("#note_line_code").val dataHolder.data("lineCode") diff --git a/app/assets/javascripts/right_sidebar.js.coffee b/app/assets/javascripts/right_sidebar.js.coffee index 2d084b76cfe1f4..c9cb0f4bb3285d 100644 --- a/app/assets/javascripts/right_sidebar.js.coffee +++ b/app/assets/javascripts/right_sidebar.js.coffee @@ -10,6 +10,40 @@ class @Sidebar $('.dropdown').on('loading.gl.dropdown', @sidebarDropdownLoading) $('.dropdown').on('loaded.gl.dropdown', @sidebarDropdownLoaded) + + $(document) + .off 'click', '.js-sidebar-toggle' + .on 'click', '.js-sidebar-toggle', (e, triggered) -> + e.preventDefault() + $this = $(this) + $thisIcon = $this.find 'i' + $allGutterToggleIcons = $('.js-sidebar-toggle i') + if $thisIcon.hasClass('fa-angle-double-right') + $allGutterToggleIcons + .removeClass('fa-angle-double-right') + .addClass('fa-angle-double-left') + $('aside.right-sidebar') + .removeClass('right-sidebar-expanded') + .addClass('right-sidebar-collapsed') + $('.page-with-sidebar') + .removeClass('right-sidebar-expanded') + .addClass('right-sidebar-collapsed') + else + $allGutterToggleIcons + .removeClass('fa-angle-double-left') + .addClass('fa-angle-double-right') + $('aside.right-sidebar') + .removeClass('right-sidebar-collapsed') + .addClass('right-sidebar-expanded') + $('.page-with-sidebar') + .removeClass('right-sidebar-collapsed') + .addClass('right-sidebar-expanded') + if not triggered + $.cookie("collapsed_gutter", + $('.right-sidebar') + .hasClass('right-sidebar-collapsed'), { path: '/' }) + + sidebarDropdownLoading: (e) -> $sidebarCollapsedIcon = $(@).closest('.block').find('.sidebar-collapsed-icon') img = $sidebarCollapsedIcon.find('img') @@ -76,7 +110,7 @@ class @Sidebar @triggerOpenSidebar() if not @isOpen() if action is 'hide' - @triggerOpenSidebar() is @isOpen() + @triggerOpenSidebar() if @isOpen() isOpen: -> @sidebar.is('.right-sidebar-expanded') diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee index 6a7b4ad1db7f15..2122e80f57a5ce 100644 --- a/app/assets/javascripts/search_autocomplete.js.coffee +++ b/app/assets/javascripts/search_autocomplete.js.coffee @@ -20,8 +20,7 @@ class @SearchAutocomplete @dropdown = @wrap.find('.dropdown') @dropdownContent = @dropdown.find('.dropdown-content') - @locationBadgeEl = @getElement('.search-location-badge') - @locationText = @getElement('.location-text') + @locationBadgeEl = @getElement('.location-badge') @scopeInputEl = @getElement('#scope') @searchInput = @getElement('.search-input') @projectInputEl = @getElement('#search_project_id') @@ -133,7 +132,7 @@ class @SearchAutocomplete scope: @scopeInputEl.val() # Location badge - _location: @locationText.text() + _location: @locationBadgeEl.text() } bindEvents: -> @@ -143,12 +142,14 @@ class @SearchAutocomplete @searchInput.on 'click', @onSearchInputClick @searchInput.on 'focus', @onSearchInputFocus @clearInput.on 'click', @onClearInputClick + @locationBadgeEl.on 'click', => + @searchInput.focus() onDocumentClick: (e) => # If clicking outside the search box # And search input is not focused # And we are not clicking inside a suggestion - if not $.contains(@dropdown[0], e.target) and @isFocused and not $(e.target).parents('ul').length + if not $.contains(@dropdown[0], e.target) and @isFocused and not $(e.target).closest('.search-form').length @onSearchInputBlur() enableAutocomplete: -> @@ -221,10 +222,8 @@ class @SearchAutocomplete category = if item.category? then "#{item.category}: " else '' value = if item.value? then item.value else '' - html = " - #{category}#{value} - " - @locationBadgeEl.html(html) + badgeText = "#{category}#{value}" + @locationBadgeEl.text(badgeText).show() @wrap.addClass('has-location-badge') restoreOriginalState: -> @@ -233,9 +232,8 @@ class @SearchAutocomplete for input in inputs @getElement("##{input}").val(@originalState[input]) - if @originalState._location is '' - @locationBadgeEl.empty() + @locationBadgeEl.hide() else @addLocationBadge( value: @originalState._location @@ -244,7 +242,7 @@ class @SearchAutocomplete @dropdown.removeClass 'open' badgePresent: -> - @locationBadgeEl.children().length + @locationBadgeEl.length resetSearchState: -> inputs = Object.keys @originalState @@ -257,7 +255,7 @@ class @SearchAutocomplete @getElement("##{input}").val('') removeLocationBadge: -> - @locationBadgeEl.empty() + @locationBadgeEl.hide() # Reset state @resetSearchState() diff --git a/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee b/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee index 4a05bdccdb3688..cca2b8a1fccadf 100644 --- a/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee +++ b/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee @@ -3,10 +3,10 @@ class @ShortcutsDashboardNavigation extends Shortcuts constructor: -> super() - Mousetrap.bind('g a', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-activity')) - Mousetrap.bind('g i', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-issues')) - Mousetrap.bind('g m', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-merge_requests')) - Mousetrap.bind('g p', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-projects')) + Mousetrap.bind('g a', -> ShortcutsDashboardNavigation.findAndFollowLink('.dashboard-shortcuts-activity')) + Mousetrap.bind('g i', -> ShortcutsDashboardNavigation.findAndFollowLink('.dashboard-shortcuts-issues')) + Mousetrap.bind('g m', -> ShortcutsDashboardNavigation.findAndFollowLink('.dashboard-shortcuts-merge_requests')) + Mousetrap.bind('g p', -> ShortcutsDashboardNavigation.findAndFollowLink('.dashboard-shortcuts-projects')) @findAndFollowLink: (selector) -> link = $(selector).attr('href') diff --git a/app/assets/javascripts/shortcuts_issuable.coffee b/app/assets/javascripts/shortcuts_issuable.coffee index ad9b3c1c6bfe2e..ccb42ab2168351 100644 --- a/app/assets/javascripts/shortcuts_issuable.coffee +++ b/app/assets/javascripts/shortcuts_issuable.coffee @@ -6,6 +6,10 @@ class @ShortcutsIssuable extends ShortcutsNavigation super() Mousetrap.bind('a', @openSidebarDropdown.bind(@, 'assignee')) Mousetrap.bind('m', @openSidebarDropdown.bind(@, 'milestone')) + Mousetrap.bind('r', => + @replyWithSelectedText() + return false + ) Mousetrap.bind('j', => @prevIssue() return false diff --git a/app/assets/javascripts/sidebar.js.coffee b/app/assets/javascripts/sidebar.js.coffee index 860d4f438d0117..ea4ac52da31cfc 100644 --- a/app/assets/javascripts/sidebar.js.coffee +++ b/app/assets/javascripts/sidebar.js.coffee @@ -12,7 +12,7 @@ toggleSidebar = -> niceScrollBars.updateScrollBar(); ), 300 -$(document).on("click", '.toggle-nav-collapse', (e) -> +$(document).on("click", '.toggle-nav-collapse, .side-nav-toggle', (e) -> e.preventDefault() toggleSidebar() diff --git a/app/assets/javascripts/user_tabs.js.coffee b/app/assets/javascripts/user_tabs.js.coffee index c2aeffe23819a5..70614396a4e561 100644 --- a/app/assets/javascripts/user_tabs.js.coffee +++ b/app/assets/javascripts/user_tabs.js.coffee @@ -26,6 +26,10 @@ # Personal projects # # +#
  • +# +# +#
  • # # #
    @@ -41,6 +45,9 @@ #
    # Projects content #
    +#
    +# Snippets content +#
    #
    # #
    @@ -100,7 +107,7 @@ class @UserTabs if action is 'activity' @loadActivities(source) - if action in ['groups', 'contributed', 'projects'] + if action in ['groups', 'contributed', 'projects', 'snippets'] @loadTab(source, action) loadTab: (source, action) -> diff --git a/app/assets/javascripts/users/application.js.coffee b/app/assets/javascripts/users/application.js.coffee new file mode 100644 index 00000000000000..647ffbf5f45f53 --- /dev/null +++ b/app/assets/javascripts/users/application.js.coffee @@ -0,0 +1,8 @@ +# This is a manifest file that'll be compiled into including all the files listed below. +# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically +# be included in the compiled file accessible from http://example.com/assets/application.js +# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +# the compiled file. +# +#= require d3 +#= require_tree . diff --git a/app/assets/javascripts/users/calendar.js.coffee b/app/assets/javascripts/users/calendar.js.coffee new file mode 100644 index 00000000000000..26a26061539076 --- /dev/null +++ b/app/assets/javascripts/users/calendar.js.coffee @@ -0,0 +1,198 @@ +class @Calendar + constructor: (timestamps, @calendar_activities_path) -> + @currentSelectedDate = '' + @daySpace = 1 + @daySize = 15 + @daySizeWithSpace = @daySize + (@daySpace * 2) + @monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + @months = [] + @highestValue = 0 + + # Get the highest value from the timestampes + _.each timestamps, (count) => + if count > @highestValue + @highestValue = count + + # Loop through the timestamps to create a group of objects + # The group of objects will be grouped based on the day of the week they are + @timestampsTmp = [] + i = 0 + group = 0 + _.each timestamps, (count, date) => + newDate = new Date parseInt(date) * 1000 + day = newDate.getDay() + + # Create a new group array if this is the first day of the week + # or if is first object + if (day is 0 and i isnt 0) or i is 0 + @timestampsTmp.push [] + group++ + + innerArray = @timestampsTmp[group-1] + + # Push to the inner array the values that will be used to render map + innerArray.push + count: count + date: newDate + day: day + + i++ + + # Init color functions + @color = @initColor() + @colorKey = @initColorKey() + + # Init the svg element + @renderSvg(group) + @renderDays() + @renderMonths() + @renderDayTitles() + @renderKey() + + @initTooltips() + + renderSvg: (group) -> + @svg = d3.select '.js-contrib-calendar' + .append 'svg' + .attr 'width', (group + 1) * @daySizeWithSpace + .attr 'height', 167 + .attr 'class', 'contrib-calendar' + + renderDays: -> + @svg.selectAll 'g' + .data @timestampsTmp + .enter() + .append 'g' + .attr 'transform', (group, i) => + _.each group, (stamp, a) => + if a is 0 and stamp.day is 0 + month = stamp.date.getMonth() + x = (@daySizeWithSpace * i + 1) + @daySizeWithSpace + lastMonth = _.last(@months) + if lastMonth? + lastMonthX = lastMonth.x + + if !lastMonth? + @months.push + month: month + x: x + else if month isnt lastMonth.month and x - @daySizeWithSpace isnt lastMonthX + @months.push + month: month + x: x + + "translate(#{(@daySizeWithSpace * i + 1) + @daySizeWithSpace}, 18)" + .selectAll 'rect' + .data (stamp) -> + stamp + .enter() + .append 'rect' + .attr 'x', '0' + .attr 'y', (stamp, i) => + (@daySizeWithSpace * stamp.day) + .attr 'width', @daySize + .attr 'height', @daySize + .attr 'title', (stamp) => + contribText = 'No contributions' + + if stamp.count > 0 + contribText = "#{stamp.count} contribution#{if stamp.count > 1 then 's' else ''}" + + date = dateFormat(stamp.date, 'mmm d, yyyy') + + "#{contribText}
    #{date}" + .attr 'class', 'user-contrib-cell js-tooltip' + .attr 'fill', (stamp) => + if stamp.count isnt 0 + @color(stamp.count) + else + '#ededed' + .attr 'data-container', 'body' + .on 'click', @clickDay + + renderDayTitles: -> + days = [{ + text: 'M' + y: 29 + (@daySizeWithSpace * 1) + }, { + text: 'W' + y: 29 + (@daySizeWithSpace * 3) + }, { + text: 'F' + y: 29 + (@daySizeWithSpace * 5) + }] + @svg.append 'g' + .selectAll 'text' + .data days + .enter() + .append 'text' + .attr 'text-anchor', 'middle' + .attr 'x', 8 + .attr 'y', (day) -> + day.y + .text (day) -> + day.text + .attr 'class', 'user-contrib-text' + + renderMonths: -> + @svg.append 'g' + .selectAll 'text' + .data @months + .enter() + .append 'text' + .attr 'x', (date) -> + date.x + .attr 'y', 10 + .attr 'class', 'user-contrib-text' + .text (date) => + @monthNames[date.month] + + renderKey: -> + keyColors = ['#ededed', @colorKey(0), @colorKey(1), @colorKey(2), @colorKey(3)] + @svg.append 'g' + .attr 'transform', "translate(18, #{@daySizeWithSpace * 8 + 16})" + .selectAll 'rect' + .data keyColors + .enter() + .append 'rect' + .attr 'width', @daySize + .attr 'height', @daySize + .attr 'x', (color, i) => + @daySizeWithSpace * i + .attr 'y', 0 + .attr 'fill', (color) -> + color + + initColor: -> + d3.scale + .linear() + .range(['#acd5f2', '#254e77']) + .domain([0, @highestValue]) + + initColorKey: -> + d3.scale + .linear() + .range(['#acd5f2', '#254e77']) + .domain([0, 3]) + + clickDay: (stamp) => + if @currentSelectedDate isnt stamp.date + @currentSelectedDate = stamp.date + formatted_date = @currentSelectedDate.getFullYear() + "-" + (@currentSelectedDate.getMonth()+1) + "-" + @currentSelectedDate.getDate() + + $.ajax + url: @calendar_activities_path + data: + date: formatted_date + cache: false + dataType: 'html' + beforeSend: -> + $('.user-calendar-activities').html '
    ' + success: (data) -> + $('.user-calendar-activities').html data + else + $('.user-calendar-activities').html '' + + initTooltips: -> + $('.js-contrib-calendar .js-tooltip').tooltip + html: true diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index b80b1b861ccca0..519618aa61795f 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -93,7 +93,9 @@ class @UsersSelect $dropdown.glDropdown( data: (term, callback) => - @users term, (users) => + isAuthorFilter = $('.js-author-search') + + @users term, term is '' and isAuthorFilter, (users) => if term.length is 0 showDivider = 0 @@ -138,7 +140,7 @@ class @UsersSelect toggleLabel: (selected) -> if selected && 'id' of selected - selected.name + if selected.text then selected.text else selected.name else defaultLabel @@ -219,7 +221,7 @@ class @UsersSelect multiple: $(select).hasClass('multiselect') minimumInputLength: 0 query: (query) => - @users query.term, (users) => + @users query.term, @projectId?, (users) => data = { results: users } if query.term.length == 0 @@ -302,7 +304,7 @@ class @UsersSelect # Return users list. Filtered by query # Only active users retrieved - users: (query, callback) => + users: (query, fromProject, callback) => url = @buildUrl(@usersPath) $.ajax( @@ -311,7 +313,7 @@ class @UsersSelect search: query per_page: 20 active: true - project_id: @projectId + project_id: @projectId if fromProject group_id: @groupId current_user: @showCurrentUser author_id: @authorId diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 69b3b6586de586..8b93665d085eb8 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -8,9 +8,7 @@ *= require select2 *= require_self *= require dropzone/basic - *= require cal-heatmap *= require cropper.css - *= require animate */ /* diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 560de9fc0bddb6..3cbddc59f11af5 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -5,6 +5,7 @@ @import 'framework/tw_bootstrap'; @import "framework/layout"; +@import "framework/animations.scss"; @import "framework/avatar.scss"; @import "framework/blocks.scss"; @import "framework/buttons.scss"; diff --git a/app/assets/stylesheets/framework/animations.scss b/app/assets/stylesheets/framework/animations.scss new file mode 100644 index 00000000000000..1fec61bdba1eca --- /dev/null +++ b/app/assets/stylesheets/framework/animations.scss @@ -0,0 +1,72 @@ +// This file is based off animate.css 3.5.1, available here: +// https://github.com/daneden/animate.css/blob/3.5.1/animate.css +// +// animate.css - http://daneden.me/animate +// Version - 3.5.1 +// Licensed under the MIT license - http://opensource.org/licenses/MIT +// +// Copyright (c) 2016 Daniel Eden + +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.animated.infinite { + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; +} + +.animated.hinge { + -webkit-animation-duration: 2s; + animation-duration: 2s; +} + +.animated.flipOutX, +.animated.flipOutY, +.animated.bounceIn, +.animated.bounceOut { + -webkit-animation-duration: .75s; + animation-duration: .75s; +} + +@-webkit-keyframes pulse { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes pulse { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.pulse { + -webkit-animation-name: pulse; + animation-name: pulse; +} diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index f5ce70b606b047..bb8d71fbae8711 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -45,6 +45,7 @@ &.s32 { font-size: 20px; line-height: 32px; } &.s40 { font-size: 16px; line-height: 40px; } &.s60 { font-size: 32px; line-height: 60px; } + &.s70 { font-size: 34px; line-height: 70px; } &.s90 { font-size: 36px; line-height: 90px; } &.s110 { font-size: 40px; line-height: 112px; font-weight: 300; } &.s140 { font-size: 72px; line-height: 140px; } diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 434a26d57c6672..6981f834d30e58 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -24,8 +24,8 @@ background-color: $background-color; padding: $gl-padding; margin-bottom: 0; - border-top: 1px solid $border-color; - border-bottom: 1px solid $border-color; + border-top: 1px solid $white-dark; + border-bottom: 1px solid $white-dark; color: $gl-gray; &.oneline-block { @@ -110,9 +110,9 @@ .cover-title { color: $gl-header-color; margin: 0; - font-size: 23px; + font-size: 24px; font-weight: normal; - margin: 16px 0 5px; + margin-bottom: 5px; color: #4c4e54; font-size: 23px; line-height: 1.1; @@ -137,7 +137,6 @@ } .cover-desc { - padding: 0 $gl-padding 3px; color: $gl-text-color; &.username:last-child { @@ -205,7 +204,7 @@ .content-block { padding: $gl-padding 0; - border-bottom: 1px solid $border-color; + border-bottom: 1px solid $white-dark; &.oneline-block { line-height: 36px; diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index eaf85bb17ca487..467f3b35d743aa 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -16,6 +16,19 @@ @include btn-default; } +@mixin btn-outline($background, $text, $border, $hover-background, $hover-text, $hover-border) { + background-color: $background; + color: $text; + border-color: $border; + + &:hover, + &:focus { + background-color: $hover-background; + color: $hover-text; + border-color: $hover-border;; + } +} + @mixin btn-color($light, $border-light, $normal, $border-normal, $dark, $border-dark, $color) { background-color: $light; border-color: $border-light; @@ -106,11 +119,14 @@ @include btn-blue; } - &.btn-close, &.btn-warning { @include btn-orange; } + &.btn-close { + @include btn-outline($white-light, $orange-normal, $orange-normal, $orange-light, $white-light, $orange-light); + } + &.btn-danger, &.btn-remove, &.btn-red { diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss index 11f39d583bd175..8642b7530e25ca 100644 --- a/app/assets/stylesheets/framework/calendar.scss +++ b/app/assets/stylesheets/framework/calendar.scss @@ -1,70 +1,44 @@ .calender-block { + padding-left: 0; + padding-right: 0; + @media (min-width: $screen-sm-min) and (max-width: $screen-lg-min) { overflow-x: scroll; } } .user-calendar-activities { - .calendar_onclick_hr { - padding: 0; - margin: 10px 0; - } - .str-truncated { max-width: 70%; } - .text-expander { - background: #eee; - color: #555; - padding: 0 5px; - cursor: pointer; - margin-left: 4px; - &:hover { - background-color: #ddd; - } + .user-calendar-activities-loading { + font-size: 24px; } } -/** -* This overwrites the default values of the cal-heatmap gem -*/ -.calendar { - .qi { - fill: #fff; - } - - .q1 { - fill: #ededed !important; - } +.user-calendar { + text-align: center; - .q2 { - fill: #acd5f2 !important; - } - - .q3 { - fill: #7fa8d1 !important; - } - - .q4 { - fill: #49729b !important; - } - - .q5 { - fill: #254e77 !important; + .calendar { + display: inline-block; } +} - .future { - visibility: hidden; +.user-contrib-cell { + &:hover { + cursor: pointer; + stroke: #000; } +} - .domain-background { - fill: none; - shape-rendering: crispedges; - } +.user-contrib-text { + font-size: 12px; + fill: #959494; +} - .ch-tooltip { - padding: 3px; - font-weight: 550; - } +.calendar-hint { + margin-top: -23px; + float: right; + font-size: 12px; } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 3386523dbf7da1..f8aecd0558d325 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -289,7 +289,7 @@ table { text-shadow: none; @media (min-width: $screen-sm-min) { - margin-top: 11px; + margin-top: 8px; } } diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 4bf3a0504030f1..93c63c6984325f 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -154,7 +154,7 @@ color: $dropdown-header-color; font-size: 13px; line-height: 22px; - padding: 0 10px 10px; + padding: 0 10px; } .separator + .dropdown-header { @@ -162,6 +162,10 @@ } } +.dropdown-menu-full-width { + width: 100%; +} + .dropdown-menu-paging { .dropdown-page-two, .dropdown-menu-back { diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index 61d9954c6c87df..71a9f79be3ef5e 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -5,6 +5,10 @@ .file-holder { border: 1px solid $border-color; + &.file-holder-no-border { + border: 0; + } + &.readme-holder { margin: $gl-padding-top 0; } @@ -23,8 +27,17 @@ word-wrap: break-word; border-radius: 3px 3px 0 0; + &.file-title-clear { + padding-left: 0; + padding-right: 0; + background-color: transparent; + + .file-actions { + right: 0; + } + } + .file-actions { - float: right; position: absolute; top: 5px; right: 15px; @@ -36,22 +49,6 @@ } } - .filename { - &.old { - display: inline-block; - span.idiff { - background-color: #f8cbcb; - } - } - - &.new { - display: inline-block; - span.idiff { - background-color: #a6f3a6; - } - } - } - a:not(.btn) { color: $gl-dark-link-color; } diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index 558b133f593ff9..46acc3b772fbe3 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -28,10 +28,6 @@ input[type='text'].danger { } label { - &.control-label { - @extend .col-sm-2; - } - &.inline-label { margin: 0; } @@ -41,6 +37,10 @@ label { } } +.control-label { + @extend .col-sm-2; +} + .inline-input-group { width: 250px; } diff --git a/app/assets/stylesheets/framework/gitlab-theme.scss b/app/assets/stylesheets/framework/gitlab-theme.scss index c83cf881596f64..16cf394c426eab 100644 --- a/app/assets/stylesheets/framework/gitlab-theme.scss +++ b/app/assets/stylesheets/framework/gitlab-theme.scss @@ -9,8 +9,7 @@ @mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) { .page-with-sidebar { .header-logo { - background-color: $color; - border-color: $color; + background: $color-darker; a { color: $color-light; @@ -21,9 +20,13 @@ } &:hover { - background-color: $color-darker; + background-color: $color-dark; a { color: #fff; + + h3 { + color: #fff; + } } } } @@ -87,8 +90,8 @@ } $theme-blue: #2980b9; -$theme-charcoal: #333c47; -$theme-graphite: #888; +$theme-charcoal: #3d454d; +$theme-graphite: #666; $theme-gray: #373737; $theme-green: #019875; $theme-violet: #548; @@ -99,11 +102,11 @@ body { } &.ui_charcoal { - @include gitlab-theme(#c5d0de, $theme-charcoal, #2b333d, #24272d); + @include gitlab-theme(#d6d7d9, #485157, $theme-charcoal, #353b41); } &.ui_graphite { - @include gitlab-theme(#ccc, $theme-graphite, #777, #666); + @include gitlab-theme(#ccc, #777, $theme-graphite, #555); } &.ui_gray { diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 97f9d5820073c7..0da96c4017dbf6 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -6,12 +6,12 @@ header { transition-duration: .3s; &.navbar-empty { - height: 58px; + height: $header-height; background: #fff; - border-bottom: 1px solid #eee; + border-bottom: 1px solid $btn-gray-hover; .center-logo { - margin: 11px 0; + margin: 8px 0; text-align: center; #tanuki-logo, img { @@ -22,14 +22,18 @@ header { } &.navbar-gitlab { - padding: 0 20px; + padding: 0 16px; z-index: 100; margin-bottom: 0; - min-height: $header-height; + height: $header-height; background-color: $background-color; border: none; border-bottom: 1px solid $border-color; + @media (max-width: $screen-xs-min) { + padding: 0 16px; + } + &.with-horizontal-nav { border-bottom: none; } @@ -60,16 +64,44 @@ header { margin: 6px 0; border-radius: 0; position: absolute; - right: 2px; + right: -10px; + padding: 6px 10px; &:hover { - background-color: #eee; + background-color: $btn-gray-hover; } + &.active { color: $gl-icon-color; } } } + + &.header-collapsed { + padding: 0 16px; + } + + .side-nav-toggle { + display: none; + position: absolute; + left: -10px; + margin: 6px 0; + padding: 6px 10px; + border: none; + background-color: $background-color; + + &:hover { + background-color: $btn-gray-hover; + } + + &:focus { + outline: none; + } + + @media (max-width: $screen-xs-min) { + display: block; + } + } } .header-content { @@ -77,6 +109,10 @@ header { height: $header-height; padding-right: 40px; + @media (max-width: $screen-xs-min) { + padding-left: 40px; + } + @media (min-width: $screen-sm-min) { padding-right: 0; } @@ -145,6 +181,10 @@ header { @media (min-width: $screen-md-min) { @include collapsed-header; } + + @media (max-width: $screen-xs-min) { + margin-left: 0; + } } .header-expanded { @@ -153,6 +193,10 @@ header { @media (min-width: $screen-md-min) { margin-left: $sidebar_width; } + + @media (max-width: $screen-xs-min) { + margin-left: 0; + } } @media (max-width: $screen-xs-max) { diff --git a/app/assets/stylesheets/framework/mobile.scss b/app/assets/stylesheets/framework/mobile.scss index 33cbee85987ae7..bd531f8376b158 100644 --- a/app/assets/stylesheets/framework/mobile.scss +++ b/app/assets/stylesheets/framework/mobile.scss @@ -48,10 +48,6 @@ display: block; } - .project-home-desc { - font-size: 21px; - } - .project-repo-buttons, .git-clone-holder { display: none; diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index 7c18e93a261c9f..7eb7a8e4544734 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -1,3 +1,34 @@ +@mixin fade($gradient-direction, $rgba, $gradient-color) { + visibility: visible; + opacity: 1; + position: absolute; + bottom: 12px; + width: 43px; + height: 30px; + transition-duration: .3s; + -webkit-transform: translateZ(0); + background: -webkit-linear-gradient($gradient-direction, $rgba, $gradient-color 45%); + background: -o-linear-gradient($gradient-direction, $rgba, $gradient-color 45%); + background: -moz-linear-gradient($gradient-direction, $rgba, $gradient-color 45%); + background: linear-gradient($gradient-direction, $rgba, $gradient-color 45%); + + &.end-scroll { + visibility: hidden; + opacity: 0; + transition-duration: .3s; + } +} + +@mixin scrolling-links() { + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + &::-webkit-scrollbar { + display: none; + } +} + .nav-links { padding: 0; margin: 0; @@ -119,7 +150,7 @@ } input { - height: 34px; + height: 35px; display: inline-block; position: relative; top: 2px; @@ -196,14 +227,22 @@ position: fixed; top: $header-height; width: 100%; - z-index: 1; + z-index: 11; background: $background-color; border-bottom: 1px solid $border-color; transition-duration: .3s; + .container-fluid { + position: relative; + } + .controls { float: right; - padding: 7px 5px 0 0; + padding: 7px 0 0; + + @media (max-width: $screen-xs-max) { + display: none; + } i { color: $layout-link-gray; @@ -221,14 +260,31 @@ .dropdown { margin-left: 7px; + + @media (max-width: $screen-xs-min) { + margin-left: 0; + } + + li.active { + font-weight: bold; + } } } .nav-links { + @include scrolling-links(); border-bottom: none; height: 51px; - white-space: nowrap; - overflow-x: auto; + + .fade-right { + @include fade(left, rgba(250, 250, 250, 0.4), $background-color); + right: 0; + } + + .fade-left { + @include fade(right, rgba(250, 250, 250, 0.4), $background-color); + left: 0; + } li { @@ -252,8 +308,62 @@ } } + .nav-control { + .fade-right { + + @media (min-width: $screen-xs-max) { + right: 67px; + } + @media (max-width: $screen-xs-min) { + right: 0; + } + } + } +} + +.nav-block { + position: relative; + + .nav-links { + @include scrolling-links(); + + .fade-right { + @include fade(left, rgba(255, 255, 255, 0.4), $white-light); + right: 0; + } + + .fade-left { + @include fade(right, rgba(255, 255, 255, 0.4), $white-light); + left: 0; + } + + &.event-filter { + .fade-right { + visibility: hidden; + + @media (max-width: $screen-xs-max) { + visibility: visible; + } + } + } + } } .page-with-layout-nav { - margin-top: 50px; + margin-top: $header-height + 2; + + .right-sidebar { + top: ($header-height * 2) + 2; + } +} + +.activities { + + .nav-block { + border-bottom: 1px solid $border-color; + + .nav-links { + border-bottom: none; + } + } } diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index e940fd7286eab6..67f491b6d9c1d4 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -98,7 +98,7 @@ } .sidebar-user { - padding: 9px 22px; + padding: 7px 22px; position: fixed; bottom: 40px; width: $sidebar_width; @@ -210,15 +210,33 @@ } } +.sidebar-wrapper { + &.hidden-nav { + width: 0; + } +} + .page-sidebar-collapsed { padding-left: $sidebar_collapsed_width; + @media (max-width: $screen-xs-min) { + padding-left: 0; + } + .sidebar-wrapper { width: $sidebar_collapsed_width; + @media (max-width: $screen-xs-min) { + width: 0; + } + .header-logo { width: $sidebar_collapsed_width; + @media (max-width: $screen-xs-min) { + width: 0; + } + a { padding-left: ($sidebar_collapsed_width - 36) / 2; @@ -244,12 +262,22 @@ .collapse-nav a { width: $sidebar_collapsed_width; + + @media (max-width: $screen-xs-min) { + width: 0; + } } .sidebar-user { padding-left: ($sidebar_collapsed_width - 36) / 2; width: $sidebar_collapsed_width; + @media (max-width: $screen-xs-min) { + width: 0; + padding-left: 0; + padding-right: 0; + } + .username { display: none; } @@ -258,6 +286,10 @@ .layout-nav { padding-right: $sidebar_collapsed_width; + + @media (max-width: $screen-xs-min) { + padding-right: 0;; + } } } @@ -268,6 +300,10 @@ padding-left: $sidebar_width; } + @media (max-width: $screen-xs-min) { + padding-left: 0; + } + .sidebar-wrapper { width: $sidebar_width; @@ -276,7 +312,7 @@ } .nav-sidebar li a { - width: 230px; + width: $sidebar_width; &.back-link { i { @@ -287,7 +323,17 @@ } .layout-nav { - padding-right: $sidebar_width; + @media (max-width: $screen-xs-min) { + padding-right: 0; + } + + @media (min-width: $screen-xs-min) and (max-width: $screen-md-min) { + padding-right: 62px; + } + + @media (min-width: $screen-md-min) { + padding-right: $sidebar_width; + } } } diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 2779cd56788bd0..3575984b2290e1 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -269,3 +269,11 @@ h1, h2, h3, h4 { text-align: right; } } + +.idiff.deletion { + background: $line-removed-dark; +} + +.idiff.addition { + background: $line-added-dark; +} diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index ccb4e5381b7930..f253da814bc639 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -2,7 +2,7 @@ * Layout */ $sidebar_collapsed_width: 62px; -$sidebar_width: 230px; +$sidebar_width: 220px; $gutter_collapsed_width: 62px; $gutter_width: 290px; $gutter_inner_width: 258px; @@ -12,7 +12,7 @@ $gutter_inner_width: 258px; */ $border-color: #e5e5e5; $focus-border-color: #3aabf0; -$table-border-color: #ececec; +$table-border-color: #f0f0f0; $background-color: #fafafa; /* @@ -63,7 +63,8 @@ $gl-padding-top: 10px; /* * Misc */ -$row-hover: #f4f8fe; +$row-hover: #f7faff; +$row-hover-border: #b2d7ff; $progress-color: #c0392b; $avatar_radius: 50%; $header-height: 50px; @@ -104,7 +105,7 @@ $blue-medium-light: #3498cb; $blue-medium: #2f8ebf; $blue-medium-dark: #2d86b4; -$orange-light: rgba(252, 109, 38, 0.80); +$orange-light: #fc8a51; $orange-normal: #e75e40; $orange-dark: #ce5237; @@ -119,8 +120,8 @@ $border-white-light: #f1f2f4; $border-white-normal: #d6dae2; $border-white-dark: #c6cacf; -$border-gray-light: rgba(0, 0, 0, 0.06); -$border-gray-normal: rgba(0, 0, 0, 0.10);; +$border-gray-light: #dcdcdc; +$border-gray-normal: rgba(0, 0, 0, 0.10); $border-gray-dark: #c6cacf; $border-green-light: #2faa60; @@ -178,6 +179,7 @@ $table-border-gray: #f0f0f0; $line-target-blue: #eaf3fc; $line-select-yellow: #fcf8e7; $line-select-yellow-dark: #f0e2bd; + /* * Fonts */ @@ -215,6 +217,7 @@ $dropdown-toggle-hover-icon-color: $dropdown-toggle-hover-border-color; $btn-active-gray: #ececec; $btn-placeholder-gray: #c7c7c7; $btn-white-active: #848484; +$btn-gray-hover: #eee; /* * Award emoji diff --git a/app/assets/stylesheets/framework/zen.scss b/app/assets/stylesheets/framework/zen.scss index f870ea0d87f5d8..ff02ebdd34ca8c 100644 --- a/app/assets/stylesheets/framework/zen.scss +++ b/app/assets/stylesheets/framework/zen.scss @@ -32,7 +32,7 @@ } } -.zen-cotrol { +.zen-control { padding: 0; color: #555; background: none; diff --git a/app/assets/stylesheets/mailers/devise.scss b/app/assets/stylesheets/mailers/devise.scss new file mode 100644 index 00000000000000..28611a5ec81f33 --- /dev/null +++ b/app/assets/stylesheets/mailers/devise.scss @@ -0,0 +1,134 @@ +// NOTE: This stylesheet is for the exclusive use of the `devise_mailer` layout +// used for Devise email templates, and _should not_ be included in any +// application stylesheets. +// +// Styles defined here are embedded directly into the resulting email HTML via +// the `premailer` gem. + +$body-background-color: #363636; +$message-background-color: #fafafa; + +$header-color: #6b4fbb; +$body-color: #444; +$cta-color: #e14329; +$footer-link-color: #7e7e7e; + +$font-family: Helvetica, Arial, sans-serif; + +body { + background-color: $body-background-color; + font-family: $font-family; + margin: 0; + padding: 0; +} + +table { + -premailer-cellpadding: 0; + -premailer-cellspacing: 0; + + border: 0; + border-collapse: separate; + + &#wrapper { + background-color: $body-background-color; + width: 100%; + } + + &#header { + margin: 0 auto; + text-align: left; + width: 600px; + } + + &#body { + background-color: $message-background-color; + border: 1px solid #000; + border-radius: 4px; + margin: 0 auto; + width: 600px; + } + + &#footer { + color: $footer-link-color; + font-size: 14px; + text-align: center; + width: 100%; + } + + td { + &#body-container { + padding: 20px 40px; + } + } +} + +.center { + text-align: center; +} + +#logo { + border: none; + outline: none; + min-height: 88px; + width: 134px; +} + +#content { + h2 { + color: $header-color; + font-size: 30px; + font-weight: 400; + line-height: 34px; + margin-top: 0; + } + + p { + color: $body-color; + font-size: 17px; + line-height: 24px; + margin-bottom: 0; + } +} + +#cta { + border: 1px solid $cta-color; + border-radius: 3px; + display: inline-block; + margin: 20px 0; + padding: 12px 24px; + + a { + background-color: $message-background-color; + color: $cta-color; + display: inline-block; + text-decoration: none; + } +} + +#tanuki { + padding: 40px 0 0; + + img { + border: none; + outline: none; + width: 37px; + min-height: 36px; + } +} + +#tagline { + font-size: 22px; + font-weight: 100; + padding: 4px 0 40px; +} + +#social { + padding: 0 10px 20px; + width: 600px; + word-spacing: 20px; + + a { + color: $footer-link-color; + text-decoration: none; + } +} diff --git a/app/assets/stylesheets/mailers/repository_push_email.scss b/app/assets/stylesheets/mailers/repository_push_email.scss new file mode 100644 index 00000000000000..001994db97b729 --- /dev/null +++ b/app/assets/stylesheets/mailers/repository_push_email.scss @@ -0,0 +1,43 @@ +@import "framework/variables"; + +table.code { + width: 100%; + font-family: monospace; + border: none; + border-collapse: separate; + margin: 0; + padding: 0; + -premailer-cellpadding: 0; + -premailer-cellspacing: 0; + -premailer-width: 100%; + + td { + line-height: $code_line_height; + font-family: monospace; + font-size: $code_font_size; + } + + td.diff-line-num { + margin: 0; + padding: 0; + border: none; + background: $background-color; + color: rgba(0, 0, 0, 0.3); + padding: 0 5px; + border-right: 1px solid $border-color; + text-align: right; + min-width: 35px; + max-width: 50px; + width: 35px; + } + + td.line_content { + display: block; + margin: 0; + padding: 0 0.5em; + border: none; + white-space: pre; + } +} + +@import "highlight/white"; diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss index c2cd227571f3cf..fc3f214aba55e7 100644 --- a/app/assets/stylesheets/pages/commit.scss +++ b/app/assets/stylesheets/pages/commit.scss @@ -26,8 +26,28 @@ .commit-info-row { margin-bottom: 10px; + + &.commit-info-row-header { + line-height: 34px; + + @media (min-width: $screen-sm-min) { + margin-bottom: 0; + } + + .commit-options-dropdown-caret { + @media (max-width: $screen-sm) { + margin-left: 0; + } + } + } + .avatar { @extend .avatar-inline; + margin-left: 0; + + @media (min-width: $screen-sm-min) { + margin-left: 4px; + } } .commit-committer-link, .commit-author-link { @@ -35,10 +55,6 @@ font-weight: bold; } - .time_ago { - margin-left: 8px; - } - .fa-clipboard { color: $dropdown-title-btn-color; } diff --git a/app/assets/stylesheets/pages/detail_page.scss b/app/assets/stylesheets/pages/detail_page.scss index 5e61e61d85cadd..1b389d83525da3 100644 --- a/app/assets/stylesheets/pages/detail_page.scss +++ b/app/assets/stylesheets/pages/detail_page.scss @@ -29,8 +29,6 @@ margin-top: 6px; p { - overflow-x: auto; - &:last-child { margin-bottom: 0; } diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index 8981f070a20337..22679c764dc881 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -23,7 +23,7 @@ .file-title { @extend .monospace; - line-height: 42px; + line-height: 35px; padding-top: 7px; padding-bottom: 7px; @@ -43,7 +43,7 @@ .editor-file-name { @extend .monospace; - + float: left; margin-right: 10px; } @@ -59,7 +59,22 @@ } .encoding-selector, - .license-selector { + .license-selector, + .gitignore-selector { display: inline-block; + vertical-align: top; + font-family: $regular_font; + } + + .gitignore-selector { + + .dropdown { + line-height: 21px; + } + + .dropdown-menu-toggle { + vertical-align: top; + width: 220px; + } } } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 1cf3023ecc976c..787c387379e774 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -125,7 +125,7 @@ .right-sidebar { position: fixed; - top: 58px; + top: $header-height; bottom: 0; right: 0; z-index: 10; @@ -150,6 +150,10 @@ font-weight: 600; } + .light { + font-weight: normal; + } + .sidebar-collapsed-icon { display: none; } diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index fc9db97132dd46..4e35ca329e465d 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -40,11 +40,6 @@ } } -.issue-search-form { - margin: 0; - height: 24px; -} - form.edit-issue { margin: 0; } @@ -96,8 +91,3 @@ form.edit-issue { .issue-form .select2-container { width: 250px !important; } - -.issue-closed-by-widget { - color: $gl-text-color; - margin-left: 52px; -} diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index c4005ba1e69265..8046e203a99675 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -41,7 +41,7 @@ margin: 0; margin-left: 20px; padding: 5px; - padding-top: 12px; + padding-top: 8px; line-height: 20px; &.right { @@ -110,6 +110,29 @@ p:last-child { margin-bottom: 0; } + + @media (max-width: $screen-sm-max) { + h4 { + font-size: 15px; + } + + p { + font-size: 13px; + } + + .btn, + .btn-group, + .accept-action { + width: 100%; + margin-bottom: 4px; + } + + .accept-control { + width: 100%; + text-align: center; + margin: 0; + } + } } .mr-widget-footer { @@ -280,11 +303,5 @@ background-color: $white-light; color: $gl-placeholder-color; } - - th, - td { - padding: 16px; - } } } - diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 624c8249f7e154..a3e1ac13a4374f 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -226,8 +226,7 @@ ul.notes { } } -.note-action-button, -.discussion-action-button { +.note-action-button { display: inline-block; margin-left: 10px; line-height: 24px; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss new file mode 100644 index 00000000000000..6128868b670a43 --- /dev/null +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -0,0 +1,24 @@ +.pipelines { + .stage { + max-width: 100px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .duration, .finished_at { + margin: 4px 0; + } + + .commit-title { + margin: 0; + } + + .controls { + white-space: nowrap; + } + + .btn { + margin: 4px; + } +} diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index abc5a0e9877377..167ab40d881666 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -66,12 +66,6 @@ } } -.calendar-hint { - margin-top: -12px; - float: right; - font-size: 12px; -} - .profile-link-holder { display: inline; @@ -134,14 +128,6 @@ } } -.change-username-title { - color: $gl-warning; -} - -.remove-account-title { - color: $gl-danger; -} - .provider-btn-group { display: inline-block; margin-right: 10px; @@ -218,7 +204,7 @@ .btn { display: inline-block; - width: 48%; + width: 46%; } } } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index c20f04653fcc9d..edef336481d46e 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -7,10 +7,10 @@ } .no-ssh-key-message, .project-limit-message { background-color: #f28d35; - margin-bottom: 16px; + margin-bottom: 0; } .new_project, -.edit_project { +.edit-project { fieldset.features { .control-label { font-weight: normal; @@ -26,8 +26,13 @@ } .project-home-panel { - padding-bottom: 40px; - border-bottom: 1px solid $border-color; + background: $white-light; + text-align: left; + padding: 24px 0; + + .container-fluid { + position: relative; + } .cover-controls { .project-settings-dropdown { @@ -43,21 +48,55 @@ } } - .project-identicon-holder { - margin-bottom: 16px; + .cover-title { + margin-bottom: 0; + } - .avatar, .identicon { - margin: 0 auto; - float: none; + .project-image-container { + @include make-sm-column(1); + max-width: 86px; + min-width: 86px; + padding-right: 0; + margin: 11px 0; + + @media (max-width: $screen-md-max) { + padding-left: 0; + margin: 0 0 10px; + max-width: none; + min-width: none; + + .avatar.s70 { + margin: auto; + } } + } - .identicon { - @include border-radius(50%); + .project-info { + @include make-sm-column(10); + + h1 { + font-size: 24px; + font-weight: normal; + margin: 0; + } + + .project-home-desc { + p { + margin: 0; + } } } + .identicon { + float: left; + @include border-radius(50%); + } + + .avatar { + float: none; + } + .notifications-btn { - margin-top: -28px; .fa-bell { margin-right: 6px; @@ -69,28 +108,45 @@ } .project-repo-buttons { - margin-top: 20px; - margin-bottom: 0; + font-size: 0; - .count-buttons { - display: block; - margin-bottom: 20px; - } + .btn { + @include btn-gray; + padding: 3px 10px; + text-transform: none; + background-color: $background-color; - .clone-row { - .split-repo-buttons, - .project-clone-holder { - display: inline-block; + .fa { + color: $layout-link-gray; } - .split-repo-buttons { - margin: 0 12px; + .fa-caret-down { + margin-left: 3px; } } - .btn { - @include btn-gray; - text-transform: none; + .btn-group:not(:first-child):not(:last-child) > .btn { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + } + + form { + margin-left: 10px; + } + + .count-buttons { + display: inline-block; + vertical-align: top; + margin-top: 16px; + } + + .project-clone-holder { + display: inline-block; + margin-top: 16px; + + input { + height: 29px; + } } .count-with-arrow { @@ -140,14 +196,18 @@ line-height: 13px; padding: $gl-vert-padding $gl-padding; letter-spacing: .4px; - padding: 10px 14px; + padding: 7px 14px; text-align: center; vertical-align: middle; touch-action: manipulation; cursor: pointer; background-image: none; white-space: nowrap; - margin: 0 11px 0 4px; + margin: 0 10px 0 4px; + + a { + color: inherit; + } &:hover { background: #fff; @@ -155,13 +215,37 @@ } } } + + .project-right-buttons { + position: absolute; + right: 16px; + bottom: 0; + + .btn { + padding: 3px 10px; + background-color: $background-color; + } + + @media (max-width: 1304px) { + top: 0; + } + } + + @media (max-width: $screen-md-max) { + text-align: center; + + .project-info, + .project-image-container { + width: 100%; + } + } } .split-one { display: inline-table; margin-right: 12px; - a { + > a { margin: -1px; } } @@ -285,11 +369,11 @@ a.deploy-project-label { } .project-stats { - text-align: center; margin-top: $gl-padding; margin-bottom: 0; - padding-top: 10px; - padding-bottom: 4px; + padding: 16px 0; + background-color: $white-light; + font-size: 0; ul.nav { display: inline-block; @@ -300,12 +384,11 @@ a.deploy-project-label { } .nav > li > a { - @include btn-default; - @include btn-gray; - background-color: transparent; - border: 1px solid #f7f8fa; - margin-left: 12px; + margin-right: 12px; + padding: 0 10px; + font-size: 15px; + color: $notes-light-color; } li { @@ -325,6 +408,10 @@ a.deploy-project-label { background-color: #f0f2f5; } } + + &.row-content-block.second-block { + margin-top: 0; + } } pre.light-well { @@ -442,9 +529,14 @@ pre.light-well { border-top: 0; .edit-project-readme { - z-index: 100; + z-index: 2; position: relative; } + + .wiki h1 { + border-bottom: none; + padding: 0; + } } .git-clone-holder { diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 2bff70c8c6489c..037ad52054569d 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -28,6 +28,7 @@ } .search-input { + padding-right: 20px; border: none; font-size: 14px; outline: none; @@ -47,6 +48,7 @@ display: inline-block; background-color: $location-badge-bg; vertical-align: top; + cursor: default; } .search-input-container { @@ -55,7 +57,7 @@ position: relative; } - .search-location-badge, .search-input-wrap { + .search-input-wrap { // Fallback if flexbox is not supported display: inline-block; } diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index 3fb700857135b5..2e8f356298d473 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -12,3 +12,11 @@ border: 1px solid $warning-message-border; border-radius: $border-radius-base; } + +.warning-title { + color: $gl-warning; +} + +.danger-title { + color: $gl-danger; +} diff --git a/app/assets/stylesheets/pages/snippets.scss b/app/assets/stylesheets/pages/snippets.scss index 639d639d5b0796..2aa939b7dc3891 100644 --- a/app/assets/stylesheets/pages/snippets.scss +++ b/app/assets/stylesheets/pages/snippets.scss @@ -16,19 +16,6 @@ } } -.snippet-box { - @include border-radius(2px); - - display: block; - float: left; - padding: 0 $gl-padding; - font-weight: normal; - margin-right: 10px; - font-size: $gl-font-size; - border: 1px solid; - line-height: 32px; -} - .markdown-snippet-copy { position: fixed; top: -10px; @@ -36,3 +23,34 @@ max-height: 0; max-width: 0; } + +.file-holder.snippet-file-content { + padding-bottom: $gl-padding; + border-bottom: 1px solid $border-color; + + .file-title { + padding-top: $gl-padding; + padding-bottom: $gl-padding; + } + + .file-actions { + top: 12px; + } + + .file-content { + border-left: 1px solid $border-color; + border-right: 1px solid $border-color; + border-bottom: 1px solid $border-color; + } +} + +.snippet-title { + font-size: 24px; + font-weight: normal; +} + +.snippet-actions { + @media (min-width: $screen-sm-min) { + float: right; + } +} diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index e51c3491dae714..afc00a68572189 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -29,6 +29,17 @@ .todo-item { .todo-title { @include str-truncated(calc(100% - 174px)); + overflow: visible; + } + + .status-box { + margin: 0; + float: none; + display: inline-block; + font-weight: normal; + padding: 0 5px; + line-height: inherit; + font-size: 14px; } .todo-body { @@ -76,12 +87,11 @@ @media (max-width: $screen-xs-max) { .todo-item { - padding-left: $gl-padding; - .todo-title { white-space: normal; overflow: visible; max-width: 100%; + margin-bottom: 10px; } .avatar { diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index a84fc2e0318af4..f16fc7f388f4bc 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -15,16 +15,23 @@ margin-bottom: 0; tr { - > td, > th { + border-bottom: 1px solid $table-border-gray; + border-top: 1px solid $table-border-gray; + + td, th { line-height: 23px; } &:hover { + cursor: pointer; + td { - background: $row-hover; + background-color: $row-hover; + border-top: 1px solid $row-hover-border; + border-bottom: 1px solid $row-hover-border; } - cursor: pointer; } + &.selected { td { background: $gray-dark; diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb index e9b0972bdd8725..5055c318a5f63c 100644 --- a/app/controllers/admin/abuse_reports_controller.rb +++ b/app/controllers/admin/abuse_reports_controller.rb @@ -9,6 +9,6 @@ def destroy abuse_report.remove_user(deleted_by: current_user) if params[:remove_user] abuse_report.destroy - render nothing: true + head :ok end end diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index ec22548ddeb145..0a34a12e2a7e52 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -19,6 +19,12 @@ def reset_runners_token redirect_to admin_runners_path end + def reset_health_check_token + @application_setting.reset_health_check_access_token! + flash[:notice] = 'New health check access token has been generated!' + redirect_to :back + end + def clear_repository_check_states RepositoryCheck::ClearWorker.perform_async @@ -53,6 +59,12 @@ def application_setting_params end end + enabled_oauth_sign_in_sources = params[:application_setting].delete(:enabled_oauth_sign_in_sources) + + params[:application_setting][:disabled_oauth_sign_in_sources] = + AuthHelper.button_based_providers.map(&:to_s) - + Array(enabled_oauth_sign_in_sources) + params.require(:application_setting).permit( :default_projects_limit, :default_branch_protection, @@ -94,8 +106,11 @@ def application_setting_params :email_author_in_body, :repository_checks_enabled, :metrics_packet_size, + :send_user_confirmation_email, + :container_registry_token_expire_delay, restricted_visibility_levels: [], - import_sources: [] + import_sources: [], + disabled_oauth_sign_in_sources: [] ) end end diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb index fc342924987237..82055006ac0ef6 100644 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ b/app/controllers/admin/broadcast_messages_controller.rb @@ -32,7 +32,7 @@ def destroy respond_to do |format| format.html { redirect_back_or_default(default: { action: 'index' }) } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/admin/health_check_controller.rb b/app/controllers/admin/health_check_controller.rb new file mode 100644 index 00000000000000..241c7be0ea14df --- /dev/null +++ b/app/controllers/admin/health_check_controller.rb @@ -0,0 +1,5 @@ +class Admin::HealthCheckController < Admin::ApplicationController + def show + @errors = HealthCheck::Utils.process_checks('standard') + end +end diff --git a/app/controllers/admin/keys_controller.rb b/app/controllers/admin/keys_controller.rb index cb33fdd9763415..054bb52b69606b 100644 --- a/app/controllers/admin/keys_controller.rb +++ b/app/controllers/admin/keys_controller.rb @@ -6,7 +6,7 @@ def show respond_to do |format| format.html - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index a701d49b844b95..7345c91f67df3b 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -9,23 +9,18 @@ def index end def show - @builds = @runner.builds.order('id DESC').first(30) - @projects = - if params[:search].present? - ::Project.search(params[:search]) - else - Project.all - end - @projects = @projects.where.not(id: @runner.projects.select(:id)) if @runner.projects.any? - @projects = @projects.page(params[:page]).per(30) + assign_builds_and_projects end def update - @runner.update_attributes(runner_params) - - respond_to do |format| - format.js - format.html { redirect_to admin_runner_path(@runner) } + if @runner.update_attributes(runner_params) + respond_to do |format| + format.js + format.html { redirect_to admin_runner_path(@runner) } + end + else + assign_builds_and_projects + render 'show' end end @@ -58,6 +53,18 @@ def runner end def runner_params - params.require(:runner).permit(:token, :description, :tag_list, :active) + params.require(:runner).permit(Ci::Runner::FORM_EDITABLE) + end + + def assign_builds_and_projects + @builds = runner.builds.order('id DESC').first(30) + @projects = + if params[:search].present? + ::Project.search(params[:search]) + else + Project.all + end + @projects = @projects.where.not(id: runner.projects.select(:id)) if runner.projects.any? + @projects = @projects.page(params[:page]).per(30) end end diff --git a/app/controllers/admin/spam_logs_controller.rb b/app/controllers/admin/spam_logs_controller.rb index 377e9741e5f141..3a2f0185315d4c 100644 --- a/app/controllers/admin/spam_logs_controller.rb +++ b/app/controllers/admin/spam_logs_controller.rb @@ -11,7 +11,7 @@ def destroy redirect_to admin_spam_logs_path, notice: "User #{spam_log.user.username} was successfully removed." else spam_log.destroy - render nothing: true + head :ok end end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index f2f654c7bcdeb3..f35f4a8c811255 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -119,6 +119,7 @@ def update user_params_with_pass.merge!( password: params[:user][:password], password_confirmation: params[:user][:password_confirmation], + password_expires_at: Time.now ) end @@ -153,7 +154,7 @@ def remove_email respond_to do |format| format.html { redirect_back_or_admin_user(notice: "Successfully removed email.") } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 17b3f49aed1c82..c28d1ca9e3bf01 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -176,7 +176,7 @@ def validate_user_service_ticket! end def check_password_expiration - if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user? + 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 end end @@ -232,7 +232,7 @@ def view_to_html_string(partial, locals = {}) end def configure_permitted_parameters - devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me, :otp_attempt) } + devise_parameter_sanitizer.permit(:sign_in, keys: [:username, :email, :password, :login, :remember_me, :otp_attempt]) end def hexdigest(string) @@ -263,7 +263,7 @@ def set_filters_params # internal repos where you are not a member. Enable this filter # or improve current implementation to filter only issues you # created or assigned or mentioned - #@filter_params[:authorized_only] = true + # @filter_params[:authorized_only] = true end @filter_params diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index eb0abc80ab43e3..3865b2d61fd1be 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -31,6 +31,24 @@ def user render json: @user, only: [:name, :username, :id], methods: [:avatar_url] end + def projects + project = Project.find_by_id(params[:project_id]) + + projects = current_user.authorized_projects + projects = projects.select do |project| + current_user.can?(:admin_issue, project) + end + + no_project = { + id: 0, + name_with_namespace: 'No project', + } + projects.unshift(no_project) + projects.delete(project) + + render json: projects.to_json(only: [:id, :name_with_namespace], methods: :name_with_namespace) + end + private def find_users diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index 787416c17ab65a..dacb5679dd300f 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -122,7 +122,7 @@ def set_commit_variables # Merge request from fork to this project @mr_source_project = @tree_edit_project @mr_target_project = @project - @mr_target_branch ||= @ref + @mr_target_branch ||= @ref end end end diff --git a/app/controllers/concerns/toggle_subscription_action.rb b/app/controllers/concerns/toggle_subscription_action.rb index 8a43c0b93c4c2b..9e3b9be2ff4086 100644 --- a/app/controllers/concerns/toggle_subscription_action.rb +++ b/app/controllers/concerns/toggle_subscription_action.rb @@ -6,7 +6,7 @@ def toggle_subscription subscribable_resource.toggle_subscription(current_user) - render nothing: true + head :ok end private diff --git a/app/controllers/dashboard/labels_controller.rb b/app/controllers/dashboard/labels_controller.rb index 23a4ef21ea20e1..2a88350a4cabeb 100644 --- a/app/controllers/dashboard/labels_controller.rb +++ b/app/controllers/dashboard/labels_controller.rb @@ -1,6 +1,6 @@ class Dashboard::LabelsController < Dashboard::ApplicationController def index - labels = Label.where(project_id: projects).select(:title, :color).uniq(:title) + labels = Label.where(project_id: projects).select(:id, :title, :color).uniq(:title) respond_to do |format| format.json { render json: labels } diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index 71acc244a9170b..c08eb8115322e8 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -28,7 +28,7 @@ def index end def starred - @projects = current_user.starred_projects.sorted_by_activity + @projects = current_user.viewable_starred_projects.sorted_by_activity @projects = filter_projects(@projects) @projects = @projects.includes(:namespace, :forked_from_project, :tags) @projects = @projects.sort(@sort = params[:sort]) diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 5abf97342c3ad4..f9a1929c117a4e 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -12,7 +12,7 @@ def destroy respond_to do |format| format.html { redirect_to dashboard_todos_path, notice: todo_notice } - format.js { render nothing: true } + format.js { head :ok } format.json do render json: { count: @todos.size, done_count: current_user.todos.done.count } end @@ -24,7 +24,7 @@ def destroy_all respond_to do |format| format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' } - format.js { render nothing: true } + format.js { head :ok } format.json do find_todos render json: { count: @todos.size, done_count: current_user.todos.done.count } diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 1dce4a21729f88..4dda4e51f6a5a2 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -25,7 +25,7 @@ def activity def load_events projects = if params[:filter] == "starred" - current_user.starred_projects + current_user.viewable_starred_projects else current_user.authorized_projects end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index d5ef33888c6929..48dbf656e84a92 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -40,7 +40,7 @@ def destroy respond_to do |format| format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb new file mode 100644 index 00000000000000..037da7d2bceaa4 --- /dev/null +++ b/app/controllers/health_check_controller.rb @@ -0,0 +1,22 @@ +class HealthCheckController < HealthCheck::HealthCheckController + before_action :validate_health_check_access! + + private + + def validate_health_check_access! + render_404 unless token_valid? + end + + def token_valid? + token = params[:token].presence || request.headers['TOKEN'] + token.present? && + ActiveSupport::SecurityUtils.variable_size_secure_compare( + token, + current_application_settings.health_check_access_token + ) + end + + def render_404 + render file: Rails.root.join('public', '404'), layout: false, status: '404' + end +end diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb new file mode 100644 index 00000000000000..cee3b6c43e7139 --- /dev/null +++ b/app/controllers/jwt_controller.rb @@ -0,0 +1,87 @@ +class JwtController < ApplicationController + skip_before_action :authenticate_user! + skip_before_action :verify_authenticity_token + before_action :authenticate_project_or_user + + SERVICES = { + Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService, + } + + def auth + service = SERVICES[params[:service]] + return head :not_found unless service + + result = service.new(@project, @user, auth_params).execute + + render json: result, status: result[:http_status] + end + + private + + def authenticate_project_or_user + authenticate_with_http_basic do |login, password| + # if it's possible we first try to authenticate project with login and password + @project = authenticate_project(login, password) + return if @project + + @user = authenticate_user(login, password) + return if @user + + render_403 + end + end + + def auth_params + params.permit(:service, :scope, :account, :client_id) + end + + def authenticate_project(login, password) + if login == 'gitlab-ci-token' + Project.find_by(builds_enabled: true, runners_token: password) + end + end + + def authenticate_user(login, password) + # TODO: this is a copy and paste from grack_auth, + # it should be refactored in the future + + user = Gitlab::Auth.new.find(login, password) + + # If the user authenticated successfully, we reset the auth failure count + # from Rack::Attack for that IP. A client may attempt to authenticate + # with a username and blank password first, and only after it receives + # a 401 error does it present a password. Resetting the count prevents + # false positives from occurring. + # + # Otherwise, we let Rack::Attack know there was a failed authentication + # attempt from this IP. This information is stored in the Rails cache + # (Redis) and will be used by the Rack::Attack middleware to decide + # whether to block requests from this IP. + config = Gitlab.config.rack_attack.git_basic_auth + + if config.enabled + if user + # A successful login will reset the auth failure count from this IP + Rack::Attack::Allow2Ban.reset(request.ip, config) + else + banned = Rack::Attack::Allow2Ban.filter(request.ip, config) do + # Unless the IP is whitelisted, return true so that Allow2Ban + # increments the counter (stored in Rails.cache) for the IP + if config.ip_whitelist.include?(request.ip) + false + else + true + end + end + + if banned + Rails.logger.info "IP #{request.ip} failed to login " \ + "as #{login} but has been temporarily banned from Git auth" + return + end + end + end + + user + end +end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index df98f56a1cd16f..f35d631df0cea8 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -97,7 +97,7 @@ def handle_omniauth handle_signup_error end - def handle_service_ticket provider, ticket + def handle_service_ticket(provider, ticket) Gitlab::OAuth::Session.create provider, ticket session[:service_tickets] ||= {} session[:service_tickets][provider] = ticket diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb index 0ede9b8e21ba05..1c24c4db993e62 100644 --- a/app/controllers/profiles/emails_controller.rb +++ b/app/controllers/profiles/emails_controller.rb @@ -24,7 +24,7 @@ def destroy respond_to do |format| format.html { redirect_to profile_emails_url } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb index a12549d6bcb7dc..830e0b9591bcbf 100644 --- a/app/controllers/profiles/keys_controller.rb +++ b/app/controllers/profiles/keys_controller.rb @@ -32,7 +32,7 @@ def destroy respond_to do |format| format.html { redirect_to profile_keys_url } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index be872a93feee0c..776ba92c9abe52 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -26,7 +26,7 @@ def project project_path = "#{namespace}/#{id}" @project = Project.find_with_namespace(project_path) - if @project && can?(current_user, :read_project, @project) + if can?(current_user, :read_project, @project) && !@project.pending_delete? if @project.path_with_namespace != project_path redirect_to request.original_url.gsub(project_path, @project.path_with_namespace) end diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index d09e7375b6740a..dd9508da04912b 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -50,7 +50,7 @@ def destroy redirect_to namespace_project_branches_path(@project.namespace, @project), status: 303 end - format.js { render status: status[:return_code] } + format.js { render nothing: true, status: status[:return_code] } end end diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index b8b9e78427d5f8..bb1f6c5e980969 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -38,6 +38,14 @@ def show end end + def trace + respond_to do |format| + format.json do + render json: @build.trace_with_state(params[:state]).merge!(id: @build.id, status: @build.status) + end + end + end + def retry unless @build.retryable? return render_404 diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index a202cb38692cd9..10b5932affabb6 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -17,12 +17,12 @@ class Projects::CommitController < Projects::ApplicationController def show apply_diff_view_cookie! - @line_notes = commit.notes.inline + @grouped_diff_notes = commit.notes.grouped_diff_notes + @note = @project.build_commit_note(commit) - @notes = commit.notes.not_inline.fresh + @notes = commit.notes.non_diff_notes.fresh @noteable = @commit - @comments_allowed = @reply_allowed = true - @comments_target = { + @comments_target = { noteable_type: 'Commit', commit_id: @commit.id } @@ -67,10 +67,10 @@ def revert create_commit(Commits::RevertService, success_notice: "The #{@commit.change_type_title} has been successfully reverted.", success_path: successful_change_path, failure_path: failed_change_path) end - + def cherry_pick assign_change_commit_vars(@commit.cherry_pick_branch_name) - + return render_404 if @target_branch.blank? create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title} has been successfully cherry-picked.", diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index 671d5c2302488f..af0b69a2442321 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -22,7 +22,8 @@ def show @base_commit = @project.merge_base_commit(@base_ref, @head_ref) @diffs = compare.diffs(diff_options) @diff_refs = [@base_commit, @commit] - @line_notes = [] + @diff_notes_disabled = true + @grouped_diff_notes = {} end end diff --git a/app/controllers/projects/container_registry_controller.rb b/app/controllers/projects/container_registry_controller.rb new file mode 100644 index 00000000000000..d1f46497207159 --- /dev/null +++ b/app/controllers/projects/container_registry_controller.rb @@ -0,0 +1,34 @@ +class Projects::ContainerRegistryController < Projects::ApplicationController + before_action :verify_registry_enabled + before_action :authorize_read_container_image! + before_action :authorize_update_container_image!, only: [:destroy] + layout 'project' + + def index + @tags = container_registry_repository.tags + end + + def destroy + url = namespace_project_container_registry_index_path(project.namespace, project) + + if tag.delete + redirect_to url + else + redirect_to url, alert: 'Failed to remove tag' + end + end + + private + + def verify_registry_enabled + render_404 unless Gitlab.config.registry.enabled + end + + def container_registry_repository + @container_registry_repository ||= project.container_registry_repository + end + + def tag + @tag ||= container_registry_repository.tag(params[:id]) + end +end diff --git a/app/controllers/projects/find_file_controller.rb b/app/controllers/projects/find_file_controller.rb index 54a0c447aee992..cf53ad0a670afc 100644 --- a/app/controllers/projects/find_file_controller.rb +++ b/app/controllers/projects/find_file_controller.rb @@ -1,26 +1,26 @@ -# Controller for viewing a repository's file structure -class Projects::FindFileController < Projects::ApplicationController - include ExtractsPath - include ActionView::Helpers::SanitizeHelper - include TreeHelper - - before_action :require_non_empty_project - before_action :assign_ref_vars - before_action :authorize_download_code! - - def show - return render_404 unless @repository.commit(@ref) - - respond_to do |format| - format.html - end - end - - def list - file_paths = @repo.ls_files(@ref) - - respond_to do |format| - format.json { render json: file_paths } - end - end -end +# Controller for viewing a repository's file structure +class Projects::FindFileController < Projects::ApplicationController + include ExtractsPath + include ActionView::Helpers::SanitizeHelper + include TreeHelper + + before_action :require_non_empty_project + before_action :assign_ref_vars + before_action :authorize_download_code! + + def show + return render_404 unless @repository.commit(@ref) + + respond_to do |format| + format.html + end + end + + def list + file_paths = @repo.ls_files(@ref) + + respond_to do |format| + format.json { render json: file_paths } + end + end +end diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index dfa9bd259e80fb..a60027ff4779f2 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -27,8 +27,10 @@ def test if !@project.empty_repo? status, message = TestHookService.new.execute(hook, current_user) - if status - flash[:notice] = 'Hook successfully executed.' + if status && status >= 200 && status < 400 + flash[:notice] = "Hook executed successfully: HTTP #{status}" + elsif status + flash[:alert] = "Hook executed successfully but returned HTTP #{status} #{message}" else flash[:alert] = "Hook execution failed: #{message}" end @@ -61,7 +63,8 @@ def hook_params :push_events, :tag_push_events, :token, - :url + :url, + :wiki_page_events ) end end diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb index 7756f0f0ed3b04..a1b84afcd9170f 100644 --- a/app/controllers/projects/imports_controller.rb +++ b/app/controllers/projects/imports_controller.rb @@ -20,6 +20,7 @@ def create @project.import_retry else @project.import_start + @project.add_import_job end end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 9c147b3689ebac..d54284d7b205ff 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -73,12 +73,12 @@ def diffs # but we need it for the "View file @ ..." link by deleted files @base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit - @comments_allowed = @reply_allowed = true @comments_target = { noteable_type: 'MergeRequest', noteable_id: @merge_request.id } - @line_notes = @merge_request.notes.where("line_code is not null") + + @grouped_diff_notes = @merge_request.notes.grouped_diff_notes respond_to do |format| format.html @@ -117,6 +117,7 @@ def new @commit = @merge_request.last_commit @base_commit = @merge_request.diff_base_commit @diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare + @diff_notes_disabled = true @ci_commit = @merge_request.ci_commit @statuses = @ci_commit.statuses if @ci_commit @@ -204,7 +205,7 @@ def merge end def branch_from - #This is always source + # This is always source @source_project = @merge_request.nil? ? @project : @merge_request.source_project @commit = @repository.commit(params[:ref]) if params[:ref].present? render layout: false @@ -228,6 +229,8 @@ def ci_status if ci_commit status = ci_commit.status coverage = ci_commit.try(:coverage) + + status ||= "preparing" else ci_service = @merge_request.source_project.ci_service status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch) if ci_service @@ -237,8 +240,6 @@ def ci_status end end - status = "preparing" if status.nil? - response = { title: merge_request.title, sha: merge_request.last_commit_short_sha, @@ -300,7 +301,7 @@ def define_show_vars # Build a note object for comment form @note = @project.notes.new(noteable: @merge_request) @notes = @merge_request.mr_and_commit_notes.nonawards.inc_author.fresh - @discussions = Note.discussions_from_notes(@notes) + @discussions = @notes.discussions @noteable = @merge_request # Get commits from repository @@ -333,7 +334,8 @@ def merge_request_params params.require(:merge_request).permit( :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, - :state_event, :description, :task_num, label_ids: [] + :state_event, :description, :task_num, :force_remove_source_branch, + label_ids: [] ) end diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index f7b6d137bde73e..da2892bfb3f5e9 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -75,7 +75,7 @@ def destroy respond_to do |format| format.html { redirect_to namespace_project_milestones_path } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 707a0d0e5c646a..40b24d550e0efe 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -43,7 +43,7 @@ def destroy end respond_to do |format| - format.js { render nothing: true } + format.js { head :ok } end end @@ -52,7 +52,7 @@ def delete_attachment note.update_attribute(:attachment, nil) respond_to do |format| - format.js { render nothing: true } + format.js { head :ok } end end @@ -96,7 +96,7 @@ def note_to_html(note) end def note_to_discussion_html(note) - return unless note.for_diff_line? + return unless note.diff_note? if params[:view] == 'parallel' template = "projects/notes/_diff_notes_with_reply_parallel" @@ -120,7 +120,7 @@ def note_to_discussion_html(note) end def note_to_discussion_with_diff_html(note) - return unless note.for_diff_line? + return unless note.diff_note? render_to_string( "projects/notes/_discussion", @@ -158,7 +158,7 @@ def authorize_admin_note! def note_params params.require(:note).permit( :note, :noteable, :noteable_id, :noteable_type, :project_id, - :attachment, :line_code, :commit_id + :attachment, :line_code, :commit_id, :type ) end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb new file mode 100644 index 00000000000000..b36081205d8723 --- /dev/null +++ b/app/controllers/projects/pipelines_controller.rb @@ -0,0 +1,59 @@ +class Projects::PipelinesController < Projects::ApplicationController + before_action :pipeline, except: [:index, :new, :create] + before_action :commit, only: [:show] + before_action :authorize_read_pipeline! + before_action :authorize_create_pipeline!, only: [:new, :create] + before_action :authorize_update_pipeline!, only: [:retry, :cancel] + + def index + @scope = params[:scope] + all_pipelines = project.ci_commits + @pipelines_count = all_pipelines.count + @running_or_pending_count = all_pipelines.running_or_pending.count + @pipelines = PipelinesFinder.new(project).execute(all_pipelines, @scope) + @pipelines = @pipelines.order(id: :desc).page(params[:page]).per(30) + end + + def new + @pipeline = project.ci_commits.new(ref: @project.default_branch) + end + + def create + @pipeline = Ci::CreatePipelineService.new(project, current_user, create_params).execute + unless @pipeline.persisted? + render 'new' + return + end + + redirect_to namespace_project_pipeline_path(project.namespace, project, @pipeline) + end + + def show + end + + def retry + pipeline.retry_failed + + redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project) + end + + def cancel + pipeline.cancel_running + + redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project) + end + + private + + def create_params + params.require(:pipeline).permit(:ref) + end + + def pipeline + @pipeline ||= project.ci_commits.find_by!(id: params[:id]) + end + + def commit + @commit ||= @pipeline.commit_data + end +end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 33b2625c0ac5b0..cdea5f0b776258 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -55,7 +55,7 @@ def destroy format.html do redirect_to namespace_project_project_members_path(@project.namespace, @project) end - format.js { render nothing: true } + format.js { head :ok } end end @@ -81,7 +81,7 @@ def leave respond_to do |format| format.html { redirect_to dashboard_projects_path, notice: "You left the project." } - format.js { render nothing: true } + format.js { head :ok } end else if current_user == @project.owner diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb index e49259c34b6d6c..efa7bf14d0f5c9 100644 --- a/app/controllers/projects/protected_branches_controller.rb +++ b/app/controllers/projects/protected_branches_controller.rb @@ -39,7 +39,7 @@ def destroy respond_to do |format| format.html { redirect_to namespace_project_protected_branches_path } - format.js { render nothing: true } + format.js { head :ok } end end diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index 0dd2d6a99bec9c..0b4fa572501705 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -20,7 +20,7 @@ def update if @runner.update_attributes(runner_params) redirect_to runner_path(@runner), notice: 'Runner was successfully updated.' else - redirect_to runner_path(@runner), alert: 'Runner was not updated.' + render 'edit' end end @@ -64,6 +64,6 @@ def set_runner end def runner_params - params.require(:runner).permit(:description, :tag_list, :active) + params.require(:runner).permit(Ci::Runner::FORM_EDITABLE) end end diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb index 00234654578038..6f0687293907c6 100644 --- a/app/controllers/projects/variables_controller.rb +++ b/app/controllers/projects/variables_controller.rb @@ -3,20 +3,44 @@ class Projects::VariablesController < Projects::ApplicationController layout 'project_settings' + def index + @variable = Ci::Variable.new + end + def show + @variable = @project.variables.find(params[:id]) end def update - if project.update_attributes(project_params) + @variable = @project.variables.find(params[:id]) + + if @variable.update_attributes(project_params) + redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variable was successfully updated.' + else + render action: "show" + end + end + + def create + @variable = Ci::Variable.new(project_params) + + if @variable.valid? && @project.variables << @variable redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variables were successfully updated.' else - render action: 'show' + render action: "index" end end + def destroy + @key = @project.variables.find(params[:id]) + @key.destroy + + redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variable was successfully removed.' + end + private def project_params - params.require(:project).permit({ variables_attributes: [:id, :key, :value, :_destroy] }) + params.require(:variable).permit([:id, :key, :value, :_destroy]) end end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 0d6c32fabd255e..4b404eb03fa548 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -91,8 +91,8 @@ def destroy def markdown_preview text = params[:text] - ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user) - ext.analyze(text) + ext = Gitlab::ReferenceExtractor.new(@project, current_user) + ext.analyze(text, author: current_user) render json: { body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki), diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3768efe142aa2a..f94e2a84fa2d54 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -101,13 +101,7 @@ def show respond_to do |format| format.html do - if current_user - @membership = @project.team.find_member(current_user.id) - - if @membership - @notification_setting = current_user.notification_settings_for(@project) - end - end + @notification_setting = current_user.notification_settings_for(@project) if current_user if @project.repository_exists? if @project.empty_repo? @@ -147,6 +141,7 @@ def autocomplete_sources @suggestions = { emojis: AwardEmoji.urls, issues: autocomplete.issues, + milestones: autocomplete.milestones, mergerequests: autocomplete.merge_requests, members: participants } @@ -202,8 +197,8 @@ def toggle_star def markdown_preview text = params[:text] - ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user) - ext.analyze(text) + ext = Gitlab::ReferenceExtractor.new(@project, current_user) + ext.analyze(text, author: current_user) render json: { body: view_context.markdown(text), @@ -235,7 +230,8 @@ def load_events def project_params params.require(:project).permit( :name, :path, :description, :issues_tracker, :tag_list, :runners_token, - :issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch, + :issues_enabled, :merge_requests_enabled, :snippets_enabled, :container_registry_enabled, + :issues_tracker_id, :default_branch, :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex, :public_builds, diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 352bff19383357..75b78a49eab7b1 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -37,8 +37,8 @@ def build_resource(hash=nil) super end - def after_sign_up_path_for(_resource) - users_almost_there_path + def after_sign_up_path_for(user) + user.confirmed? ? dashboard_projects_path : users_almost_there_path end def after_inactive_sign_up_path_for(_resource) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index c29f4609e93cb5..d68c2a708e399b 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,5 +1,6 @@ class SessionsController < Devise::SessionsController include AuthenticatesWithTwoFactor + include Devise::Controllers::Rememberable include Recaptcha::ClientHelper skip_before_action :check_2fa_requirement, only: [:destroy] @@ -96,6 +97,7 @@ def authenticate_with_two_factor # Remove any lingering user data from login session.delete(:otp_user_id) + remember_me(user) if user_params[:remember_me] == '1' sign_in(user) and return else flash.now[:alert] = 'Invalid two-factor code.' diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 2daceed039b119..2a17c1f34db282 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -10,7 +10,7 @@ class SnippetsController < ApplicationController # Allow destroy snippet before_action :authorize_admin_snippet!, only: [:destroy] - skip_before_action :authenticate_user!, only: [:index, :user_index, :show, :raw] + skip_before_action :authenticate_user!, only: [:index, :show, :raw] layout 'snippets' respond_to :html diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 2ae180c8a124d1..a99632454d94f3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -58,11 +58,22 @@ def contributed end end + def snippets + load_snippets + + respond_to do |format| + format.html { render 'show' } + format.json do + render json: { + html: view_to_html_string("snippets/_snippets", collection: @snippets) + } + end + end + end + def calendar calendar = contributions_calendar @timestamps = calendar.timestamps - @starting_year = calendar.starting_year - @starting_month = calendar.starting_month render 'calendar', layout: false end @@ -116,6 +127,15 @@ def load_groups @groups = JoinedGroupsFinder.new(user).execute(current_user) end + def load_snippets + @snippets = SnippetsFinder.new.execute( + current_user, + filter: :by_user, + user: user, + scope: params[:scope] + ).page(params[:page]) + end + def projects_for_current_user ProjectsFinder.new.execute(current_user) end diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb index 3b9a421b11871f..aa8f4c1d0e4da5 100644 --- a/app/finders/group_projects_finder.rb +++ b/app/finders/group_projects_finder.rb @@ -18,7 +18,7 @@ def group_projects(current_user) projects = [] if current_user - if @group.users.include?(current_user) + if @group.users.include?(current_user) || current_user.admin? projects << @group.projects unless only_shared projects << @group.shared_projects unless only_owned else diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index f00f3f709e99c7..7d8c56f4c222a7 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -250,12 +250,12 @@ def filter_by_upcoming_milestone? def by_milestone(items) if milestones? if filter_by_no_milestone? - items = items.where(milestone_id: [-1, nil]) + items = items.left_joins_milestones.where(milestone_id: [-1, nil]) elsif filter_by_upcoming_milestone? - upcoming = Milestone.where(project_id: projects).upcoming - items = items.joins(:milestone).where(milestones: { title: upcoming.try(:title) }) + upcoming_ids = Milestone.upcoming_ids_by_projects(projects) + items = items.left_joins_milestones.where(milestone_id: upcoming_ids) else - items = items.joins(:milestone).where(milestones: { title: params[:milestone_title] }) + items = items.with_milestone(params[:milestone_title]) if projects items = items.where(milestones: { project_id: projects }) @@ -271,7 +271,7 @@ def by_label(items) if filter_by_no_label? items = items.without_label else - items = items.with_label(label_names) + items = items.with_label(label_names, params[:sort]) if projects items = items.where(labels: { project_id: projects }) end diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb index fa4c635f55cfc5..c41be333537f87 100644 --- a/app/finders/notes_finder.rb +++ b/app/finders/notes_finder.rb @@ -10,7 +10,7 @@ def execute(project, current_user, params) notes = case target_type when "commit" - project.notes.for_commit_id(target_id).not_inline + project.notes.for_commit_id(target_id).non_diff_notes when "issue" project.issues.find(target_id).notes.nonawards.inc_author when "merge_request" diff --git a/app/finders/pipelines_finder.rb b/app/finders/pipelines_finder.rb new file mode 100644 index 00000000000000..c19a795d467ac9 --- /dev/null +++ b/app/finders/pipelines_finder.rb @@ -0,0 +1,38 @@ +class PipelinesFinder + attr_reader :project + + def initialize(project) + @project = project + end + + def execute(pipelines, scope) + case scope + when 'running' + pipelines.running_or_pending + when 'branches' + from_ids(pipelines, ids_for_ref(pipelines, branches)) + when 'tags' + from_ids(pipelines, ids_for_ref(pipelines, tags)) + else + pipelines + end + end + + private + + def ids_for_ref(pipelines, refs) + pipelines.where(ref: refs).group(:ref).select('max(id)') + end + + def from_ids(pipelines, ids) + pipelines.unscoped.where(id: ids) + end + + def branches + project.repository.branches.map(&:name) + end + + def tags + project.repository.tags.map(&:name) + end +end diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb index 3ba27c405041c7..4bd46a76087470 100644 --- a/app/finders/todos_finder.rb +++ b/app/finders/todos_finder.rb @@ -36,7 +36,7 @@ def execute private def action_id? - action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED].include?(action_id.to_i) + action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED, Todo::BUILD_FAILED].include?(action_id.to_i) end def action_id diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 3e0074da394209..439b015b3b8274 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -110,8 +110,7 @@ def grouped_options_refs ] # If reference is commit id - we should add it to branch/tag selectbox - if(@ref && !options.flatten.include?(@ref) && - @ref =~ /\A[0-9a-zA-Z]{6,52}\z/) + if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/ options << ['Commit', [@ref]] end @@ -263,6 +262,8 @@ def page_filter_path(options = {}) assignee_id: params[:assignee_id], author_id: params[:author_id], sort: params[:sort], + issue_search: params[:issue_search], + label_name: params[:label_name] } options = exist_opts.merge(options) @@ -273,16 +274,11 @@ def page_filter_path(options = {}) end end - path = request.path - path << "?#{options.to_param}" - if add_label - if params[:label_name].present? and params[:label_name].respond_to?('any?') - params[:label_name].each do |label| - path << "&label_name[]=#{label}" - end - end - end - path + params = options.compact + + params.delete(:label_name) unless add_label + + "#{request.path}?#{params.to_param}" end def outdated_browser? diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 914b0ef6042626..03080d259316a9 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -60,4 +60,18 @@ def import_sources_checkboxes(help_block_id) end end end + + def oauth_providers_checkboxes + button_based_providers.map do |source| + disabled = current_application_settings.disabled_oauth_sign_in_sources.include?(source.to_s) + css_class = 'btn' + css_class << ' active' unless disabled + checkbox_name = 'application_setting[enabled_oauth_sign_in_sources][]' + + label_tag(checkbox_name, class: css_class) do + check_box_tag(checkbox_name, source, !disabled, + autocomplete: 'off') + Gitlab::OAuth::Provider.label_for(source) + end + end + end end diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index b4f80fd9b3ea37..b05fa0a14d6c88 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -38,6 +38,16 @@ def button_based_providers auth_providers.reject { |provider| form_based_provider?(provider) } end + def enabled_button_based_providers + disabled_providers = current_application_settings.disabled_oauth_sign_in_sources || [] + + button_based_providers.map(&:to_s) - disabled_providers + end + + def button_based_providers_enabled? + enabled_button_based_providers.any? + end + def provider_image_tag(provider, size = 64) label = label_for_provider(provider) diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 93241b3afb7762..cec2dc753fea0c 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -184,4 +184,14 @@ def licenses_for_select Other: licenses.reject(&:featured).map { |license| [license.name, license.key] } } end + + def gitignore_names + return @gitignore_names if defined?(@gitignore_names) + + @gitignore_names = { + Global: Gitlab::Gitignore.global.map { |gitignore| { name: gitignore.name } }, + # Note that the key here doesn't cover it really + Languages: Gitlab::Gitignore.languages_frameworks.map{ |gitignore| { name: gitignore.name } } + } + end end diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb index a9047ede8c5830..f742922d9269f7 100644 --- a/app/helpers/button_helper.rb +++ b/app/helpers/button_helper.rb @@ -30,7 +30,7 @@ def http_clone_button(project) content_tag :a, protocol, class: klass, - href: @project.http_url_to_repo, + href: project.http_url_to_repo, data: { html: true, placement: 'right', diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 417050b41327b2..cfad17dcacf598 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -38,19 +38,30 @@ def ci_icon_for_status(status) icon(icon_name + ' fw') end - def render_ci_status(ci_commit, tooltip_placement: 'auto left') - # TODO: split this method into - # - render_commit_status - # - render_pipeline_status - link_to ci_icon_for_status(ci_commit.status), - ci_status_path(ci_commit), - class: "ci-status-link ci-status-icon-#{ci_commit.status.dasherize}", - title: "Build #{ci_label_for_status(ci_commit.status)}", - data: { toggle: 'tooltip', placement: tooltip_placement } + def render_commit_status(commit, tooltip_placement: 'auto left') + project = commit.project + path = builds_namespace_project_commit_path(project.namespace, project, commit) + render_status_with_link('commit', commit.status, path, tooltip_placement) + end + + def render_pipeline_status(pipeline, tooltip_placement: 'auto left') + project = pipeline.project + path = namespace_project_pipeline_path(project.namespace, project, pipeline) + render_status_with_link('pipeline', pipeline.status, path, tooltip_placement) end def no_runners_for_project?(project) project.runners.blank? && Ci::Runner.shared.blank? end + + private + + def render_status_with_link(type, status, path, tooltip_placement) + link_to ci_icon_for_status(status), + path, + class: "ci-status-link ci-status-icon-#{status.dasherize}", + title: "#{type.titleize}: #{ci_label_for_status(status)}", + data: { toggle: 'tooltip', placement: tooltip_placement } + end end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index b59c3982edd169..d328f56c80caf9 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -123,13 +123,14 @@ def link_to_browse_code(project, commit) ) end - def revert_commit_link(commit, continue_to_path, btn_class: nil) + def revert_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true) return unless current_user - tooltip = "Revert this #{commit.change_type_title} in a new merge request" + tooltip = "Revert this #{commit.change_type_title} in a new merge request" if has_tooltip if can_collaborate_with_project? - link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class} has-tooltip" + btn_class = "btn btn-grouped btn-close btn-#{btn_class}" unless btn_class.nil? + link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: (tooltip if has_tooltip), class: "#{btn_class} #{'has-tooltip' if has_tooltip}" elsif can?(current_user, :fork_project, @project) continue_params = { to: continue_to_path, @@ -140,17 +141,20 @@ def revert_commit_link(commit, continue_to_path, btn_class: nil) namespace_key: current_user.namespace.id, continue: continue_params) - link_to 'Revert', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip + btn_class = "btn btn-grouped btn-close" unless btn_class.nil? + + link_to 'Revert', fork_path, class: btn_class, method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: (tooltip if has_tooltip) end end - def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil) + def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true) return unless current_user tooltip = "Cherry-pick this #{commit.change_type_title} in a new merge request" if can_collaborate_with_project? - link_to 'Cherry-pick', '#modal-cherry-pick-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class} has-tooltip" + btn_class = "btn btn-default btn-grouped btn-#{btn_class}" unless btn_class.nil? + link_to 'Cherry-pick', '#modal-cherry-pick-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: (tooltip if has_tooltip), class: "#{btn_class} #{'has-tooltip' if has_tooltip}" elsif can?(current_user, :fork_project, @project) continue_params = { to: continue_to_path, @@ -161,7 +165,8 @@ def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil) namespace_key: current_user.namespace.id, continue: continue_params) - link_to 'Cherry-pick', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip + btn_class = "btn btn-grouped btn-close" unless btn_class.nil? + link_to 'Cherry-pick', fork_path, class: "#{btn_class}", method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: (tooltip if has_tooltip) end end diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 9f73edb45534e3..cbe471768315ba 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -2,8 +2,8 @@ module DiffHelper def mark_inline_diffs(old_line, new_line) old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_line, new_line).inline_diffs - marked_old_line = Gitlab::Diff::InlineDiffMarker.new(old_line).mark(old_diffs) - marked_new_line = Gitlab::Diff::InlineDiffMarker.new(new_line).mark(new_diffs) + marked_old_line = Gitlab::Diff::InlineDiffMarker.new(old_line).mark(old_diffs, mode: :deletion) + marked_new_line = Gitlab::Diff::InlineDiffMarker.new(new_line).mark(new_diffs, mode: :addition) [marked_old_line, marked_new_line] end @@ -39,11 +39,11 @@ def generate_line_code(file_path, line) end def unfold_bottom_class(bottom) - (bottom) ? 'js-unfold-bottom' : '' + bottom ? 'js-unfold-bottom' : '' end def unfold_class(unfold) - (unfold) ? 'unfold js-unfold' : '' + unfold ? 'unfold js-unfold' : '' end def diff_line_content(line, line_type = nil) @@ -55,22 +55,18 @@ def diff_line_content(line, line_type = nil) end end - def line_comments - @line_comments ||= @line_notes.select(&:active?).sort_by(&:created_at).group_by(&:line_code) - end - - def organize_comments(type_left, type_right, line_code_left, line_code_right) - comments_left = comments_right = nil + def organize_comments(left, right) + notes_left = notes_right = nil - unless type_left.nil? && type_right == 'new' - comments_left = line_comments[line_code_left] + unless left[:type].nil? && right[:type] == 'new' + notes_left = @grouped_diff_notes[left[:line_code]] end - unless type_left.nil? && type_right.nil? - comments_right = line_comments[line_code_right] + unless left[:type].nil? && right[:type].nil? + notes_right = @grouped_diff_notes[right[:line_code]] end - [comments_left, comments_right] + [notes_left, notes_right] end def inline_diff_btn @@ -96,8 +92,8 @@ def submodule_link(blob, ref, repository = @repository) ].join(' ').html_safe end - def commit_for_diff(diff) - if diff.deleted_file + def commit_for_diff(diff_file) + if diff_file.deleted_file @base_commit || @commit.parent || @commit else @commit diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index 41b5bd7be9060b..8466d0aa0ba323 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -32,12 +32,6 @@ def action_title(url) nil end - def color_email_diff(diffcontent) - formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', inline_theme: 'github') - lexer = Rouge::Lexers::Diff - raw formatter.format(lexer.lex(diffcontent)) - end - def password_reset_token_valid_time valid_hours = Devise.reset_password_within / 60 / 60 if valid_hours >= 24 diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 592bad8ba24cef..bfedcb1c42b627 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -3,7 +3,7 @@ def link_to_author(event) author = event.author if author - link_to author.name, user_path(author.username), title: h(author.name) + link_to author.name, user_path(author.username), title: author.name else event.author_name end @@ -39,15 +39,6 @@ def event_filter_link(key, tooltip) end end - def icon_for_event - { - EventFilter.push => 'upload', - EventFilter.merged => 'check-square-o', - EventFilter.comments => 'comments', - EventFilter.team => 'user', - } - end - def event_preposition(event) if event.push? || event.commented? || event.target "at" @@ -66,11 +57,7 @@ def event_feed_title(event) words << event.ref_name words << "at" elsif event.commented? - if event.note_commit? - words << event.note_short_commit_id - else - words << "##{truncate event.note_target_iid}" - end + words << event.note_target_reference words << "at" elsif event.milestone? words << "##{event.target_iid}" if event.target_iid @@ -93,21 +80,12 @@ def event_feed_url(event) elsif event.merge_request? namespace_project_merge_request_url(event.project.namespace, event.project, event.merge_request) - elsif event.note? && event.note_commit? + elsif event.note? && event.commit_note? namespace_project_commit_url(event.project.namespace, event.project, event.note_target) elsif event.note? if event.note_target - if event.note_commit? - namespace_project_commit_path(event.project.namespace, event.project, - event.note_commit_id, - anchor: dom_id(event.target)) - elsif event.note_project_snippet? - namespace_project_snippet_path(event.project.namespace, - event.project, event.note_target) - else - event_note_target_path(event) - end + event_note_target_path(event) end elsif event.push? push_event_feed_url(event) @@ -143,42 +121,30 @@ def event_feed_summary(event) end def event_note_target_path(event) - if event.note? && event.note_commit? - namespace_project_commit_path(event.project.namespace, event.project, - event.note_target) + if event.note? && event.commit_note? + namespace_project_commit_path(event.project.namespace, + event.project, + event.note_target, + anchor: dom_id(event.target)) + elsif event.project_snippet_note? + namespace_project_snippet_path(event.project.namespace, + event.project, + event.note_target, + anchor: dom_id(event.target)) else polymorphic_path([event.project.namespace.becomes(Namespace), event.project, event.note_target], - anchor: dom_id(event.target)) + anchor: dom_id(event.target)) end end def event_note_title_html(event) if event.note_target - if event.note_commit? - link_to( - namespace_project_commit_path(event.project.namespace, event.project, - event.note_commit_id, - anchor: dom_id(event.target), title: h(event.target_title)), - class: "commit_short_id" - ) do - "#{event.note_target_type} #{event.note_short_commit_id}" - end - elsif event.note_project_snippet? - link_to(namespace_project_snippet_path(event.project.namespace, - event.project, - event.note_target), title: h(event.project.name)) do - "#{event.note_target_type} #{truncate event.note_target.to_reference}" - end - else - link_to event_note_target_path(event) do - "#{event.note_target_type} #{truncate event.note_target.to_reference}" - end + link_to(event_note_target_path(event), title: event.target_title, class: 'has-tooltip') do + "#{event.note_target_type} #{event.note_target_reference}" end else - content_tag :strong do - "(deleted)" - end + content_tag(:strong, '(deleted)') end end @@ -193,28 +159,6 @@ def event_commit_title(message) "--broken encoding" end - def event_to_atom(xml, event) - if event.visible_to_user?(current_user) - xml.entry do - event_link = event_feed_url(event) - event_title = event_feed_title(event) - event_summary = event_feed_summary(event) - - xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" - xml.link href: event_link - xml.title truncate(event_title, length: 80) - xml.updated event.created_at.xmlschema - xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(event.author_email)) - xml.author do |author| - xml.name event.author_name - xml.email event.author_email - end - - xml.summary(type: "xhtml") { |x| x << event_summary unless event_summary.nil? } - end - end - end - def event_row_class(event) if event.body? "event-block" diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 3a45205563e721..0a1b48af21978c 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -13,7 +13,7 @@ module GitlabMarkdownHelper def link_to_gfm(body, url, html_options = {}) return "" if body.blank? - escaped_body = if body =~ /\A\ opts[:push_code_to_protected_branches], - author_id: opts[:author_id] || '' + author_id: opts[:author_id] || '' } } diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 96a836710096e1..563ddd2a511819 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -95,7 +95,9 @@ def current_path?(path) end def project_tab_class - return "active" if current_page?(controller: "/projects", action: :edit, id: @project) + if controller.controller_path.start_with?('projects') + return 'active' + end if ['services', 'hooks', 'deploy_keys', 'protected_branches'].include? controller.controller_name "active" @@ -112,7 +114,7 @@ def branches_tab_class end def profile_tab_class - if controller.controller_path =~ /\Aprofiles/ + if controller.controller_path.start_with?('profiles') return 'active' end diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 2f066682180e7e..b4923fbb1383df 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -11,12 +11,15 @@ def todo_action_name(todo) case todo.action when Todo::ASSIGNED then 'assigned you' when Todo::MENTIONED then 'mentioned you on' + when Todo::BUILD_FAILED then 'The build failed for your' end end def todo_target_link(todo) target = todo.target_type.titleize.downcase - link_to "#{target} #{todo.target_reference}", todo_target_path(todo), { title: todo.target.title } + link_to "#{target} #{todo.target_reference}", todo_target_path(todo), + class: 'has-tooltip', + title: todo.target.title end def todo_target_path(todo) @@ -28,8 +31,21 @@ def todo_target_path(todo) namespace_project_commit_path(todo.project.namespace.becomes(Namespace), todo.project, todo.target, anchor: anchor) else - polymorphic_path([todo.project.namespace.becomes(Namespace), - todo.project, todo.target], anchor: anchor) + path = [todo.project.namespace.becomes(Namespace), todo.project, todo.target] + + path.unshift(:builds) if todo.build_failed? + + polymorphic_path(path, anchor: anchor) + end + end + + def todo_target_state_pill(todo) + return unless show_todo_state?(todo) + + content_tag(:span, nil, class: 'target-status') do + content_tag(:span, nil, class: "status-box status-box-#{todo.target.state.dasherize}") do + todo.target.state.capitalize + end end end @@ -91,4 +107,10 @@ def todo_types_options options_from_collection_for_select(types, 'name', 'title', params[:type]) end + + private + + def show_todo_state?(todo) + (todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && ['closed', 'merged'].include?(todo.target.state) + end end diff --git a/app/mailers/devise_mailer.rb b/app/mailers/devise_mailer.rb index b616add283a8b4..415f6e12885805 100644 --- a/app/mailers/devise_mailer.rb +++ b/app/mailers/devise_mailer.rb @@ -1,4 +1,6 @@ class DeviseMailer < Devise::Mailer default from: "#{Gitlab.config.gitlab.email_display_name} <#{Gitlab.config.gitlab.email_from}>" default reply_to: Gitlab.config.gitlab.email_reply_to + + layout 'devise_mailer' end diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb index 377c2999d6c21f..fdf1e9f5afcdd9 100644 --- a/app/mailers/emails/projects.rb +++ b/app/mailers/emails/projects.rb @@ -59,20 +59,20 @@ def project_was_moved_email(project_id, user_id, old_path_with_namespace) subject: subject("Project was moved")) end - def repository_push_email(project_id, recipient, opts = {}) + def repository_push_email(project_id, opts = {}) @message = - Gitlab::Email::Message::RepositoryPush.new(self, project_id, recipient, opts) + Gitlab::Email::Message::RepositoryPush.new(self, project_id, opts) # used in notify layout @target_url = @message.target_url - @project = Project.find project_id + @project = Project.find(project_id) + @diff_notes_disabled = true add_project_headers headers['X-GitLab-Author'] = @message.author_username mail(from: sender(@message.author_id, @message.send_from_committer_email?), reply_to: @message.reply_to, - to: @message.recipient, subject: @message.subject) end end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index 826e5f96fa1ed5..1c663bdd521275 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -10,6 +10,8 @@ class Notify < BaseMailer include Emails::Builds add_template_helper MergeRequestsHelper + add_template_helper DiffHelper + add_template_helper BlobHelper add_template_helper EmailsHelper def test_email(recipient_email, subject, body) diff --git a/app/models/ability.rb b/app/models/ability.rb index 6103a2947e2a6f..44515550d9ed6e 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -23,20 +23,41 @@ def allowed(user, subject) end.concat(global_abilities(user)) end + # Given a list of users and a project this method returns the users that can + # read the given project. + def users_that_can_read_project(users, project) + if project.public? + users + else + users.select do |user| + if user.admin? + true + elsif project.internal? && !user.external? + true + elsif project.owner == user + true + elsif project.team.members.include?(user) + true + else + false + end + end + end + end + # List of possible abilities for anonymous user def anonymous_abilities(user, subject) - case true - when subject.is_a?(PersonalSnippet) + if subject.is_a?(PersonalSnippet) anonymous_personal_snippet_abilities(subject) - when subject.is_a?(ProjectSnippet) + elsif subject.is_a?(ProjectSnippet) anonymous_project_snippet_abilities(subject) - when subject.is_a?(CommitStatus) + elsif subject.is_a?(CommitStatus) anonymous_commit_status_abilities(subject) - when subject.is_a?(Project) || subject.respond_to?(:project) + elsif subject.is_a?(Project) || subject.respond_to?(:project) anonymous_project_abilities(subject) - when subject.is_a?(Group) || subject.respond_to?(:group) + elsif subject.is_a?(Group) || subject.respond_to?(:group) anonymous_group_abilities(subject) - when subject.is_a?(User) + elsif subject.is_a?(User) anonymous_user_abilities else [] @@ -60,7 +81,9 @@ def anonymous_project_abilities(subject) :read_project_member, :read_merge_request, :read_note, + :read_pipeline, :read_commit_status, + :read_container_image, :download_code ] @@ -203,6 +226,8 @@ def project_report_rules :admin_label, :read_commit_status, :read_build, + :read_container_image, + :read_pipeline, ] end @@ -214,9 +239,13 @@ def project_dev_rules :update_commit_status, :create_build, :update_build, + :create_pipeline, + :update_pipeline, :create_merge_request, :create_wiki, - :push_code + :push_code, + :create_container_image, + :update_container_image, ] end @@ -242,7 +271,9 @@ def project_master_rules :admin_wiki, :admin_project, :admin_commit_status, - :admin_build + :admin_build, + :admin_container_image, + :admin_pipeline ] end @@ -285,6 +316,11 @@ def project_disabled_features_rules(project) unless project.builds_enabled rules += named_abilities('build') + rules += named_abilities('pipeline') + end + + unless project.container_registry_enabled + rules += named_abilities('container_image') end rules diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb index b61f51231278de..b01a244032d9de 100644 --- a/app/models/abuse_report.rb +++ b/app/models/abuse_report.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: abuse_reports -# -# id :integer not null, primary key -# reporter_id :integer -# user_id :integer -# message :text -# created_at :datetime -# updated_at :datetime -# - class AbuseReport < ActiveRecord::Base belongs_to :reporter, class_name: 'User' belongs_to :user diff --git a/app/models/appearance.rb b/app/models/appearance.rb index 4528760fefabdf..4cf8dd9a8ce2f3 100644 --- a/app/models/appearance.rb +++ b/app/models/appearance.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: appearances -# -# id :integer not null, primary key -# title :string -# description :text -# header_logo :string -# logo :string -# created_at :datetime not null -# updated_at :datetime not null -# - class Appearance < ActiveRecord::Base validates :title, presence: true validates :description, presence: true diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 72ec91d29092d4..42f908aa344464 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -1,63 +1,13 @@ -# == Schema Information -# -# Table name: application_settings -# -# id :integer not null, primary key -# default_projects_limit :integer -# signup_enabled :boolean -# signin_enabled :boolean -# gravatar_enabled :boolean -# sign_in_text :text -# created_at :datetime -# updated_at :datetime -# home_page_url :string -# default_branch_protection :integer default(2) -# restricted_visibility_levels :text -# version_check_enabled :boolean default(TRUE) -# max_attachment_size :integer default(10), not null -# default_project_visibility :integer -# default_snippet_visibility :integer -# restricted_signup_domains :text -# user_oauth_applications :boolean default(TRUE) -# after_sign_out_path :string -# session_expire_delay :integer default(10080), not null -# import_sources :text -# help_page_text :text -# admin_notification_email :string -# shared_runners_enabled :boolean default(TRUE), not null -# max_artifacts_size :integer default(100), not null -# runners_registration_token :string -# require_two_factor_authentication :boolean default(FALSE) -# two_factor_grace_period :integer default(48) -# metrics_enabled :boolean default(FALSE) -# metrics_host :string default("localhost") -# metrics_pool_size :integer default(16) -# metrics_timeout :integer default(10) -# metrics_method_call_threshold :integer default(10) -# recaptcha_enabled :boolean default(FALSE) -# recaptcha_site_key :string -# recaptcha_private_key :string -# metrics_port :integer default(8089) -# metrics_sample_interval :integer default(15) -# sentry_enabled :boolean default(FALSE) -# sentry_dsn :string -# akismet_enabled :boolean default(FALSE) -# akismet_api_key :string -# email_author_in_body :boolean default(FALSE) -# default_group_visibility :integer -# repository_checks_enabled :boolean default(FALSE) -# metrics_packet_size :integer default(1) -# shared_runners_text :text -# - class ApplicationSetting < ActiveRecord::Base include TokenAuthenticatable add_authentication_token_field :runners_registration_token + add_authentication_token_field :health_check_access_token CACHE_KEY = 'application_setting.last' serialize :restricted_visibility_levels serialize :import_sources + serialize :disabled_oauth_sign_in_sources, Array serialize :restricted_signup_domains, Array attr_accessor :restricted_signup_domains_raw @@ -101,6 +51,10 @@ class ApplicationSetting < ActiveRecord::Base presence: true, numericality: { only_integer: true, greater_than: 0 } + validates :container_registry_token_expire_delay, + presence: true, + numericality: { only_integer: true, greater_than: 0 } + validates_each :restricted_visibility_levels do |record, attr, value| unless value.nil? value.each do |level| @@ -121,7 +75,18 @@ class ApplicationSetting < ActiveRecord::Base end end + validates_each :disabled_oauth_sign_in_sources do |record, attr, value| + unless value.nil? + value.each do |source| + unless Devise.omniauth_providers.include?(source.to_sym) + record.errors.add(attr, "'#{source}' is not an OAuth sign-in source") + end + end + end + end + before_save :ensure_runners_registration_token + before_save :ensure_health_check_access_token after_commit do Rails.cache.write(CACHE_KEY, self) @@ -137,6 +102,10 @@ def self.expire Rails.cache.delete(CACHE_KEY) end + def self.cached + Rails.cache.fetch(CACHE_KEY) + end + def self.create_from_defaults create( default_projects_limit: Settings.gitlab['default_projects_limit'], @@ -159,6 +128,9 @@ def self.create_from_defaults recaptcha_enabled: false, akismet_enabled: false, repository_checks_enabled: true, + disabled_oauth_sign_in_sources: [], + send_user_confirmation_email: false, + container_registry_token_expire_delay: 5, ) end @@ -185,4 +157,8 @@ def restricted_signup_domains_raw=(values) def runners_registration_token ensure_runners_registration_token! end + + def health_check_access_token + ensure_health_check_access_token! + end end diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb index 44b090260e755a..967ffd46db0832 100644 --- a/app/models/audit_event.rb +++ b/app/models/audit_event.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: audit_events -# -# id :integer not null, primary key -# author_id :integer not null -# type :string not null -# entity_id :integer not null -# entity_type :string not null -# details :text -# created_at :datetime -# updated_at :datetime -# - class AuditEvent < ActiveRecord::Base serialize :details, Hash diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb index 075ac733bfcccd..61498140f27da8 100644 --- a/app/models/broadcast_message.rb +++ b/app/models/broadcast_message.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# created_at :datetime -# updated_at :datetime -# color :string -# font :string -# - class BroadcastMessage < ActiveRecord::Base include Sortable diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 4bc3a225e2c5d2..64723ab6b4b9ff 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -1,40 +1,3 @@ -# == Schema Information -# -# Table name: ci_builds -# -# id :integer not null, primary key -# project_id :integer -# status :string -# finished_at :datetime -# trace :text -# created_at :datetime -# updated_at :datetime -# started_at :datetime -# runner_id :integer -# coverage :float -# commit_id :integer -# commands :text -# job_id :integer -# name :string -# deploy :boolean default(FALSE) -# options :text -# allow_failure :boolean default(FALSE), not null -# stage :string -# trigger_request_id :integer -# stage_idx :integer -# tag :boolean -# ref :string -# user_id :integer -# type :string -# target_url :string -# description :string -# artifacts_file :text -# gl_project_id :integer -# artifacts_metadata :text -# erased_by_id :integer -# erased_at :datetime -# - module Ci class Build < CommitStatus belongs_to :runner, class_name: 'Ci::Runner' @@ -90,6 +53,7 @@ def retry(build) new_build.stage_idx = build.stage_idx new_build.trigger_request = build.trigger_request new_build.save + MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build) new_build end end @@ -132,8 +96,12 @@ def depends_on_builds end def trace_html - html = Ci::Ansi2html::convert(trace) if trace.present? - html || '' + trace_with_state[:html] || '' + end + + def trace_with_state(state = nil) + trace_with_state = Ci::Ansi2html::convert(trace, state) if trace.present? + trace_with_state || {} end def timeout @@ -238,7 +206,7 @@ def trace=(trace) end def recreate_trace_dir - unless Dir.exists?(dir_to_trace) + unless Dir.exist?(dir_to_trace) FileUtils.mkdir_p(dir_to_trace) end end @@ -318,14 +286,20 @@ def token project.runners_token end - def valid_token? token + def valid_token?(token) project.valid_runners_token? token end def can_be_served?(runner) + return false unless has_tags? || runner.run_untagged? + (tag_list - runner.tag_list).empty? end + def has_tags? + tag_list.any? + end + def any_runners_online? project.any_runners? { |runner| runner.active? && runner.online? && can_be_served?(runner) } end @@ -339,6 +313,7 @@ def execute_hooks build_data = Gitlab::BuildDataBuilder.build(self) project.execute_hooks(build_data.dup, :build_hooks) project.execute_services(build_data.dup, :build_hooks) + project.running_or_pending_build_count(force: true) end def artifacts? diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 4ac4e0fb8b2250..f22b573a94c9d2 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: ci_commits -# -# id :integer not null, primary key -# project_id :integer -# ref :string -# sha :string -# before_sha :string -# push_data :text -# created_at :datetime -# updated_at :datetime -# tag :boolean default(FALSE) -# yaml_errors :text -# committed_at :datetime -# gl_project_id :integer -# status :string -# started_at :datetime -# finished_at :datetime -# duration :integer -# - module Ci class Commit < ActiveRecord::Base extend Ci::Model @@ -30,8 +8,6 @@ class Commit < ActiveRecord::Base has_many :builds, class_name: 'Ci::Build' has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest' - delegate :stages, to: :statuses - validates_presence_of :sha validates_presence_of :status validate :valid_commit_sha @@ -44,7 +20,8 @@ def self.truncate_sha(sha) end def self.stages - CommitStatus.where(commit: all).stages + # We use pluck here due to problems with MySQL which doesn't allow LIMIT/OFFSET in queries + CommitStatus.where(commit: pluck(:id)).stages end def project_id @@ -89,6 +66,29 @@ def retryable? end end + def cancelable? + builds.running_or_pending.any? + end + + def cancel_running + builds.running_or_pending.each(&:cancel) + end + + def retry_failed + builds.latest.failed.select(&:retryable?).each(&:retry) + end + + def latest? + return false unless ref + commit = project.commit(ref) + return false unless commit + commit.sha == sha + end + + def triggered? + trigger_requests.any? + end + def create_builds(user, trigger_request = nil) return unless config_processor config_processor.stages.any? do |stage| diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index add59a08892f7d..adb652922085d2 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -1,28 +1,10 @@ -# == Schema Information -# -# Table name: ci_runners -# -# id :integer not null, primary key -# token :string -# created_at :datetime -# updated_at :datetime -# description :string -# contacted_at :datetime -# active :boolean default(TRUE), not null -# is_shared :boolean default(FALSE) -# name :string -# version :string -# revision :string -# platform :string -# architecture :string -# - module Ci class Runner < ActiveRecord::Base extend Ci::Model LAST_CONTACT_TIME = 5.minutes.ago - AVAILABLE_SCOPES = ['specific', 'shared', 'active', 'paused', 'online'] + AVAILABLE_SCOPES = %w[specific shared active paused online] + FORM_EDITABLE = %i[description tag_list active run_untagged] has_many :builds, class_name: 'Ci::Build' has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject' @@ -44,6 +26,8 @@ class Runner < ActiveRecord::Base .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end + validate :tag_constraints + acts_as_taggable # Searches for runners matching the given query. @@ -76,7 +60,7 @@ def assign_to(project, current_user = nil) end def display_name - return short_sha unless !description.blank? + return short_sha if description.blank? description end @@ -114,5 +98,18 @@ def only_for?(project) def short_sha token[0...8] if token end + + def has_tags? + tag_list.any? + end + + private + + def tag_constraints + unless has_tags? || run_untagged? + errors.add(:tags_list, + 'can not be empty when runner is not allowed to pick untagged jobs') + end + end end end diff --git a/app/models/ci/runner_project.rb b/app/models/ci/runner_project.rb index 7b16f207a265fe..4b44ffa886e6b8 100644 --- a/app/models/ci/runner_project.rb +++ b/app/models/ci/runner_project.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: ci_runner_projects -# -# id :integer not null, primary key -# runner_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# gl_project_id :integer -# - module Ci class RunnerProject < ActiveRecord::Base extend Ci::Model diff --git a/app/models/ci/trigger.rb b/app/models/ci/trigger.rb index 4f3f4d79fac836..a0b19b51a127a4 100644 --- a/app/models/ci/trigger.rb +++ b/app/models/ci/trigger.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: ci_triggers -# -# id :integer not null, primary key -# token :string -# project_id :integer -# deleted_at :datetime -# created_at :datetime -# updated_at :datetime -# gl_project_id :integer -# - module Ci class Trigger < ActiveRecord::Base extend Ci::Model diff --git a/app/models/ci/trigger_request.rb b/app/models/ci/trigger_request.rb index 9973d2e5ade0a8..872d5fb31de10f 100644 --- a/app/models/ci/trigger_request.rb +++ b/app/models/ci/trigger_request.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: ci_trigger_requests -# -# id :integer not null, primary key -# trigger_id :integer not null -# variables :text -# created_at :datetime -# updated_at :datetime -# commit_id :integer -# - module Ci class TriggerRequest < ActiveRecord::Base extend Ci::Model diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb index 4229fe085a1587..f8d5d4486fd43f 100644 --- a/app/models/ci/variable.rb +++ b/app/models/ci/variable.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: ci_variables -# -# id :integer not null, primary key -# project_id :integer -# key :string -# value :text -# encrypted_value :text -# encrypted_value_salt :string -# encrypted_value_iv :string -# gl_project_id :integer -# - module Ci class Variable < ActiveRecord::Base extend Ci::Model @@ -25,6 +11,9 @@ class Variable < ActiveRecord::Base format: { with: /\A[a-zA-Z0-9_]+\z/, message: "can contain only letters, digits and '_'." } - attr_encrypted :value, mode: :per_attribute_iv_and_salt, key: Gitlab::Application.secrets.db_key_base + attr_encrypted :value, + mode: :per_attribute_iv_and_salt, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' end end diff --git a/app/models/commit.rb b/app/models/commit.rb index 562c3ed15b2115..f96c7cb34d0cef 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -8,7 +8,10 @@ class Commit include StaticModel attr_mentionable :safe_message, pipeline: :single_line - participant :author, :committer, :notes + + participant :author + participant :committer + participant :notes_with_associations attr_accessor :project @@ -194,6 +197,10 @@ def notes project.notes.for_commit_id(self.id) end + def notes_with_associations + notes.includes(:author, :project) + end + def method_missing(m, *args, &block) @raw.send(m, *args, &block) end @@ -219,7 +226,7 @@ def status def revert_branch_name "revert-#{short_id}" end - + def cherry_pick_branch_name project.repository.next_branch("cherry-pick-#{short_id}", mild: true) end @@ -251,11 +258,13 @@ def merged_merge_request end def has_been_reverted?(current_user = nil, noteable = self) - Gitlab::ReferenceExtractor.lazily do - noteable.notes.system.flat_map do |note| - note.all_references(current_user).commits - end - end.any? { |commit_ref| commit_ref.reverts_commit?(self) } + ext = all_references(current_user) + + noteable.notes_with_associations.system.each do |note| + note.all_references(current_user, extractor: ext) + end + + ext.commits.any? { |commit_ref| commit_ref.reverts_commit?(self) } end def change_type_title diff --git a/app/models/commit_range.rb b/app/models/commit_range.rb index 51673897d98849..4066958f67c0b1 100644 --- a/app/models/commit_range.rb +++ b/app/models/commit_range.rb @@ -62,7 +62,7 @@ def self.link_reference_pattern def initialize(range_string, project) @project = project - range_string.strip! + range_string = range_string.strip unless range_string =~ /\A#{PATTERN}\z/ raise ArgumentError, "invalid CommitRange string format: #{range_string}" diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 1260c448de3533..f774b6e0efb2b3 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -1,40 +1,3 @@ -# == Schema Information -# -# Table name: ci_builds -# -# id :integer not null, primary key -# project_id :integer -# status :string -# finished_at :datetime -# trace :text -# created_at :datetime -# updated_at :datetime -# started_at :datetime -# runner_id :integer -# coverage :float -# commit_id :integer -# commands :text -# job_id :integer -# name :string -# deploy :boolean default(FALSE) -# options :text -# allow_failure :boolean default(FALSE), not null -# stage :string -# trigger_request_id :integer -# stage_idx :integer -# tag :boolean -# ref :string -# user_id :integer -# type :string -# target_url :string -# description :string -# artifacts_file :text -# gl_project_id :integer -# artifacts_metadata :text -# erased_by_id :integer -# erased_at :datetime -# - class CommitStatus < ActiveRecord::Base include Statuseable @@ -51,7 +14,8 @@ class CommitStatus < ActiveRecord::Base alias_attribute :author, :user scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :commit_id)) } - scope :ordered, -> { order(:ref, :stage_idx, :name) } + scope :retried, -> { where.not(id: latest) } + scope :ordered, -> { order(:name) } scope :ignored, -> { where(allow_failure: true, status: [:failed, :canceled]) } state_machine :status, initial: :pending do @@ -82,6 +46,10 @@ class CommitStatus < ActiveRecord::Base after_transition [:pending, :running] => :success do |commit_status| MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.commit.project, nil).trigger(commit_status) end + + after_transition any => :failed do |commit_status| + MergeRequests::AddTodoWhenBuildFailsService.new(commit_status.commit.project, nil).execute(commit_status) + end end delegate :sha, :short_sha, to: :commit @@ -91,13 +59,15 @@ def before_sha end def self.stages - order_by = 'max(stage_idx)' - group('stage').order(order_by).pluck(:stage, order_by).map(&:first).compact + # We group by stage name, but order stages by theirs' index + unscoped.from(all, :sg).group('stage').order('max(stage_idx)', 'stage').pluck('sg.stage') end def self.stages_status - all.stages.inject({}) do |h, stage| - h[stage] = all.where(stage: stage).status + # We execute subquery for each stage to calculate a stage status + statuses = unscoped.from(all, :sg).group('stage').pluck('sg.stage', all.where('stage=sg.stage').status_sql) + statuses.inject({}) do |h, k| + h[k.first] = k.last h end end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 2e4efc4e8d8101..e86d5236abbe80 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -31,18 +31,21 @@ module Issuable scope :unassigned, -> { where("assignee_id IS NULL") } scope :of_projects, ->(ids) { where(project_id: ids) } scope :of_milestones, ->(ids) { where(milestone_id: ids) } + scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) } scope :opened, -> { with_state(:opened, :reopened) } scope :only_opened, -> { with_state(:opened) } scope :only_reopened, -> { with_state(:reopened) } scope :closed, -> { with_state(:closed) } - scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') } - scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') } - 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 :left_joins_milestones, -> { joins("LEFT OUTER JOIN milestones ON #{table_name}.milestone_id = milestones.id") } + scope :order_milestone_due_desc, -> { left_joins_milestones.reorder('milestones.due_date IS NULL, milestones.id IS NULL, milestones.due_date DESC') } + scope :order_milestone_due_asc, -> { left_joins_milestones.reorder('milestones.due_date IS NULL, milestones.id IS NULL, milestones.due_date ASC') } + + 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 :references_project, -> { references(:project) } scope :non_archived, -> { join_project.where(projects: { archived: false }) } - scope :outer_join_milestone, -> { joins("LEFT OUTER JOIN milestones ON milestones.id = #{table_name}.milestone_id") } + delegate :name, :email, @@ -56,11 +59,23 @@ module Issuable prefix: true attr_mentionable :title, pipeline: :single_line - attr_mentionable :description, cache: true - participant :author, :assignee, :notes_with_associations + attr_mentionable :description + + participant :author + participant :assignee + participant :notes_with_associations + strip_attributes :title acts_as_paranoid + + after_save :update_assignee_cache_counts, if: :assignee_id_changed? + + def update_assignee_cache_counts + # make sure we flush the cache for both the old *and* new assignee + User.find(assignee_id_was).update_cache_counts if assignee_id_was + assignee.update_cache_counts if assignee + end end module ClassMethods @@ -123,13 +138,29 @@ def order_votes_desc(award_emoji_name) joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC") end - def with_label(title) - if title.is_a?(Array) && title.count > 1 - joins(:labels).where(labels: { title: title }).group('issues.id').having("count(distinct labels.title) = #{title.count}") + def with_label(title, sort = nil) + if title.is_a?(Array) && title.size > 1 + joins(:labels).where(labels: { title: title }).group(*grouping_columns(sort)).having("COUNT(DISTINCT labels.title) = #{title.size}") else joins(:labels).where(labels: { title: title }) end end + + # Includes table keys in group by clause when sorting + # preventing errors in postgres + # + # Returns an array of arel columns + def grouping_columns(sort) + grouping_columns = [arel_table[:id]] + + if ["milestone_due_desc", "milestone_due_asc"].include?(sort) + milestone_table = Milestone.arel_table + grouping_columns << milestone_table[:id] + grouping_columns << milestone_table[:due_date] + end + + grouping_columns + end end def today? @@ -160,6 +191,10 @@ def upvotes notes.awards.where(note: "thumbsup").count end + def user_notes_count + notes.user.count + end + def subscribed_without_subscriptions?(user) participants(user).include?(user) end @@ -178,6 +213,10 @@ def to_hook_data(user) hook_data end + def labels_array + labels.to_a + end + def label_names labels.order('title ASC').pluck(:title) end diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 98f71ae8cb04a5..f00b5b8497c13a 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -23,7 +23,7 @@ def mentionable_attrs included do if self < Participable - participant ->(current_user) { mentioned_users(current_user) } + participant -> (user, ext) { all_references(user, extractor: ext) } end end @@ -43,23 +43,22 @@ def local_reference self end - def all_references(current_user = self.author, text = nil) - ext = Gitlab::ReferenceExtractor.new(self.project, current_user, self.author) + def all_references(current_user = nil, text = nil, extractor: nil) + extractor ||= Gitlab::ReferenceExtractor. + new(project, current_user || author) if text - ext.analyze(text) + extractor.analyze(text, author: author) else self.class.mentionable_attrs.each do |attr, options| - text = send(attr) + text = __send__(attr) + options = options.merge(cache_key: [self, attr], author: author) - context = options.dup - context[:cache_key] = [self, attr] if context.delete(:cache) && self.persisted? - - ext.analyze(text, context) + extractor.analyze(text, options) end end - ext + extractor end def mentioned_users(current_user = nil) diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb index fc6f83b918b492..9056722f45e44f 100644 --- a/app/models/concerns/participable.rb +++ b/app/models/concerns/participable.rb @@ -3,8 +3,6 @@ # Contains functionality related to objects that can have participants, such as # an author, an assignee and people mentioned in its description or comments. # -# Used by Issue, Note, MergeRequest, Snippet and Commit. -# # Usage: # # class Issue < ActiveRecord::Base @@ -12,22 +10,36 @@ # # # ... # -# participant :author, :assignee, :notes, ->(current_user) { mentioned_users(current_user) } +# participant :author +# participant :assignee +# participant :notes +# +# participant -> (current_user, ext) do +# ext.analyze('...') +# end # end # # issue = Issue.last # users = issue.participants -# # `users` will contain the issue's author, its assignee, -# # all users returned by its #mentioned_users method, -# # as well as all participants to all of the issue's notes, -# # since Note implements Participable as well. -# module Participable extend ActiveSupport::Concern module ClassMethods - def participant(*attrs) - participant_attrs.concat(attrs) + # Adds a list of participant attributes. Attributes can either be symbols or + # Procs. + # + # When using a Proc instead of a Symbol the Proc will be given two + # arguments: + # + # 1. The current user (as an instance of User) + # 2. An instance of `Gitlab::ReferenceExtractor` + # + # It is expected that a Proc populates the given reference extractor + # instance with data. The return value of the Proc is ignored. + # + # attr - The name of the attribute or a Proc + def participant(attr) + participant_attrs << attr end def participant_attrs @@ -35,42 +47,42 @@ def participant_attrs end end - # Be aware that this method makes a lot of sql queries. - # Save result into variable if you are going to reuse it inside same request - def participants(current_user = self.author) - participants = - Gitlab::ReferenceExtractor.lazily do - self.class.participant_attrs.flat_map do |attr| - value = - if attr.respond_to?(:call) - instance_exec(current_user, &attr) - else - send(attr) - end + # Returns the users participating in a discussion. + # + # This method processes attributes of objects in breadth-first order. + # + # Returns an Array of User instances. + def participants(current_user = nil) + current_user ||= author + ext = Gitlab::ReferenceExtractor.new(project, current_user) + participants = Set.new + process = [self] - participants_for(value, current_user) - end.compact.uniq - end + until process.empty? + source = process.pop - unless Gitlab::ReferenceExtractor.lazy? - participants.select! do |user| - user.can?(:read_project, project) + case source + when User + participants << source + when Participable + source.class.participant_attrs.each do |attr| + if attr.respond_to?(:call) + source.instance_exec(current_user, ext, &attr) + else + process << source.__send__(attr) + end + end + when Enumerable, ActiveRecord::Relation + # This uses reverse_each so we can use "pop" to get the next value to + # process (in order). Using unshift instead of pop would require + # moving all Array values one index to the left (which can be + # expensive). + source.reverse_each { |obj| process << obj } end end - participants - end - - private + participants.merge(ext.users) - def participants_for(value, current_user = nil) - case value - when User, Banzai::LazyReference - [value] - when Enumerable, ActiveRecord::Relation - value.flat_map { |v| participants_for(v, current_user) } - when Participable - value.participants(current_user) - end + Ability.users_that_can_read_project(participants.to_a, project) end end diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index d5a881b24457f9..083257f1005330 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -36,6 +36,12 @@ def toggle_subscription(user) update(subscribed: !subscribed?(user)) end + def subscribe(user) + subscriptions. + find_or_initialize_by(user_id: user.id). + update(subscribed: true) + end + def unsubscribe(user) subscriptions. find_or_initialize_by(user_id: user.id). diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb index 43cf625f770aaf..2c525d4cd7a780 100644 --- a/app/models/deploy_key.rb +++ b/app/models/deploy_key.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string -# type :string -# fingerprint :string -# public :boolean default(FALSE), not null -# - class DeployKey < Key has_many :deploy_keys_projects, dependent: :destroy has_many :projects, through: :deploy_keys_projects diff --git a/app/models/deploy_keys_project.rb b/app/models/deploy_keys_project.rb index 18db521741fba8..ae8486bd9acd31 100644 --- a/app/models/deploy_keys_project.rb +++ b/app/models/deploy_keys_project.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: deploy_keys_projects -# -# id :integer not null, primary key -# deploy_key_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - class DeployKeysProject < ActiveRecord::Base belongs_to :project belongs_to :deploy_key diff --git a/app/models/email.rb b/app/models/email.rb index eae2472f337652..32a412ab878aed 100644 --- a/app/models/email.rb +++ b/app/models/email.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: emails -# -# id :integer not null, primary key -# user_id :integer not null -# email :string not null -# created_at :datetime -# updated_at :datetime -# - class Email < ActiveRecord::Base include Sortable diff --git a/app/models/event.rb b/app/models/event.rb index 25c7c3e6dc7814..716039fb54b953 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: events -# -# id :integer not null, primary key -# target_type :string -# target_id :integer -# title :string -# data :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# action :integer -# author_id :integer -# - class Event < ActiveRecord::Base include Sortable default_scope { where.not(author_id: nil) } @@ -96,7 +80,7 @@ def project_name end def target_title - target.title if target && target.respond_to?(:title) + target.try(:title) end def created? @@ -282,28 +266,20 @@ def last_push_to_non_root? branch? && project.default_branch != branch_name end - def note_commit_id - target.commit_id - end - def target_iid target.respond_to?(:iid) ? target.iid : target_id end - def note_short_commit_id - Commit.truncate_sha(note_commit_id) - end - - def note_commit? - target.noteable_type == "Commit" + def commit_note? + target.for_commit? end def issue_note? - note? && target && target.noteable_type == "Issue" + note? && target && target.for_issue? end - def note_project_snippet? - target.noteable_type == "Snippet" + def project_snippet_note? + target.for_snippet? end def note_target @@ -311,19 +287,22 @@ def note_target end def note_target_id - if note_commit? + if commit_note? target.commit_id else target.noteable_id.to_s end end - def note_target_iid - if note_target.respond_to?(:iid) - note_target.iid + def note_target_reference + return unless note_target + + # Commit#to_reference returns the full SHA, but we want the short one here + if commit_note? + note_target.short_id else - note_target_id - end.to_s + note_target.to_reference + end end def note_target_type diff --git a/app/models/forked_project_link.rb b/app/models/forked_project_link.rb index 9b0c6263a96ac6..9803bae0beec8d 100644 --- a/app/models/forked_project_link.rb +++ b/app/models/forked_project_link.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - class ForkedProjectLink < ActiveRecord::Base belongs_to :forked_to_project, class_name: Project belongs_to :forked_from_project, class_name: Project diff --git a/app/models/generic_commit_status.rb b/app/models/generic_commit_status.rb index d4afd8cbe84085..fa54e3540d07bd 100644 --- a/app/models/generic_commit_status.rb +++ b/app/models/generic_commit_status.rb @@ -1,40 +1,3 @@ -# == Schema Information -# -# Table name: ci_builds -# -# id :integer not null, primary key -# project_id :integer -# status :string -# finished_at :datetime -# trace :text -# created_at :datetime -# updated_at :datetime -# started_at :datetime -# runner_id :integer -# coverage :float -# commit_id :integer -# commands :text -# job_id :integer -# name :string -# deploy :boolean default(FALSE) -# options :text -# allow_failure :boolean default(FALSE), not null -# stage :string -# trigger_request_id :integer -# stage_idx :integer -# tag :boolean -# ref :string -# user_id :integer -# type :string -# target_url :string -# description :string -# artifacts_file :text -# gl_project_id :integer -# artifacts_metadata :text -# erased_by_id :integer -# erased_at :datetime -# - class GenericCommitStatus < CommitStatus before_validation :set_default_values diff --git a/app/models/group.rb b/app/models/group.rb index cff76877958f6c..aec92e335e63a3 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,20 +1,3 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string not null -# path :string not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string -# description :string default(""), not null -# avatar :string -# share_with_group_lock :boolean default(FALSE) -# visibility_level :integer default(20), not null -# - require 'carrierwave/orm/activerecord' class Group < Namespace diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb index 2b8f34a056844f..ba42a8eeb70bdd 100644 --- a/app/models/hooks/project_hook.rb +++ b/app/models/hooks/project_hook.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(2000) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# note_events :boolean default(FALSE), not null -# enable_ssl_verification :boolean default(TRUE) -# build_events :boolean default(FALSE), not null -# wiki_page_events :boolean default(FALSE), not null -# token :string -# - class ProjectHook < WebHook belongs_to :project diff --git a/app/models/hooks/service_hook.rb b/app/models/hooks/service_hook.rb index 0e176de5ef81b8..eef24052a064fa 100644 --- a/app/models/hooks/service_hook.rb +++ b/app/models/hooks/service_hook.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(2000) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# note_events :boolean default(FALSE), not null -# enable_ssl_verification :boolean default(TRUE) -# build_events :boolean default(FALSE), not null -# wiki_page_events :boolean default(FALSE), not null -# token :string -# - class ServiceHook < WebHook belongs_to :service diff --git a/app/models/hooks/system_hook.rb b/app/models/hooks/system_hook.rb index ad508cbbcb8a74..777bad1e724166 100644 --- a/app/models/hooks/system_hook.rb +++ b/app/models/hooks/system_hook.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(2000) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# note_events :boolean default(FALSE), not null -# enable_ssl_verification :boolean default(TRUE) -# build_events :boolean default(FALSE), not null -# wiki_page_events :boolean default(FALSE), not null -# token :string -# - class SystemHook < WebHook def async_execute(data, hook_name) Sidekiq::Client.enqueue(SystemHookWorker, id, data, hook_name) diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 8e58c9583abada..8b87b6c3d64fc1 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(2000) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# note_events :boolean default(FALSE), not null -# enable_ssl_verification :boolean default(TRUE) -# build_events :boolean default(FALSE), not null -# wiki_page_events :boolean default(FALSE), not null -# token :string -# - class WebHook < ActiveRecord::Base include Sortable include HTTParty @@ -60,7 +38,7 @@ def execute(data, hook_name) basic_auth: auth) end - [(response.code >= 200 && response.code < 300), ActionView::Base.full_sanitizer.sanitize(response.to_s)] + [response.code, response.to_s] rescue SocketError, OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e logger.error("WebHook Error => #{e}") [false, e.to_s] diff --git a/app/models/identity.rb b/app/models/identity.rb index ef4d5f99091bf1..3bacc450e6e6cf 100644 --- a/app/models/identity.rb +++ b/app/models/identity.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: identities -# -# id :integer not null, primary key -# extern_uid :string -# provider :string -# user_id :integer -# created_at :datetime -# updated_at :datetime -# - class Identity < ActiveRecord::Base include Sortable include CaseSensitivity diff --git a/app/models/issue.rb b/app/models/issue.rb index abaa509707c15d..bd0fbc96d18caa 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: issues -# -# id :integer not null, primary key -# title :string -# assignee_id :integer -# author_id :integer -# project_id :integer -# created_at :datetime -# updated_at :datetime -# position :integer default(0) -# branch_name :string -# description :text -# milestone_id :integer -# state :string -# iid :integer -# updated_by_id :integer -# moved_to_id :integer -# confidential :boolean default(FALSE) -# deleted_at :datetime -# due_date :date -# - require 'carrierwave/orm/activerecord' class Issue < ActiveRecord::Base @@ -119,14 +95,13 @@ def to_reference(from_project = nil) end def referenced_merge_requests(current_user = nil) - @referenced_merge_requests ||= {} - @referenced_merge_requests[current_user] ||= begin - Gitlab::ReferenceExtractor.lazily do - [self, *notes].flat_map do |note| - note.all_references(current_user).merge_requests - end - end.sort_by(&:iid).uniq + ext = all_references(current_user) + + notes_with_associations.each do |object| + object.all_references(current_user, extractor: ext) end + + ext.merge_requests.sort_by(&:iid) end # All branches containing the current issue's ID, except for @@ -163,9 +138,13 @@ def source_project def closed_by_merge_requests(current_user = nil) return [] unless open? - notes.system.flat_map do |note| - note.all_references(current_user).merge_requests - end.uniq.select { |mr| mr.open? && mr.closes_issue?(self) } + ext = all_references(current_user) + + notes.system.each do |note| + note.all_references(current_user, extractor: ext) + end + + ext.merge_requests.select { |mr| mr.open? && mr.closes_issue?(self) } end def moved? diff --git a/app/models/key.rb b/app/models/key.rb index b2b57849f8a55a..0532e84f47d0dc 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string -# type :string -# fingerprint :string -# public :boolean default(FALSE), not null -# - require 'digest/md5' class Key < ActiveRecord::Base @@ -41,7 +26,7 @@ def strip_white_space end def publishable_key - #Removes anything beyond the keytype and key itself + # Removes anything beyond the keytype and key itself self.key.split[0..1].join(' ') end diff --git a/app/models/label.rb b/app/models/label.rb index 9a22398d9523f4..e5ad11983bea14 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: labels -# -# id :integer not null, primary key -# title :string -# color :string -# project_id :integer -# created_at :datetime -# updated_at :datetime -# template :boolean default(FALSE) -# description :string -# - class Label < ActiveRecord::Base include Referable include Subscribable @@ -117,6 +103,10 @@ def text_color LabelsHelper::text_color_for_bg(self.color) end + def title=(value) + write_attribute(:title, Sanitize.clean(value.to_s)) if value.present? + end + private def label_format_reference(format = :id) diff --git a/app/models/label_link.rb b/app/models/label_link.rb index 7b8e872b6dd193..47bd6eaf35f91d 100644 --- a/app/models/label_link.rb +++ b/app/models/label_link.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string -# created_at :datetime -# updated_at :datetime -# - class LabelLink < ActiveRecord::Base belongs_to :target, polymorphic: true belongs_to :label diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb new file mode 100644 index 00000000000000..bbefc911b29ca4 --- /dev/null +++ b/app/models/legacy_diff_note.rb @@ -0,0 +1,157 @@ +class LegacyDiffNote < Note + serialize :st_diff + + validates :line_code, presence: true, line_code: true + + before_create :set_diff + + class << self + def build_discussion_id(noteable_type, noteable_id, line_code, active = true) + [super(noteable_type, noteable_id), line_code, active].join("-") + end + end + + def diff_note? + true + end + + def legacy_diff_note? + true + end + + def discussion_id + @discussion_id ||= self.class.build_discussion_id(noteable_type, noteable_id || commit_id, line_code, active?) + end + + def diff_file_hash + line_code.split('_')[0] if line_code + end + + def diff_old_line + line_code.split('_')[1].to_i if line_code + end + + def diff_new_line + line_code.split('_')[2].to_i if line_code + end + + def diff + @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map) + end + + def diff_file_path + diff.new_path.presence || diff.old_path + end + + def diff_lines + @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line) + end + + def diff_line + @diff_line ||= diff_lines.find { |line| generate_line_code(line) == self.line_code } + end + + def diff_line_text + diff_line.try(:text) + end + + def diff_line_type + diff_line.try(:type) + end + + def highlighted_diff_lines + Gitlab::Diff::Highlight.new(diff_lines).highlight + end + + def truncated_diff_lines + max_number_of_lines = 16 + prev_match_line = nil + prev_lines = [] + + highlighted_diff_lines.each do |line| + if line.type == "match" + prev_lines.clear + prev_match_line = line + else + prev_lines << line + + break if generate_line_code(line) == self.line_code + + prev_lines.shift if prev_lines.length >= max_number_of_lines + end + end + + prev_lines + end + + # Check if this note is part of an "active" discussion + # + # This will always return true for anything except MergeRequest noteables, + # which have special logic. + # + # If the note's current diff cannot be matched in the MergeRequest's current + # diff, it's considered inactive. + def active? + return @active if defined?(@active) + return true if for_commit? + return true unless self.diff + return false unless noteable + + noteable_diff = find_noteable_diff + + if noteable_diff + parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line) + + @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line_text } + else + @active = false + end + + @active + end + + private + + def find_diff + return nil unless noteable + return @diff if defined?(@diff) + + @diff = noteable.diffs(Commit.max_diff_options).find do |d| + d.new_path && Digest::SHA1.hexdigest(d.new_path) == diff_file_hash + end + end + + def set_diff + # First lets find notes with same diff + # before iterating over all mr diffs + diff = diff_for_line_code unless for_merge_request? + diff ||= find_diff + + self.st_diff = diff.to_hash if diff + end + + def diff_for_line_code + attributes = { + noteable_type: noteable_type, + line_code: line_code + } + + if for_commit? + attributes[:commit_id] = commit_id + else + attributes[:noteable_id] = noteable_id + end + + self.class.where(attributes).last.try(:diff) + end + + def generate_line_code(line) + Gitlab::Diff::LineCode.generate(diff_file_path, line.new_pos, line.old_pos) + end + + # Find the diff on noteable that matches our own + def find_noteable_diff + diffs = noteable.diffs(Commit.max_diff_options) + diffs.find { |d| d.new_path == self.diff.new_path } + end +end diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 927e764af92698..18657c3e1c893e 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: lfs_objects -# -# id :integer not null, primary key -# oid :string not null -# size :integer not null -# created_at :datetime -# updated_at :datetime -# file :string -# - class LfsObject < ActiveRecord::Base has_many :lfs_objects_projects, dependent: :destroy has_many :projects, through: :lfs_objects_projects diff --git a/app/models/lfs_objects_project.rb b/app/models/lfs_objects_project.rb index 890736bfc80bac..0fd5f089db9076 100644 --- a/app/models/lfs_objects_project.rb +++ b/app/models/lfs_objects_project.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: lfs_objects_projects -# -# id :integer not null, primary key -# lfs_object_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - class LfsObjectsProject < ActiveRecord::Base belongs_to :project belongs_to :lfs_object diff --git a/app/models/member.rb b/app/models/member.rb index cca82da89f1879..d3060f07fc0fec 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -1,22 +1,3 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string not null -# user_id :integer -# notification_level :integer not null -# type :string -# created_at :datetime -# updated_at :datetime -# created_by_id :integer -# invite_email :string -# invite_token :string -# invite_accepted_at :datetime -# - class Member < ActiveRecord::Base include Sortable include Gitlab::Access diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index a48c1943e6f86d..f63a0debf1a803 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -1,22 +1,3 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string not null -# user_id :integer -# notification_level :integer not null -# type :string -# created_at :datetime -# updated_at :datetime -# created_by_id :integer -# invite_email :string -# invite_token :string -# invite_accepted_at :datetime -# - class GroupMember < Member SOURCE_TYPE = 'Namespace' diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index 143350a0b55d8e..46955b430f35c2 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -1,22 +1,3 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string not null -# user_id :integer -# notification_level :integer not null -# type :string -# created_at :datetime -# updated_at :datetime -# created_by_id :integer -# invite_email :string -# invite_token :string -# invite_accepted_at :datetime -# - class ProjectMember < Member SOURCE_TYPE = 'Project' @@ -24,7 +5,6 @@ class ProjectMember < Member belongs_to :project, class_name: 'Project', foreign_key: 'source_id' - # 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/ @@ -34,6 +14,8 @@ class ProjectMember < Member scope :in_projects, ->(projects) { where(source_id: projects.pluck(:id)) } scope :with_user, ->(user) { where(user_id: user.id) } + before_destroy :delete_member_todos + class << self # Add users to project teams with passed access option @@ -121,6 +103,10 @@ def owner? private + def delete_member_todos + user.todos.where(project_id: source_id).destroy_all if user + end + def send_invite notification_service.invite_project_member(self, @raw_invite_token) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 4175e1e5fbabb9..722c258244c4e9 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -1,33 +1,3 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string not null -# source_branch :string not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string -# merge_status :string -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# updated_by_id :integer -# merge_error :string -# merge_params :text -# merge_when_build_succeeds :boolean default(FALSE), not null -# merge_user_id :integer -# merge_commit_sha :string -# deleted_at :datetime -# - class MergeRequest < ActiveRecord::Base include InternalId include Issuable @@ -56,6 +26,10 @@ class MergeRequest < ActiveRecord::Base # when creating new merge request attr_accessor :can_be_created, :compare_commits, :compare + # Temporary fields to store target_sha, and base_sha to + # compare when importing pull requests from GitHub + attr_accessor :base_target_sha, :head_source_sha + state_machine :state, initial: :opened do event :close do transition [:reopened, :opened] => :closed @@ -312,6 +286,18 @@ def can_remove_source_branch?(current_user) last_commit == source_project.commit(source_branch) end + def should_remove_source_branch? + merge_params['should_remove_source_branch'].present? + end + + def force_remove_source_branch? + merge_params['force_remove_source_branch'].present? + end + + def remove_source_branch? + should_remove_source_branch? || force_remove_source_branch? + end + def mr_and_commit_notes # Fetch comments only from last 100 commits commits_for_notes_limit = 100 @@ -452,7 +438,10 @@ def reset_merge_when_build_succeeds self.merge_when_build_succeeds = false self.merge_user = nil - self.merge_params = nil + if merge_params + merge_params.delete('should_remove_source_branch') + merge_params.delete('commit_message') + end self.save end @@ -520,10 +509,14 @@ def state_icon_name end def target_sha - @target_sha ||= target_project.repository.commit(target_branch).try(:sha) + return @base_target_sha if defined?(@base_target_sha) + + target_project.repository.commit(target_branch).try(:sha) end def source_sha + return @head_source_sha if defined?(@head_source_sha) + last_commit.try(:sha) || source_tip.try(:sha) end @@ -544,7 +537,7 @@ def ref_path end def ref_is_fetched? - File.exists?(File.join(project.repository.path_to_repo, ref_path)) + File.exist?(File.join(project.repository.path_to_repo, ref_path)) end def ensure_ref_fetched diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 8951e92a0b87dc..7d5103748f567d 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: merge_request_diffs -# -# id :integer not null, primary key -# state :string -# st_commits :text -# st_diffs :text -# merge_request_id :integer not null -# created_at :datetime -# updated_at :datetime -# base_commit_sha :string -# real_size :string -# - class MergeRequestDiff < ActiveRecord::Base include Sortable @@ -21,7 +6,7 @@ class MergeRequestDiff < ActiveRecord::Base belongs_to :merge_request - delegate :target_branch, :source_branch, to: :merge_request, prefix: nil + delegate :head_source_sha, :target_branch, :source_branch, to: :merge_request, prefix: nil state_machine :state, initial: :empty do state :collected @@ -53,8 +38,8 @@ def diffs(options={}) @diffs_no_whitespace ||= begin compare = Gitlab::Git::Compare.new( self.repository.raw_repository, - self.target_branch, - self.source_sha, + self.base, + self.head, ) compare.diffs(options) end @@ -113,9 +98,7 @@ def unmerged_commits commits = compare.commits if commits.present? - commits = Commit.decorate(commits, merge_request.source_project). - sort_by(&:created_at). - reverse + commits = Commit.decorate(commits, merge_request.source_project).reverse end commits @@ -159,7 +142,7 @@ def reload_diffs self.st_diffs = new_diffs - self.base_commit_sha = self.repository.merge_base(self.source_sha, self.target_branch) + self.base_commit_sha = self.repository.merge_base(self.head, self.base) self.save end @@ -175,10 +158,24 @@ def repository end def source_sha + return head_source_sha if head_source_sha.present? + source_commit = merge_request.source_project.commit(source_branch) source_commit.try(:sha) end + def target_sha + merge_request.target_sha + end + + def base + self.target_sha || self.target_branch + end + + def head + self.source_sha + end + def compare @compare ||= begin @@ -187,8 +184,8 @@ def compare Gitlab::Git::Compare.new( self.repository.raw_repository, - self.target_branch, - self.source_sha + self.base, + self.head ) end end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 5ee8a965ad8bea..e0c8454a998573 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: milestones -# -# id :integer not null, primary key -# title :string not null -# project_id :integer not null -# description :text -# due_date :date -# created_at :datetime -# updated_at :datetime -# state :string -# iid :integer -# - class Milestone < ActiveRecord::Base # Represents a "No Milestone" state used for filtering Issues and Merge # Requests that have no milestone assigned. @@ -74,25 +59,67 @@ def search(query) end end + def self.reference_prefix + '%' + end + def self.reference_pattern - nil + # NOTE: The iid pattern only matches when all characters on the expression + # are digits, so it will match %2 but not %2.1 because that's probably a + # milestone name and we want it to be matched as such. + @reference_pattern ||= %r{ + (#{Project.reference_pattern})? + #{Regexp.escape(reference_prefix)} + (?: + (? + \d+(?!\S\w)\b # Integer-based milestone iid, or + ) | + (? + [^"\s]+\b | # String-based single-word milestone title, or + "[^"]+" # String-based multi-word milestone surrounded in quotes + ) + ) + }x end def self.link_reference_pattern @link_reference_pattern ||= super("milestones", /(?\d+)/) end - def self.upcoming - self.where('due_date > ?', Time.now).reorder(due_date: :asc).first - end + def self.upcoming_ids_by_projects(projects) + rel = unscoped.of_projects(projects).active.where('due_date > ?', Time.now) - def to_reference(from_project = nil) - escaped_title = self.title.gsub("]", "\\]") + 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) + end + end - h = Gitlab::Routing.url_helpers - url = h.namespace_project_milestone_url(self.project.namespace, self.project, self) + ## + # Returns the String necessary to reference this Milestone in Markdown + # + # format - Symbol format to use (default: :iid, optional: :name) + # + # Examples: + # + # Milestone.first.to_reference # => "%1" + # Milestone.first.to_reference(format: :name) # => "%\"goal\"" + # Milestone.first.to_reference(project) # => "gitlab-org/gitlab-ce%1" + # + def to_reference(from_project = nil, format: :iid) + format_reference = milestone_format_reference(format) + reference = "#{self.class.reference_prefix}#{format_reference}" - "[#{escaped_title}](#{url})" + if cross_project_reference?(from_project) + project.to_reference + reference + else + reference + end end def reference_link_text(from_project = nil) @@ -129,6 +156,10 @@ def author_id nil end + def title=(value) + write_attribute(:title, Sanitize.clean(value.to_s)) if value.present? + end + # Sorts the issues for the given IDs. # # This method runs a single SQL query using a CASE statement to update the @@ -160,4 +191,16 @@ def sort_issues(ids) issues.where(id: ids). update_all(["position = CASE #{conditions} ELSE position END", *pairs]) end + + private + + def milestone_format_reference(format = :iid) + raise ArgumentError, 'Unknown format' unless [:iid, :name].include?(format) + + if format == :name && !name.include?('"') + %("#{name}") + else + iid + end + end end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 741e912171d5d2..da19462f2652ff 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -1,20 +1,3 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string not null -# path :string not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string -# description :string default(""), not null -# avatar :string -# share_with_group_lock :boolean default(FALSE) -# visibility_level :integer default(20), not null -# - class Namespace < ActiveRecord::Base include Sortable include Gitlab::ShellAdapter @@ -127,6 +110,10 @@ def move_dir # Ensure old directory exists before moving it gitlab_shell.add_namespace(path_was) + if any_project_has_container_registry_tags? + raise Exception.new('Namespace cannot be moved, because at least one project has tags in container registry') + end + if gitlab_shell.mv_namespace(path_was, path) Gitlab::UploadsTransfer.new.rename_namespace(path_was, path) @@ -148,6 +135,10 @@ def move_dir end end + def any_project_has_container_registry_tags? + projects.any?(&:has_container_registry_tags?) + end + def send_update_instructions projects.each do |project| project.send_move_instructions("#{path_was}/#{project.path}") diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index f4e90125373dba..a2aee2f925bca3 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -22,9 +22,16 @@ def initialize(project, ref, commit, filter_ref) 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| - h[item.commit_id] = item.note_count.to_i - end + + @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 + h end @@ -89,7 +96,7 @@ def count_to_display_commit_in_center end end - if self.class.max_count / 2 < offset then + if self.class.max_count / 2 < offset # get max index that commit is displayed in the center. offset - self.class.max_count / 2 else @@ -130,7 +137,7 @@ def find_free_parent_spaces(commit) commit.parents(@map).each do |parent| range = commit.time..parent.time - space = if commit.space >= parent.space then + space = if commit.space >= parent.space find_free_parent_space(range, parent.space, -1, commit.space) else find_free_parent_space(range, commit.space, -1, parent.space) @@ -144,7 +151,7 @@ def find_free_parent_spaces(commit) end def find_free_parent_space(range, space_base, space_step, space_default) - if is_overlap?(range, space_default) then + if is_overlap?(range, space_default) find_free_space(range, space_step, space_base, space_default) else space_default @@ -155,9 +162,9 @@ def is_overlap?(range, overlap_space) range.each do |i| if i != range.first && i != range.last && - @commits[i].spaces.include?(overlap_space) then + @commits[i].spaces.include?(overlap_space) - return true; + return true end end @@ -198,7 +205,7 @@ def place_chain(commit, parent_time = nil) # Visit branching chains leaves.each do |l| parents = l.parents(@map).select{|p| p.space.zero?} - for p in parents + parents.each do |p| place_chain(p, l.time) end end @@ -216,7 +223,7 @@ def get_space_base(leaves) end def mark_reserved(time_range, space) - for day in time_range + time_range.each do |day| @reserved[day].push(space) end end @@ -225,15 +232,15 @@ def find_free_space(time_range, space_step, space_base = 1, space_default = nil) space_default ||= space_base reserved = [] - for day in time_range + time_range.each do |day| reserved.push(*@reserved[day]) end reserved.uniq! space = space_default - while reserved.include?(space) do + while reserved.include?(space) space += space_step - if space < space_base then + if space < space_base space_step *= -1 space = space_base + space_step end @@ -253,7 +260,7 @@ def take_left_leaves(raw_commit) leaves = [] leaves.push(commit) if commit.space.zero? - while true + loop do return leaves if commit.parents(@map).count.zero? commit = commit.parents(@map).first diff --git a/app/models/note.rb b/app/models/note.rb index deee2b9e8854cf..c21981ead84392 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -1,34 +1,12 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string -# line_code :string -# commit_id :string -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# updated_by_id :integer -# is_award :boolean default(FALSE), not null -# - -require 'carrierwave/orm/activerecord' - class Note < ActiveRecord::Base + extend ActiveModel::Naming include Gitlab::CurrentSettings include Participable include Mentionable default_value_for :system, false - attr_mentionable :note, cache: true, pipeline: :note + attr_mentionable :note, pipeline: :note participant :author belongs_to :project @@ -41,29 +19,33 @@ class Note < ActiveRecord::Base delegate :gfm_reference, :local_reference, to: :noteable delegate :name, to: :project, prefix: true delegate :name, :email, to: :author, prefix: true + delegate :title, to: :noteable, allow_nil: true before_validation :set_award! - before_validation :clear_blank_line_code! validates :note, :project, presence: true validates :note, uniqueness: { scope: [:author, :noteable_type, :noteable_id] }, if: ->(n) { n.is_award } validates :note, inclusion: { in: Emoji.emojis_names }, if: ->(n) { n.is_award } - validates :line_code, line_code: true, allow_blank: true # Attachments are deprecated and are handled by Markdown uploader validates :attachment, file_size: { maximum: :max_attachment_size } - validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' } - validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' } + validates :noteable_type, presence: true + validates :noteable_id, presence: true, unless: :for_commit? + validates :commit_id, presence: true, if: :for_commit? validates :author, presence: true + validate unless: :for_commit? do |note| + unless note.noteable.try(:project) == note.project + errors.add(:invalid_project, 'Note and noteable project mismatch') + end + end + mount_uploader :attachment, AttachmentUploader # Scopes scope :awards, ->{ where(is_award: true) } scope :nonawards, ->{ where(is_award: false) } scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) } - scope :inline, ->{ where("line_code IS NOT NULL") } - scope :not_inline, ->{ where(line_code: nil) } scope :system, ->{ where(system: true) } scope :user, ->{ where(system: false) } scope :common, ->{ where(noteable_type: ["", nil]) } @@ -71,52 +53,61 @@ class Note < ActiveRecord::Base scope :inc_author_project, ->{ includes(:project, :author) } scope :inc_author, ->{ includes(:author) } + scope :legacy_diff_notes, ->{ where(type: 'LegacyDiffNote') } + scope :non_diff_notes, ->{ where(type: ['Note', nil]) } + scope :with_associations, -> do includes(:author, :noteable, :updated_by, project: [:project_members, { group: [:group_members] }]) end - serialize :st_diff - before_create :set_diff, if: ->(n) { n.line_code.present? } + before_validation :clear_blank_line_code! class << self - def discussions_from_notes(notes) - discussion_ids = [] - discussions = [] - - notes.each do |note| - next if discussion_ids.include?(note.discussion_id) - - # don't group notes for the main target - if !note.for_diff_line? && note.for_merge_request? - discussions << [note] - else - discussions << notes.select do |other_note| - note.discussion_id == other_note.discussion_id - end - discussion_ids << note.discussion_id - end - end + def model_name + ActiveModel::Name.new(self, nil, 'note') + end + + def build_discussion_id(noteable_type, noteable_id) + [:discussion, noteable_type.try(:underscore), noteable_id].join("-") + end - discussions + def discussions + all.group_by(&:discussion_id).values end - def build_discussion_id(type, id, line_code) - [:discussion, type.try(:underscore), id, line_code].join("-").to_sym + def grouped_diff_notes + legacy_diff_notes.select(&:active?).sort_by(&:created_at).group_by(&:line_code) end # Searches for notes matching the given query. # # This method uses ILIKE on PostgreSQL and LIKE on MySQL. # - # query - The search query as a String. + # query - The search query as a String. + # as_user - Limit results to those viewable by a specific user # # Returns an ActiveRecord::Relation. - def search(query) + def search(query, as_user: nil) table = arel_table pattern = "%#{query}%" - where(table[:note].matches(pattern)) + found_notes = joins('LEFT JOIN issues ON issues.id = noteable_id'). + where(table[:note].matches(pattern)) + + if as_user + found_notes.where(' + issues.confidential IS NULL + OR issues.confidential IS FALSE + OR (issues.confidential IS TRUE + AND (issues.author_id = :user_id + OR issues.assignee_id = :user_id + OR issues.project_id IN(:project_ids)))', + user_id: as_user.id, + project_ids: as_user.authorized_projects.select(:id)) + else + found_notes.where('issues.confidential IS NULL OR issues.confidential IS FALSE') + end end def grouped_awards @@ -137,167 +128,39 @@ def cross_reference? system && SystemNoteService.cross_reference?(note) end - def max_attachment_size - current_application_settings.max_attachment_size.megabytes.to_i - end - - def find_diff - return nil unless noteable - return @diff if defined?(@diff) - - # Don't use ||= because nil is a valid value for @diff - @diff = noteable.diffs(Commit.max_diff_options).find do |d| - Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path - end + def diff_note? + false end - def hook_attrs - attributes + def legacy_diff_note? + false end - def set_diff - # First lets find notes with same diff - # before iterating over all mr diffs - diff = diff_for_line_code unless for_merge_request? - diff ||= find_diff - - self.st_diff = diff.to_hash if diff - end - - def diff - @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map) - end - - def diff_for_line_code - Note.where(noteable_id: noteable_id, noteable_type: noteable_type, line_code: line_code).last.try(:diff) - end - - # Check if this note is part of an "active" discussion - # - # This will always return true for anything except MergeRequest noteables, - # which have special logic. - # - # If the note's current diff cannot be matched in the MergeRequest's current - # diff, it's considered inactive. def active? - return true unless self.diff - return false unless noteable - return @active if defined?(@active) - - noteable_diff = find_noteable_diff - - if noteable_diff - parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line) - - @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line } - else - @active = false - end - - @active - end - - def diff_file_index - line_code.split('_')[0] if line_code - end - - def diff_file_name - diff.new_path if diff - end - - def file_path - if diff.new_path.present? - diff.new_path - elsif diff.old_path.present? - diff.old_path - end - end - - def diff_old_line - line_code.split('_')[1].to_i if line_code - end - - def diff_new_line - line_code.split('_')[2].to_i if line_code + true end - def generate_line_code(line) - Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos) - end - - def diff_line - return @diff_line if @diff_line - - if diff - diff_lines.each do |line| - if generate_line_code(line) == self.line_code - @diff_line = line.text - end - end - end - - @diff_line - end - - def diff_line_type - return @diff_line_type if @diff_line_type - - if diff - diff_lines.each do |line| - if generate_line_code(line) == self.line_code - @diff_line_type = line.type - end - end - end - - @diff_line_type - end - - def truncated_diff_lines - max_number_of_lines = 16 - prev_match_line = nil - prev_lines = [] - - highlighted_diff_lines.each do |line| - if line.type == "match" - prev_lines.clear - prev_match_line = line + def discussion_id + @discussion_id ||= + if for_merge_request? + [:discussion, :note, id].join("-") else - prev_lines << line - - break if generate_line_code(line) == self.line_code - - prev_lines.shift if prev_lines.length >= max_number_of_lines + self.class.build_discussion_id(noteable_type, noteable_id || commit_id) end - end - - prev_lines end - def diff_lines - @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line) - end - - def highlighted_diff_lines - Gitlab::Diff::Highlight.new(diff_lines).highlight + def max_attachment_size + current_application_settings.max_attachment_size.megabytes.to_i end - def discussion_id - @discussion_id ||= Note.build_discussion_id(noteable_type, noteable_id || commit_id, line_code) + def hook_attrs + attributes end def for_commit? noteable_type == "Commit" end - def for_commit_diff_line? - for_commit? && for_diff_line? - end - - def for_diff_line? - line_code.present? - end - def for_issue? noteable_type == "Issue" end @@ -306,10 +169,6 @@ def for_merge_request? noteable_type == "MergeRequest" end - def for_merge_request_diff_line? - for_merge_request? && for_diff_line? - end - def for_snippet? noteable_type == "Snippet" end @@ -382,14 +241,8 @@ def clear_blank_line_code! self.line_code = nil if self.line_code.blank? end - # Find the diff on noteable that matches our own - def find_noteable_diff - diffs = noteable.diffs(Commit.max_diff_options) - diffs.find { |d| d.new_path == self.diff.new_path } - end - def awards_supported? - (for_issue? || for_merge_request?) && !for_diff_line? + (for_issue? || for_merge_request?) && !diff_note? end def contains_emoji_only? diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index 846773752a67f0..5001738f411f43 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: notification_settings -# -# id :integer not null, primary key -# user_id :integer not null -# source_id :integer not null -# source_type :string not null -# level :integer default(0), not null -# created_at :datetime not null -# updated_at :datetime not null -# - class NotificationSetting < ActiveRecord::Base enum level: { disabled: 0, participating: 1, watch: 2, global: 3, mention: 4 } diff --git a/app/models/oauth_access_token.rb b/app/models/oauth_access_token.rb index c78c7f4aa0e3eb..116fb71ac083e2 100644 --- a/app/models/oauth_access_token.rb +++ b/app/models/oauth_access_token.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: oauth_access_tokens -# -# id :integer not null, primary key -# resource_owner_id :integer -# application_id :integer -# token :string not null -# refresh_token :string -# expires_in :integer -# revoked_at :datetime -# created_at :datetime not null -# scopes :string -# - class OauthAccessToken < ActiveRecord::Base belongs_to :resource_owner, class_name: 'User' belongs_to :application, class_name: 'Doorkeeper::Application' diff --git a/app/models/personal_snippet.rb b/app/models/personal_snippet.rb index 1d5f4c50254f6f..82c1c4de3a0fcb 100644 --- a/app/models/personal_snippet.rb +++ b/app/models/personal_snippet.rb @@ -1,18 +1,2 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string -# type :string -# visibility_level :integer default(0), not null -# - class PersonalSnippet < Snippet end diff --git a/app/models/project.rb b/app/models/project.rb index fdbabc7cf710b8..74db163bcb594d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,48 +1,3 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string -# path :string -# description :text -# created_at :datetime -# updated_at :datetime -# creator_id :integer -# issues_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# namespace_id :integer -# issues_tracker :string default("gitlab"), not null -# issues_tracker_id :string -# snippets_enabled :boolean default(TRUE), not null -# last_activity_at :datetime -# import_url :string -# visibility_level :integer default(0), not null -# archived :boolean default(FALSE), not null -# avatar :string -# import_status :string -# repository_size :float default(0.0) -# star_count :integer default(0), not null -# import_type :string -# import_source :string -# commit_count :integer default(0) -# import_error :text -# ci_id :integer -# builds_enabled :boolean default(TRUE), not null -# shared_runners_enabled :boolean default(TRUE), not null -# runners_token :string -# build_coverage_regex :string -# build_allow_git_fetch :boolean default(TRUE), not null -# build_timeout :integer default(3600), not null -# pending_delete :boolean default(FALSE) -# public_builds :boolean default(TRUE), not null -# main_language :string -# pushes_since_gc :integer default(0) -# last_repository_check_failed :boolean -# last_repository_check_at :datetime -# - require 'carrierwave/orm/activerecord' class Project < ActiveRecord::Base @@ -67,6 +22,7 @@ class Project < ActiveRecord::Base default_value_for :builds_enabled, gitlab_config_features.builds default_value_for :wiki_enabled, gitlab_config_features.wiki default_value_for :snippets_enabled, gitlab_config_features.snippets + default_value_for :container_registry_enabled, gitlab_config_features.container_registry default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled } # set last_activity_at to the same as created_at @@ -94,6 +50,8 @@ def update_forks_visibility_level attr_accessor :new_default_branch attr_accessor :old_path_with_namespace + alias_attribute :title, :name + # Relations belongs_to :creator, foreign_key: 'creator_id', class_name: 'User' belongs_to :group, -> { where(type: Group) }, foreign_key: 'namespace_id' @@ -213,17 +171,17 @@ def update_forks_visibility_level scope :sorted_by_activity, -> { reorder(last_activity_at: :desc) } scope :sorted_by_stars, -> { reorder('projects.star_count DESC') } - scope :sorted_by_names, -> { joins(:namespace).reorder('namespaces.name ASC, projects.name ASC') } - scope :without_user, ->(user) { where('projects.id NOT IN (:ids)', ids: user.authorized_projects.map(&:id) ) } - scope :without_team, ->(team) { team.projects.present? ? where('projects.id NOT IN (:ids)', ids: team.projects.map(&:id)) : scoped } - scope :not_in_group, ->(group) { where('projects.id NOT IN (:ids)', ids: group.project_ids ) } scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) } - scope :in_group_namespace, -> { joins(:group) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) } + scope :visible_to_user, ->(user) { where(id: user.authorized_projects.select(:id).reorder(nil)) } scope :non_archived, -> { where(archived: false) } scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct } + scope :with_push, -> { joins(:events).where('events.action = ?', Event::PUSHED) } + + scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') } + scope :abandoned, -> { where('projects.last_activity_at < ?', 6.months.ago) } state_machine :import_status, initial: :none do event :import_start do @@ -246,23 +204,10 @@ def update_forks_visibility_level state :finished state :failed - after_transition any => :started, do: :schedule_add_import_job - after_transition any => :finished, do: :clear_import_data + after_transition any => :finished, do: :reset_cache_and_import_attrs end class << self - def abandoned - where('projects.last_activity_at < ?', 6.months.ago) - end - - def with_push - joins(:events).where('events.action = ?', Event::PUSHED) - end - - def active - joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') - end - # Searches for a list of projects based on the query given in `query`. # # On PostgreSQL this method uses "ILIKE" to perform a case-insensitive @@ -324,10 +269,6 @@ def find_with_namespace(id) projects.iwhere('projects.path' => project_path).take end - def find_by_ci_id(id) - find_by(ci_id: id.to_i) - end - def visibility_levels Gitlab::VisibilityLevel.options end @@ -358,10 +299,6 @@ def trending(since = 1.month.ago) joins(join_body).reorder('join_note_counts.amount DESC') end - - def visible_to_user(user) - where(id: user.authorized_projects.select(:id).reorder(nil)) - end end def team @@ -372,6 +309,34 @@ def repository @repository ||= Repository.new(path_with_namespace, self) end + def container_registry_path_with_namespace + path_with_namespace.downcase + end + + def container_registry_repository + return unless Gitlab.config.registry.enabled + + @container_registry_repository ||= begin + token = Auth::ContainerRegistryAuthenticationService.full_access_token(container_registry_path_with_namespace) + url = Gitlab.config.registry.api_url + host_port = Gitlab.config.registry.host_port + registry = ContainerRegistry::Registry.new(url, token: token, path: host_port) + registry.repository(container_registry_path_with_namespace) + end + end + + def container_registry_repository_url + if Gitlab.config.registry.enabled + "#{Gitlab.config.registry.host_port}/#{container_registry_path_with_namespace}" + end + end + + def has_container_registry_tags? + return unless container_registry_repository + + container_registry_repository.tags.any? + end + def commit(id = 'HEAD') repository.commit(id) end @@ -385,10 +350,6 @@ def saved? id && persisted? end - def schedule_add_import_job - run_after_commit(:add_import_job) - end - def add_import_job if forked? job_id = RepositoryForkWorker.perform_async(self.id, forked_from_project.path_with_namespace, self.namespace.path) @@ -403,7 +364,7 @@ def add_import_job end end - def clear_import_data + def reset_cache_and_import_attrs update(import_error: nil) ProjectCacheWorker.perform_async(self.id) @@ -412,14 +373,14 @@ def clear_import_data end def import_url=(value) - import_url = Gitlab::ImportUrl.new(value) + import_url = Gitlab::UrlSanitizer.new(value) create_or_update_import_data(credentials: import_url.credentials) super(import_url.sanitized_url) end def import_url if import_data && super - import_url = Gitlab::ImportUrl.new(super, credentials: import_data.credentials) + import_url = Gitlab::UrlSanitizer.new(super, credentials: import_data.credentials) import_url.full_url else super @@ -469,17 +430,18 @@ def import_finished? end def safe_import_url - result = URI.parse(self.import_url) - result.password = '*****' unless result.password.nil? - result.user = '*****' unless result.user.nil? || result.user == "git" #tokens or other data may be saved as user - result.to_s - rescue - self.import_url + Gitlab::UrlSanitizer.new(import_url).masked_url end def check_limit unless creator.can_create_project? or namespace.kind == 'group' - self.errors.add(:limit_reached, "Your project limit is #{creator.projects_limit} projects! Please contact your administrator to increase it") + projects_limit = creator.projects_limit + + if projects_limit == 0 + self.errors.add(:limit_reached, "Personal project creation is not allowed. Please contact your administrator with questions") + else + self.errors.add(:limit_reached, "Your project limit is #{projects_limit} projects! Please contact your administrator to increase it") + end end rescue self.errors.add(:base, "Can't check your ability to create project") @@ -787,6 +749,11 @@ def rename_repo expire_caches_before_rename(old_path_with_namespace) + if has_container_registry_tags? + # we currently doesn't support renaming repository if it contains tags in container registry + raise Exception.new('Project cannot be renamed, because tags are present in its container registry') + end + if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace) # If repository moved successfully we need to send update instructions to users. # However we cannot allow rollback since we moved repository @@ -983,13 +950,13 @@ def any_runners?(&block) shared_runners_enabled? && Ci::Runner.shared.active.any?(&block) end - def valid_runners_token? token + def valid_runners_token?(token) self.runners_token && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.runners_token) end # TODO (ayufan): For now we use runners_token (backward compatibility) # In 8.4 every build will have its own individual token valid for time of build - def valid_build_token? token + def valid_build_token?(token) self.builds_enabled? && self.runners_token && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.runners_token) end @@ -1045,6 +1012,24 @@ def schedule_delete!(user_id, params) update_attribute(:pending_delete, true) end + def running_or_pending_build_count(force: false) + Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do + builds.running_or_pending.count(:all) + end + end + + def mark_import_as_failed(error_message) + original_errors = errors.dup + sanitized_message = Gitlab::UrlSanitizer.sanitize(error_message) + + import_fail + update_column(:import_error, sanitized_message) + rescue ActiveRecord::ActiveRecordError => e + Rails.logger.error("Error setting import status to failed: #{e.message}. Original error: #{sanitized_message}") + ensure + @errors = original_errors + end + def add_export_job(current_user_id:) job_id = ProjectExportWorker.perform_async(current_user_id, self.id) diff --git a/app/models/project_group_link.rb b/app/models/project_group_link.rb index 66f5a609bf5f30..e52a6bd7c8473b 100644 --- a/app/models/project_group_link.rb +++ b/app/models/project_group_link.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: project_group_links -# -# id :integer not null, primary key -# project_id :integer not null -# group_id :integer not null -# created_at :datetime -# updated_at :datetime -# group_access :integer default(30), not null -# - class ProjectGroupLink < ActiveRecord::Base GUEST = 10 REPORTER = 20 diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb index 7830f764ed3f18..ca8a9b4217b6e5 100644 --- a/app/models/project_import_data.rb +++ b/app/models/project_import_data.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: project_import_data -# -# id :integer not null, primary key -# project_id :integer -# data :text -# encrypted_credentials :text -# encrypted_credentials_iv :string -# encrypted_credentials_salt :string -# - require 'carrierwave/orm/activerecord' class ProjectImportData < ActiveRecord::Base @@ -18,7 +6,8 @@ class ProjectImportData < ActiveRecord::Base key: Gitlab::Application.secrets.db_key_base, marshal: true, encode: true, - mode: :per_attribute_iv_and_salt + mode: :per_attribute_iv_and_salt, + algorithm: 'aes-256-cbc' serialize :data, JSON diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb index 368485a060aa8e..7c23b76676374c 100644 --- a/app/models/project_services/asana_service.rb +++ b/app/models/project_services/asana_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - require 'asana' class AsanaService < Service diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb index ffb7455b0143db..d839221d315e04 100644 --- a/app/models/project_services/assembla_service.rb +++ b/app/models/project_services/assembla_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class AssemblaService < Service include HTTParty diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb index c36ee95e37801e..1d1780dcfbf3e2 100644 --- a/app/models/project_services/bamboo_service.rb +++ b/app/models/project_services/bamboo_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class BambooService < CiService include HTTParty diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb index f9f4897a065f02..86a06321e212d4 100644 --- a/app/models/project_services/buildkite_service.rb +++ b/app/models/project_services/buildkite_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - require "addressable/uri" class BuildkiteService < CiService diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb index 20cdfcaffb210e..54da4d74fc5b21 100644 --- a/app/models/project_services/builds_email_service.rb +++ b/app/models/project_services/builds_email_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class BuildsEmailService < Service prop_accessor :recipients boolean_accessor :add_pusher diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb index 28c969fe57f3f1..511b2eac792dbd 100644 --- a/app/models/project_services/campfire_service.rb +++ b/app/models/project_services/campfire_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class CampfireService < Service prop_accessor :token, :subdomain, :room validates :token, presence: true, if: :activated? diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb index 9bc8f982da614a..596c00705adcba 100644 --- a/app/models/project_services/ci_service.rb +++ b/app/models/project_services/ci_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - # Base class for CI services # List methods you need to implement to get your CI service # working with GitLab Merge Requests diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb index 4d1319eb6f8329..6b2b1daa724bab 100644 --- a/app/models/project_services/custom_issue_tracker_service.rb +++ b/app/models/project_services/custom_issue_tracker_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class CustomIssueTrackerService < IssueTrackerService prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb index d8e00e018cc562..966dbc41d737ed 100644 --- a/app/models/project_services/drone_ci_service.rb +++ b/app/models/project_services/drone_ci_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class DroneCiService < CiService prop_accessor :drone_url, :token, :enable_ssl_verification diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb index 2dbd29062dfac6..e0083c43adb260 100644 --- a/app/models/project_services/emails_on_push_service.rb +++ b/app/models/project_services/emails_on_push_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class EmailsOnPushService < Service prop_accessor :send_from_committer_email prop_accessor :disable_diffs diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb index 5469049bb5eb74..d7b6e505191b8c 100644 --- a/app/models/project_services/external_wiki_service.rb +++ b/app/models/project_services/external_wiki_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class ExternalWikiService < Service include HTTParty @@ -49,7 +25,7 @@ def fields def execute(_data) @response = HTTParty.get(properties['external_wiki_url'], verify: true) rescue nil - if @response !=200 + if @response != 200 nil end end diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb index 3dc1e0fbe8b9ca..dd00275187f635 100644 --- a/app/models/project_services/flowdock_service.rb +++ b/app/models/project_services/flowdock_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - require "flowdock-git-hook" class FlowdockService < Service diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb index b4c311cf664d92..598aca5e06d28b 100644 --- a/app/models/project_services/gemnasium_service.rb +++ b/app/models/project_services/gemnasium_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - require "gemnasium/gitlab_service" class GemnasiumService < Service diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index a92f722608388e..bbc312f521555c 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - # TODO(ayufan): The GitLabCiService is deprecated and the type should be removed when the database entries are removed class GitlabCiService < CiService # We override the active accessor to always make GitLabCiService disabled diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb index 1adaeeb3b2baa5..5d17c3583306c5 100644 --- a/app/models/project_services/gitlab_issue_tracker_service.rb +++ b/app/models/project_services/gitlab_issue_tracker_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class GitlabIssueTrackerService < IssueTrackerService include Gitlab::Routing.url_helpers diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index f9ddf5887226dd..0ff4f4c8dd2cd9 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class HipchatService < Service MAX_COMMITS = 3 diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index b9a592d709635b..2e5e854fc5e1bf 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - require 'uri' class IrkerService < Service @@ -94,7 +70,7 @@ def help private def get_channels - return true unless :activated? + return true unless activated? return true if recipients.nil? || recipients.empty? map_recipients diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index 98a3a7c6b86f3c..6ae9b16d3ce496 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class IssueTrackerService < Service validates :project_url, :issues_url, :new_issue_url, presence: true, url: true, if: :activated? diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index ba68658f0bd162..beda89d396317a 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class JiraService < IssueTrackerService include HTTParty include Gitlab::Routing.url_helpers diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb index acaa0c393651d2..ad19b7795da86d 100644 --- a/app/models/project_services/pivotaltracker_service.rb +++ b/app/models/project_services/pivotaltracker_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class PivotaltrackerService < Service include HTTParty diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index a640c8cb4404c2..3dd878e4c7d773 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class PushoverService < Service include HTTParty base_uri 'https://api.pushover.net/1' diff --git a/app/models/project_services/redmine_service.rb b/app/models/project_services/redmine_service.rb index e2137e92c62798..11cce3e0561f82 100644 --- a/app/models/project_services/redmine_service.rb +++ b/app/models/project_services/redmine_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class RedmineService < IssueTrackerService prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 83ffa53a407e35..cf9e4d5a8b60c4 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class SlackService < Service prop_accessor :webhook, :username, :channel boolean_accessor :notify_only_broken_builds diff --git a/app/models/project_services/slack_service/build_message.rb b/app/models/project_services/slack_service/build_message.rb index c124cad4afd042..69c21b3fc387fd 100644 --- a/app/models/project_services/slack_service/build_message.rb +++ b/app/models/project_services/slack_service/build_message.rb @@ -35,8 +35,8 @@ def attachments private def message - "#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status} in #{duration} second(s)" - end + "#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status} in #{duration} #{'second'.pluralize(duration)}" + end def format(string) Slack::Notifier::LinkFormatter.format(string) diff --git a/app/models/project_services/slack_service/issue_message.rb b/app/models/project_services/slack_service/issue_message.rb index 438ff33fdffa5d..88e053ec19274d 100644 --- a/app/models/project_services/slack_service/issue_message.rb +++ b/app/models/project_services/slack_service/issue_message.rb @@ -34,7 +34,12 @@ def attachments private def message - "#{user_name} #{state} #{issue_link} in #{project_link}: *#{title}*" + case state + when "opened" + "[#{project_link}] Issue #{state} by #{user_name}" + else + "[#{project_link}] Issue #{issue_link} #{state} by #{user_name}" + end end def opened_issue? @@ -42,7 +47,11 @@ def opened_issue? end def description_message - [{ text: format(description), color: attachment_color }] + [{ + title: issue_title, + title_link: issue_url, + text: format(description), + color: "#C95823" }] end def project_link @@ -50,7 +59,11 @@ def project_link end def issue_link - "[issue ##{issue_iid}](#{issue_url})" + "[#{issue_title}](#{issue_url})" + end + + def issue_title + "##{issue_iid} #{title}" end end end diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb index 4015da31509a72..b0dcb52eba15db 100644 --- a/app/models/project_services/teamcity_service.rb +++ b/app/models/project_services/teamcity_service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - class TeamcityService < CiService include HTTParty diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb index b4b2807eba43ec..25b5d777641127 100644 --- a/app/models/project_snippet.rb +++ b/app/models/project_snippet.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string -# type :string -# visibility_level :integer default(0), not null -# - class ProjectSnippet < Snippet belongs_to :project belongs_to :author, class_name: "User" @@ -23,5 +7,6 @@ class ProjectSnippet < Snippet # Scopes scope :fresh, -> { order("created_at DESC") } - participant :author, :notes + participant :author + participant :notes_with_associations end diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index 7c1a61bb0bfcb9..25d82929c0b1ff 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -27,6 +27,10 @@ def path_with_namespace @project.path_with_namespace + ".wiki" end + def web_url + Gitlab::Routing.url_helpers.namespace_project_wiki_url(@project.namespace, @project, :home) + end + def url_to_repo gitlab_shell.url_to_repo(path_with_namespace) end @@ -40,7 +44,7 @@ def http_url_to_repo end def wiki_base_path - ["/", @project.path_with_namespace, "/wikis"].join('') + [Gitlab.config.gitlab.relative_url_root, "/", @project.path_with_namespace, "/wikis"].join('') end # Returns the Gollum::Wiki object. @@ -113,7 +117,7 @@ def delete_page(page, message = nil) end def page_title_and_dir(title) - title_array = title.split("/") + title_array = title.split("/") title = title_array.pop [title, title_array.join("/")] end @@ -142,6 +146,16 @@ def create_repo! wiki end + def hook_attrs + { + web_url: web_url, + git_ssh_url: ssh_url_to_repo, + git_http_url: http_url_to_repo, + path_with_namespace: path_with_namespace, + default_branch: default_branch + } + end + private def init_repo(path_with_namespace) diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index 3d2052c892ca75..33cf046fa75c47 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: protected_branches -# -# id :integer not null, primary key -# project_id :integer not null -# name :string not null -# created_at :datetime -# updated_at :datetime -# developers_can_push :boolean default(FALSE), not null -# - class ProtectedBranch < ActiveRecord::Base include Gitlab::ShellAdapter diff --git a/app/models/release.rb b/app/models/release.rb index dc700d1ea5a42c..e196b84eb18845 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: releases -# -# id :integer not null, primary key -# tag :string -# description :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# - class Release < ActiveRecord::Base belongs_to :project diff --git a/app/models/repository.rb b/app/models/repository.rb index 7aebfe279fb5f2..1ab163510bf60f 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -81,7 +81,7 @@ def has_visible_content? def commit(id = 'HEAD') return nil unless exists? commit = Gitlab::Git::Commit.find(raw_repository, id) - commit = Commit.new(commit, @project) if commit + commit = ::Commit.new(commit, @project) if commit commit rescue Rugged::OdbError nil @@ -195,6 +195,10 @@ def branch_names cache.fetch(:branch_names) { branches.map(&:name) } end + def branch_exists?(branch_name) + branch_names.include?(branch_name) + end + def tag_names cache.fetch(:tag_names) { raw_repository.tag_names } end @@ -241,7 +245,7 @@ def diverging_commit_counts(branch) def cache_keys %i(size branch_names tag_names commit_count readme version contribution_guide changelog - license_blob license_key) + license_blob license_key gitignore) end def build_cache @@ -252,6 +256,10 @@ def build_cache end end + def expire_gitignore + cache.expire(:gitignore) + end + def expire_tags_cache cache.expire(:tag_names) @tags = nil @@ -453,7 +461,7 @@ def readme def version cache.fetch(:version) do tree(:head).blobs.find do |file| - file.name.downcase == 'version' + file.name.casecmp('version').zero? end end end @@ -468,33 +476,37 @@ def contribution_guide def changelog cache.fetch(:changelog) do - tree(:head).blobs.find do |file| - file.name =~ /\A(changelog|history|changes|news)/i - end + file_on_head(/\A(changelog|history|changes|news)/i) end end def license_blob - return nil if !exists? || empty? + return nil unless head_exists? cache.fetch(:license_blob) do - tree(:head).blobs.find do |file| - file.name =~ /\A(licen[sc]e|copying)(\..+|\z)/i - end + file_on_head(/\A(licen[sc]e|copying)(\..+|\z)/i) end end def license_key - return nil if !exists? || empty? + return nil unless head_exists? cache.fetch(:license_key) do Licensee.license(path).try(:key) end end - def gitlab_ci_yml + def gitignore return nil if !exists? || empty? + cache.fetch(:gitignore) do + file_on_head(/\A\.gitignore\z/) + end + end + + def gitlab_ci_yml + return nil unless head_exists? + @gitlab_ci_yml ||= tree(:head).blobs.find do |file| file.name == '.gitlab-ci.yml' end @@ -795,7 +807,7 @@ def cherry_pick(user, commit, base_branch, cherry_pick_tree_id = nil) def check_revert_content(commit, base_branch) source_sha = find_branch(base_branch).target args = [commit.id, source_sha] - args << { mainline: 1 } if commit.merge_commit? + args << { mainline: 1 } if commit.merge_commit? revert_index = rugged.revert_commit(*args) return false if revert_index.conflicts? @@ -809,7 +821,7 @@ def check_revert_content(commit, base_branch) def check_cherry_pick_content(commit, base_branch) source_sha = find_branch(base_branch).target args = [commit.id, source_sha] - args << 1 if commit.merge_commit? + args << 1 if commit.merge_commit? cherry_pick_index = rugged.cherrypick_commit(*args) return false if cherry_pick_index.conflicts? @@ -850,7 +862,7 @@ def is_ancestor?(ancestor_id, descendant_id) def search_files(query, ref) offset = 2 - args = %W(#{Gitlab.config.git.bin_path} grep -i -I -n --before-context #{offset} --after-context #{offset} -e #{Regexp.escape(query)} #{ref || root_ref}) + args = %W(#{Gitlab.config.git.bin_path} grep -i -I -n --before-context #{offset} --after-context #{offset} -E -e #{Regexp.escape(query)} #{ref || root_ref}) Gitlab::Popen.popen(args, path_to_repo).first.scrub.split(/^--$/) end @@ -960,12 +972,6 @@ def copy_gitattributes(ref) end end - def main_language - return if empty? || rugged.head_unborn? - - Linguist::Repository.new(rugged, rugged.head.target_id).language - end - def avatar return nil unless exists? @@ -981,4 +987,12 @@ def avatar def cache @cache ||= RepositoryCache.new(path_with_namespace) end + + def head_exists? + exists? && !empty? && !rugged.head_unborn? + end + + def file_on_head(regex) + tree(:head).blobs.find { |file| file.name =~ regex } + end end diff --git a/app/models/security_event.rb b/app/models/security_event.rb index 0bee03974f1452..d131c11cb6c6d7 100644 --- a/app/models/security_event.rb +++ b/app/models/security_event.rb @@ -1,16 +1,2 @@ -# == Schema Information -# -# Table name: audit_events -# -# id :integer not null, primary key -# author_id :integer not null -# type :string not null -# entity_id :integer not null -# entity_type :string not null -# details :text -# created_at :datetime -# updated_at :datetime -# - class SecurityEvent < AuditEvent end diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb index 99279a2e083082..375f195dba7234 100644 --- a/app/models/sent_notification.rb +++ b/app/models/sent_notification.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: sent_notifications -# -# id :integer not null, primary key -# project_id :integer -# noteable_id :integer -# noteable_type :string -# recipient_id :integer -# commit_id :string -# reply_key :string not null -# line_code :string -# - class SentNotification < ActiveRecord::Base belongs_to :project belongs_to :noteable, polymorphic: true diff --git a/app/models/service.rb b/app/models/service.rb index bf16a5453071bf..de3fd24584a438 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string -# title :string -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# active :boolean not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# build_events :boolean default(FALSE), not null -# category :string default("common"), not null -# default :boolean default(FALSE) -# wiki_page_events :boolean default(TRUE) -# - # To add new service you should build a class inherited from Service # and implement a set of methods class Service < ActiveRecord::Base diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 2f905a90942475..407697b745ce0e 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -1,19 +1,3 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string -# type :string -# visibility_level :integer default(0), not null -# - class Snippet < ActiveRecord::Base include Gitlab::VisibilityLevel include Linguist::BlobHelper @@ -46,7 +30,8 @@ class Snippet < ActiveRecord::Base scope :public_and_internal, -> { where(visibility_level: [Snippet::PUBLIC, Snippet::INTERNAL]) } scope :fresh, -> { order("created_at DESC") } - participant :author, :notes + participant :author + participant :notes_with_associations def self.reference_prefix '$' @@ -116,6 +101,10 @@ def no_highlighting? content.lines.count > 1000 end + def notes_with_associations + notes.includes(:author, :project) + end + class << self # Searches for snippets with a matching title or file name. # diff --git a/app/models/spam_log.rb b/app/models/spam_log.rb index f49eb7d88e20e3..12df68ef83bf17 100644 --- a/app/models/spam_log.rb +++ b/app/models/spam_log.rb @@ -1,20 +1,3 @@ -# == Schema Information -# -# Table name: spam_logs -# -# id :integer not null, primary key -# user_id :integer -# source_ip :string -# user_agent :string -# via_api :boolean -# project_id :integer -# noteable_type :string -# title :string -# description :text -# created_at :datetime not null -# updated_at :datetime not null -# - class SpamLog < ActiveRecord::Base belongs_to :user diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 242faa7d32eb5a..3b8aa1eb8669be 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: subscriptions -# -# id :integer not null, primary key -# user_id :integer -# subscribable_id :integer -# subscribable_type :string -# subscribed :boolean -# created_at :datetime -# updated_at :datetime -# - class Subscription < ActiveRecord::Base belongs_to :user belongs_to :subscribable, polymorphic: true diff --git a/app/models/todo.rb b/app/models/todo.rb index d85f7bfdf57219..3a091373329115 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -1,24 +1,7 @@ -# == Schema Information -# -# Table name: todos -# -# id :integer not null, primary key -# user_id :integer not null -# project_id :integer not null -# target_id :integer -# target_type :string not null -# author_id :integer -# action :integer not null -# state :string not null -# created_at :datetime -# updated_at :datetime -# note_id :integer -# commit_id :string -# - class Todo < ActiveRecord::Base - ASSIGNED = 1 - MENTIONED = 2 + ASSIGNED = 1 + MENTIONED = 2 + BUILD_FAILED = 3 belongs_to :author, class_name: "User" belongs_to :note @@ -46,6 +29,10 @@ class Todo < ActiveRecord::Base state :done end + def build_failed? + action == BUILD_FAILED + end + def body if note.present? note.note diff --git a/app/models/user.rb b/app/models/user.rb index 959b1f93758ffd..172845c9d25a1b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,68 +1,3 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# email :string default(""), not null -# encrypted_password :string default(""), not null -# reset_password_token :string -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default(0) -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string -# last_sign_in_ip :string -# created_at :datetime -# updated_at :datetime -# name :string -# admin :boolean default(FALSE), not null -# projects_limit :integer default(10) -# skype :string default(""), not null -# linkedin :string default(""), not null -# twitter :string default(""), not null -# authentication_token :string -# theme_id :integer default(1), not null -# bio :string -# failed_attempts :integer default(0) -# locked_at :datetime -# username :string -# can_create_group :boolean default(TRUE), not null -# can_create_team :boolean default(TRUE), not null -# state :string -# color_scheme_id :integer default(1), not null -# notification_level :integer default(1), not null -# password_expires_at :datetime -# created_by_id :integer -# last_credential_check_at :datetime -# avatar :string -# confirmation_token :string -# confirmed_at :datetime -# confirmation_sent_at :datetime -# unconfirmed_email :string -# hide_no_ssh_key :boolean default(FALSE) -# website_url :string default(""), not null -# notification_email :string -# hide_no_password :boolean default(FALSE) -# password_automatically_set :boolean default(FALSE) -# location :string -# encrypted_otp_secret :string -# encrypted_otp_secret_iv :string -# encrypted_otp_secret_salt :string -# otp_required_for_login :boolean default(FALSE), not null -# otp_backup_codes :text -# public_email :string default(""), not null -# dashboard :integer default(0) -# project_view :integer default(0) -# consumed_timestep :integer -# layout :integer default(0) -# hide_project_limit :boolean default(FALSE) -# unlock_token :string -# otp_grace_period_started_at :datetime -# ldap_email :boolean default(FALSE), not null -# external :boolean default(FALSE) -# - require 'carrierwave/orm/activerecord' class User < ActiveRecord::Base @@ -85,14 +20,19 @@ class User < ActiveRecord::Base default_value_for :hide_no_password, false default_value_for :theme_id, gitlab_config.default_theme + attr_encrypted :otp_secret, + key: Gitlab::Application.config.secret_key_base, + mode: :per_attribute_iv_and_salt, + algorithm: 'aes-256-cbc' + devise :two_factor_authenticatable, - otp_secret_encryption_key: File.read(Rails.root.join('.secret')).chomp + otp_secret_encryption_key: Gitlab::Application.config.secret_key_base alias_attribute :two_factor_enabled, :otp_required_for_login devise :two_factor_backupable, otp_number_of_backup_codes: 10 serialize :otp_backup_codes, JSON - devise :lockable, :async, :recoverable, :rememberable, :trackable, + devise :lockable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable attr_accessor :force_random_password @@ -177,6 +117,7 @@ class User < ActiveRecord::Base before_save :ensure_external_user_rights after_save :ensure_namespace_correct after_initialize :set_projects_limit + before_create :check_confirmation_email after_create :post_create_hook after_destroy :post_destroy_hook @@ -372,6 +313,10 @@ def generate_reset_token @reset_token end + def check_confirmation_email + skip_confirmation! unless current_application_settings.send_user_confirmation_email + end + def recently_sent_password_reset? reset_password_sent_at.present? && reset_password_sent_at >= 1.minute.ago end @@ -446,17 +391,17 @@ def authorized_projects Project.where("projects.id IN (#{projects_union.to_sql})") end + def viewable_starred_projects + starred_projects.where("projects.visibility_level IN (?) OR projects.id IN (#{projects_union.to_sql})", + [Project::PUBLIC, Project::INTERNAL]) + end + def owned_projects @owned_projects ||= Project.where('namespace_id IN (?) OR namespace_id = ?', owned_groups.select(:id), namespace.id).joins(:namespace) end - # Team membership in authorized projects - def tm_in_authorized_projects - ProjectMember.where(source_id: authorized_projects.map(&:id), user_id: self.id) - end - def is_admin? admin end @@ -546,10 +491,6 @@ def name_with_username "#{name} (#{username})" end - def tm_of(project) - project.project_member_by_id(self.id) - end - def already_forked?(project) !!fork_of(project) end @@ -835,6 +776,23 @@ def notification_settings_for(source) notification_settings.find_or_initialize_by(source: source) end + def assigned_open_merge_request_count(force: false) + Rails.cache.fetch(['users', id, 'assigned_open_merge_request_count'], force: force) do + assigned_merge_requests.opened.count + end + end + + def assigned_open_issues_count(force: false) + Rails.cache.fetch(['users', id, 'assigned_open_issues_count'], force: force) do + assigned_issues.opened.count + end + end + + def update_cache_counts + assigned_open_merge_request_count(force: true) + assigned_open_issues_count(force: true) + end + private def projects_union diff --git a/app/models/users_star_project.rb b/app/models/users_star_project.rb index 413f3f485a85be..0dfe597317e361 100644 --- a/app/models/users_star_project.rb +++ b/app/models/users_star_project.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: users_star_projects -# -# id :integer not null, primary key -# project_id :integer not null -# user_id :integer not null -# created_at :datetime -# updated_at :datetime -# - class UsersStarProject < ActiveRecord::Base belongs_to :project, counter_cache: :star_count, touch: true belongs_to :user diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb new file mode 100644 index 00000000000000..e57b95f21ecca2 --- /dev/null +++ b/app/services/auth/container_registry_authentication_service.rb @@ -0,0 +1,87 @@ +module Auth + class ContainerRegistryAuthenticationService < BaseService + include Gitlab::CurrentSettings + + AUDIENCE = 'container_registry' + + def execute + return error('not found', 404) unless registry.enabled + + unless current_user || project + return error('forbidden', 403) unless scope + end + + { token: authorized_token(scope).encoded } + end + + def self.full_access_token(*names) + registry = Gitlab.config.registry + token = JSONWebToken::RSAToken.new(registry.key) + token.issuer = registry.issuer + token.audience = AUDIENCE + token.expire_time = token_expire_at + token[:access] = names.map do |name| + { type: 'repository', name: name, actions: %w(*) } + end + token.encoded + end + + private + + def authorized_token(*accesses) + token = JSONWebToken::RSAToken.new(registry.key) + token.issuer = registry.issuer + token.audience = params[:service] + token.subject = current_user.try(:username) + token.expire_time = ContainerRegistryAuthenticationService.token_expire_at + token[:access] = accesses.compact + token + end + + def scope + return unless params[:scope] + + @scope ||= process_scope(params[:scope]) + end + + def process_scope(scope) + type, name, actions = scope.split(':', 3) + actions = actions.split(',') + return unless type == 'repository' + + process_repository_access(type, name, actions) + end + + def process_repository_access(type, name, actions) + requested_project = Project.find_with_namespace(name) + return unless requested_project + + actions = actions.select do |action| + can_access?(requested_project, action) + end + + { type: type, name: name, actions: actions } if actions.present? + end + + def can_access?(requested_project, requested_action) + return false unless requested_project.container_registry_enabled? + + case requested_action + when 'pull' + requested_project == project || can?(current_user, :read_container_image, requested_project) + when 'push' + requested_project == project || can?(current_user, :create_container_image, requested_project) + else + false + end + end + + def registry + Gitlab.config.registry + end + + def self.token_expire_at + Time.now + current_application_settings.container_registry_token_expire_delay.minutes + end + end +end diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb new file mode 100644 index 00000000000000..5bc0c31cb42edf --- /dev/null +++ b/app/services/ci/create_pipeline_service.rb @@ -0,0 +1,50 @@ +module Ci + class CreatePipelineService < BaseService + def execute + pipeline = project.ci_commits.new(params) + + unless ref_names.include?(params[:ref]) + pipeline.errors.add(:base, 'Reference not found') + return pipeline + end + + unless commit + pipeline.errors.add(:base, 'Commit not found') + return pipeline + end + + unless can?(current_user, :create_pipeline, project) + pipeline.errors.add(:base, 'Insufficient permissions to create a new pipeline') + return pipeline + end + + begin + Ci::Commit.transaction do + pipeline.sha = commit.id + + unless pipeline.config_processor + pipeline.errors.add(:base, pipeline.yaml_errors || 'Missing .gitlab-ci.yml file') + raise ActiveRecord::Rollback + end + + pipeline.save! + pipeline.create_builds(current_user) + end + rescue + pipeline.errors.add(:base, 'The pipeline could not be created. Please try again.') + end + + pipeline + end + + private + + def ref_names + @ref_names ||= project.repository.ref_names + end + + def commit + @commit ||= project.commit(params[:ref]) + end + end +end diff --git a/app/services/create_commit_builds_service.rb b/app/services/create_commit_builds_service.rb index 0d2aa1ff03dc47..5b6fefe669e26f 100644 --- a/app/services/create_commit_builds_service.rb +++ b/app/services/create_commit_builds_service.rb @@ -18,19 +18,16 @@ def execute(project, user, params) return false end - commit = project.ci_commit(sha, ref) - unless commit - commit = project.ci_commits.new(sha: sha, ref: ref, before_sha: before_sha, tag: tag) + commit = Ci::Commit.new(project: project, sha: sha, ref: ref, before_sha: before_sha, tag: tag) - # Skip creating ci_commit when no gitlab-ci.yml is found - unless commit.ci_yaml_file - return false - end - - # Create a new ci_commit - commit.save! + # Skip creating ci_commit when no gitlab-ci.yml is found + unless commit.ci_yaml_file + return false end + # Create a new ci_commit + commit.save! + # Skip creating builds for commits that have [ci skip] unless commit.skip_ci? # Create builds for commit diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 66136b6261749d..a886f35981f42c 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -53,10 +53,6 @@ def execute # could cause the last commit of a merge request to change. update_merge_requests - # Checks if the main language has changed in the project and if so - # it updates it accordingly - update_main_language - perform_housekeeping end @@ -64,19 +60,6 @@ def update_gitattributes @project.repository.copy_gitattributes(params[:ref]) end - def update_main_language - # Performance can be bad so for now only check main_language once - # See https://gitlab.com/gitlab-org/gitlab-ce/issues/14937 - return if @project.main_language.present? - - return unless is_default_branch? - return unless push_to_new_branch? || push_to_existing_branch? - - current_language = @project.repository.main_language - @project.update_attributes(main_language: current_language) - true - end - protected def update_merge_requests diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb index 7410442609d33f..299a0a967b068e 100644 --- a/app/services/git_tag_push_service.rb +++ b/app/services/git_tag_push_service.rb @@ -23,7 +23,7 @@ def build_push_data commits = [] message = nil - if !Gitlab::Git.blank_ref?(params[:newrev]) + unless Gitlab::Git.blank_ref?(params[:newrev]) tag_name = Gitlab::Git.ref_name(params[:ref]) tag = project.repository.find_tag(tag_name) if tag && tag.target == params[:newrev] diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 3563cbaa997e2d..c7d406cc3317ba 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -24,6 +24,10 @@ def handle_changes(issue, old_labels: []) todo_service.reassigned_issue(issue, current_user) end + if issue.previous_changes.include?('confidential') + create_confidentiality_note(issue) + end + added_labels = issue.labels - old_labels if added_labels.present? notification_service.relabeled_issue(issue, added_labels, current_user) @@ -37,5 +41,11 @@ def reopen_service def close_service Issues::CloseService end + + private + + def create_confidentiality_note(issue) + SystemNoteService.change_issue_confidentiality(issue, issue.project, current_user) + end end end diff --git a/app/services/merge_requests/add_todo_when_build_fails_service.rb b/app/services/merge_requests/add_todo_when_build_fails_service.rb new file mode 100644 index 00000000000000..566049525cb724 --- /dev/null +++ b/app/services/merge_requests/add_todo_when_build_fails_service.rb @@ -0,0 +1,17 @@ +module MergeRequests + class AddTodoWhenBuildFailsService < MergeRequests::BaseService + # Adds a todo to the parent merge_request when a CI build fails + def execute(commit_status) + each_merge_request(commit_status) do |merge_request| + todo_service.merge_request_build_failed(merge_request) + end + end + + # Closes any pending build failed todos for the parent MRs when a build is retried + def close(commit_status) + each_merge_request(commit_status) do |merge_request| + todo_service.merge_request_build_retried(merge_request) + end + end + end +end diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index e6837a186963e1..9d7fca6882db3c 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -38,5 +38,30 @@ def execute_hooks(merge_request, action = 'open') def filter_params super(:merge_request) end + + def merge_request_from(commit_status) + branches = commit_status.ref + + # This is for ref-less builds + branches ||= @project.repository.branch_names_contains(commit_status.sha) + + return [] if branches.blank? + + merge_requests = @project.origin_merge_requests.opened.where(source_branch: branches).to_a + merge_requests += @project.fork_merge_requests.opened.where(source_branch: branches).to_a + + merge_requests.uniq.select(&:source_project) + end + + def each_merge_request(commit_status) + merge_request_from(commit_status).each do |merge_request| + ci_commit = merge_request.ci_commit + + next unless ci_commit + next unless ci_commit.sha == commit_status.sha + + yield merge_request, ci_commit + end + end end end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index cd4230aa5e4d37..1b48899bb0a0f8 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -66,7 +66,7 @@ def set_title_and_description(merge_request) commits = merge_request.compare_commits if commits && commits.count == 1 commit = commits.first - merge_request.title = commit.title + merge_request.title = commit.title merge_request.description ||= commit.description.try(:strip) elsif iid && (issue = merge_request.target_project.get_issue(iid)) && !issue.try(:confidential?) case issue diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb index 33609d01f20fed..96a25330af1004 100644 --- a/app/services/merge_requests/create_service.rb +++ b/app/services/merge_requests/create_service.rb @@ -8,11 +8,14 @@ def execute @project = Project.find(params[:target_project_id]) if params[:target_project_id] filter_params - label_params = params[:label_ids] - merge_request = MergeRequest.new(params.except(:label_ids)) + label_params = params.delete(:label_ids) + force_remove_source_branch = params.delete(:force_remove_source_branch) + + merge_request = MergeRequest.new(params) merge_request.source_project = source_project merge_request.target_project ||= source_project merge_request.author = current_user + merge_request.merge_params['force_remove_source_branch'] = force_remove_source_branch if merge_request.save merge_request.update_attributes(label_ids: label_params) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 9a58383b398a85..9aaf5a5e561804 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -45,10 +45,14 @@ def commit def after_merge MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) - if params[:should_remove_source_branch].present? - DeleteBranchService.new(@merge_request.source_project, current_user). + 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) end end + + def branch_deletion_user + @merge_request.force_remove_source_branch? ? @merge_request.author : current_user + end end end diff --git a/app/services/merge_requests/merge_when_build_succeeds_service.rb b/app/services/merge_requests/merge_when_build_succeeds_service.rb index d6af12f9739832..8fd6a4ea1f68ed 100644 --- a/app/services/merge_requests/merge_when_build_succeeds_service.rb +++ b/app/services/merge_requests/merge_when_build_succeeds_service.rb @@ -20,15 +20,9 @@ def execute(merge_request) # Triggers the automatic merge of merge_request once the build succeeds def trigger(commit_status) - merge_requests = merge_request_from(commit_status) - - merge_requests.each do |merge_request| + each_merge_request(commit_status) do |merge_request, ci_commit| next unless merge_request.merge_when_build_succeeds? next unless merge_request.mergeable? - - ci_commit = merge_request.ci_commit - next unless ci_commit - next unless ci_commit.sha == commit_status.sha next unless ci_commit.success? MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params) @@ -47,20 +41,5 @@ def cancel(merge_request) end end - private - - def merge_request_from(commit_status) - branches = commit_status.ref - - # This is for ref-less builds - branches ||= @project.repository.branch_names_contains(commit_status.sha) - - return [] if branches.blank? - - merge_requests = @project.origin_merge_requests.opened.where(source_branch: branches).to_a - merge_requests += @project.fork_merge_requests.opened.where(source_branch: branches).to_a - - merge_requests.uniq.select(&:source_project) - end end end diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb index 8b3d56c2b4c1b5..fe0579744b45ae 100644 --- a/app/services/merge_requests/refresh_service.rb +++ b/app/services/merge_requests/refresh_service.rb @@ -12,6 +12,7 @@ def execute(oldrev, newrev, ref) close_merge_requests reload_merge_requests reset_merge_when_build_succeeds + mark_pending_todos_done # Leave a system note if a branch was deleted/added if branch_added? || branch_removed? @@ -80,6 +81,12 @@ def reset_merge_when_build_succeeds merge_requests_for_source_branch.each(&:reset_merge_when_build_succeeds) end + def mark_pending_todos_done + merge_requests_for_source_branch.each do |merge_request| + todo_service.merge_request_push(merge_request, @current_user) + end + end + def find_new_commits if branch_added? @commits = [] diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 477c64e7377d91..026a37997d4437 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -11,6 +11,8 @@ def execute(merge_request) params.except!(:target_project_id) params.except!(:source_branch) + merge_request.merge_params['force_remove_source_branch'] = params.delete(:force_remove_source_branch) + update(merge_request) end diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb index 01586994813cca..2bb312bb252ca4 100644 --- a/app/services/notes/create_service.rb +++ b/app/services/notes/create_service.rb @@ -5,8 +5,6 @@ def execute note.author = current_user note.system = false - return unless valid_project?(note) - if note.save # Finish the harder work in the background NewNoteWorker.perform_in(2.seconds, note.id, params) @@ -15,14 +13,5 @@ def execute note end - - private - - def valid_project?(note) - return false unless project - return true if note.for_commit? - - note.noteable.try(:project) == project - end end end diff --git a/app/services/projects/autocomplete_service.rb b/app/services/projects/autocomplete_service.rb index ba50305dbd5fca..eb73948006e790 100644 --- a/app/services/projects/autocomplete_service.rb +++ b/app/services/projects/autocomplete_service.rb @@ -4,6 +4,10 @@ def issues @project.issues.visible_to_user(current_user).opened.select([:iid, :title]) end + def milestones + @project.milestones.active.reorder(due_date: :asc, title: :asc).select([:iid, :title]) + end + def merge_requests @project.merge_requests.opened.select([:iid, :title]) end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 501e58c1407255..61cac5419ad00f 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -6,6 +6,7 @@ def initialize(user, params) def execute forked_from_project_id = params.delete(:forked_from_project_id) + import_data = params.delete(:import_data) @project = Project.new(params) @@ -49,22 +50,20 @@ def execute @project.build_forked_project_link(forked_from_project_id: forked_from_project_id) end - Project.transaction do - @project.save + save_project_and_import_data(import_data) - if @project.persisted? && !@project.import? - raise 'Failed to create repository' unless @project.create_repository - end - end + @project.import_start if @project.import? after_create_actions if @project.persisted? + if @project.errors.empty? + @project.add_import_job if @project.import? + else + fail(error: @project.errors.full_messages.join(', ')) + end @project rescue => e - message = "Unable to save project: #{e.message}" - Rails.logger.error(message) - @project.errors.add(:base, message) if @project - @project + fail(error: e.message) end protected @@ -93,8 +92,30 @@ def after_create_actions unless @project.group @project.team << [current_user, :master, current_user] end + end - @project.import_start if @project.import? + def save_project_and_import_data(import_data) + Project.transaction do + @project.create_or_update_import_data(data: import_data[:data], credentials: import_data[:credentials]) if import_data + + if @project.save && !@project.import? + raise 'Failed to create repository' unless @project.create_repository + end + end + end + + def fail(error:) + message = "Unable to save project. Error: #{error}" + message << "Project ID: #{@project.id}" if @project && @project.id + + Rails.logger.error(message) + + if @project && @project.import? + @project.errors.add(:base, message) + @project.mark_import_as_failed(message) + end + + @project end end end diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 19aab999e002c4..f09072975c3e9a 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -26,6 +26,10 @@ def execute Project.transaction do project.destroy! + unless remove_registry_tags + raise_error('Failed to remove project container registry. Please try again or contact administrator') + end + unless remove_repository(repo_path) raise_error('Failed to remove project repository. Please try again or contact administrator') end @@ -35,7 +39,7 @@ def execute end end - log_info("Project \"#{project.name}\" was removed") + log_info("Project \"#{project.path_with_namespace}\" was removed") system_hook_service.execute_hooks_for(project, :destroy) true end @@ -59,6 +63,12 @@ def remove_repository(path) end end + def remove_registry_tags + return true unless Gitlab.config.registry.enabled + + project.container_registry_repository.delete_tags + end + def raise_error(message) raise DestroyError.new(message) end diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 0577ae778d54d1..de6dc38cc8e345 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -3,7 +3,7 @@ class ForkService < BaseService def execute new_params = { forked_from_project_id: @project.id, - visibility_level: @project.visibility_level, + visibility_level: allowed_visibility_level, description: @project.description, name: @project.name, path: @project.path, @@ -19,5 +19,17 @@ def execute new_project = CreateService.new(current_user, new_params).execute new_project end + + private + + def allowed_visibility_level + project_level = @project.visibility_level + + if Gitlab::VisibilityLevel.non_restricted_level?(project_level) + project_level + else + Gitlab::VisibilityLevel.highest_allowed_level + end + end end end diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb index 3b7c36f0908b61..43db29315a166c 100644 --- a/app/services/projects/housekeeping_service.rb +++ b/app/services/projects/housekeeping_service.rb @@ -22,7 +22,7 @@ def initialize(project) end def execute - raise LeaseTaken if !try_obtain_lease + raise LeaseTaken unless try_obtain_lease GitlabShellOneShotWorker.perform_async(:gc, @project.path_with_namespace) ensure diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb index ef15ef6a47310c..c4838d31f2f64a 100644 --- a/app/services/projects/import_service.rb +++ b/app/services/projects/import_service.rb @@ -39,7 +39,7 @@ def import_repository begin gitlab_shell.import_repository(project.path_with_namespace, project.import_url) rescue Gitlab::Shell::Error => e - raise Error, e.message + raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}" end end diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index 111b3ec05eabfb..03b57dea51e4d4 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -34,6 +34,11 @@ def transfer(project, new_namespace) raise TransferError.new("Project with same path in target namespace already exists") end + if project.has_container_registry_tags? + # we currently doesn't support renaming repository if it contains tags in container registry + raise TransferError.new('Project cannot be transferred, because tags are present in its container registry') + end + project.expire_caches_before_rename(old_path) # Apply new namespace id and visibility level diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index e43b5b51e5b8b9..1fb72cf89e9ee7 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -85,7 +85,7 @@ def project_data(model) path_with_namespace: model.path_with_namespace, project_id: model.id, owner_name: owner.name, - owner_email: owner.respond_to?(:email) ? owner.email : "", + owner_email: owner.respond_to?(:email) ? owner.email : "", project_visibility: Project.visibility_levels.key(model.visibility_level_field).downcase } end diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 4bdb1b0c0747fe..4e8fa0818b9e2a 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -169,12 +169,33 @@ def self.add_merge_request_wip(noteable, project, author) # # Returns the created Note object def self.change_title(noteable, project, author, old_title) - return unless noteable.respond_to?(:title) + new_title = noteable.title.dup - body = "Title changed from **#{old_title}** to **#{noteable.title}**" + old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_title, new_title).inline_diffs + + marked_old_title = Gitlab::Diff::InlineDiffMarker.new(old_title).mark(old_diffs, mode: :deletion, markdown: true) + marked_new_title = Gitlab::Diff::InlineDiffMarker.new(new_title).mark(new_diffs, mode: :addition, markdown: true) + + body = "Changed title: **#{marked_old_title}** → **#{marked_new_title}**" create_note(noteable: noteable, project: project, author: author, note: body) end + # Called when the confidentiality changes + # + # issue - Issue object + # project - Project owning the issue + # author - User performing the change + # + # Example Note text: + # + # "Made the issue confidential" + # + # Returns the created Note object + def self.change_issue_confidentiality(issue, project, author) + body = issue.confidential ? 'Made the issue confidential' : 'Made the issue visible' + create_note(noteable: issue, project: project, author: author, note: body) + end + # Called when a branch in Noteable is changed # # noteable - Noteable object diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb index 42c5bca90fda93..4bf4e144727c54 100644 --- a/app/services/todo_service.rb +++ b/app/services/todo_service.rb @@ -80,6 +80,30 @@ def merge_merge_request(merge_request, current_user) mark_pending_todos_as_done(merge_request, current_user) end + # When a build fails on the HEAD of a merge request we should: + # + # * create a todo for that user to fix it + # + def merge_request_build_failed(merge_request) + create_build_failed_todo(merge_request) + end + + # When a new commit is pushed to a merge request we should: + # + # * mark all pending todos related to the merge request for that user as done + # + def merge_request_push(merge_request, current_user) + mark_pending_todos_as_done(merge_request, current_user) + end + + # When a build is retried to a merge request we should: + # + # * mark all pending todos related to the merge request for the author as done + # + def merge_request_build_retried(merge_request) + mark_pending_todos_as_done(merge_request, merge_request.author) + end + # When create a note we should: # # * mark all pending todos related to the noteable for the note author as done @@ -145,6 +169,12 @@ def create_mention_todos(project, target, author, note = nil) create_todos(mentioned_users, attributes) end + def create_build_failed_todo(merge_request) + author = merge_request.author + attributes = attributes_for_todo(merge_request.project, merge_request, author, Todo::BUILD_FAILED) + create_todos(author, attributes) + end + def attributes_for_target(target) attributes = { project_id: target.project.id, diff --git a/app/services/wiki_pages/base_service.rb b/app/services/wiki_pages/base_service.rb index 9162f1286026c7..4c0a2c6b4d834c 100644 --- a/app/services/wiki_pages/base_service.rb +++ b/app/services/wiki_pages/base_service.rb @@ -6,9 +6,8 @@ def hook_data(page, action) object_kind: page.class.name.underscore, user: current_user.hook_attrs, project: @project.hook_attrs, - object_attributes: page.hook_attrs, - # DEPRECATED - repository: @project.hook_attrs.slice(:name, :url, :description, :homepage) + wiki: @project.wiki.hook_attrs, + object_attributes: page.hook_attrs } page_url = Gitlab::UrlBuilder.build(page) diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml index 2ab01704b7768c..862b86d9d4a8be 100644 --- a/app/views/admin/abuse_reports/_abuse_report.html.haml +++ b/app/views/admin/abuse_reports/_abuse_report.html.haml @@ -16,7 +16,7 @@ .light.small = time_ago_with_tooltip(abuse_report.created_at) %td - = markdown(abuse_report.message.squish!, pipeline: :single_line) + = markdown(abuse_report.message.squish!, pipeline: :single_line, author: reporter) %td - if user = link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true), diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index e0d8d16a9545c7..f149f9eb431185 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -103,12 +103,25 @@ = f.label :signup_enabled do = f.check_box :signup_enabled Sign-up enabled + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :send_user_confirmation_email do + = f.check_box :send_user_confirmation_email + Send confirmation email on sign-up .form-group .col-sm-offset-2.col-sm-10 .checkbox = f.label :signin_enabled do = f.check_box :signin_enabled Sign-in enabled + - if omniauth_enabled? && button_based_providers.any? + .form-group + = f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth Sign-In sources', class: 'control-label col-sm-2' + .col-sm-10 + .btn-group{ data: { toggle: 'buttons' } } + - oauth_providers_checkboxes.each do |source| + = source .form-group = f.label :two_factor_authentication, 'Two-factor authentication', class: 'control-label col-sm-2' .col-sm-10 @@ -165,6 +178,14 @@ .col-sm-10 = f.number_field :max_artifacts_size, class: 'form-control' + - if Gitlab.config.registry.enabled + %fieldset + %legend Container Registry + .form-group + = f.label :container_registry_token_expire_delay, 'Authorization token duration (minutes)', class: 'control-label col-sm-2' + .col-sm-10 + = f.number_field :container_registry_token_expire_delay, class: 'form-control' + %fieldset %legend Metrics %p diff --git a/app/views/admin/builds/index.html.haml b/app/views/admin/builds/index.html.haml index 804d7851bdb09c..d74cf8598e8a43 100644 --- a/app/views/admin/builds/index.html.haml +++ b/app/views/admin/builds/index.html.haml @@ -20,7 +20,7 @@ = link_to 'Cancel all', cancel_all_admin_builds_path, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post .row-content-block.second-block - #{(@scope || 'running').capitalize} builds + #{(@scope || 'all').capitalize} builds %ul.content-list - if @builds.blank? @@ -47,4 +47,3 @@ = render "admin/builds/build", build: build = paginate @builds, theme: 'gitlab' - diff --git a/app/views/admin/health_check/show.html.haml b/app/views/admin/health_check/show.html.haml new file mode 100644 index 00000000000000..c2313986a7fefa --- /dev/null +++ b/app/views/admin/health_check/show.html.haml @@ -0,0 +1,49 @@ +- page_title "Health Check" + +%h3.page-title + Health Check +.bs-callout.clearfix + .pull-left + %p + Access token is + %code#health-check-token= current_application_settings.health_check_access_token + = button_to reset_health_check_token_admin_application_settings_path, + method: :put, class: 'btn btn-default', + data: { confirm: 'Are you sure you want to reset the health check token?' } do + = icon('refresh') + Reset health check access token +%p.light + Health information can be retrieved as plain text, JSON, or XML using: + %ul + %li + %code= health_check_url(token: current_application_settings.health_check_access_token) + %li + %code= health_check_url(token: current_application_settings.health_check_access_token, format: :json) + %li + %code= health_check_url(token: current_application_settings.health_check_access_token, format: :xml) + +%p.light + You can also ask for the status of specific services: + %ul + %li + %code= health_check_url(token: current_application_settings.health_check_access_token, checks: :cache) + %li + %code= health_check_url(token: current_application_settings.health_check_access_token, checks: :database) + %li + %code= health_check_url(token: current_application_settings.health_check_access_token, checks: :migrations) + +%hr +.panel.panel-default + .panel-heading + Current Status: + - if @errors.blank? + = icon('circle', class: 'cgreen') + Healthy + - else + = icon('warning', class: 'cred') + Unhealthy + .panel-body + - if @errors.blank? + No Health Problems Detected + - else + = @errors diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml index 6745e58deca5f6..36b21eefdee8dd 100644 --- a/app/views/admin/runners/_runner.html.haml +++ b/app/views/admin/runners/_runner.html.haml @@ -11,18 +11,10 @@ = link_to admin_runner_path(runner) do = runner.short_sha %td - .runner-description - = runner.description - %span (#{link_to 'edit', '#', class: 'edit-runner-link'}) - .runner-description-form.hide - = form_for [:admin, runner], remote: true, html: { class: 'form-inline' } do |f| - .form-group - = f.text_field :description, class: 'form-control' - = f.submit 'Save', class: 'btn' - %span (#{link_to 'cancel', '#', class: 'cancel'}) + = runner.description %td - if runner.shared? - \- + n/a - else = runner.projects.count(:all) %td diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index 8700b4820cd6b9..c3784bf7192df4 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -9,8 +9,6 @@ %span.runner-state.runner-state-specific Specific - - - if @runner.shared? .bs-callout.bs-callout-success %h4 This runner will process builds from ALL UNASSIGNED projects @@ -22,25 +20,9 @@ %h4 This runner will process builds only from ASSIGNED projects %p You can't make this a shared runner. %hr -= form_for @runner, url: admin_runner_path(@runner), html: { class: 'form-horizontal' } do |f| - .form-group - = label_tag :token, class: 'control-label' do - Token - .col-sm-10 - = f.text_field :token, class: 'form-control', readonly: true - .form-group - = label_tag :description, class: 'control-label' do - Description - .col-sm-10 - = f.text_field :description, class: 'form-control' - .form-group - = label_tag :tag_list, class: 'control-label' do - Tags - .col-sm-10 - = f.text_field :tag_list, value: @runner.tag_list.to_s, class: 'form-control' - .help-block You can setup builds to only use runners with specific tags - .form-actions - = f.submit 'Save', class: 'btn btn-save' + +.append-bottom-20 + = render '/projects/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner) .row .col-md-6 diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder index 0d7b1b30dc3408..83c0c6da21ba41 100644 --- a/app/views/dashboard/issues.atom.builder +++ b/app/views/dashboard/issues.atom.builder @@ -6,8 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id issues_dashboard_url xml.updated @issues.first.created_at.xmlschema if @issues.any? - @issues.each do |issue| - issue_to_atom(xml, issue) - end + xml << render(partial: 'issues/issue', collection: @issues) if @issues.any? end - diff --git a/app/views/dashboard/projects/index.atom.builder b/app/views/dashboard/projects/index.atom.builder index d4daf07c6c0ee1..fb5be63b47236f 100644 --- a/app/views/dashboard/projects/index.atom.builder +++ b/app/views/dashboard/projects/index.atom.builder @@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id dashboard_projects_url xml.updated @events[0].updated_at.xmlschema if @events[0] - @events.each do |event| - event_to_atom(xml, event) - end + xml << render(partial: 'events/event', collection: @events) if @events.any? end diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index aa0aff86d4d97f..98f302d2f937dc 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -1,13 +1,15 @@ %li{class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo), data:{url: todo_target_path(todo)} } .todo-item.todo-block = image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:'' - .todo-title.title - %span.author-name - - if todo.author - = link_to_author(todo) - - else - (removed) + - unless todo.build_failed? + = todo_target_state_pill(todo) + + %span.author-name + - if todo.author + = link_to_author(todo) + - else + (removed) %span.todo-label = todo_action_name(todo) - if todo.target diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb deleted file mode 100644 index c6fa8f0ee361b4..00000000000000 --- a/app/views/devise/mailer/confirmation_instructions.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -

    Welcome <%= @resource.name %>!

    - -<% if @resource.unconfirmed_email.present? %> -

    You can confirm your email (<%= @resource.unconfirmed_email %>) through the link below:

    -<% else %> -

    You can confirm your account through the link below:

    -<% end %> - -

    <%= link_to 'Confirm your account', confirmation_url(@resource, confirmation_token: @token) %>

    diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml new file mode 100644 index 00000000000000..086bb8e083d389 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.haml @@ -0,0 +1,16 @@ +.center + - if @resource.unconfirmed_email.present? + #content + %h2= @resource.unconfirmed_email + %p Click the link below to confirm your email address. + #cta + = link_to 'Confirm your email address', confirmation_url(@resource, confirmation_token: @token) + - else + #content + - if Gitlab.com? + %h2 Thanks for signing up to GitLab! + - else + %h2 Welcome, #{@resource.name}! + %p To get started, click the link below to confirm your account. + #cta + = link_to 'Confirm your account', confirmation_url(@resource, confirmation_token: @token) diff --git a/app/views/devise/mailer/confirmation_instructions.text.erb b/app/views/devise/mailer/confirmation_instructions.text.erb new file mode 100644 index 00000000000000..9f76edb76a4ed8 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.text.erb @@ -0,0 +1,9 @@ +Welcome, <%= @resource.name %>! + +<% if @resource.unconfirmed_email.present? %> +You can confirm your email (<%= @resource.unconfirmed_email %>) through the link below: +<% else %> +You can confirm your account through the link below: +<% end %> + +<%= confirmation_url(@resource, confirmation_token: @token) %> diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index d65fa60025cefa..28194506accff5 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -4,7 +4,7 @@ = render 'devise/shared/signin_box' -# Omniauth fits between signin/ldap signin and signup and does not have a surrounding box - - if omniauth_enabled? && devise_mapping.omniauthable? + - if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled? .clearfix.prepend-top-20 = render 'devise/shared/omniauth_box' diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml index c9d1e454a5e174..8c6a1552a53cec 100644 --- a/app/views/devise/sessions/two_factor.html.haml +++ b/app/views/devise/sessions/two_factor.html.haml @@ -4,6 +4,7 @@ %h3 Two-factor Authentication .login-body = form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f| + = f.hidden_field :remember_me, value: params[resource_name][:remember_me] = f.text_field :otp_attempt, class: 'form-control', placeholder: 'Two-factor Authentication code', required: true, autofocus: true %p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes. .prepend-top-20 diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index ecf680e7b23313..de18bc2d844123 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -1,7 +1,7 @@ %p %span.light Sign in with   - - providers = button_based_providers + - providers = enabled_button_based_providers - providers.each do |provider| %span.light - has_icon = provider_has_icon?(provider) diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml index eae80e5210fd2f..ce050007204f14 100644 --- a/app/views/doorkeeper/authorizations/new.html.haml +++ b/app/views/doorkeeper/authorizations/new.html.haml @@ -1,4 +1,4 @@ -%h3.page-title Authorize required +%h3.page-title Authorization required %main{:role => "main"} %p.h4 Authorize diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml index dce4081288cecb..1bc9f604438588 100644 --- a/app/views/events/_commit.html.haml +++ b/app/views/events/_commit.html.haml @@ -2,4 +2,4 @@ .commit-row-title = link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: '', title: truncate_sha(commit[:id]) · - = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line + = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line, author: event.author diff --git a/app/views/events/_event.atom.builder b/app/views/events/_event.atom.builder new file mode 100644 index 00000000000000..7890e717aa7c60 --- /dev/null +++ b/app/views/events/_event.atom.builder @@ -0,0 +1,20 @@ +return unless event.visible_to_user?(current_user) + +xml.entry do + xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" + xml.link href: event_feed_url(event) + xml.title truncate(event_feed_title(event), length: 80) + xml.updated event.created_at.xmlschema + xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(event.author_email)) + + xml.author do + xml.name event.author_name + xml.email event.author_email + end + + xml.summary(type: "xhtml") do |summary| + event_summary = event_feed_summary(event) + + summary << event_summary unless event_summary.nil? + end +end diff --git a/app/views/events/_event_issue.atom.haml b/app/views/events/_event_issue.atom.haml index fad65310021542..083c3936212d09 100644 --- a/app/views/events/_event_issue.atom.haml +++ b/app/views/events/_event_issue.atom.haml @@ -1,2 +1,2 @@ %div{xmlns: "http://www.w3.org/1999/xhtml"} - = markdown(issue.description, pipeline: :atom, project: issue.project) + = markdown(issue.description, pipeline: :atom, project: issue.project, author: issue.author) diff --git a/app/views/events/_event_merge_request.atom.haml b/app/views/events/_event_merge_request.atom.haml index 19bdc7b9ca540f..d7e05600627cc6 100644 --- a/app/views/events/_event_merge_request.atom.haml +++ b/app/views/events/_event_merge_request.atom.haml @@ -1,2 +1,2 @@ %div{xmlns: "http://www.w3.org/1999/xhtml"} - = markdown(merge_request.description, pipeline: :atom, project: merge_request.project) + = markdown(merge_request.description, pipeline: :atom, project: merge_request.project, author: merge_request.author) diff --git a/app/views/events/_event_note.atom.haml b/app/views/events/_event_note.atom.haml index b730ebbd5f9f50..1154f98282130b 100644 --- a/app/views/events/_event_note.atom.haml +++ b/app/views/events/_event_note.atom.haml @@ -1,2 +1,2 @@ %div{xmlns: "http://www.w3.org/1999/xhtml"} - = markdown(note.note, pipeline: :atom, project: note.project) + = markdown(note.note, pipeline: :atom, project: note.project, author: note.author) diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml index b271b9daff1160..28bee1d0a33a53 100644 --- a/app/views/events/_event_push.atom.haml +++ b/app/views/events/_event_push.atom.haml @@ -6,7 +6,7 @@ %i at = commit[:timestamp].to_time.to_s(:short) - %blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project) + %blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project, author: event.author) - if event.commits_count > 15 %p %i diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml index c994e3b997de6b..c7f29f2fc0e5f0 100644 --- a/app/views/events/event/_common.html.haml +++ b/app/views/events/event/_common.html.haml @@ -4,7 +4,7 @@ = event_action_name(event) - if event.target - %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target] + %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], class: 'has-tooltip', title: event.target_title = event_preposition(event) diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index 235bd46107ee7d..dc4ff17e31abfc 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -15,7 +15,7 @@ %ul.well-list.event_commits - few_commits = event.commits[0...2] - few_commits.each do |commit| - = render "events/commit", commit: commit, project: project + = render "events/commit", commit: commit, project: project, event: event - create_mr = event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project) - if event.commits_count > 1 diff --git a/app/views/groups/_activities.html.haml b/app/views/groups/_activities.html.haml index dc76599b7767fe..71cc4d87b1f3ee 100644 --- a/app/views/groups/_activities.html.haml +++ b/app/views/groups/_activities.html.haml @@ -4,7 +4,7 @@ .nav-block - if current_user .controls - = link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'btn rss-btn' do + = link_to group_path(@group, format: :atom, private_token: current_user.private_token), class: 'btn rss-btn' do %i.fa.fa-rss = render 'shared/event_filter' diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder index 486d1d8587a6a7..c19671295af3c4 100644 --- a/app/views/groups/issues.atom.builder +++ b/app/views/groups/issues.atom.builder @@ -1,13 +1,10 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "#{@user.name} issues" - xml.link href: issues_dashboard_url(format: :atom, private_token: @user.private_token), rel: "self", type: "application/atom+xml" - xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html" - xml.id issues_dashboard_url + xml.title "#{@group.name} issues" + xml.link href: issues_group_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" + xml.link href: issues_group_url, rel: "alternate", type: "text/html" + xml.id issues_group_url xml.updated @issues.first.created_at.xmlschema if @issues.any? - @issues.each do |issue| - issue_to_atom(xml, issue) - end + xml << render(partial: 'issues/issue', collection: @issues) if @issues.any? end - diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder index c66b82bb484f06..b68bf444d27f5e 100644 --- a/app/views/groups/show.atom.builder +++ b/app/views/groups/show.atom.builder @@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id group_url(@group) xml.updated @events[0].updated_at.xmlschema if @events[0] - @events.each do |event| - event_to_atom(xml, event) - end + xml << render(@events) if @events.any? end diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml index e3a356b53792c2..aedb8468eca9e1 100644 --- a/app/views/import/gitlab/status.html.haml +++ b/app/views/import/gitlab/status.html.haml @@ -47,7 +47,7 @@ %td.import-target = repo["path_with_namespace"] %td.import-actions.job-status - = button_tag class: "btn js-add-to-import" do + = button_tag class: "btn btn-import js-add-to-import" do Import = icon("spinner spin", class: "loading-icon") diff --git a/app/views/issues/_issue.atom.builder b/app/views/issues/_issue.atom.builder new file mode 100644 index 00000000000000..68a2d19e58dc8a --- /dev/null +++ b/app/views/issues/_issue.atom.builder @@ -0,0 +1,14 @@ +xml.entry do + xml.id namespace_project_issue_url(issue.project.namespace, issue.project, issue) + xml.link href: namespace_project_issue_url(issue.project.namespace, issue.project, issue) + xml.title truncate(issue.title, length: 80) + xml.updated issue.created_at.xmlschema + xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(issue.author_email)) + + xml.author do |author| + xml.name issue.author_name + xml.email issue.author_email + end + + xml.summary issue.title +end diff --git a/app/views/kaminari/gitlab/_first_page.html.haml b/app/views/kaminari/gitlab/_first_page.html.haml index ada7306d98de10..e7a70e3bb28d5b 100644 --- a/app/views/kaminari/gitlab/_first_page.html.haml +++ b/app/views/kaminari/gitlab/_first_page.html.haml @@ -2,7 +2,7 @@ -# available local variables -# url: url to the first page -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote %li.first diff --git a/app/views/kaminari/gitlab/_gap.html.haml b/app/views/kaminari/gitlab/_gap.html.haml index 3ffd12f8587aa7..80ca30f36e66f1 100644 --- a/app/views/kaminari/gitlab/_gap.html.haml +++ b/app/views/kaminari/gitlab/_gap.html.haml @@ -1,7 +1,7 @@ -# Non-link tag that stands for skipped pages... -# available local variables -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote %li{class: "page"} diff --git a/app/views/kaminari/gitlab/_last_page.html.haml b/app/views/kaminari/gitlab/_last_page.html.haml index 3431d029bcce57..53f780d1d1bc96 100644 --- a/app/views/kaminari/gitlab/_last_page.html.haml +++ b/app/views/kaminari/gitlab/_last_page.html.haml @@ -2,7 +2,7 @@ -# available local variables -# url: url to the last page -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote %li.last diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml index c805914fc3fcc0..125f09777ba503 100644 --- a/app/views/kaminari/gitlab/_next_page.html.haml +++ b/app/views/kaminari/gitlab/_next_page.html.haml @@ -2,7 +2,7 @@ -# available local variables -# url: url to the next page -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote - if current_page.last? diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml index a52d883b9a8461..522e4d1d05fd57 100644 --- a/app/views/kaminari/gitlab/_page.html.haml +++ b/app/views/kaminari/gitlab/_page.html.haml @@ -3,7 +3,7 @@ -# page: a page object for "this" page -# url: url to this page -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote %li{class: "page#{' active' if page.current?}"} diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml index a12c53bcfe7134..f5e0d2ed3f30df 100644 --- a/app/views/kaminari/gitlab/_paginator.html.haml +++ b/app/views/kaminari/gitlab/_paginator.html.haml @@ -1,7 +1,7 @@ -# The container tag -# available local variables -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote -# paginator: the paginator that renders the pagination tags inside @@ -9,7 +9,7 @@ %div.gl-pagination %ul.pagination.clearfix - unless current_page.first? - = first_page_tag unless num_pages < 5 # As kaminari will always show the first 5 pages + = first_page_tag unless total_pages < 5 # As kaminari will always show the first 5 pages = prev_page_tag - each_page do |page| - if page.left_outer? || page.right_outer? || page.inside_window? @@ -18,5 +18,5 @@ = gap_tag = next_page_tag - unless current_page.last? - = last_page_tag unless num_pages < 5 + = last_page_tag unless total_pages < 5 diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml index afb20455e0a372..7edf10498a80e2 100644 --- a/app/views/kaminari/gitlab/_prev_page.html.haml +++ b/app/views/kaminari/gitlab/_prev_page.html.haml @@ -2,7 +2,7 @@ -# available local variables -# url: url to the previous page -# current_page: a page object for the currently displayed page --# num_pages: total number of pages +-# total_pages: total number of pages -# per_page: number of items to fetch per page -# remote: data-remote - if current_page.first? diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 79cdbac1f37bae..b30fb0a5da9ecb 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -30,6 +30,9 @@ = javascript_include_tag "application" + - if page_specific_javascripts + = javascript_include_tag page_specific_javascripts, {"data-turbolinks-track" => true} + = csrf_meta_tags = include_gon diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 3c3bc41bf0e129..1e961853c7079d 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -1,5 +1,4 @@ .page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" } - = render "layouts/broadcast" .sidebar-wrapper.nicescroll{ class: nav_sidebar_class } .header-logo %a#logo @@ -26,7 +25,8 @@ .layout-nav .container-fluid = render "layouts/nav/#{nav}" - .content-wrapper{ class: ('page-with-layout-nav' if defined?(nav) && nav) } + .content-wrapper{ class: "#{layout_nav_class}" } + = render "layouts/broadcast" = render "layouts/flash" = yield :flash_message %div{ class: (container_class unless @no_container) } diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 6b208c3d0bb485..b49207fc3150ee 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -6,11 +6,8 @@ .search.search-form{class: "#{'has-location-badge' if label.present?}"} = form_tag search_path, method: :get, class: 'navbar-form' do |f| .search-input-container - .search-location-badge - - if label.present? - %span.location-badge - %i.location-text - = label + - if label.present? + .location-badge= label .search-input-wrap .dropdown{ data: {url: search_autocomplete_path } } = search_field_tag "search", nil, placeholder: 'Search', class: "search-input dropdown-menu-toggle", spellcheck: false, tabindex: "1", autocomplete: 'off', data: { toggle: 'dropdown' } diff --git a/app/views/layouts/devise_mailer.html.haml b/app/views/layouts/devise_mailer.html.haml new file mode 100644 index 00000000000000..c258eafdd51c22 --- /dev/null +++ b/app/views/layouts/devise_mailer.html.haml @@ -0,0 +1,34 @@ +!!! 5 +%html + %head + %meta(content='text/html; charset=UTF-8' http-equiv='Content-Type') + = stylesheet_link_tag 'mailers/devise' + + %body + %table#wrapper + %tr + %td + %table#header + %td{valign: "top"} + = image_tag('mailers/gitlab_header_logo.png', id: 'logo', alt: 'GitLab Wordmark') + + %table#body + %tr + %td#body-container + = yield + + - if Gitlab.com? + %table#footer + %tr + %td#tanuki + = image_tag('mailers/gitlab_tanuki_2x.png', alt: 'GitLab Logo') + %tr + %td#tagline + Everyone can contribute + %tr + %td#social + = link_to 'Blog', 'https://about.gitlab.com/blog/' + = link_to 'Twitter', 'https://twitter.com/gitlab' + = link_to 'Facebook', 'https://www.facebook.com/gitlab/' + = link_to 'YouTube', 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg' + = link_to 'LinkedIn', 'https://www.linkedin.com/company/gitlab-com' diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 86930d4eaaf85f..c33740e23fad45 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -1,9 +1,12 @@ %header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class } %div{ class: fluid_layout ? "container-fluid" : "container-fluid" } .header-content - %button.navbar-toggle{type: 'button'} + %button.side-nav-toggle{type: 'button'} %span.sr-only Toggle navigation = icon('bars') + %button.navbar-toggle{type: 'button'} + %span.sr-only Toggle navigation + = icon('angle-left') .navbar-collapse.collapse %ul.nav.navbar-nav @@ -24,8 +27,9 @@ %li = link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = icon('bell fw') - %span.badge.todos-pending-count - = todos_pending_count + - unless todos_pending_count == 0 + %span.badge.todos-pending-count + = todos_pending_count - if current_user.can_create_project? %li = link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index 280a1b93729ba4..f292730fe4575f 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -41,6 +41,11 @@ = icon('file-text fw') %span Logs + = nav_link(controller: :health_check) do + = link_to admin_health_check_path, title: 'Health Check' do + = icon('medkit fw') + %span + Health Check = nav_link(controller: :broadcast_messages) do = link_to admin_broadcast_messages_path, title: 'Messages' do = icon('bullhorn fw') diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index fad4224e945379..306ebd5fcf71e7 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -1,6 +1,6 @@ %ul.nav.nav-sidebar - = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: 'home'}) do - = link_to dashboard_projects_path, title: 'Projects' do + = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: "#{project_tab_class} home"}) do + = link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do = icon('bookmark fw') %span Projects @@ -11,7 +11,7 @@ Todos %span.count.todos-pending-count= number_with_delimiter(todos_pending_count) = nav_link(path: 'dashboard#activity') do - = link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity' do + = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do = icon('dashboard fw') %span Activity @@ -26,17 +26,17 @@ %span Milestones = nav_link(path: 'dashboard#issues') do - = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues' do + = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues' do = icon('exclamation-circle fw') %span Issues - %span.count= number_with_delimiter(current_user.assigned_issues.opened.count) + %span.count= number_with_delimiter(current_user.assigned_open_issues_count) = nav_link(path: 'dashboard#merge_requests') do - = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests' do + = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'dashboard-shortcuts-merge_requests' do = icon('tasks fw') %span Merge Requests - %span.count= number_with_delimiter(current_user.assigned_merge_requests.opened.count) + %span.count= number_with_delimiter(current_user.assigned_open_merge_request_count) = nav_link(controller: :snippets) do = link_to dashboard_snippets_path, title: 'Snippets' do = icon('clipboard fw') diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index 3438005863ad2f..de15add361767f 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -1,37 +1,40 @@ -= render 'layouts/nav/group_settings' +%div{ class: nav_control_class } + = render 'layouts/nav/group_settings' -%ul.nav-links - = nav_link(path: 'groups#show', html_options: {class: 'home'}) do - = link_to group_path(@group), title: 'Home' do - = icon('group fw') - %span - Group - = nav_link(path: 'groups#activity') do - = link_to activity_group_path(@group), title: 'Activity' do - = icon('dashboard fw') - %span - Activity - = nav_link(controller: [:group, :milestones]) do - = link_to group_milestones_path(@group), title: 'Milestones' do - = icon('clock-o fw') - %span - Milestones - = nav_link(path: 'groups#issues') do - = link_to issues_group_path(@group), title: 'Issues' do - = icon('exclamation-circle fw') - %span - Issues - - issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute - %span.badge.count= number_with_delimiter(issues.count) - = nav_link(path: 'groups#merge_requests') do - = link_to merge_requests_group_path(@group), title: 'Merge Requests' do - = icon('tasks fw') - %span - Merge Requests - - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').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 - = icon('users fw') - %span - Members + %ul.nav-links.scrolling-tabs + .fade-left + = nav_link(path: 'groups#show', html_options: {class: 'home'}) do + = link_to group_path(@group), title: 'Home' do + = icon('group fw') + %span + Group + = nav_link(path: 'groups#activity') do + = link_to activity_group_path(@group), title: 'Activity' do + = icon('dashboard fw') + %span + Activity + = nav_link(controller: [:group, :milestones]) do + = link_to group_milestones_path(@group), title: 'Milestones' do + = icon('clock-o fw') + %span + Milestones + = nav_link(path: 'groups#issues') do + = link_to issues_group_path(@group), title: 'Issues' do + = icon('exclamation-circle fw') + %span + Issues + - issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute + %span.badge.count= number_with_delimiter(issues.count) + = nav_link(path: 'groups#merge_requests') do + = link_to merge_requests_group_path(@group), title: 'Merge Requests' do + = icon('tasks fw') + %span + Merge Requests + - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').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 + = icon('users fw') + %span + Members + .fade-right diff --git a/app/views/layouts/nav/_group_settings.html.haml b/app/views/layouts/nav/_group_settings.html.haml index e391ec7f2b7faa..0b2673f1a8291f 100644 --- a/app/views/layouts/nav/_group_settings.html.haml +++ b/app/views/layouts/nav/_group_settings.html.haml @@ -1,7 +1,7 @@ - if current_user - if access = @group.users.find_by(id: current_user.id) .controls - %span.dropdown.group-settings-dropdown + .dropdown.group-settings-dropdown %a.dropdown-new.btn.btn-default#group-settings-button{href: '#', 'data-toggle' => 'dropdown'} = icon('cog') = icon('caret-down') diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index d730840d63a9e9..2efc6c48a48517 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -1,4 +1,5 @@ -%ul.nav-links +%ul.nav-links.scrolling-tabs + .fade-left = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = link_to profile_path, title: 'Profile Settings' do = icon('user fw') @@ -47,3 +48,4 @@ = icon('history fw') %span Audit Log + .fade-right diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 479bde33719e6c..9792c1c93b4dc4 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -1,131 +1,131 @@ -%ul.nav.nav-sidebar - - if @project.group - = nav_link do - = link_to group_path(@project.group), title: 'Go to group', class: 'back-link' do - = icon('caret-square-o-left fw') +- if current_user + .controls + - access = user_max_access_in_project(current_user.id, @project) + - can_edit = can?(current_user, :admin_project, @project) + .dropdown.project-settings-dropdown + %a.dropdown-new.btn.btn-default#project-settings-button{href: '#', 'data-toggle' => 'dropdown'} + = icon('cog') + = icon('caret-down') + %ul.dropdown-menu.dropdown-menu-align-right + = render 'layouts/nav/project_settings' + %li.divider + - if can_edit + %li + = link_to edit_project_path(@project) do + Edit Project + - if access + %li + = link_to leave_namespace_project_project_members_path(@project.namespace, @project), + data: { confirm: leave_project_message(@project) }, method: :delete, title: 'Leave project' do + Leave Project + +%div{ class: nav_control_class } + %ul.nav-links.scrolling-tabs + .fade-left + = nav_link(path: 'projects#show', html_options: {class: 'home'}) do + = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do + = icon('bookmark fw') %span - Go to group - - else - = nav_link do - = link_to root_path, title: 'Go to dashboard', class: 'back-link' do - = icon('caret-square-o-left fw') + Project + = nav_link(path: 'projects#activity') do + = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do + = icon('dashboard fw') %span - Go to dashboard - - %li.separate-item - - = nav_link(path: 'projects#show', html_options: {class: 'home'}) do - = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do - = icon('bookmark fw') - %span - Project - = nav_link(path: 'projects#activity') do - = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do - = icon('dashboard fw') - %span - Activity - - if project_nav_tab? :files - = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do - = link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do - = icon('files-o fw') - %span - Files - - - if project_nav_tab? :commits - = nav_link(controller: %w(commit commits compare repositories tags branches releases network)) do - = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do - = icon('history fw') - %span - Commits + Activity + - if project_nav_tab? :files + = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do + = link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do + = icon('code fw') + %span + Code + + - if project_nav_tab? :pipelines + = nav_link(controller: :pipelines) do + = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do + = icon('ship fw') + %span + Pipelines + + - if project_nav_tab? :container_registry + = nav_link(controller: %w(container_registry)) do + = link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do + = icon('hdd-o fw') + %span + Container Registry + + - if project_nav_tab? :graphs + = nav_link(controller: %w(graphs)) do + = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs' do + = icon('area-chart fw') + %span + Graphs + + - if project_nav_tab? :milestones + = nav_link(controller: :milestones) do + = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do + = icon('clock-o fw') + %span + Milestones + + - if project_nav_tab? :issues + = nav_link(controller: :issues) do + = link_to url_for_project_issues(@project, only_path: true), title: 'Issues', class: 'shortcuts-issues' do + = icon('exclamation-circle fw') + %span + Issues + - if @project.default_issues_tracker? + %span.badge.count.issue_counter= number_with_delimiter(@project.issues.visible_to_user(current_user).opened.count) + + - if project_nav_tab? :merge_requests + = nav_link(controller: :merge_requests) do + = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do + = icon('tasks fw') + %span + Merge Requests + %span.badge.count.merge_counter= number_with_delimiter(@project.merge_requests.opened.count) + + - if project_nav_tab? :labels + = nav_link(controller: :labels) do + = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do + = icon('tags fw') + %span + Labels + + - if project_nav_tab? :wiki + = nav_link(controller: :wikis) do + = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do + = icon('book fw') + %span + Wiki + + - if project_nav_tab? :snippets + = nav_link(controller: :snippets) do + = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do + = icon('clipboard fw') + %span + Snippets + + -# Global shortcut to network page for compatibility + - if project_nav_tab? :network + %li.hidden + = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do + Network + + -# Shortcut to create a new issue + %li.hidden + = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do + Create a new issue - - if project_nav_tab? :builds - = nav_link(controller: %w(builds)) do - = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do - = icon('cubes fw') - %span + -# Shortcut to builds page + - if project_nav_tab? :builds + %li.hidden + = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do Builds - %span.count.builds_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all)) - - - if project_nav_tab? :graphs - = nav_link(controller: %w(graphs)) do - = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs' do - = icon('area-chart fw') - %span - Graphs - - - if project_nav_tab? :milestones - = nav_link(controller: :milestones) do - = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do - = icon('clock-o fw') - %span - Milestones - - - if project_nav_tab? :issues - = nav_link(controller: :issues) do - = link_to url_for_project_issues(@project, only_path: true), title: 'Issues', class: 'shortcuts-issues' do - = icon('exclamation-circle fw') - %span - Issues - - if @project.default_issues_tracker? - %span.count.issue_counter= number_with_delimiter(@project.issues.visible_to_user(current_user).opened.count) - - - if project_nav_tab? :merge_requests - = nav_link(controller: :merge_requests) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do - = icon('tasks fw') - %span - Merge Requests - %span.count.merge_counter= number_with_delimiter(@project.merge_requests.opened.count) - - - if project_nav_tab? :team - = nav_link(controller: [:project_members, :teams]) do - = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab' do - = icon('users fw') - %span - Members - - - if project_nav_tab? :labels - = nav_link(controller: :labels) do - = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do - = icon('tags fw') - %span - Labels - - - if project_nav_tab? :wiki - = nav_link(controller: :wikis) do - = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do - = icon('book fw') - %span - Wiki - - if project_nav_tab? :forks - = nav_link(controller: :forks, action: :index) do - = link_to namespace_project_forks_path(@project.namespace, @project), title: 'Forks' do - = icon('code-fork fw') - %span - Forks - - - if project_nav_tab? :snippets - = nav_link(controller: :snippets) do - = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do - = icon('clipboard fw') - %span - Snippets - - - if project_nav_tab? :settings - = nav_link(html_options: {class: "#{project_tab_class} separate-item"}) do - = link_to edit_project_path(@project), title: 'Settings' do - = icon('cogs fw') - %span - Settings - - -# Global shortcut to network page for compatibility - - if project_nav_tab? :network - %li.hidden - = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do - Network + -# Shortcut to commits page + - if project_nav_tab? :commits + %li.hidden + = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do + Commits - -# Shortcut to create a new issue - %li.hidden - = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do - Create a new issue + .fade-right diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml index d429a928464db1..885e78d38c6a17 100644 --- a/app/views/layouts/nav/_project_settings.html.haml +++ b/app/views/layouts/nav/_project_settings.html.haml @@ -1,63 +1,45 @@ -%ul.nav.nav-sidebar - = nav_link do - = link_to project_path(@project), title: 'Go to project', class: 'back-link' do - = icon('caret-square-o-left fw') +- if project_nav_tab? :team + = nav_link(controller: [:project_members, :teams]) do + = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab' do %span - Go to project + Members - %li.separate-item - - %ul.sidebar-subnav - = nav_link(path: 'projects#edit') do - = link_to edit_project_path(@project), title: 'Project Settings' do - = icon('pencil-square-o fw') - %span - Project Settings - - if @project.allowed_to_share_with_group? - = nav_link(controller: :group_links) do - = link_to namespace_project_group_links_path(@project.namespace, @project), title: "Groups" do - = icon('share-square-o fw') - %span - Groups - = nav_link(controller: :deploy_keys) do - = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys' do - = icon('key fw') - %span - Deploy Keys - = nav_link(controller: :hooks) do - = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Webhooks' do - = icon('link fw') - %span - Webhooks - = nav_link(controller: :services) do - = link_to namespace_project_services_path(@project.namespace, @project), title: 'Services' do - = icon('cogs fw') - %span - Services - = nav_link(controller: :protected_branches) do - = link_to namespace_project_protected_branches_path(@project.namespace, @project), title: 'Protected Branches' do - = icon('lock fw') - %span - Protected Branches +- if @project.allowed_to_share_with_group? + = nav_link(controller: :group_links) do + = link_to namespace_project_group_links_path(@project.namespace, @project), title: "Groups" do + %span + Groups += nav_link(controller: :deploy_keys) do + = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys' do + %span + Deploy Keys += nav_link(controller: :hooks) do + = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Webhooks' do + %span + Webhooks += nav_link(controller: :services) do + = link_to namespace_project_services_path(@project.namespace, @project), title: 'Services' do + %span + Services += nav_link(controller: :protected_branches) do + = link_to namespace_project_protected_branches_path(@project.namespace, @project), title: 'Protected Branches' do + %span + Protected Branches - - if @project.builds_enabled? - = nav_link(controller: :runners) do - = link_to namespace_project_runners_path(@project.namespace, @project), title: 'Runners' do - = icon('cog fw') - %span - Runners - = nav_link(controller: :variables) do - = link_to namespace_project_variables_path(@project.namespace, @project), title: 'Variables' do - = icon('code fw') - %span - Variables - = nav_link(controller: :triggers) do - = link_to namespace_project_triggers_path(@project.namespace, @project), title: 'Triggers' do - = icon('retweet fw') - %span - Triggers - = nav_link(controller: :badges) do - = link_to namespace_project_badges_path(@project.namespace, @project), title: 'Badges' do - = icon('star-half-empty fw') - %span - Badges +- if @project.builds_enabled? + = nav_link(controller: :runners) do + = link_to namespace_project_runners_path(@project.namespace, @project), title: 'Runners' do + %span + Runners + = nav_link(controller: :variables) do + = link_to namespace_project_variables_path(@project.namespace, @project), title: 'Variables' do + %span + Variables + = nav_link(controller: :triggers) do + = link_to namespace_project_triggers_path(@project.namespace, @project), title: 'Triggers' do + %span + Triggers + = nav_link(controller: :badges) do + = link_to namespace_project_badges_path(@project.namespace, @project), title: 'Badges' do + %span + Badges diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 2997f59d946b4d..dde2e2889dc31c 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -4,6 +4,7 @@ %title GitLab = stylesheet_link_tag 'notify' + = yield :head %body %div.content = yield diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 6dfe7fbdae8115..20d6cdf7246a7d 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -1,7 +1,7 @@ - page_title @project.name_with_namespace - page_description @project.description unless page_description - header_title project_title(@project) unless header_title -- sidebar "project" unless sidebar +- nav "project" - content_for :scripts_body_top do - project = @target_project || @project diff --git a/app/views/layouts/project_settings.html.haml b/app/views/layouts/project_settings.html.haml index 59ce38f67bbd86..4bc94bd132daa3 100644 --- a/app/views/layouts/project_settings.html.haml +++ b/app/views/layouts/project_settings.html.haml @@ -1,5 +1,4 @@ - page_title "Settings" -- header_title project_title(@project, "Settings", edit_project_path(@project)) -- sidebar "project_settings" +- nav "project" = render template: "layouts/project" diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml index 12ded41fbf2ae5..e9c66170877c85 100644 --- a/app/views/notify/_note_message.html.haml +++ b/app/views/notify/_note_message.html.haml @@ -2,4 +2,4 @@ %div #{link_to @note.author_name, user_url(@note.author)} wrote: %div - = markdown(@note.note, pipeline: :email) + = markdown(@note.note, pipeline: :email, author: @note.author) diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml index ad3ab2525bbfca..f42b150c0d60cd 100644 --- a/app/views/notify/new_issue_email.html.haml +++ b/app/views/notify/new_issue_email.html.haml @@ -2,7 +2,7 @@ %div #{link_to @issue.author_name, user_url(@issue.author)} wrote: -if @issue.description - = markdown(@issue.description, pipeline: :email) + = markdown(@issue.description, pipeline: :email, author: @issue.author) - if @issue.assignee_id.present? %p diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml index 23423e7d981019..158404de396084 100644 --- a/app/views/notify/new_merge_request_email.html.haml +++ b/app/views/notify/new_merge_request_email.html.haml @@ -9,4 +9,4 @@ Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} -if @merge_request.description - = markdown(@merge_request.description, pipeline: :email) + = markdown(@merge_request.description, pipeline: :email, author: @merge_request.author) diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml index 65f0e4c4068fbb..a3643a00cfe731 100644 --- a/app/views/notify/note_merge_request_email.html.haml +++ b/app/views/notify/note_merge_request_email.html.haml @@ -1,7 +1,7 @@ -- if @note.diff_file_name +- if @note.legacy_diff_note? %p.details New comment on diff for - = link_to @note.diff_file_name, @target_url + = link_to @note.diff_file_path, @target_url \: = render 'note_message' diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml index f2e405b14fd30c..f1532371b2efe8 100644 --- a/app/views/notify/repository_push_email.html.haml +++ b/app/views/notify/repository_push_email.html.haml @@ -1,3 +1,6 @@ += content_for :head do + = stylesheet_link_tag 'mailers/repository_push_email' + %h3 #{@message.author_name} #{@message.action_name} #{@message.ref_type} #{@message.ref_name} at #{link_to(@message.project_name_with_namespace, namespace_project_url(@message.project_namespace, @message.project))} @@ -43,26 +46,38 @@ = diff.new_path - unless @message.disable_diffs? - %h4 Changes: - - @message.diffs.each_with_index do |diff, i| - %li{id: "diff-#{i}"} - %a{href: @message.target_url + "#diff-#{i}"} - - if diff.deleted_file - %strong - = diff.old_path - deleted - - elsif diff.renamed_file - %strong - = diff.old_path - → - %strong - = diff.new_path - - else - %strong - = diff.new_path - %hr - = color_email_diff(diff.diff) - %br + - diff_files = @message.diffs - - if @message.compare_timeout - %h5 Huge diff. To prevent performance issues changes are hidden + - if @message.compare_timeout + %h5 The diff was not included because it is too large. + - else + %h4 Changes: + - diff_files.each_with_index do |diff_file, i| + %li{id: "diff-#{i}"} + %a{href: @message.target_url + "#diff-#{i}"}< + - if diff_file.deleted_file + %strong< + = diff_file.old_path + deleted + - elsif diff_file.renamed_file + %strong< + = diff_file.old_path + → + %strong< + = diff_file.new_path + - else + %strong< + = diff_file.new_path + - if diff_file.too_large? + The diff for this file was not included because it is too large. + - else + %hr + - diff_commit = diff_file.deleted_file ? @message.diff_refs.first : @message.diff_refs.last + - blob = @message.project.repository.blob_for_diff(diff_commit, diff_file) + - if blob && blob.respond_to?(:text?) && blob_text_viewable?(blob) + %table.code.white + - diff_file.highlighted_diff_lines.each do |line| + = render "projects/diffs/line", {line: line, diff_file: diff_file, line_code: nil, plain: true} + - else + No preview for this file type + %br diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml index 53869e36b2806d..5ac23aa3997f67 100644 --- a/app/views/notify/repository_push_email.text.haml +++ b/app/views/notify/repository_push_email.text.haml @@ -25,24 +25,28 @@ - else \- #{diff.new_path} - unless @message.disable_diffs? - \ - \ - Changes: - - @message.diffs.each do |diff| + - if @message.compare_timeout \ - \===================================== - - if diff.deleted_file - #{diff.old_path} deleted - - elsif diff.renamed_file - #{diff.old_path} → #{diff.new_path} - - else - = diff.new_path - \===================================== - != diff.diff - - if @message.compare_timeout - \ - \ - Huge diff. To prevent performance issues it was hidden + \ + The diff was not included because it is too large. + - else + \ + \ + Changes: + - @message.diffs.each do |diff_file| + \ + \===================================== + - if diff_file.deleted_file + #{diff_file.old_path} deleted + - elsif diff_file.renamed_file + #{diff_file.old_path} → #{diff_file.new_path} + - else + = diff_file.new_path + \===================================== + - if diff_file.too_large? + The diff for this file was not included because it is too large. + - else + != diff_file.diff.diff - if @message.target_url \ \ diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index afd3d79321f045..01ac8161945d2b 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -70,7 +70,7 @@ - if current_user.can_change_username? .row.prepend-top-default .col-lg-3.profile-settings-sidebar - %h4.prepend-top-0.change-username-title + %h4.prepend-top-0.warning-title Change username %p Changing your username will change path to all personal projects! @@ -94,7 +94,7 @@ - if signup_enabled? .row.prepend-top-default .col-lg-3.profile-settings-sidebar - %h4.prepend-top-0.remove-account-title + %h4.prepend-top-0.danger-title Remove account .col-lg-9 - if @user.can_be_removed? diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index bfe53be6854c0a..1b1b16d656f1ed 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -5,7 +5,7 @@ %h4.prepend-top-0 Application theme %p - This setting allows you to customize the appearance of the site, ex. sidebar. + This setting allows you to customize the appearance of the site, e.g. the sidebar. .col-lg-9.application-theme - Gitlab::Themes.each do |theme| = label_tag do diff --git a/app/views/projects/_builds_settings.html.haml b/app/views/projects/_builds_settings.html.haml index 0de019983ca4ef..0568c2d305e8f8 100644 --- a/app/views/projects/_builds_settings.html.haml +++ b/app/views/projects/_builds_settings.html.haml @@ -1,74 +1,65 @@ %fieldset.builds-feature - %legend - Builds: - + %h5.prepend-top-0 + Builds - unless @repository.gitlab_ci_yml .form-group - .col-sm-offset-2.col-sm-10 - %p Builds need to be configured before you can begin using Continuous Integration. - = link_to 'Get started with Builds', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info' - %hr - + %p Builds need to be configured before you can begin using Continuous Integration. + = link_to 'Get started with Builds', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info' .form-group - .col-sm-offset-2.col-sm-10 - %p Get recent application code using the following command: - .radio - = f.label :build_allow_git_fetch_false do - = f.radio_button :build_allow_git_fetch, 'false' - %strong git clone - %br - %span.descr Slower but makes sure you have a clean dir before every build - .radio - = f.label :build_allow_git_fetch_true do - = f.radio_button :build_allow_git_fetch, 'true' - %strong git fetch - %br - %span.descr Faster + %p Get recent application code using the following command: + .radio + = f.label :build_allow_git_fetch_false do + = f.radio_button :build_allow_git_fetch, 'false' + %strong git clone + %br + %span.descr Slower but makes sure you have a clean dir before every build + .radio + = f.label :build_allow_git_fetch_true do + = f.radio_button :build_allow_git_fetch, 'true' + %strong git fetch + %br + %span.descr Faster .form-group - = f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label' - .col-sm-10 - = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0' - %p.help-block per build in minutes + = f.label :build_timeout_in_minutes, 'Timeout', class: 'label-light' + = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0' + %p.help-block per build in minutes .form-group - = f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label' - .col-sm-10 - .input-group - %span.input-group-addon / - = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered' - %span.input-group-addon / - %p.help-block - We will use this regular expression to find test coverage output in build trace. - Leave blank if you want to disable this feature - .bs-callout.bs-callout-info - %p Below are examples of regex for existing tools: - %ul - %li - Simplecov (Ruby) - - %code \(\d+.\d+\%\) covered - %li - pytest-cov (Python) - - %code \d+\%\s*$ - %li - phpunit --coverage-text --colors=never (PHP) - - %code ^\s*Lines:\s*\d+.\d+\% - %li - gcovr (C/C++) - - %code ^TOTAL.*\s+(\d+\%)$ - %li - tap --coverage-report=text-summary (Node.js) - - %code ^Statements\s*:\s*([^%]+) + = 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' + %span.input-group-addon / + %p.help-block + We will use this regular expression to find test coverage output in build trace. + Leave blank if you want to disable this feature + .bs-callout.bs-callout-info + %p Below are examples of regex for existing tools: + %ul + %li + Simplecov (Ruby) - + %code \(\d+.\d+\%\) covered + %li + pytest-cov (Python) - + %code \d+\%\s*$ + %li + phpunit --coverage-text --colors=never (PHP) - + %code ^\s*Lines:\s*\d+.\d+\% + %li + gcovr (C/C++) - + %code ^TOTAL.*\s+(\d+\%)$ + %li + tap --coverage-report=text-summary (Node.js) - + %code ^Statements\s*:\s*([^%]+) .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :public_builds do - = f.check_box :public_builds - %strong Public builds - .help-block Allow everyone to access builds for Public and Internal projects + .checkbox + = f.label :public_builds do + = f.check_box :public_builds + %strong Public builds + .help-block Allow everyone to access builds for Public and Internal projects - .form-group - = f.label :runners_token, "Runners token", class: 'control-label' - .col-sm-10 - = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' - %p.help-block The secure token used to checkout project. + .form-group.append-bottom-0 + = f.label :runners_token, "Runners token", class: 'label-light' + = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' + %p.help-block The secure token used to checkout project. diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 9b5de17dd3bb88..57c3d1b0a65bb0 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,59 +1,37 @@ - empty_repo = @project.empty_repo? .project-home-panel.cover-block.clearfix{:class => ("empty-project" if empty_repo)} - .project-identicon-holder - = project_icon(@project, alt: '', class: 'project-avatar avatar s90') - .cover-title.project-home-desc - %h1 - = @project.name - %span.visibility-icon.has-tooltip{data: { container: 'body' }, title: visibility_icon_description(@project)} - = visibility_level_icon(@project.visibility_level, fw: false) - - - if @project.description.present? - .cover-desc.project-home-desc - = markdown(@project.description, pipeline: :description) - - - if forked_from_project = @project.forked_from_project - .cover-desc - Forked from - = link_to project_path(forked_from_project) do - = forked_from_project.namespace.try(:name) - - .cover-controls - - if current_user - = link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), class: 'btn btn-gray' do - = icon('rss') - - access = user_max_access_in_project(current_user.id, @project) - - can_edit = can?(current_user, :admin_project, @project) - - if access || can_edit - %span.dropdown.project-settings-dropdown - %a.dropdown-new.btn.btn-gray#project-settings-button{href: '#', 'data-toggle' => 'dropdown'} - = icon('cog') - = icon('angle-down') - %ul.dropdown-menu.dropdown-menu-right - - if can_edit - %li - = link_to edit_project_path(@project) do - Edit Project - - if access - %li - = link_to leave_namespace_project_project_members_path(@project.namespace, @project), - data: { confirm: leave_project_message(@project) }, method: :delete, title: 'Leave project' do - Leave Project - - .project-repo-buttons - .split-one.count-buttons - = render 'projects/buttons/star' - = render 'projects/buttons/fork' - - .clone-row - .project-clone-holder - = render "shared/clone_panel" - - .split-repo-buttons - .btn-group.pull-left - = render "projects/buttons/download" - = render 'projects/buttons/dropdown' - + .container-fluid.container-limited + .row + .project-image-container + = project_icon(@project, alt: '', class: 'project-avatar avatar s70') + .project-info + .cover-title.project-home-desc + %h1 + = @project.name + %span.visibility-icon.has-tooltip{data: { container: 'body' }, title: visibility_icon_description(@project)} + = visibility_level_icon(@project.visibility_level, fw: false) + + - if @project.description.present? + .cover-desc.project-home-desc + = markdown(@project.description, pipeline: :description) + + - if forked_from_project = @project.forked_from_project + .cover-desc + Forked from + = link_to project_path(forked_from_project) do + = forked_from_project.namespace.try(:name) + + .project-repo-buttons + .count-buttons + = render 'projects/buttons/star' + = render 'projects/buttons/fork' + + .project-clone-holder + = render "shared/clone_panel" + + .project-repo-buttons.btn-group.project-right-buttons + = render "projects/buttons/download" + = render 'projects/buttons/dropdown' = render 'projects/buttons/notifications' :javascript diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml index 8de44a6c914980..81afea2c60a214 100644 --- a/app/views/projects/_md_preview.html.haml +++ b/app/views/projects/_md_preview.html.haml @@ -8,7 +8,7 @@ %a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 } Preview %li.pull-right - %button.zen-cotrol.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 } + %button.zen-control.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 } Go full screen .md-write-holder diff --git a/app/views/projects/_zen.html.haml b/app/views/projects/_zen.html.haml index e1e35013968516..413477a2d3a008 100644 --- a/app/views/projects/_zen.html.haml +++ b/app/views/projects/_zen.html.haml @@ -4,5 +4,5 @@ = f.text_area attr, class: classes, placeholder: placeholder - else = text_area_tag attr, nil, class: classes, placeholder: placeholder - %a.zen-cotrol.zen-control-leave.js-zen-leave{ href: "#" } + %a.zen-control.zen-control-leave.js-zen-leave{ href: "#" } = icon('compress') diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml index 69fa4ad37c4bba..3c0f01cbf6f683 100644 --- a/app/views/projects/activity.html.haml +++ b/app/views/projects/activity.html.haml @@ -1,5 +1,4 @@ - page_title "Activity" -- header_title project_title(@project, "Activity", activity_project_path(@project)) = render 'projects/last_push' diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml index 49f95ff37dbe2b..ede01dcc1aa184 100644 --- a/app/views/projects/artifacts/browse.html.haml +++ b/app/views/projects/artifacts/browse.html.haml @@ -1,5 +1,4 @@ - page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds' -= render 'projects/builds/header_title' .top-block.row-content-block.clearfix .pull-right diff --git a/app/views/projects/badges/index.html.haml b/app/views/projects/badges/index.html.haml index c22384ddf46c8b..ee63bc55a303f6 100644 --- a/app/views/projects/badges/index.html.haml +++ b/app/views/projects/badges/index.html.haml @@ -1,6 +1,5 @@ - page_title 'Badges' - badges_path = namespace_project_badges_path(@project.namespace, @project) -- header_title project_title(@project, 'Badges', badges_path) .prepend-top-10 .panel.panel-default diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index 5f9a92ff93f6a1..377665b096f588 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -1,5 +1,4 @@ - page_title "Blame", @blob.path, @ref -- header_title project_title(@project, "Files", project_files_path(@project)) %h3.page-title Blame view diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml index fefa652a3da9cc..4071b59c003796 100644 --- a/app/views/projects/blob/_editor.html.haml +++ b/app/views/projects/blob/_editor.html.haml @@ -16,6 +16,9 @@ .license-selector.js-license-selector.hide = select_tag :license_type, grouped_options_for_select(licenses_for_select, @project.repository.license_key), include_blank: true, class: 'select2 license-select', data: {placeholder: 'Choose a license template', project: @project.name, fullname: @project.namespace.human_name} + .gitignore-selector.hidden + = dropdown_tag("Choose a .gitignore template", options: { toggle_class: 'js-gitignore-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { filenames: gitignore_names } } ) + .encoding-selector = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2' diff --git a/app/views/projects/blob/_header_title.html.haml b/app/views/projects/blob/_header_title.html.haml deleted file mode 100644 index 78c5ef20a5fa87..00000000000000 --- a/app/views/projects/blob/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Files", project_files_path(@project)) diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml index effcce5a1c4b25..e4f04ca7764e8d 100644 --- a/app/views/projects/blob/edit.html.haml +++ b/app/views/projects/blob/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", @blob.path, @ref -= render "header_title" .file-editor %ul.nav-links.no-bottom.js-edit-mode diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml index 0459699432e8b9..c952bc7e5dbcf7 100644 --- a/app/views/projects/blob/new.html.haml +++ b/app/views/projects/blob/new.html.haml @@ -1,5 +1,4 @@ - page_title "New File", @path.presence, @ref -= render "header_title" %h3.page-title New File diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index 6988039b6c7233..ed670dae88d9f9 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -1,5 +1,4 @@ - page_title @blob.path, @ref -= render "header_title" = render 'projects/last_push' diff --git a/app/views/projects/branches/destroy.js.haml b/app/views/projects/branches/destroy.js.haml deleted file mode 100644 index a21ddaf4930291..00000000000000 --- a/app/views/projects/branches/destroy.js.haml +++ /dev/null @@ -1 +0,0 @@ -$('.js-totalbranch-count').html("#{@repository.branch_count}") diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index ac7790421a4067..08148b1a18b0be 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -1,5 +1,4 @@ - page_title "Branches" -= render "projects/commits/header_title" = render "projects/commits/head" .row-content-block .pull-right diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index c659af6338c477..5a6c8c243fa77a 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Branch" -= render "projects/commits/header_title" - if @error .alert.alert-danger diff --git a/app/views/projects/builds/_header_title.html.haml b/app/views/projects/builds/_header_title.html.haml deleted file mode 100644 index 082dab1f5b06bc..00000000000000 --- a/app/views/projects/builds/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Builds", project_builds_path(@project)) diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml index 2e8015d119b66e..818d5d28f045ce 100644 --- a/app/views/projects/builds/index.html.haml +++ b/app/views/projects/builds/index.html.haml @@ -1,5 +1,5 @@ - page_title "Builds" -= render "header_title" += render "projects/pipelines/head" .top-area %ul.nav-links @@ -35,9 +35,6 @@ = icon('wrench') %span CI Lint -.row-content-block - #{(@scope || 'running').capitalize} builds from this project - %ul.content-list - if @builds.blank? %li diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index c0f7a7686f0b1d..16017c994ba87e 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -1,5 +1,5 @@ - page_title "#{@build.name} (##{@build.id})", "Builds" -= render "header_title" +- trace_with_state = @build.trace_with_state .build-page .row-content-block.top-block @@ -85,7 +85,9 @@ %pre.trace#build-trace %code.bash = preserve do - = raw @build.trace_html + = raw trace_with_state[:html] + - if @build.active? + %i{:class => "fa fa-refresh fa-spin"} %div#down-build-trace @@ -216,4 +218,4 @@ :javascript - new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{@build.status}") + new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{@build.status}", "#{trace_with_state[:state]}") diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml index 1e4c46fca2f159..16b8e1cca9134e 100644 --- a/app/views/projects/buttons/_dropdown.html.haml +++ b/app/views/projects/buttons/_dropdown.html.haml @@ -2,7 +2,7 @@ .btn-group %a.btn.dropdown-toggle{href: '#', "data-toggle" => "dropdown"} = icon('plus') - %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown + %ul.dropdown-menu.dropdown-menu-align-right.project-home-dropdown - can_create_issue = can?(current_user, :create_issue, @project) - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project)) - can_create_snippet = can?(current_user, :create_snippet, @project) diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml index 5fb5fe5af2fe00..34ad9fe2c438fe 100644 --- a/app/views/projects/buttons/_fork.html.haml +++ b/app/views/projects/buttons/_fork.html.haml @@ -12,7 +12,8 @@ = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn has-tooltip' do = icon('code-fork fw') Fork - = link_to namespace_project_forks_path(@project.namespace, @project), class: 'count-with-arrow' do + %div.count-with-arrow %span.arrow %span.count - = @project.forks_count + = link_to namespace_project_forks_path(@project.namespace, @project) do + = @project.forks_count diff --git a/app/views/projects/buttons/_notifications.html.haml b/app/views/projects/buttons/_notifications.html.haml index c1e3e5b73a2c3d..1d05da50581fdd 100644 --- a/app/views/projects/buttons/_notifications.html.haml +++ b/app/views/projects/buttons/_notifications.html.haml @@ -1,11 +1,11 @@ - if @notification_setting = form_for @notification_setting, url: namespace_project_notification_setting_path(@project.namespace.becomes(Namespace), @project), method: :patch, remote: true, html: { class: 'inline', id: 'notification-form' } do |f| = f.hidden_field :level - %span.dropdown + .dropdown %a.dropdown-new.btn.notifications-btn#notifications-button{href: '#', "data-toggle" => "dropdown"} = icon('bell') = notification_title(@notification_setting.level) - = icon('angle-down') - %ul.dropdown-menu.dropdown-menu-right.project-home-dropdown + = icon('caret-down') + %ul.dropdown-menu.dropdown-menu-align-right.project-home-dropdown - NotificationSetting.levels.each do |level| = notification_list_item(level.first, @notification_setting) diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index 8e95f04027384d..5bd6e3f0ebc67a 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -13,7 +13,9 @@ %strong ##{build.id} - if build.stuck? - %i.fa.fa-warning.text-warning + = icon('warning', class: 'text-warning has-tooltip', title: 'Build is stuck. Check runners.') + - if defined?(retried) && retried + = icon('warning', class: 'text-warning has-tooltip', title: 'Build was retried.') - if defined?(commit_sha) && commit_sha %td @@ -70,11 +72,11 @@ .pull-right - if can?(current_user, :read_build, build) && build.artifacts? = link_to download_namespace_project_build_artifacts_path(build.project.namespace, build.project, build), title: 'Download artifacts', class: 'btn btn-build' do - %i.fa.fa-download + = icon('download') - if can?(current_user, :update_build, build) - if build.active? = link_to cancel_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do - %i.fa.fa-remove.cred + = icon('remove', class: 'cred') - elsif defined?(allow_retry) && allow_retry && build.retryable? = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do - %i.fa.fa-refresh + = icon('refresh') diff --git a/app/views/projects/ci/commits/_commit.html.haml b/app/views/projects/ci/commits/_commit.html.haml new file mode 100644 index 00000000000000..5e3a4123a8efd9 --- /dev/null +++ b/app/views/projects/ci/commits/_commit.html.haml @@ -0,0 +1,71 @@ +- status = commit.status +%tr.commit + %td.commit-link + = link_to namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: "ci-status ci-#{status}" do + = ci_icon_for_status(status) + %strong ##{commit.id} + + %td + %div.branch-commit + - if commit.ref + = link_to commit.ref, namespace_project_commits_path(@project.namespace, @project, commit.ref), class: "monospace" + · + = link_to commit.short_sha, namespace_project_commit_path(@project.namespace, @project, commit.sha), class: "commit-id monospace" +   + - if commit.tag? + %span.label.label-primary tag + - elsif commit.latest? + %span.label.label-success.has-tooltip{ title: 'Latest build for this branch' } latest + - if commit.triggered? + %span.label.label-primary triggered + - if commit.yaml_errors.present? + %span.label.label-danger.has-tooltip{ title: "#{commit.yaml_errors}" } yaml invalid + - if commit.builds.any?(&:stuck?) + %span.label.label-warning stuck + + %p.commit-title + - if commit_data = commit.commit_data + = link_to_gfm truncate(commit_data.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit_data.id), class: "commit-row-message" + - else + Cant find HEAD commit for this branch + + + - stages_status = commit.statuses.stages_status + - stages.each do |stage| + %td + - status = stages_status[stage] + - tooltip = "#{stage.titleize}: #{status || 'not found'}" + - if status + = link_to namespace_project_pipeline_path(@project.namespace, @project, commit.id, anchor: stage), class: "has-tooltip ci-status-icon-#{status}", title: tooltip do + = ci_icon_for_status(status) + - else + .light.has-tooltip{ title: tooltip } + \- + + %td + - if commit.started_at && commit.finished_at + %p.duration + #{duration_in_words(commit.finished_at, commit.started_at)} + + %td + .controls.hidden-xs.pull-right + - artifacts = commit.builds.latest.select { |b| b.artifacts? } + - if artifacts.present? + .dropdown.inline.build-artifacts + %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} + = icon('download') + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - artifacts.each do |build| + %li + = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do + = icon("download") + %span #{build.name} + + - if can?(current_user, :update_pipeline, @project) + - if commit.retryable? + = link_to retry_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn has-tooltip', title: "Retry", method: :post do + = icon("repeat") + - if commit.cancelable? + = link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do + = icon("remove") diff --git a/app/views/projects/commit/_builds.html.haml b/app/views/projects/commit/_builds.html.haml index 5c9a319edebeb0..7f7a15aa2145ed 100644 --- a/app/views/projects/commit/_builds.html.haml +++ b/app/views/projects/commit/_builds.html.haml @@ -1,2 +1,2 @@ - @ci_commits.each do |ci_commit| - = render "ci_commit", ci_commit: ci_commit + = render "ci_commit", ci_commit: ci_commit, pipeline_details: true diff --git a/app/views/projects/commit/_ci_commit.html.haml b/app/views/projects/commit/_ci_commit.html.haml index e849aefb1880cb..32ff4d3097766b 100644 --- a/app/views/projects/commit/_ci_commit.html.haml +++ b/app/views/projects/commit/_ci_commit.html.haml @@ -1,24 +1,27 @@ .row-content-block.build-content.middle-block .pull-right - - if can?(current_user, :update_build, @project) + - if can?(current_user, :update_pipeline, ci_commit.project) - if ci_commit.builds.latest.failed.any?(&:retryable?) - = link_to "Retry failed", retry_builds_namespace_project_commit_path(@project.namespace, @project, ci_commit.sha), class: 'btn btn-grouped btn-primary', method: :post + = link_to "Retry failed", retry_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: 'btn btn-grouped btn-primary', method: :post - if ci_commit.builds.running_or_pending.any? - = link_to "Cancel running", cancel_builds_namespace_project_commit_path(@project.namespace, @project, ci_commit.sha), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post + = link_to "Cancel running", cancel_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post - .oneline - = pluralize ci_commit.statuses.count(:id), "build" - - if ci_commit.ref - for - %span.label.label-info - = ci_commit.ref - - if defined?(link_to_commit) && link_to_commit - for commit - = link_to ci_commit.short_sha, namespace_project_commit_path(@project.namespace, @project, ci_commit.sha), class: "monospace" - - if ci_commit.duration - in - = time_interval_in_words ci_commit.duration + .oneline.clearfix + - if defined?(pipeline_details) && pipeline_details + Pipeline + = link_to "##{ci_commit.id}", namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: "monospace" + with + = pluralize ci_commit.statuses.count(:id), "build" + - if ci_commit.ref + for + = link_to ci_commit.ref, namespace_project_commits_path(ci_commit.project.namespace, ci_commit.project, ci_commit.ref), class: "monospace" + - if defined?(link_to_commit) && link_to_commit + for commit + = link_to ci_commit.short_sha, namespace_project_commit_path(ci_commit.project.namespace, ci_commit.project, ci_commit.sha), class: "monospace" + - if ci_commit.duration + in + = time_interval_in_words ci_commit.duration - if ci_commit.yaml_errors.present? .bs-callout.bs-callout-danger @@ -28,7 +31,7 @@ %li= error You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path} -- if @project.builds_enabled? && !ci_commit.ci_yaml_file +- if ci_commit.project.builds_enabled? && !ci_commit.ci_yaml_file .bs-callout.bs-callout-warning \.gitlab-ci.yml not found in this commit @@ -38,34 +41,12 @@ %tr %th Status %th Build ID - %th Stage %th Name %th Tags %th Duration %th Finished at - - if @project.build_coverage_enabled? + - if ci_commit.project.build_coverage_enabled? %th Coverage %th - - builds = ci_commit.statuses.latest.ordered - = render builds, coverage: @project.build_coverage_enabled?, stage: true, ref: false, allow_retry: true - -- if ci_commit.retried.any? - .row-content-block.second-block - Retried builds - - .table-holder - %table.table.builds - %thead - %tr - %th Status - %th Build ID - %th Ref - %th Stage - %th Name - %th Tags - %th Duration - %th Finished at - - if @project.build_coverage_enabled? - %th Coverage - %th - = render ci_commit.retried, coverage: @project.build_coverage_enabled?, stage: true, ref: false + - ci_commit.statuses.stages.each do |stage| + = render 'projects/commit/ci_stage', stage: stage, statuses: ci_commit.statuses.where(stage: stage) diff --git a/app/views/projects/commit/_ci_stage.html.haml b/app/views/projects/commit/_ci_stage.html.haml new file mode 100644 index 00000000000000..ae7bb01223eda2 --- /dev/null +++ b/app/views/projects/commit/_ci_stage.html.haml @@ -0,0 +1,15 @@ +%tr + %th{colspan: 10} + %strong + %a{name: stage} + - status = statuses.latest.status + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + - if stage +   + = stage.titleize.pluralize + = render statuses.latest.ordered, coverage: @project.build_coverage_enabled?, stage: false, ref: false, allow_retry: true + = render statuses.retried.ordered, coverage: @project.build_coverage_enabled?, stage: false, ref: false, retried: true + %tr + %td{colspan: 10} +   diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 01163e526b248f..6674d58417b486 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -1,37 +1,35 @@ -.pull-right.commit-action-buttons - %div - - if @notes_count > 0 - %span.btn.disabled.btn-grouped - %i.fa.fa-comment +.commit-info-row.commit-info-row-header + %span.hidden-xs Authored by + %strong + = commit_author_link(@commit, avatar: true, size: 24) + #{time_ago_with_tooltip(@commit.authored_date)} + + .pull-right.commit-action-buttons + - if defined?(@notes_count) && @notes_count > 0 + %span.btn.disabled.btn-grouped.hidden-xs + = icon('comment') = @notes_count - .pull-left.btn-group - %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} } - %i.fa.fa-download - Download as - %span.caret - %ul.dropdown-menu + = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-grouped hidden-xs hidden-sm" do + Browse Files + .dropdown.inline + %a.btn.btn-default.dropdown-toggle{ data: { toggle: "dropdown" } } + %span.hidden-xs Options + %span.caret.commit-options-dropdown-caret + %ul.dropdown-menu.dropdown-menu-align-right + %li.visible-xs-block.visible-sm-block + = link_to namespace_project_tree_path(@project.namespace, @project, @commit) do + Browse Files + - unless @commit.has_been_reverted?(current_user) + %li.clearfix + = revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false) + %li.clearfix + = cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false) + %li.divider + %li.dropdown-header + Download - unless @commit.parents.length > 1 %li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch) %li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff) - = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-grouped" do - = icon('files-o') - Browse Files - - unless @commit.has_been_reverted?(current_user) - = revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id)) - = cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id)) - %div - -%p -.commit-info-row - - if @commit.status - = link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "ci-status ci-#{@commit.status}" do - = ci_icon_for_status(@commit.status) - build: - = ci_label_for_status(@commit.status) - %span.light Authored by - %strong - = commit_author_link(@commit, avatar: true, size: 24) - #{time_ago_with_tooltip(@commit.authored_date)} - if @commit.different_committer? .commit-info-row @@ -41,8 +39,9 @@ #{time_ago_with_tooltip(@commit.committed_date)} .commit-info-row - %span.light Commit - = link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace" + %span.hidden-xs.hidden-sm Commit + = link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace hidden-xs hidden-sm" + = link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace visible-xs-inline visible-sm-inline" = clipboard_button(clipboard_text: @commit.id) %span.cgray= pluralize(@commit.parents.count, "parent") - @commit.parents.each do |parent| @@ -51,12 +50,23 @@ %span.commit-info.branches %i.fa.fa-spinner.fa-spin +- if @commit.status + .commit-info-row + Builds for + = pluralize(@commit.ci_commits.count, 'pipeline') + = link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "ci-status-link ci-status-icon-#{@commit.status}" do + = ci_icon_for_status(@commit.status) + = ci_label_for_status(@commit.status) + - if @commit.ci_commits.duration + in + = time_interval_in_words @commit.ci_commits.duration + .commit-box.content-block %h3.commit-title - = markdown escape_once(@commit.title), pipeline: :single_line + = markdown escape_once(@commit.title), pipeline: :single_line, author: @commit.author - if @commit.description.present? %pre.commit-description - = preserve(markdown(escape_once(@commit.description), pipeline: :single_line)) + = preserve(markdown(escape_once(@commit.description), pipeline: :single_line, author: @commit.author)) :javascript $(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}"); diff --git a/app/views/projects/commit/builds.html.haml b/app/views/projects/commit/builds.html.haml index 7118a4846c6744..2f051fb90e076e 100644 --- a/app/views/projects/commit/builds.html.haml +++ b/app/views/projects/commit/builds.html.haml @@ -1,7 +1,7 @@ - page_title "Builds", "#{@commit.title} (#{@commit.short_id})", "Commits" -= render "projects/commits/header_title" + .prepend-top-default = render "commit_box" -= render "ci_menu" += render "ci_menu" = render "builds" diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index e5e3d69603523c..401cb4f7e30b6b 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,8 +1,6 @@ - page_title "#{@commit.title} (#{@commit.short_id})", "Commits" - page_description @commit.description -= render "projects/commits/header_title" - .prepend-top-default = render "commit_box" - if @commit.status diff --git a/app/views/projects/commits/_commit.atom.builder b/app/views/projects/commits/_commit.atom.builder new file mode 100644 index 00000000000000..1657fb46163758 --- /dev/null +++ b/app/views/projects/commits/_commit.atom.builder @@ -0,0 +1,14 @@ +xml.entry do + xml.id namespace_project_commit_url(@project.namespace, @project, id: commit.id) + xml.link href: namespace_project_commit_url(@project.namespace, @project, id: commit.id) + xml.title truncate(commit.title, length: 80) + xml.updated commit.committed_date.xmlschema + xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(commit.author_email)) + + xml.author do |author| + xml.name commit.author_name + xml.email commit.author_email + end + + xml.summary markdown(commit.description, pipeline: :single_line) +end diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index c7d8c9a0d15b31..367027182b6508 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -17,14 +17,14 @@ .pull-right - if commit.status - = render_ci_status(commit) + = render_commit_status(commit) = clipboard_button(clipboard_text: commit.id) = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" - if commit.description? .commit-row-description.js-toggle-content %pre - = preserve(markdown(escape_once(commit.description), pipeline: :single_line)) + = preserve(markdown(escape_once(commit.description), pipeline: :single_line, author: commit.author)) .commit-row-info by diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index 64e8da9201d195..7283a78a64e4a4 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -3,7 +3,7 @@ - commits, hidden = limited_commits(@commits) -- commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits| +- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, commits| .row.commits-row .col-md-2.hidden-xs.hidden-sm %h5.commits-row-date diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index d1bd76ab5290d5..1c136133ab007a 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -1,9 +1,11 @@ %ul.nav-links + = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do + = link_to project_files_path(@project) do + Files + = nav_link(controller: [:commit, :commits]) do = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do Commits - %span.badge - = number_with_delimiter(@repository.commit_count) = nav_link(controller: %w(network)) do = link_to namespace_project_network_path(@project.namespace, @project, current_ref) do @@ -16,9 +18,7 @@ = nav_link(html_options: {class: branches_tab_class}) do = link_to namespace_project_branches_path(@project.namespace, @project) do Branches - %span.badge.js-totalbranch-count= @repository.branch_count = nav_link(controller: [:tags, :releases]) do = link_to namespace_project_tags_path(@project.namespace, @project) do Tags - %span.badge.js-totaltags-count= @repository.tag_count diff --git a/app/views/projects/commits/_header_title.html.haml b/app/views/projects/commits/_header_title.html.haml deleted file mode 100644 index e4385893dd9d0e..00000000000000 --- a/app/views/projects/commits/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Commits", project_commits_path(@project)) diff --git a/app/views/projects/commits/show.atom.builder b/app/views/projects/commits/show.atom.builder index e310fafd82ca02..30bb7412073922 100644 --- a/app/views/projects/commits/show.atom.builder +++ b/app/views/projects/commits/show.atom.builder @@ -6,18 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id namespace_project_commits_url(@project.namespace, @project, @ref) xml.updated @commits.first.committed_date.xmlschema if @commits.any? - @commits.each do |commit| - xml.entry do - xml.id namespace_project_commit_url(@project.namespace, @project, id: commit.id) - xml.link href: namespace_project_commit_url(@project.namespace, @project, id: commit.id) - xml.title truncate(commit.title, length: 80) - xml.updated commit.committed_date.xmlschema - xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(commit.author_email)) - xml.author do |author| - xml.name commit.author_name - xml.email commit.author_email - end - xml.summary markdown(commit.description, pipeline: :single_line) - end - end + xml << render(@commits) if @commits.any? end diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 088eaa28013314..2c21923ed4f883 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -1,5 +1,4 @@ - page_title "Commits", @ref -= render "header_title" = content_for :meta_tags do - if current_user = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits") diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml index 5e188dd0f3ca5e..0b8ed23b3051ef 100644 --- a/app/views/projects/compare/index.html.haml +++ b/app/views/projects/compare/index.html.haml @@ -1,5 +1,4 @@ - page_title "Compare" -= render "projects/commits/header_title" = render "projects/commits/head" .row-content-block diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index 625251682396de..cdc34f51d6df27 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -1,5 +1,4 @@ - page_title "#{params[:from]}...#{params[:to]}" -= render "projects/commits/header_title" = render "projects/commits/head" diff --git a/app/views/projects/container_registry/_tag.html.haml b/app/views/projects/container_registry/_tag.html.haml new file mode 100644 index 00000000000000..4e9f936539b564 --- /dev/null +++ b/app/views/projects/container_registry/_tag.html.haml @@ -0,0 +1,21 @@ +%tr.tag + %td + = escape_once(tag.name) + = clipboard_button(clipboard_text: "docker pull #{tag.path}") + %td + - if layer = tag.layers.first + %span.has-tooltip{ title: "#{layer.revision}" } + = layer.short_revision + - else + \- + %td + = number_to_human_size(tag.total_size) + · + = pluralize(tag.layers.size, "layer") + %td + = time_ago_in_words(tag.created_at) + - if can?(current_user, :update_container_image, @project) + %td.content + .controls.hidden-xs.pull-right + = link_to namespace_project_container_registry_path(@project.namespace, @project, tag.name), class: 'btn btn-remove has-tooltip', title: "Remove", data: { confirm: "Are you sure?" }, method: :delete do + = icon("trash cred") diff --git a/app/views/projects/container_registry/index.html.haml b/app/views/projects/container_registry/index.html.haml new file mode 100644 index 00000000000000..993da27310f405 --- /dev/null +++ b/app/views/projects/container_registry/index.html.haml @@ -0,0 +1,39 @@ +- page_title "Container Registry" + +%hr + +%ul.content-list + %li.light.prepend-top-default + %p + A 'container image' is a snapshot of a container. + You can host your container images with GitLab. + %br + To start using container images hosted on GitLab you first need to login: + %pre + %code + docker login #{Gitlab.config.registry.host_port} + %br + Then you are free to create and upload a container image with build and push commands: + %pre + docker build -t #{escape_once(@project.container_registry_repository_url)} . + %br + docker push #{escape_once(@project.container_registry_repository_url)} + + - if @tags.blank? + %li + .nothing-here-block No images in Container Registry for this project. + + - else + .table-holder + %table.table.tags + %thead + %tr + %th Name + %th Image ID + %th Size + %th Created + - if can?(current_user, :update_container_image, @project) + %th + + - @tags.each do |tag| + = render 'tag', tag: tag diff --git a/app/views/projects/deploy_keys/index.html.haml b/app/views/projects/deploy_keys/index.html.haml index e230834e8bac1c..04fbb37d93faa2 100644 --- a/app/views/projects/deploy_keys/index.html.haml +++ b/app/views/projects/deploy_keys/index.html.haml @@ -19,7 +19,7 @@ %ul.well-list = render @enabled_keys - else - .profile-settings-message.text-center + .settings-message.text-center No deploy keys found. Create one with the form above or add existing one below. %h5.prepend-top-default Deploy keys from projects you have access to (#{@available_project_keys.size}) @@ -27,7 +27,7 @@ %ul.well-list = render @available_project_keys - else - .profile-settings-message.text-center + .settings-message.text-center No deploy keys from your projects could be found. Create one with the form above or add existing one below. - if @available_public_keys.any? %h5.prepend-top-default diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 0f04fc5d33c50c..e5983c580392e5 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -11,11 +11,9 @@ = link_to "#diff-#{i}" do - if diff_file.renamed_file - old_path, new_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path) - .filename.old - = old_path + = old_path → - .filename.new - = new_path + = new_path - else %span = diff_file.new_path @@ -41,7 +39,7 @@ .diff-content.diff-wrap-lines - # Skip all non non-supported blobs - - return unless blob.respond_to?('text?') + - return unless blob.respond_to?(:text?) - if diff_file.too_large? .nothing-here-block This diff could not be displayed because it is too large. - elsif blob_text_viewable?(blob) && !project.repository.diffable?(blob) diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml index 107097ad9635b6..f1577e8a47b4cb 100644 --- a/app/views/projects/diffs/_line.html.haml +++ b/app/views/projects/diffs/_line.html.haml @@ -15,7 +15,7 @@ = link_text - else = link_to "", "##{line_code}", id: line_code, data: { linenumber: link_text } - - if @comments_allowed && can?(current_user, :create_note, @project) + - if !@diff_notes_disabled && can?(current_user, :create_note, @project) = link_to_new_diff_note(line_code) %td.new_line.diff-line-num{ class: type, data: { linenumber: line.new_pos } } - link_text = type == "old" ? " ".html_safe : line.new_pos diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml index 81948513e43c5c..4ecc9528bd2503 100644 --- a/app/views/projects/diffs/_parallel_view.html.haml +++ b/app/views/projects/diffs/_parallel_view.html.haml @@ -16,7 +16,7 @@ - else %td.old_line.diff-line-num{id: left[:line_code], class: "#{left[:type]} #{'empty-cell' if !left[:number]}"} = link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code] - - if @comments_allowed && can?(current_user, :create_note, @project) + - if !@diff_notes_disabled && can?(current_user, :create_note, @project) = link_to_new_diff_note(left[:line_code], 'old') %td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]} #{'empty-cell' if left[:text].empty?}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text]) @@ -29,14 +29,14 @@ %td.new_line.diff-line-num{id: new_line_code, class: "#{new_line_class} #{'empty-cell' if !right[:number]}", data: { linenumber: right[:number] }} = link_to raw(right[:number]), "##{new_line_code}", id: new_line_code - - if @comments_allowed && can?(current_user, :create_note, @project) - = link_to_new_diff_note(right[:line_code], 'new') + - if !@diff_notes_disabled && can?(current_user, :create_note, @project) + = link_to_new_diff_note(new_line_code, 'new') %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code} #{'empty-cell' if right[:text].empty?}", data: { line_code: new_line_code }}= diff_line_content(right[:text]) - - if @reply_allowed - - comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code]) - - if comments_left.present? || comments_right.present? - = render "projects/notes/diff_notes_with_reply_parallel", notes_left: comments_left, notes_right: comments_right + - unless @diff_notes_disabled + - notes_left, notes_right = organize_comments(left, right) + - if notes_left.present? || notes_right.present? + = render "projects/notes/diff_notes_with_reply_parallel", notes_left: notes_left, notes_right: notes_right - if diff_file.diff.diff.blank? && diff_file.mode_changed? .file-mode-changed diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml index e7169d7b599f74..068593a7dd152d 100644 --- a/app/views/projects/diffs/_text_file.html.haml +++ b/app/views/projects/diffs/_text_file.html.haml @@ -6,16 +6,15 @@ %table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' } - last_line = 0 - - raw_diff_lines = diff_file.diff_lines.to_a - diff_file.highlighted_diff_lines.each_with_index do |line, index| - line_code = generate_line_code(diff_file.file_path, line) - last_line = line.new_pos = render "projects/diffs/line", {line: line, diff_file: diff_file, line_code: line_code} - - if @reply_allowed - - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at) - - unless comments.empty? - = render "projects/notes/diff_notes_with_reply", notes: comments, line: raw_diff_lines[index].text + - unless @diff_notes_disabled + - diff_notes = @grouped_diff_notes[line_code] + - if diff_notes + = render "projects/notes/diff_notes_with_reply", notes: diff_notes - if last_line > 0 = render "projects/diffs/match_line", { line: "", diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 76a4f41193ccac..18b125ff9d4f52 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -1,251 +1,221 @@ -.project-edit-container.prepend-top-default - .project-edit-errors - .project-edit-content - .panel.panel-default - .panel-heading +.project-edit-container + .row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 Project settings - .panel-body - = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f| - - %fieldset - .form-group.project_name_holder - = f.label :name, class: 'control-label' do - Project name - .col-sm-10 - = f.text_field :name, class: "form-control", id: "project_name_edit" - - - .form-group - = f.label :description, class: 'control-label' do - Project description - %span.light (optional) - .col-sm-10 - = f.text_area :description, class: "form-control", rows: 3, maxlength: 250 - - - unless @project.empty_repo? - .form-group - = f.label :default_branch, "Default Branch", class: 'control-label' - .col-sm-10= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'}) - - - = render 'shared/visibility_level', f: f, visibility_level: @project.visibility_level, can_change_visibility_level: can_change_visibility_level?(@project, current_user), form_model: @project - + .col-lg-9 + = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit-project" }, authenticity_token: true do |f| + %fieldset.append-bottom-0 .form-group - = f.label :tag_list, "Tags", class: 'control-label' - .col-sm-10 - = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control" - %p.help-block Separate tags with commas. - - %fieldset.features - %legend - Features: - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :issues_enabled do - = f.check_box :issues_enabled - %strong Issues - %br - %span.descr Lightweight issue tracking system for this project - - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :merge_requests_enabled do - = f.check_box :merge_requests_enabled - %strong Merge Requests - %br - %span.descr Submit changes to be merged upstream - - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :builds_enabled do - = f.check_box :builds_enabled - %strong Builds - %br - %span.descr Test and deploy your changes before merge - - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :wiki_enabled do - = f.check_box :wiki_enabled - %strong Wiki - %br - %span.descr Pages for project documentation - - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :snippets_enabled do - = f.check_box :snippets_enabled - %strong Snippets - %br - %span.descr Share code pastes with others out of git repository - - = render 'builds_settings', f: f + = f.label :name, class: 'label-light' do + Project name + = f.text_field :name, class: "form-control", id: "project_name_edit" + .form-group + = f.label :description, class: 'label-light' do + Project description + %span.light (optional) + = f.text_area :description, class: "form-control", rows: 3, maxlength: 250 - %fieldset.features - %legend - Project avatar: + - unless @project.empty_repo? .form-group - .col-sm-offset-2.col-sm-10 - - if @project.avatar? - = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160') - %p.light - - if @project.avatar_in_git - Project avatar in repository: #{ @project.avatar_in_git } - %p.light - - if @project.avatar? - You can change your project avatar here - - else - You can upload a project avatar here - %a.choose-btn.btn.btn-sm.js-choose-project-avatar-button - %i.icon-paper-clip - %span Choose File ... -   - %span.file_name.js-avatar-filename File name... - = f.file_field :avatar, class: "js-project-avatar-input hidden" - .light The maximum file size allowed is 200KB. - - if @project.avatar? - %hr - = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - - - .form-actions - = f.submit 'Save changes', class: "btn btn-save" - - - - .danger-settings - .panel.panel-default - .panel-heading Housekeeping - .errors-holder - .panel-body - %p - Runs a number of housekeeping tasks within the current repository, - such as compressing file revisions and removing unreachable objects. - %br - - .form-actions - = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project), - method: :post, class: "btn btn-default" - - - if can? current_user, :archive_project, @project - - if @project.archived? - .panel.panel-success - .panel-heading - Unarchive project - .panel-body - %p - Unarchiving the project will mark its repository as active. + = f.label :default_branch, "Default Branch", class: 'label-light' + = f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'}) + .form-group.project-visibility-level-holder + = f.label :visibility_level, class: 'label-light' do + Visibility Level + = link_to "(?)", help_page_path("public_access", "public_access") + - if can_change_visibility_level?(@project, current_user) + = render('shared/visibility_radios', model_method: :visibility_level, form: f, selected_level: @project.visibility_level, form_model: @project) + - else + .info + = visibility_level_icon(@project.visibility_level) + %strong + = visibility_level_label(@project.visibility_level) + .light= visibility_level_description(@project.visibility_level, @project) + .form-group + = f.label :tag_list, "Tags", class: 'label-light' + = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control" + %p.help-block Separate tags with commas. + %hr + %fieldset.features.append-bottom-0 + %h5.prepend-top-0 + Features + .form-group + .checkbox + = f.label :issues_enabled do + = f.check_box :issues_enabled + %strong Issues %br - The project can be committed to. + %span.descr Lightweight issue tracking system for this project + .form-group + .checkbox + = f.label :merge_requests_enabled do + = f.check_box :merge_requests_enabled + %strong Merge Requests %br - %strong Once active this project shows up in the search and on the dashboard. - - .form-actions - = link_to 'Unarchive project', unarchive_namespace_project_path(@project.namespace, @project), - data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be committed to again." }, - method: :post, class: "btn btn-success" - - else - .panel.panel-warning - .panel-heading - Archive project - .panel-body - %p - Archiving the project will mark its repository as read-only. + %span.descr Submit changes to be merged upstream + .form-group + .checkbox + = f.label :builds_enabled do + = f.check_box :builds_enabled + %strong Builds + %br + %span.descr Test and deploy your changes before merge + .form-group + .checkbox + = f.label :wiki_enabled do + = f.check_box :wiki_enabled + %strong Wiki %br - It is hidden from the dashboard and doesn't show up in searches. + %span.descr Pages for project documentation + .form-group + .checkbox + = f.label :snippets_enabled do + = f.check_box :snippets_enabled + %strong Snippets %br - %strong Archived projects cannot be committed to! - - .form-actions - = link_to 'Archive project', archive_namespace_project_path(@project.namespace, @project), - data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." }, - method: :post, class: "btn btn-warning" - - else - .nothing-here-block Only the project owner can archive a project - - .panel.panel-default.panel.panel-warning - .panel-heading Rename repository - .errors-holder - .panel-body - = form_for([@project.namespace.becomes(Namespace), @project], html: { class: 'form-horizontal' }) do |f| - .form-group.project_name_holder - = f.label :name, class: 'control-label' do - Project name - .col-sm-9 - .form-group - = f.text_field :name, class: "form-control" + %span.descr Share code pastes with others out of git repository + - if Gitlab.config.registry.enabled .form-group - = f.label :path, class: 'control-label' do - %span Path - .col-sm-9 - .form-group - .input-group - .input-group-addon - #{URI.join(root_url, @project.namespace.path)}/ - = f.text_field :path, class: 'form-control' - %ul - %li Be careful. Renaming a project's repository can have unintended side effects. - %li You will need to update your local repositories to point to the new location. - .form-actions - = f.submit 'Rename project', class: "btn btn-warning" - - - if can?(current_user, :change_namespace, @project) - .panel.panel-default.panel.panel-danger - .panel-heading Transfer project - .errors-holder - .panel-body - = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_namespace_project_path(@project.namespace, @project), method: :put, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f| - .form-group - = label_tag :new_namespace_id, nil, class: 'control-label' do - %span Namespace - .col-sm-9 - .form-group - = select_tag :new_namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace', class: 'select2' } - %ul - %li Be careful. Changing the project's namespace can have unintended side effects. - %li You can only transfer the project to namespaces you manage. - %li You will need to update your local repositories to point to the new location. - %li Project visibility level will be changed to match namespace rules when transfering to a group. - .form-actions - = f.submit 'Transfer project', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => transfer_project_message(@project) } - - else - .nothing-here-block Only the project owner can transfer a project - - - if @project.forked? - - if can?(current_user, :remove_fork_project, @project) - = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_namespace_project_path(@project.namespace, @project), method: :delete, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f| - .panel.panel-default.panel.panel-danger - .panel-heading Remove fork relationship - .panel-body - %p - This will remove the fork relationship to source project - #{link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project)}. + .checkbox + = f.label :container_registry_enabled do + = f.check_box :container_registry_enabled + %strong Container Registry %br - %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source. - .form-actions - = button_to 'Remove fork relationship', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_message(@project) } + %span.descr Enable Container Registry for this repository + %hr + = render 'builds_settings', f: f + %hr + %fieldset.features.append-bottom-default + %h5.prepend-top-0 + Project avatar + .form-group + - if @project.avatar? + = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160') + %p.light + - if @project.avatar_in_git + Project avatar in repository: #{ @project.avatar_in_git } + %a.choose-btn.btn.js-choose-project-avatar-button + Browse file... + %span.file_name.prepend-left-default.js-avatar-filename No file chosen + = f.file_field :avatar, class: "js-project-avatar-input hidden" + .help-block The maximum file size allowed is 200KB. + - if @project.avatar? + %hr + = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" + = f.submit 'Save changes', class: "btn btn-save" + .row.prepend-top-default + %hr + .row.prepend-top-default + .col-lg-3 + %h4.prepend-top-0 + Housekeeping + %p.append-bottom-0 + %p + Runs a number of housekeeping tasks within the current repository, + such as compressing file revisions and removing unreachable objects. + .col-lg-9 + = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project), + method: :post, class: "btn btn-save" + %hr + - if can? current_user, :archive_project, @project + .row.prepend-top-default + .col-lg-3 + %h4.warning-title.prepend-top-0 + - if @project.archived? + Unarchive project + - else + Archive project + %p.append-bottom-0 + - if @project.archived? + Unarchiving the project will mark its repository as active. The project can be committed to. + - else + Archiving the project will mark its repository as read-only. It is hidden from the dashboard and doesn't show up in searches. + .col-lg-9 + - if @project.archived? + %p + %strong Once active this project shows up in the search and on the dashboard. + = link_to 'Unarchive project', unarchive_namespace_project_path(@project.namespace, @project), + data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be committed to again." }, + method: :post, class: "btn btn-success" - else - .nothing-here-block Only the project owner can remove the fork relationship. - - - if can?(current_user, :remove_project, @project) - .panel.panel-default.panel.panel-danger - .panel-heading Remove project - .panel-body - = form_tag(namespace_project_path(@project.namespace, @project), method: :delete, class: 'form-horizontal') do - %p - Removing the project will delete its repository and all related resources including issues, merge requests etc. - %br - %strong Removed projects cannot be restored! - .form-actions - = button_to 'Remove project', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_project_message(@project) } - - else - .nothing-here-block Only the project owner can remove a project. - + %p + %strong Archived projects cannot be committed to! + = link_to 'Archive project', archive_namespace_project_path(@project.namespace, @project), + data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." }, + method: :post, class: "btn btn-warning" + %hr + .row.prepend-top-default + .col-lg-3 + %h4.prepend-top-0.warning-title + Rename repository + .col-lg-9 + = form_for([@project.namespace.becomes(Namespace), @project]) do |f| + .form-group.project_name_holder + = f.label :name, class: 'label-light' do + Project name + .form-group + = f.text_field :name, class: "form-control" + .form-group + = f.label :path, class: 'label-light' do + %span Path + .form-group + .input-group + .input-group-addon + #{URI.join(root_url, @project.namespace.path)}/ + = f.text_field :path, class: 'form-control' + %ul + %li Be careful. Renaming a project's repository can have unintended side effects. + %li You will need to update your local repositories to point to the new location. + = f.submit 'Rename project', class: "btn btn-warning" + - if can?(current_user, :change_namespace, @project) + %hr + .row.prepend-top-default + .col-lg-3 + %h4.prepend-top-0.danger-title + Transfer project + .col-lg-9 + = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_namespace_project_path(@project.namespace, @project), method: :put, remote: true) do |f| + .form-group + = label_tag :new_namespace_id, nil, class: 'label-light' do + %span Namespace + .form-group + = select_tag :new_namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace', class: 'select2' } + %ul + %li Be careful. Changing the project's namespace can have unintended side effects. + %li You can only transfer the project to namespaces you manage. + %li You will need to update your local repositories to point to the new location. + %li Project visibility level will be changed to match namespace rules when transfering to a group. + = f.submit 'Transfer project', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => transfer_project_message(@project) } + - if @project.forked? && can?(current_user, :remove_fork_project, @project) + %hr + .row.prepend-top-default.append-bottom-default + .col-lg-3 + %h4.prepend-top-0.danger-title + Remove fork relationship + %p.append-bottom-0 + %p + This will remove the fork relationship to source project + = succeed "." do + = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project) + .col-lg-9 + = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_namespace_project_path(@project.namespace, @project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f| + %p + %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source. + = button_to 'Remove fork relationship', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_message(@project) } + - if can?(current_user, :remove_project, @project) + %hr + .row.prepend-top-default.append-bottom-default + .col-lg-3 + %h4.prepend-top-0.danger-title + Remove project + %p.append-bottom-0 + Removing the project will delete its repository and all related resources including issues, merge requests etc. + .col-lg-9 + = form_tag(namespace_project_path(@project.namespace, @project), method: :delete) do + %p + %strong Removed projects cannot be restored! + = button_to 'Remove project', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_project_message(@project) } .save-project-loader.hide .center @@ -254,5 +224,4 @@ Saving project. %p Please wait a moment, this page will automatically refresh when ready. - = render 'shared/confirm_modal', phrase: @project.path diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 1a2e59752fe5fa..636beb73ec20fa 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -15,10 +15,14 @@ If you already have files you can push them using command line instructions below. %p Otherwise you can start with adding a - = link_to "README", new_readme_path, class: 'underlined-link' + = succeed ',' do + = link_to "README", new_readme_path, class: 'underlined-link' + a + = succeed ',' do + = link_to "LICENSE", add_special_file_path(@project, file_name: 'LICENSE'), class: 'underlined-link' or a - = link_to "LICENSE", add_special_file_path(@project, file_name: 'LICENSE'), class: 'underlined-link' - file to this project. + = link_to '.gitignore', add_special_file_path(@project, file_name: '.gitignore'), class: 'underlined-link' + to this project. - if can?(current_user, :push_code, @project) %div{ class: container_class } diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml index 1fe1d98bf13eae..9322c82904f9cf 100644 --- a/app/views/projects/find_file/show.html.haml +++ b/app/views/projects/find_file/show.html.haml @@ -1,5 +1,4 @@ - page_title "Find File", @ref -- header_title project_title(@project, "Files", project_files_path(@project)) .file-finder-holder.tree-holder.clearfix .nav-block diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml index f21c864e35c44e..5bc5c71283ede1 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml @@ -12,6 +12,9 @@ - else %strong ##{generic_commit_status.id} + - if defined?(retried) && retried + = icon('warning', class: 'text-warning has-tooltip', title: 'Status was retried.') + - if defined?(commit_sha) && commit_sha %td = link_to generic_commit_status.short_sha, namespace_project_commit_path(generic_commit_status.project.namespace, generic_commit_status.project, generic_commit_status.sha), class: "monospace" @@ -37,11 +40,13 @@ %td = generic_commit_status.name - .pull-right - - if generic_commit_status.tags.any? - - generic_commit_status.tags.each do |tag| - %span.label.label-primary - = tag + %td + - if generic_commit_status.tags.any? + - generic_commit_status.tags.each do |tag| + %span.label.label-primary + = tag + - if defined?(retried) && retried + %span.label.label-warning retried %td.duration - if generic_commit_status.duration diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml index 79a56647c536ba..8becaea246f291 100644 --- a/app/views/projects/graphs/_head.html.haml +++ b/app/views/projects/graphs/_head.html.haml @@ -1,3 +1,4 @@ +- page_specific_javascripts asset_path("graphs/application.js") %ul.nav-links = nav_link(action: :show) do = link_to 'Contributors', namespace_project_graph_path diff --git a/app/views/projects/graphs/_header_title.html.haml b/app/views/projects/graphs/_header_title.html.haml deleted file mode 100644 index 1e2f61cd22b531..00000000000000 --- a/app/views/projects/graphs/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Graphs", namespace_project_graph_path(@project.namespace, @project, current_ref)) diff --git a/app/views/projects/graphs/ci.html.haml b/app/views/projects/graphs/ci.html.haml index 9f05be9982b432..19ccc125ea825f 100644 --- a/app/views/projects/graphs/ci.html.haml +++ b/app/views/projects/graphs/ci.html.haml @@ -1,5 +1,4 @@ - page_title "Continuous Integration", "Graphs" -= render "header_title" = render 'head' .row-content-block.append-bottom-default .oneline diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml index da9f648cc9c504..d9b2fb6c065d8f 100644 --- a/app/views/projects/graphs/commits.html.haml +++ b/app/views/projects/graphs/commits.html.haml @@ -1,5 +1,4 @@ - page_title "Commits", "Graphs" -= render "header_title" = render 'head' .row-content-block.append-bottom-default diff --git a/app/views/projects/graphs/languages.html.haml b/app/views/projects/graphs/languages.html.haml index ebecab1dbfcdf5..249c16f4709619 100644 --- a/app/views/projects/graphs/languages.html.haml +++ b/app/views/projects/graphs/languages.html.haml @@ -1,5 +1,4 @@ - page_title "Languages", "Graphs" -= render "header_title" = render 'head' .row-content-block.append-bottom-default diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index ad4a932d391fb8..33970e7b90912c 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -1,5 +1,4 @@ - page_title "Contributors", "Graphs" -= render "header_title" = render 'head' .row-content-block.append-bottom-default @@ -19,7 +18,7 @@ .header.clearfix %h3#date_header.page-title %p.light - Commits to #{@ref}, excluding merge commits. Limited by 6,000 commits + Commits to #{@ref}, excluding merge commits. Limited to 6,000 commits. %input#brush_change{:type => "hidden"} .graphs #contributors-master diff --git a/app/views/projects/hooks/_project_hook.html.haml b/app/views/projects/hooks/_project_hook.html.haml index 62eba5888a4f06..8151187d499613 100644 --- a/app/views/projects/hooks/_project_hook.html.haml +++ b/app/views/projects/hooks/_project_hook.html.haml @@ -3,7 +3,7 @@ .col-md-8.col-lg-7 %strong.light-header= hook.url %div - - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger| + - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events wiki_page_events).each do |trigger| - if hook.send(trigger) %span.label.label-gray.deploy-project-label= trigger.titleize .col-md-4.col-lg-5.text-right-lg.prepend-top-5 diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index 36c1d69f060d9d..917a0b805b1366 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -64,6 +64,13 @@ Build events %p.light This url will be triggered when the build status changes + %div + = f.check_box :wiki_page_events, class: 'pull-left' + .prepend-left-20 + = f.label :wiki_page_events, class: 'label-light append-bottom-0' do + Wiki Page events + %p.light + This url will be triggered when a wiki page is created/updated .form-group = f.label :enable_ssl_verification, "SSL verification", class: "label-light" %div @@ -80,5 +87,5 @@ - @hooks.each do |hook| = render "project_hook", hook: hook - else - %p.profile-settings-message.text-center.append-bottom-0 + %p.settings-message.text-center.append-bottom-0 No webhooks found, add one in the form above. diff --git a/app/views/projects/issues/_header_title.html.haml b/app/views/projects/issues/_header_title.html.haml deleted file mode 100644 index 99f03549c44ace..00000000000000 --- a/app/views/projects/issues/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Issues", namespace_project_issues_path(@project.namespace, @project)) diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 9ad86ed71c98f5..78f641506017cc 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -6,7 +6,7 @@ .issue-title.title %span.issue-title-text = confidential_icon(issue) - = link_to_gfm issue.title, issue_path(issue) + = link_to issue.title, issue_path(issue) %ul.controls - if issue.closed? %li @@ -28,16 +28,10 @@ = downvotes - note_count = issue.notes.user.nonawards.count - - if note_count > 0 - %li - = link_to issue_path(issue) + "#notes" do - = icon('comments') - = note_count - - else - %li - = link_to issue_path(issue) + "#notes", class: "issue-no-comments" do - = icon('comments') - = note_count + %li + = link_to issue_path(issue, anchor: 'notes'), class: ('issue-no-comments' if note_count.zero?) do + = icon('comments') + = note_count .issue-info #{issue.to_reference} · diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml index d6b38b327ff786..2f9dc867d0d806 100644 --- a/app/views/projects/issues/_merge_requests.html.haml +++ b/app/views/projects/issues/_merge_requests.html.haml @@ -7,7 +7,7 @@ %li %span.merge-request-ci-status - if merge_request.ci_commit - = render_ci_status(merge_request.ci_commit) + = render_pipeline_status(merge_request.ci_commit) - elsif has_any_ci = icon('blank fw') %span.merge-request-id @@ -24,5 +24,8 @@ MERGED - elsif merge_request.closed? CLOSED - - if @closed_by_merge_requests.present? + %li = render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count} + - if @closed_by_merge_requests.present? + %li + = render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count} diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml index bdfa0c7009eeca..5f9d2919982e9a 100644 --- a/app/views/projects/issues/_related_branches.html.haml +++ b/app/views/projects/issues/_related_branches.html.haml @@ -8,7 +8,7 @@ - ci_commit = @project.ci_commit(sha, branch) if sha - if ci_commit %span.related-branch-ci-status - = render_ci_status(ci_commit) + = render_pipeline_status(ci_commit) %span.related-branch-info %strong = link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch), class: "label-branch" do diff --git a/app/views/projects/issues/edit.html.haml b/app/views/projects/issues/edit.html.haml index 20216297d2558f..7cf1923456efe9 100644 --- a/app/views/projects/issues/edit.html.haml +++ b/app/views/projects/issues/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", "#{@issue.title} (##{@issue.iid})", "Issues" -= render "header_title" %h3.page-title Edit Issue ##{@issue.iid} diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder index ee8a94146572c7..7ad7c9c87e813d 100644 --- a/app/views/projects/issues/index.atom.builder +++ b/app/views/projects/issues/index.atom.builder @@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id namespace_project_issues_url(@project.namespace, @project) xml.updated @issues.first.created_at.xmlschema if @issues.any? - @issues.each do |issue| - issue_to_atom(xml, issue) - end + xml << render(partial: 'issues/issue', collection: @issues) if @issues.any? end diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index efa7642b2dc5b9..19a6f4a91f670d 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -1,5 +1,4 @@ - page_title "Issues" -= render "header_title" = content_for :meta_tags do - if current_user diff --git a/app/views/projects/issues/new.html.haml b/app/views/projects/issues/new.html.haml index b317a0c1cf4429..e8aae0f47e2652 100644 --- a/app/views/projects/issues/new.html.haml +++ b/app/views/projects/issues/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Issue" -= render "header_title" %h3.page-title New Issue diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index bde80bbb54b228..f3b0469b7d4236 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -1,7 +1,6 @@ - page_title "#{@issue.title} (##{@issue.iid})", "Issues" - page_description @issue.description - page_card_attributes @issue.card_attributes -- header_title project_title(@project, "Issues", namespace_project_issues_path(@project.namespace, @project)) .clearfix.detail-page-header .issuable-header @@ -53,12 +52,12 @@ .issue-details.issuable-details .detail-page-description.content-block %h2.title - = markdown escape_once(@issue.title), pipeline: :single_line + = markdown escape_once(@issue.title), pipeline: :single_line, author: @issue.author - if @issue.description.present? .description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' } .wiki = preserve do - = markdown(@issue.description, cache_key: [@issue, "description"]) + = markdown(@issue.description, cache_key: [@issue, "description"], author: @issue.author) %textarea.hidden.js-task-list-field = @issue.description = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue_edited_ago') diff --git a/app/views/projects/labels/_header_title.html.haml b/app/views/projects/labels/_header_title.html.haml deleted file mode 100644 index abe28da483b7a9..00000000000000 --- a/app/views/projects/labels/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Labels", namespace_project_labels_path(@project.namespace, @project)) diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml index 675a805e12fe1d..6901ba13ab70e7 100644 --- a/app/views/projects/labels/edit.html.haml +++ b/app/views/projects/labels/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", @label.name, "Labels" -= render "header_title" %h3.page-title Edit Label diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index cc41130a9dca38..2557d1a4d5b4be 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -1,5 +1,4 @@ - page_title "Labels" -= render "header_title" .top-area .nav-text @@ -18,6 +17,6 @@ - else .nothing-here-block - if can? current_user, :admin_label, @project - Create first label or #{link_to 'generate', generate_namespace_project_labels_path(@project.namespace, @project), method: :post} default set of labels + Create a label or #{link_to 'generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post}. - else No labels created diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml index e20fd7d6891fc4..49ddf9016192d9 100644 --- a/app/views/projects/labels/new.html.haml +++ b/app/views/projects/labels/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Label" -= render "header_title" %h3.page-title New Label diff --git a/app/views/projects/merge_requests/_header_title.html.haml b/app/views/projects/merge_requests/_header_title.html.haml deleted file mode 100644 index 669a9b06bdf5a1..00000000000000 --- a/app/views/projects/merge_requests/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Merge Requests", namespace_project_merge_requests_path(@project.namespace, @project)) diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index e740fe8c84d64b..c02f94490a043a 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -1,7 +1,7 @@ %li{ class: mr_css_classes(merge_request) } .merge-request-title.title %span.merge-request-title-text - = link_to_gfm merge_request.title, merge_request_path(merge_request) + = link_to merge_request.title, merge_request_path(merge_request) %ul.controls - if merge_request.merged? %li @@ -13,7 +13,7 @@ - if merge_request.ci_commit %li - = render_ci_status(merge_request.ci_commit) + = render_pipeline_status(merge_request.ci_commit) - if merge_request.open? && merge_request.broken? %li @@ -36,16 +36,10 @@ = downvotes - note_count = merge_request.mr_and_commit_notes.user.nonawards.count - - if note_count > 0 - %li - = link_to merge_request_path(merge_request) + "#notes" do - = icon('comments') - = note_count - - else - %li - = link_to merge_request_path(merge_request) + "#notes", class: "merge-request-no-comments" do - = icon('comments') - = note_count + %li + = link_to merge_request_path(merge_request, anchor: 'notes'), class: ('merge-request-no-comments' if note_count.zero?) do + = icon('comments') + = note_count .merge-request-info #{merge_request.to_reference} · diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 290753d57c6eda..7af227129ecb69 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -1,7 +1,6 @@ - page_title "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests" - page_description @merge_request.description - page_card_attributes @merge_request.card_attributes -- header_title project_title(@project, "Merge Requests", namespace_project_merge_requests_path(@project.namespace, @project)) - if diff_view == 'parallel' - fluid_layout true diff --git a/app/views/projects/merge_requests/dropdowns/_branch.html.haml b/app/views/projects/merge_requests/dropdowns/_branch.html.haml index ba8d9a5835c010..a60c445aa518a2 100644 --- a/app/views/projects/merge_requests/dropdowns/_branch.html.haml +++ b/app/views/projects/merge_requests/dropdowns/_branch.html.haml @@ -1,5 +1,5 @@ %ul - branches.each do |branch| %li - %a{ href: '#', class: "#{('is-active' if selected == branch)}", data: { id: branch } } + %a{ href: '#', class: "#{('is-active' if selected == branch)}", title: branch, data: { id: branch } } = branch diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml index b31ea5e532157a..03159f123f3764 100644 --- a/app/views/projects/merge_requests/edit.html.haml +++ b/app/views/projects/merge_requests/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests" -= render "header_title" %h3.page-title Edit Merge Request #{@merge_request.to_reference} diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index e56a44e0a79dbe..b517e874b0f9d2 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -1,5 +1,4 @@ - page_title "Merge Requests" -= render "header_title" = render 'projects/last_push' diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml index f5bf16ef3adb1e..a00d3128ffef70 100644 --- a/app/views/projects/merge_requests/invalid.html.haml +++ b/app/views/projects/merge_requests/invalid.html.haml @@ -1,5 +1,4 @@ - page_title "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests" -= render "header_title" .merge-request = render "projects/merge_requests/show/mr_title" diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/new.html.haml index d259968030e92b..2e798ce780a710 100644 --- a/app/views/projects/merge_requests/new.html.haml +++ b/app/views/projects/merge_requests/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Merge Request" -= render "header_title" - if @merge_request.can_be_created && !params[:change_branches] = render 'new_submit' diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index a23bd8d18d0512..ebf18f6ac8598b 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -1,13 +1,13 @@ .detail-page-description.content-block %h2.title - = markdown escape_once(@merge_request.title), pipeline: :single_line + = markdown escape_once(@merge_request.title), pipeline: :single_line, author: @merge_request.author %div - if @merge_request.description.present? .description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''} .wiki = preserve do - = markdown(@merge_request.description, cache_key: [@merge_request, "description"]) + = markdown(@merge_request.description, cache_key: [@merge_request, "description"], author: @merge_request.author) %textarea.hidden.js-task-list-field = @merge_request.description diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml index 55dbae598d3c88..13359abede7684 100644 --- a/app/views/projects/merge_requests/widget/_open.html.haml +++ b/app/views/projects/merge_requests/widget/_open.html.haml @@ -26,4 +26,4 @@ %i.fa.fa-check Accepting this merge request will close #{"issue".pluralize(@closes_issues.size)} = succeed '.' do - != markdown issues_sentence(@closes_issues), pipeline: :gfm + != markdown issues_sentence(@closes_issues), pipeline: :gfm, author: @merge_request.author diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml index 3c68d61c4b5915..b79508bdc344de 100644 --- a/app/views/projects/merge_requests/widget/_show.html.haml +++ b/app/views/projects/merge_requests/widget/_show.html.haml @@ -13,7 +13,7 @@ check_enable: #{@merge_request.unchecked? ? "true" : "false"}, ci_status_url: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", gitlab_icon: "#{asset_path 'gitlab_logo.png'}", - ci_status: "", + ci_status: "#{@merge_request.ci_commit ? @merge_request.ci_commit.status : ''}", ci_message: { normal: "Build {{status}} for \"{{title}}\"", preparing: "{{status}} build for \"{{title}}\"" @@ -26,4 +26,10 @@ builds_path: "#{builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}" }; + if (typeof merge_request_widget !== 'undefined') { + clearInterval(merge_request_widget.fetchBuildStatusInterval); + merge_request_widget.cancelPolling(); + merge_request_widget.clearEventListeners(); + } + merge_request_widget = new MergeRequestWidget(opts); diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index 807833741afc77..cfdf4edac3752f 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -25,7 +25,10 @@ - else = f.button class: "btn btn-create btn-grouped js-merge-button accept_merge_request #{status_class}" do Accept Merge Request - - if @merge_request.can_remove_source_branch?(current_user) + - if @merge_request.force_remove_source_branch? + .accept-control + The source branch will be removed. + - elsif @merge_request.can_remove_source_branch?(current_user) .accept-control.checkbox = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do = check_box_tag :should_remove_source_branch diff --git a/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml b/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml index 2168294c683936..b83ddcab3a4a8f 100644 --- a/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml +++ b/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml @@ -2,17 +2,16 @@ Set by #{link_to_member(@project, @merge_request.merge_user, avatar: true)} to be merged automatically when the build succeeds. %div - - should_remove_source_branch = @merge_request.merge_params["should_remove_source_branch"].present? %p = succeed '.' do The changes will be merged into %span.label-branch= @merge_request.target_branch - - if should_remove_source_branch + - if @merge_request.remove_source_branch? The source branch will be removed. - else The source branch will not be removed. - - remove_source_branch_button = @merge_request.can_remove_source_branch?(current_user) && !should_remove_source_branch && @merge_request.merge_user == current_user + - remove_source_branch_button = !@merge_request.remove_source_branch? && @merge_request.can_remove_source_branch?(current_user) && @merge_request.merge_user == current_user - user_can_cancel_automatic_merge = @merge_request.can_cancel_merge_when_build_succeeds?(current_user) - if remove_source_branch_button || user_can_cancel_automatic_merge .clearfix.prepend-top-10 diff --git a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml index a8145558ca8511..57ce1959021fa6 100644 --- a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml +++ b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml @@ -1,4 +1,6 @@ -%h4 +%h4 Ready to be merged automatically %p Ask someone with write access to this repository to merge this request. + - if @merge_request.force_remove_source_branch? + The source branch will be removed. diff --git a/app/views/projects/milestones/_header_title.html.haml b/app/views/projects/milestones/_header_title.html.haml deleted file mode 100644 index 5f4b6982a6de11..00000000000000 --- a/app/views/projects/milestones/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Milestones", namespace_project_milestones_path(@project.namespace, @project)) diff --git a/app/views/projects/milestones/edit.html.haml b/app/views/projects/milestones/edit.html.haml index 43f8863163dadb..be682226ab68e2 100644 --- a/app/views/projects/milestones/edit.html.haml +++ b/app/views/projects/milestones/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", @milestone.title, "Milestones" -= render "header_title" %h3.page-title Edit Milestone ##{@milestone.iid} diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index abe567af1dd92d..e6133b22f96dcf 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -1,6 +1,4 @@ - page_title "Milestones" -= render "header_title" - .top-area = render 'shared/milestones_filter' diff --git a/app/views/projects/milestones/new.html.haml b/app/views/projects/milestones/new.html.haml index 0d016f7831391f..7f372b41698bd4 100644 --- a/app/views/projects/milestones/new.html.haml +++ b/app/views/projects/milestones/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Milestone" -= render "header_title" %h3.page-title New Milestone diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 6ec84660157606..19944e3e023afd 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -1,8 +1,6 @@ - page_title @milestone.title, "Milestones" - page_description @milestone.description -= render "header_title" - .detail-page-header .status-box{ class: status_box_class(@milestone) } - if @milestone.closed? diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index 8065663ca2a873..326180ebe4eb3f 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -1,5 +1,4 @@ - page_title "Network", @ref -= render "projects/commits/header_title" = render "projects/commits/head" = render "head" .project-network diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index a4c6094c69af07..f9ac16b32f32d2 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -1,5 +1,5 @@ - page_title 'New Project' -- header_title "Projects", root_path +- header_title "Projects", dashboard_projects_path %h3.page-title New Project diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml index 39be072855ae01..8144c1ba49ece2 100644 --- a/app/views/projects/notes/_diff_notes_with_reply.html.haml +++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml @@ -1,10 +1,8 @@ -- note = notes.first # example note --# Check if line want not changed since comment was left -- if !defined?(line) || line == note.diff_line - %tr.notes_holder - %td.notes_line{ colspan: 2 } - %td.notes_content - %ul.notes{ data: { discussion_id: note.discussion_id } } - = render notes - .discussion-reply-holder - = link_to_reply_diff(note) +- note = notes.first +%tr.notes_holder + %td.notes_line{ colspan: 2 } + %td.notes_content + %ul.notes{ data: { discussion_id: note.discussion_id } } + = render partial: "projects/notes/note", collection: notes, as: :note + .discussion-reply-holder + = link_to_reply_discussion(note) diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml index f8aa5e2fa7dfcf..45986b0d1e8e70 100644 --- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml +++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml @@ -1,27 +1,27 @@ -- note1 = notes_left.present? ? notes_left.first : nil -- note2 = notes_right.present? ? notes_right.first : nil +- note_left = notes_left.present? ? notes_left.first : nil +- note_right = notes_right.present? ? notes_right.first : nil %tr.notes_holder - - if note1 + - if note_left %td.notes_line.old %td.notes_content.parallel.old - %ul.notes{ data: { discussion_id: note1.discussion_id } } - = render notes_left + %ul.notes{ data: { discussion_id: note_left.discussion_id } } + = render partial: "projects/notes/note", collection: notes_left, as: :note .discussion-reply-holder - = link_to_reply_diff(note1, 'old') + = link_to_reply_discussion(note_left, 'old') - else %td.notes_line.old= "" %td.notes_content.parallel.old= "" - - if note2 + - if note_right %td.notes_line.new %td.notes_content.parallel.new - %ul.notes{ data: { discussion_id: note2.discussion_id } } - = render notes_right + %ul.notes{ data: { discussion_id: note_right.discussion_id } } + = render partial: "projects/notes/note", collection: notes_right, as: :note .discussion-reply-holder - = link_to_reply_diff(note2, 'new') + = link_to_reply_discussion(note_right, 'new') - else %td.notes_line.new= "" %td.notes_content.parallel.new= "" diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml index 572b00a38c76a7..7869d6413d8d87 100644 --- a/app/views/projects/notes/_discussion.html.haml +++ b/app/views/projects/notes/_discussion.html.haml @@ -1,13 +1,46 @@ - note = discussion_notes.first +- expanded = !note.diff_note? || note.active? %li.note.note-discussion.timeline-entry .timeline-entry-inner .timeline-icon = link_to user_path(note.author) do - = image_tag avatar_icon(note.author_email), class: "avatar s40" + = image_tag avatar_icon(note.author), class: "avatar s40" .timeline-content - - if note.for_merge_request? - - (active_notes, outdated_notes) = discussion_notes.partition(&:active?) - = render "projects/notes/discussions/active", discussion_notes: active_notes if active_notes.length > 0 - = render "projects/notes/discussions/outdated", discussion_notes: outdated_notes if outdated_notes.length > 0 - - else - = render "projects/notes/discussions/commit", discussion_notes: discussion_notes + .discussion.js-toggle-container{ class: note.discussion_id } + .discussion-header + = link_to_member(@project, note.author, avatar: false) + + .inline.discussion-headline-light + = note.author.to_reference + started a discussion on + + - if note.for_commit? + - commit = note.noteable + - if commit + commit + = link_to commit.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code), class: 'monospace' + - else + a deleted commit + - else + - if note.active? + = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do + the diff + - else + an outdated diff + + = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "note-created-ago") + + .discussion-actions + = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do + - if expanded + = icon("chevron-up") + - else + = icon("chevron-down") + + Toggle discussion + + .discussion-body.js-toggle-content{ class: ("hide" unless expanded) } + - if note.diff_note? + = render "projects/notes/discussions/diff_with_notes", discussion_notes: discussion_notes + - else + = render "projects/notes/discussions/notes", discussion_notes: discussion_notes diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index d0ac380f216c41..67ed38a7b22c4d 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -6,6 +6,7 @@ = f.hidden_field :line_code = f.hidden_field :noteable_id = f.hidden_field :noteable_type + = f.hidden_field :type = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do = render 'projects/zen', f: f, attr: :note, classes: 'note-textarea js-note-text', placeholder: "Write a comment or drag your files here..." diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index aeb7c1d5ee43df..f1045bbd8c3e81 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -1,5 +1,8 @@ +- return unless note.author +- return if note.cross_reference_not_visible_for?(current_user) + - note_editable = note_editable?(note) -%li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} } +%li.timeline-entry{ id: dom_id(note), class: ["note", "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} } .timeline-entry-inner .timeline-icon %a{href: user_path(note.author)} @@ -8,8 +11,8 @@ .note-header = link_to_member(note.project, note.author, avatar: false) .inline.note-headline-light - = "#{note.author.to_reference}" - - if !note.system + = note.author.to_reference + - unless note.system commented %a{ href: "##{dom_id(note)}" } = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago') @@ -26,7 +29,7 @@ .note-body{class: note_editable ? 'js-task-list-container' : ''} .note-text = preserve do - = markdown(note.note, pipeline: :note, cache_key: [note, "note"]) + = markdown(note.note, pipeline: :note, cache_key: [note, "note"], author: note.author) - if note_editable = render 'projects/notes/edit_form', note: note = edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true) diff --git a/app/views/projects/notes/_notes.html.haml b/app/views/projects/notes/_notes.html.haml index 62db86fb18171c..ebf7e8a9cb3448 100644 --- a/app/views/projects/notes/_notes.html.haml +++ b/app/views/projects/notes/_notes.html.haml @@ -2,14 +2,9 @@ - @discussions.each do |discussion_notes| - note = discussion_notes.first - if note_for_main_target?(note) - - next if note.cross_reference_not_visible_for?(current_user) - - = render discussion_notes + = render partial: "projects/notes/note", object: note, as: :note - else = render 'projects/notes/discussion', discussion_notes: discussion_notes - else - @notes.each do |note| - - next unless note.author - - next if note.cross_reference_not_visible_for?(current_user) - - = render note + = render partial: "projects/notes/note", object: note, as: :note diff --git a/app/views/projects/notes/discussions/_active.html.haml b/app/views/projects/notes/discussions/_active.html.haml deleted file mode 100644 index 0ea8862a684d13..00000000000000 --- a/app/views/projects/notes/discussions/_active.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -- note = discussion_notes.first -.discussion.js-toggle-container{ class: note.discussion_id } - .discussion-header - = link_to_member(@project, note.author, avatar: false) - .inline.discussion-headline-light - = "#{note.author.to_reference} started a discussion" - = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do - on the diff - = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago") - .discussion-actions - = link_to "#", class: "discussion-action-button discussion-toggle-button js-toggle-button" do - %i.fa.fa-chevron-up - Show/hide discussion - - .discussion-body.js-toggle-content - = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note diff --git a/app/views/projects/notes/discussions/_commit.html.haml b/app/views/projects/notes/discussions/_commit.html.haml deleted file mode 100644 index 2a2ead58eeb584..00000000000000 --- a/app/views/projects/notes/discussions/_commit.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -- note = discussion_notes.first -- commit = note.noteable -- commit_description = commit ? 'commit' : 'a deleted commit' -.discussion.js-toggle-container{ class: note.discussion_id } - .discussion-header - = link_to_member(@project, note.author, avatar: false) - .inline.discussion-headline-light - = "#{note.author.to_reference} started a discussion on #{commit_description}" - - if commit - = link_to(commit.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable), class: 'monospace') - = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago") - .discussion-actions - = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do - %i.fa.fa-chevron-up - Show/hide discussion - .discussion-body.js-toggle-content - - if note.for_diff_line? - = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note - - else - .panel.panel-default - .notes{ data: { discussion_id: discussion_notes.first.discussion_id } } - %ul.notes.timeline - = render discussion_notes - .discussion-reply-holder - = link_to_reply_diff(discussion_notes.first) diff --git a/app/views/projects/notes/discussions/_diff.html.haml b/app/views/projects/notes/discussions/_diff.html.haml deleted file mode 100644 index d46aab000c3756..00000000000000 --- a/app/views/projects/notes/discussions/_diff.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -- diff = note.diff -- if diff - .diff-file - .diff-header - %span - - if diff.deleted_file - = diff.old_path - - else - = diff.new_path - - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode - %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" - .diff-content.code.js-syntax-highlight - %table - - note.truncated_diff_lines.each do |line| - - type = line.type - - line_code = generate_line_code(note.file_path, line) - %tr.line_holder{ id: line_code, class: "#{type}" } - - if type == "match" - %td.old_line.diff-line-num= "..." - %td.new_line.diff-line-num= "..." - %td.line_content.match= line.text - - else - %td.old_line.diff-line-num{ data: { linenumber: type == "new" ? " ".html_safe : line.old_pos } } - %td.new_line.diff-line-num{ data: { linenumber: type == "old" ? " ".html_safe : line.new_pos } } - %td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type) - - - if line_code == note.line_code - = render "projects/notes/diff_notes_with_reply", notes: discussion_notes diff --git a/app/views/projects/notes/discussions/_diff_with_notes.html.haml b/app/views/projects/notes/discussions/_diff_with_notes.html.haml new file mode 100644 index 00000000000000..6401245bf73422 --- /dev/null +++ b/app/views/projects/notes/discussions/_diff_with_notes.html.haml @@ -0,0 +1,30 @@ +- note = discussion_notes.first +- diff = note.diff +- return unless diff + +.diff-file + .diff-header + %span + - if diff.deleted_file + = diff.old_path + - else + = diff.new_path + - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode + %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" + .diff-content.code.js-syntax-highlight + %table + - note.truncated_diff_lines.each do |line| + - type = line.type + - line_code = generate_line_code(note.diff_file_path, line) + %tr.line_holder{ id: line_code, class: "#{type}" } + - if type == "match" + %td.old_line.diff-line-num= "..." + %td.new_line.diff-line-num= "..." + %td.line_content.match= line.text + - else + %td.old_line.diff-line-num{ data: { linenumber: type == "new" ? " ".html_safe : line.old_pos } } + %td.new_line.diff-line-num{ data: { linenumber: type == "old" ? " ".html_safe : line.new_pos } } + %td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type) + + - if line_code == note.line_code + = render "projects/notes/diff_notes_with_reply", notes: discussion_notes diff --git a/app/views/projects/notes/discussions/_notes.html.haml b/app/views/projects/notes/discussions/_notes.html.haml new file mode 100644 index 00000000000000..e598e3c7c6346c --- /dev/null +++ b/app/views/projects/notes/discussions/_notes.html.haml @@ -0,0 +1,7 @@ +- note = discussion_notes.first +.panel.panel-default + .notes{ data: { discussion_id: note.discussion_id } } + %ul.notes.timeline + = render partial: "projects/notes/note", collection: discussion_notes, as: :note + .discussion-reply-holder + = link_to_reply_discussion(note) diff --git a/app/views/projects/notes/discussions/_outdated.html.haml b/app/views/projects/notes/discussions/_outdated.html.haml deleted file mode 100644 index 45141bcd1dfd59..00000000000000 --- a/app/views/projects/notes/discussions/_outdated.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- note = discussion_notes.first -.discussion.js-toggle-container{ class: note.discussion_id } - .discussion-header - = link_to_member(@project, note.author, avatar: false) - .inline.discussion-headline-light - = "#{note.author.to_reference} started a discussion" - on the outdated diff - = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago") - .discussion-actions - = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do - %i.fa.fa-chevron-down - Show/hide discussion - .discussion-body.js-toggle-content.hide - = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml new file mode 100644 index 00000000000000..6e757df5417e74 --- /dev/null +++ b/app/views/projects/pipelines/_head.html.haml @@ -0,0 +1,14 @@ +%ul.nav-links + - if project_nav_tab? :pipelines + = nav_link(controller: :pipelines) do + = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do + %span + Pipelines + %span.badge.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count) + + - if project_nav_tab? :builds + = nav_link(controller: %w(builds)) do + = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do + %span + Builds + %span.badge.count.builds_counter= number_with_delimiter(@project.running_or_pending_build_count) diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml new file mode 100644 index 00000000000000..8289aefcde755c --- /dev/null +++ b/app/views/projects/pipelines/_info.html.haml @@ -0,0 +1,37 @@ +%p +.commit-info-row + Pipeline + = link_to "##{@pipeline.id}", namespace_project_pipeline_path(@project.namespace, @project, @pipeline.id), class: "monospace" + with + = pluralize @pipeline.statuses.count(:id), "build" + - if @pipeline.ref + for + = link_to @pipeline.ref, namespace_project_commits_path(@project.namespace, @project, @pipeline.ref), class: "monospace" + - if @pipeline.duration + in + = time_interval_in_words @pipeline.duration + + .pull-right + = link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), class: "ci-status ci-#{@pipeline.status}" do + = ci_icon_for_status(@pipeline.status) + = ci_label_for_status(@pipeline.status) + +- if @commit + .commit-info-row + %span.light Authored by + %strong + = commit_author_link(@commit, avatar: true, size: 24) + #{time_ago_with_tooltip(@commit.authored_date)} + +.commit-info-row + %span.light Commit + = link_to @pipeline.sha, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "monospace" + = clipboard_button(clipboard_text: @pipeline.sha) + +- if @commit + .commit-box.content-block + %h3.commit-title + = markdown escape_once(@commit.title), pipeline: :single_line + - if @commit.description.present? + %pre.commit-description + = preserve(markdown(escape_once(@commit.description), pipeline: :single_line)) diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml new file mode 100644 index 00000000000000..453767920b564d --- /dev/null +++ b/app/views/projects/pipelines/index.html.haml @@ -0,0 +1,58 @@ +- page_title "Pipelines" += render "projects/pipelines/head" + +.top-area + %ul.nav-links + %li{class: ('active' if @scope.nil?)} + = link_to project_pipelines_path(@project) do + All + %span.badge.js-totalbuilds-count + = number_with_delimiter(@pipelines_count) + + %li{class: ('active' if @scope == 'running')} + = link_to project_pipelines_path(@project, scope: :running) do + Running + %span.badge.js-running-count + = number_with_delimiter(@running_or_pending_count) + + %li{class: ('active' if @scope == 'branches')} + = link_to project_pipelines_path(@project, scope: :branches) do + Branches + + %li{class: ('active' if @scope == 'tags')} + = link_to project_pipelines_path(@project, scope: :tags) do + Tags + + .nav-controls + - if can? current_user, :create_pipeline, @project + = link_to new_namespace_project_pipeline_path(@project.namespace, @project), class: 'btn btn-create' do + = icon('plus') + New pipeline + + - unless @repository.gitlab_ci_yml + = link_to 'Get started with Pipelines', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info' + + = link_to ci_lint_path, class: 'btn btn-default' do + = icon('wrench') + %span CI Lint + +%ul.content-list.pipelines + - stages = @pipelines.stages + - if @pipelines.blank? + %li + .nothing-here-block No pipelines to show + - else + .table-holder + %table.table.builds + %tbody + %th ID + %th Commit + - stages.each do |stage| + %th.stage + %span.has-tooltip{ title: "#{stage.titleize}" } + = stage.titleize.pluralize + %th Duration + %th + = render @pipelines, commit_sha: true, stage: true, allow_retry: true, stages: stages + + = paginate @pipelines, theme: 'gitlab' diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml new file mode 100644 index 00000000000000..5f4ec2e40c85e9 --- /dev/null +++ b/app/views/projects/pipelines/new.html.haml @@ -0,0 +1,21 @@ +- page_title "New Pipeline" + +%h3.page-title + New Pipeline +%hr + += form_for @pipeline, as: :pipeline, url: namespace_project_pipelines_path(@project.namespace, @project), html: { id: "new-pipeline-form", class: "form-horizontal js-new-pipeline-form js-requires-input" } do |f| + = form_errors(@pipeline) + .form-group + = f.label :ref, 'Create for', class: 'control-label' + .col-sm-10 + = f.text_field :ref, required: true, tabindex: 2, class: 'form-control' + .help-block Existing branch name, tag + .form-actions + = f.submit 'Create pipeline', class: 'btn btn-create', tabindex: 3 + = link_to 'Cancel', namespace_project_pipelines_path(@project.namespace, @project), class: 'btn btn-cancel' + +:javascript + var availableRefs = #{@project.repository.ref_names.to_json}; + + new NewBranchForm($('.js-new-pipeline-form'), availableRefs) diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml new file mode 100644 index 00000000000000..2aad5602414c2e --- /dev/null +++ b/app/views/projects/pipelines/show.html.haml @@ -0,0 +1,8 @@ +- page_title "Pipeline" + +.prepend-top-default + - if @commit + = render "projects/pipelines/info" + %div.block-connector + += render "projects/commit/ci_commit", ci_commit: @pipeline diff --git a/app/views/projects/project_members/_header_title.html.haml b/app/views/projects/project_members/_header_title.html.haml deleted file mode 100644 index a31f0a37fa2a42..00000000000000 --- a/app/views/projects/project_members/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Members", namespace_project_project_members_path(@project.namespace, @project)) diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml index 189906498cbdfd..eef97107d7710d 100644 --- a/app/views/projects/project_members/import.html.haml +++ b/app/views/projects/project_members/import.html.haml @@ -1,5 +1,4 @@ - page_title "Import members" -= render "header_title" %h3.page-title Import members from another project diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index ebcfc907ebbfda..15dc064e7eaac0 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -1,5 +1,4 @@ - page_title "Members" -= render "header_title" .project-members-page.prepend-top-default - if can?(current_user, :admin_project_member, @project) diff --git a/app/views/projects/protected_branches/_branches_list.html.haml b/app/views/projects/protected_branches/_branches_list.html.haml index b9e9dd8aaea478..565905cbe7b9d5 100644 --- a/app/views/projects/protected_branches/_branches_list.html.haml +++ b/app/views/projects/protected_branches/_branches_list.html.haml @@ -1,7 +1,7 @@ %h5.prepend-top-0 Already Protected (#{@branches.size}) - if @branches.empty? - %p.profile-settings-message.text-center + %p.settings-message.text-center No branches are protected, protect a branch with the form above. - else - can_admin_project = can?(current_user, :admin_project, @project) diff --git a/app/views/projects/releases/edit.html.haml b/app/views/projects/releases/edit.html.haml index 0d59cec322ca9b..835398b6f9895c 100644 --- a/app/views/projects/releases/edit.html.haml +++ b/app/views/projects/releases/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", @tag.name, "Tags" -= render "projects/commits/header_title" = render "projects/commits/head" .row-content-block diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml index 6ca919f7f80292..43a6fdfd103c7c 100644 --- a/app/views/projects/repositories/_feed.html.haml +++ b/app/views/projects/repositories/_feed.html.haml @@ -12,7 +12,7 @@ = link_to namespace_project_commits_path(@project.namespace, @project, commit.id) do %code= commit.short_id = image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: '' - = markdown escape_once(truncate(commit.title, length: 40)), pipeline: :single_line + = markdown escape_once(truncate(commit.title, length: 40)), pipeline: :single_line, author: commit.author %td %span.pull-right.cgray = time_ago_with_tooltip(commit.committed_date) diff --git a/app/views/projects/runners/_form.html.haml b/app/views/projects/runners/_form.html.haml new file mode 100644 index 00000000000000..d62f5c8f131e0c --- /dev/null +++ b/app/views/projects/runners/_form.html.haml @@ -0,0 +1,32 @@ += form_for runner, url: runner_form_url, html: { class: 'form-horizontal' } do |f| + = form_errors(runner) + .form-group + = label :active, "Active", class: 'control-label' + .col-sm-10 + .checkbox + = f.check_box :active + %span.light Paused runners don't accept new builds + .form-group + = label :run_untagged, 'Run untagged jobs', class: 'control-label' + .col-sm-10 + .checkbox + = f.check_box :run_untagged + %span.light Indicates whether this runner can pick jobs without tags + .form-group + = label_tag :token, class: 'control-label' do + Token + .col-sm-10 + = f.text_field :token, class: 'form-control', readonly: true + .form-group + = label_tag :description, class: 'control-label' do + Description + .col-sm-10 + = f.text_field :description, class: 'form-control' + .form-group + = label_tag :tag_list, class: 'control-label' do + Tags + .col-sm-10 + = f.text_field :tag_list, value: runner.tag_list.to_s, class: 'form-control' + .help-block You can setup jobs to only use runners with specific tags + .form-actions + = f.submit 'Save changes', class: 'btn btn-save' diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index 47ec420189dc78..96e2aac451f027 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -5,7 +5,7 @@ - if @runners.include?(runner) = link_to runner.short_sha, runner_path(runner) %small - =link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do + = link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do %i.fa.fa-edit.btn - else = runner.short_sha diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml index 30cd1263a12235..8ae9f0d95f7f7c 100644 --- a/app/views/projects/runners/_specific_runners.html.haml +++ b/app/views/projects/runners/_specific_runners.html.haml @@ -8,7 +8,7 @@ Install GitLab Runner software. Checkout the #{link_to 'GitLab Runner section', 'https://about.gitlab.com/gitlab-ci/#gitlab-runner', target: '_blank'} to install it %li - Specify following URL during runner setup: + Specify the following URL during runner setup: %code #{ci_root_url(only_path: false)} %li Use the following registration token during setup: diff --git a/app/views/projects/runners/edit.html.haml b/app/views/projects/runners/edit.html.haml index eba03028af8c34..95706888655722 100644 --- a/app/views/projects/runners/edit.html.haml +++ b/app/views/projects/runners/edit.html.haml @@ -1,29 +1,6 @@ - page_title "Edit", "#{@runner.description} ##{@runner.id}", "Runners" %h4 Runner ##{@runner.id} + %hr -= form_for @runner, url: runner_path(@runner), html: { class: 'form-horizontal' } do |f| - .form-group - = label :active, "Active", class: 'control-label' - .col-sm-10 - .checkbox - = f.check_box :active - %span.light Paused runners don't accept new builds - .form-group - = label_tag :token, class: 'control-label' do - Token - .col-sm-10 - = f.text_field :token, class: 'form-control', readonly: true - .form-group - = label_tag :description, class: 'control-label' do - Description - .col-sm-10 - = f.text_field :description, class: 'form-control' - .form-group - = label_tag :tag_list, class: 'control-label' do - Tags - .col-sm-10 - = f.text_field :tag_list, value: @runner.tag_list.to_s, class: 'form-control' - .help-block You can setup jobs to only use runners with specific tags - .form-actions - = f.submit 'Save changes', class: 'btn btn-save' + = render 'form', runner: @runner, runner_form_url: runner_path(@runner) diff --git a/app/views/projects/runners/show.html.haml b/app/views/projects/runners/show.html.haml index 5bf4c09ca25e09..f24e1b9144e8e7 100644 --- a/app/views/projects/runners/show.html.haml +++ b/app/views/projects/runners/show.html.haml @@ -17,50 +17,39 @@ %th Property Name %th Value %tr - %td - Tags + %td Active + %td= @runner.active? ? 'Yes' : 'No' + %tr + %td Can run untagged jobs + %td= @runner.run_untagged? ? 'Yes' : 'No' + %tr + %td Tags %td - @runner.tag_list.each do |tag| %span.label.label-primary = tag %tr - %td - Name - %td - = @runner.name + %td Name + %td= @runner.name %tr - %td - Version - %td - = @runner.version + %td Version + %td= @runner.version %tr - %td - Revision - %td - = @runner.revision + %td Revision + %td= @runner.revision %tr - %td - Platform - %td - = @runner.platform + %td Platform + %td= @runner.platform %tr - %td - Architecture - %td - = @runner.architecture + %td Architecture + %td= @runner.architecture %tr - %td - Description - %td - = @runner.description + %td Description + %td= @runner.description %tr - %td - Last contact + %td Last contact %td - if @runner.contacted_at #{time_ago_in_words(@runner.contacted_at)} ago - else Never - - - diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index 1b70880043a85f..1f13ea28b4e142 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -1,18 +1,16 @@ -%h3.page-title - = @service.title - = boolean_to_icon @service.activated? +.row.prepend-top-default.append-bottom-default + .col-lg-3 + %h4.prepend-top-0 + = @service.title + = boolean_to_icon @service.activated? -%p= @service.description - -%hr - -= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form| - = render 'shared/service_settings', form: form - - .form-actions - = form.submit 'Save changes', class: 'btn btn-save' -   - - if @service.valid? && @service.activated? - - disabled = @service.can_test? ? '':'disabled' - = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}" - = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel" + %p= @service.description + .col-lg-9 + = form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form| + = render 'shared/service_settings', form: form + = form.submit 'Save changes', class: 'btn btn-save' +   + - if @service.valid? && @service.activated? + - disabled = @service.can_test? ? '':'disabled' + = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}" + = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel" diff --git a/app/views/projects/services/index.html.haml b/app/views/projects/services/index.html.haml index c1356f6db02daf..4a33a5bc6f6b8a 100644 --- a/app/views/projects/services/index.html.haml +++ b/app/views/projects/services/index.html.haml @@ -1,24 +1,32 @@ - page_title "Services" -%h3.page-title Project services -%p.light Project services allow you to integrate GitLab with other applications -.table-holder - %table.table - %thead - %tr - %th - %th Service - %th Description - %th Last edit - - @services.sort_by(&:title).each do |service| - %tr - %td - = boolean_to_icon service.activated? - %td - = link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do - %strong= service.title - %td - = service.description - %td.light - = time_ago_in_words service.updated_at - ago +.row.prepend-top-default.append-bottom-default + .col-lg-3 + %h4.prepend-top-0 + Project services + %p Project services allow you to integrate GitLab with other applications + .col-lg-9 + %table.table + %colgroup + %col + %col + %col.hidden-xs + %col{ width: "120" } + %thead + %tr + %th + %th Service + %th.hidden-xs Description + %th Last edit + - @services.sort_by(&:title).each do |service| + %tr + %td + = boolean_to_icon service.activated? + %td + = link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do + %strong= service.title + %td.hidden-xs + = service.description + %td.light + = time_ago_in_words service.updated_at + ago diff --git a/app/views/projects/show.atom.builder b/app/views/projects/show.atom.builder index 9b3d3f069d9bf9..11310d5e1e1f51 100644 --- a/app/views/projects/show.atom.builder +++ b/app/views/projects/show.atom.builder @@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id namespace_project_url(@project.namespace, @project) xml.updated @events[0].updated_at.xmlschema if @events[0] - @events.each do |event| - event_to_atom(xml, event) - end + xml << render(@events) if @events.any? end diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 74feb9e3282db6..a19c7c406a060a 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -13,50 +13,50 @@ = render "home_panel" .project-stats.row-content-block.second-block - %ul.nav - %li - = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do - = pluralize(number_with_delimiter(@project.commit_count), 'commit') - %li - = link_to namespace_project_branches_path(@project.namespace, @project) do - = pluralize(number_with_delimiter(@repository.branch_names.count), 'branch') - %li - = link_to namespace_project_tags_path(@project.namespace, @project) do - = pluralize(number_with_delimiter(@repository.tag_names.count), 'tag') - - %li - = link_to project_files_path(@project) do - = repository_size - - - if default_project_view != 'readme' && @repository.readme + .container-fluid.container-limited + %ul.nav %li - = link_to 'Readme', readme_path(@project) - - - if @repository.changelog + = link_to project_files_path(@project) do + Files (#{repository_size}) %li - = link_to 'Changelog', changelog_path(@project) - - - if @repository.license_blob + = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do + #{'Commit'.pluralize(@project.commit_count)} (#{number_with_delimiter(@project.commit_count)}) %li - = link_to license_short_name(@project), license_path(@project) - - - if @repository.contribution_guide + = link_to namespace_project_branches_path(@project.namespace, @project) do + #{'Branch'.pluralize(@repository.branch_names.count)} (#{number_with_delimiter(@repository.branch_names.count)}) %li - = link_to 'Contribution guide', contribution_guide_path(@project) + = link_to namespace_project_tags_path(@project.namespace, @project) do + #{'Tag'.pluralize(@repository.tag_names.count)} (#{number_with_delimiter(@repository.tag_names.count)}) + + - if default_project_view != 'readme' && @repository.readme + %li + = link_to 'Readme', readme_path(@project) + + - if @repository.changelog + %li + = link_to 'Changelog', changelog_path(@project) + + - 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 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 + - 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 - if @repository.commit .content-block.second-block.white diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml index 4a515469422043..bf57beb9d07141 100644 --- a/app/views/projects/snippets/_actions.html.haml +++ b/app/views/projects/snippets/_actions.html.haml @@ -1,11 +1,27 @@ -= link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped new-snippet-link', title: "New Snippet" do - = icon('plus') - New Snippet -- if can?(current_user, :admin_project_snippet, @snippet) - = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-remove", title: 'Delete Snippet' do - = icon('trash-o') - Delete -- if can?(current_user, :update_project_snippet, @snippet) - = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped snippable-edit" do - = icon('pencil-square-o') - Edit +.hidden-xs + = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped btn-create new-snippet-link', title: "New Snippet" do + = icon('plus') + New Snippet + - if can?(current_user, :update_project_snippet, @snippet) + = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped snippable-edit" do + Edit + - if can?(current_user, :update_project_snippet, @snippet) + = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-warning", title: 'Delete Snippet' do + Delete +.visible-xs-block.dropdown + %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } } + Options + %span.caret + .dropdown-menu.dropdown-menu-full-width + %ul + %li + = link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do + New Snippet + - if can?(current_user, :update_project_snippet, @snippet) + %li + = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet) do + Edit + - if can?(current_user, :update_project_snippet, @snippet) + %li + = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, title: 'Delete Snippet' do + Delete diff --git a/app/views/projects/snippets/_header_title.html.haml b/app/views/projects/snippets/_header_title.html.haml deleted file mode 100644 index 04f0bbe9853e20..00000000000000 --- a/app/views/projects/snippets/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, "Snippets", namespace_project_snippets_path(@project.namespace, @project)) diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml index dc3ea1fcf12687..216f70f5605240 100644 --- a/app/views/projects/snippets/edit.html.haml +++ b/app/views/projects/snippets/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", @snippet.title, "Snippets" -= render "header_title" %h3.page-title Edit Snippet diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index 103ff447464e24..96fee3b17b215a 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -1,5 +1,4 @@ - page_title "Snippets" -= render "header_title" .row-content-block.top-block .pull-right diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml index e57237991b4458..772a594269ca8b 100644 --- a/app/views/projects/snippets/new.html.haml +++ b/app/views/projects/snippets/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Snippets" -= render "header_title" %h3.page-title New Snippet diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index 7c599563ce4513..bae4d8f349f2c6 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -1,18 +1,15 @@ - page_title @snippet.title, "Snippets" -= render "header_title" .snippet-holder = render 'shared/snippets/header' - %article.file-holder - .file-title + %article.file-holder.file-holder-no-border.snippet-file-content + .file-title.file-title-clear = blob_icon 0, @snippet.file_name - %strong - = @snippet.file_name + = @snippet.file_name .file-actions.hidden-xs = clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']") = link_to 'Raw', raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank" - = render 'shared/snippets/blob' %div#notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/tags/destroy.js.haml b/app/views/projects/tags/destroy.js.haml index ffeacb5a0043b8..e4a78fadbebb6b 100644 --- a/app/views/projects/tags/destroy.js.haml +++ b/app/views/projects/tags/destroy.js.haml @@ -1,3 +1,2 @@ -$('.js-totaltags-count').html("#{@repository.tags.size}"); - if @repository.tags.empty? $('.tags').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000) diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index dc6ece30dd292e..8f381663e6ef12 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -1,5 +1,4 @@ - page_title "Tags" -= render "projects/commits/header_title" = render "projects/commits/head" .row-content-block diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index b40a6e5cb2d3c1..3a097750d6eeba 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -1,5 +1,4 @@ - page_title "New Tag" -= render "projects/commits/header_title" - if @error .alert.alert-danger @@ -23,7 +22,7 @@ .form-group = label_tag :message, nil, class: 'control-label' .col-sm-10 - = text_field_tag :message, nil, required: false, tabindex: 3, class: 'form-control' + = text_area_tag :message, nil, required: false, tabindex: 3, class: 'form-control', rows: 5 .help-block Optionally, enter a message to create an annotated tag. %hr .form-group diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index 9c916fd02de7b5..b7d7d5c5382da2 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -1,5 +1,4 @@ - page_title @tag.name, "Tags" -= render "projects/commits/header_title" = render "projects/commits/head" .row-content-block @@ -19,15 +18,13 @@ %i.fa.fa-trash-o .title %span.item-title= @tag.name - - if @tag.message.present? - %span.light -   - = strip_gpg_signature(@tag.message) - if @commit = render 'projects/branches/commit', commit: @commit, project: @project - else Cant find HEAD commit for this tag - + - if @tag.message.present? + %pre.body + = strip_gpg_signature(@tag.message) .append-bottom-default.prepend-top-default - if @release.description.present? diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 91fb2a44594760..59f60c4687c958 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -1,9 +1,9 @@ - page_title @path.presence || "Files", @ref -- header_title project_title(@project, "Files", project_files_path(@project)) = content_for :meta_tags do - if current_user = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits") = render 'projects/last_push' += render "projects/commits/head" .tree-controls = render 'projects/find_file_link' diff --git a/app/views/projects/triggers/index.html.haml b/app/views/projects/triggers/index.html.haml index f91885b216dee7..7f3de47d7df431 100644 --- a/app/views/projects/triggers/index.html.haml +++ b/app/views/projects/triggers/index.html.haml @@ -5,7 +5,7 @@ %h4.prepend-top-0 = page_title %p - Triggers can be used to force a rebuild of a specific branch or tag with an API call. + Triggers can force a specific branch or tag to rebuild with an API call. .col-lg-9 %h5.prepend-top-0 Your triggers @@ -18,8 +18,8 @@ %th = render partial: 'trigger', collection: @triggers, as: :trigger - else - %p.profile-settings-message.text-center.append-bottom-default - There are no triggers to use, add one by the button below. + %p.settings-message.text-center.append-bottom-default + No triggers have been created yet. Add one using the button below. = form_for @trigger, url: url_for(controller: 'projects/triggers', action: 'create') do |f| = f.submit "Add Trigger", class: 'btn btn-success' @@ -28,8 +28,7 @@ Use CURL %p.light - Copy the token above and set your branch or tag name. This is the reference that will be rebuild. - + Copy the token above, set your branch or tag name, and that reference will be rebuilt. %pre :plain @@ -41,10 +40,10 @@ Use .gitlab-ci.yml %p.light - Copy the snippet to - %i .gitlab-ci.yml - of dependent project. - At the end of your build it will trigger this project to rebuilt. + In the + %code .gitlab-ci.yml + of the dependent project, include the following snippet. + The project will rebuild at the end of the build. %pre :plain @@ -57,9 +56,8 @@ %p.light Add - %strong variables[VARIABLE]=VALUE - to API request. - The value of variable could then be used to distinguish triggered build from normal one. + %code variables[VARIABLE]=VALUE + to an API request. Variable values can be used to distinguish between triggered builds and normal builds. %pre.append-bottom-0 :plain diff --git a/app/views/projects/variables/_content.html.haml b/app/views/projects/variables/_content.html.haml new file mode 100644 index 00000000000000..0249e0c1bf1fcd --- /dev/null +++ b/app/views/projects/variables/_content.html.haml @@ -0,0 +1,8 @@ +%h4.prepend-top-0 + Secret Variables +%p + These variables will be set to environment by the runner. +%p + So you can use them for passwords, secret keys or whatever you want. +%p + The value of the variable can be visible in build log if explicitly asked to do so. diff --git a/app/views/projects/variables/_form.html.haml b/app/views/projects/variables/_form.html.haml new file mode 100644 index 00000000000000..a5bae83e0cec2a --- /dev/null +++ b/app/views/projects/variables/_form.html.haml @@ -0,0 +1,10 @@ += form_for [@project.namespace.becomes(Namespace), @project, @variable] do |f| + = form_errors(@variable) + + .form-group + = f.label :key, "Key", class: "label-light" + = 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.submit btn_text, class: "btn btn-save" diff --git a/app/views/projects/variables/_table.html.haml b/app/views/projects/variables/_table.html.haml new file mode 100644 index 00000000000000..6c43f822db4957 --- /dev/null +++ b/app/views/projects/variables/_table.html.haml @@ -0,0 +1,25 @@ +.table-responsive.variables-table + %table.table + %colgroup + %col + %col + %col{ width: 100 } + %thead + %th Key + %th Value + %th + %tbody + - @project.variables.each do |variable| + - if variable.id? + %tr + %td= variable.key + %td= variable.value + %td + = link_to namespace_project_variable_path(@project.namespace, @project, variable), class: "btn btn-transparent btn-variable-edit" do + %span.sr-only + Update + = icon("pencil") + = link_to namespace_project_variable_path(@project.namespace, @project, variable), class: "btn btn-transparent btn-variable-delete", method: :delete, data: { confirm: "Are you sure?" } do + %span.sr-only + Remove + = icon("trash") diff --git a/app/views/projects/variables/index.html.haml b/app/views/projects/variables/index.html.haml new file mode 100644 index 00000000000000..09bb54600afff9 --- /dev/null +++ b/app/views/projects/variables/index.html.haml @@ -0,0 +1,17 @@ +- page_title "Variables" + +.row.prepend-top-default.append-bottom-default + .col-lg-3 + = render "content" + .col-lg-9 + %h5.prepend-top-0 + Add a variable + = render "form", btn_text: "Add new variable" + %hr + %h5.prepend-top-0 + Your variables (#{@project.variables.size}) + - if @project.variables.empty? + %p.settings-message.text-center.append-bottom-0 + No variables found, add one with the form above. + - else + = render "table" diff --git a/app/views/projects/variables/show.html.haml b/app/views/projects/variables/show.html.haml index ca284b84d39150..297a53ca98c679 100644 --- a/app/views/projects/variables/show.html.haml +++ b/app/views/projects/variables/show.html.haml @@ -1,36 +1,9 @@ - page_title "Variables" -%h3.page-title - Secret Variables -%p.light - These variables will be set to environment by the runner. - %br - So you can use them for passwords, secret keys or whatever you want. - %br - The value of the variable can be visible in build log if explicitly asked to do so. - -%hr - - -= nested_form_for @project, url: url_for(controller: 'projects/variables', action: 'update'), html: { class: 'form-horizontal' } do |f| - = form_errors(@project) - - = f.fields_for :variables do |variable_form| - .form-group - = variable_form.label :key, 'Key', class: 'control-label' - .col-sm-10 - = variable_form.text_field :key, class: 'form-control', placeholder: "PROJECT_VARIABLE" - - .form-group - = variable_form.label :value, 'Value', class: 'control-label' - .col-sm-10 - = variable_form.text_area :value, class: 'form-control', rows: 2, placeholder: "" - - = variable_form.link_to_remove "Remove this variable", class: 'btn btn-danger pull-right prepend-top-10' - %hr - %p - .clearfix - = f.link_to_add "Add a variable", :variables, class: 'btn btn-success pull-right' - - .form-actions - = f.submit 'Save changes', class: 'btn btn-save', return_to: request.original_url +.row.prepend-top-default.append-bottom-default + .col-lg-3 + = render "content" + .col-lg-9 + %h5.prepend-top-0 + Update variable + = render "form", btn_text: "Save variable" diff --git a/app/views/projects/wikis/_header_title.html.haml b/app/views/projects/wikis/_header_title.html.haml deleted file mode 100644 index 408adc36ca60bc..00000000000000 --- a/app/views/projects/wikis/_header_title.html.haml +++ /dev/null @@ -1 +0,0 @@ -- header_title project_title(@project, 'Wiki', get_project_wiki_path(@project)) diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 4dd818c7f6762d..aaa15dd3bbe1d3 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -1,5 +1,4 @@ - page_title "Edit", @page.title.capitalize, "Wiki" -= render "header_title" = render 'nav' .top-area diff --git a/app/views/projects/wikis/empty.html.haml b/app/views/projects/wikis/empty.html.haml index c7e490c3cd1120..7dfa405d0639c9 100644 --- a/app/views/projects/wikis/empty.html.haml +++ b/app/views/projects/wikis/empty.html.haml @@ -1,5 +1,4 @@ - page_title "Wiki" -= render "header_title" %h3.page-title Empty page %hr diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index ba3f2cadc4811c..ccceab6155e8aa 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -1,5 +1,4 @@ - page_title "Git Access", "Wiki" -= render "header_title" = render 'nav' .row-content-block diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml index dcaddae2b04124..45460ed9f41ad2 100644 --- a/app/views/projects/wikis/history.html.haml +++ b/app/views/projects/wikis/history.html.haml @@ -1,5 +1,4 @@ - page_title "History", @page.title.capitalize, "Wiki" -= render "header_title" = render 'nav' .top-area diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 92b494a513cad5..2f6162fa3c5f01 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -1,5 +1,4 @@ - page_title "Pages", "Wiki" -= render "header_title" = render 'nav' diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 067fb7f8f54782..1cb48a1e85d856 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -1,5 +1,4 @@ - page_title @page.title.capitalize, "Wiki" -= render "header_title" = render 'nav' .top-area diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml index 640890fbe928f1..8f68d6d1b87048 100644 --- a/app/views/search/results/_issue.html.haml +++ b/app/views/search/results/_issue.html.haml @@ -7,7 +7,7 @@ - if issue.description.present? .description.term = preserve do - = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project })) + = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project, author: issue.author })) %span.light #{issue.project.name_with_namespace} - if issue.closed? diff --git a/app/views/search/results/_merge_request.html.haml b/app/views/search/results/_merge_request.html.haml index 333f6533213f6b..6331c2bd6b044e 100644 --- a/app/views/search/results/_merge_request.html.haml +++ b/app/views/search/results/_merge_request.html.haml @@ -6,7 +6,7 @@ - if merge_request.description.present? .description.term = preserve do - = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project })) + = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project, author: merge_request.author })) %span.light #{merge_request.project.name_with_namespace} .pull-right diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml index d9400b1d9fa63e..8163aff43b6722 100644 --- a/app/views/search/results/_note.html.haml +++ b/app/views/search/results/_note.html.haml @@ -19,4 +19,4 @@ .note-search-result .term = preserve do - = search_md_sanitize(markdown(note.note, {no_header_anchors: true})) + = search_md_sanitize(markdown(note.note, {no_header_anchors: true, author: note.author})) diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index 974751d99705d4..84b3f44c0adfdd 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -5,7 +5,7 @@ %a#clone-dropdown.clone-dropdown-btn.btn{href: '#', 'data-toggle' => 'dropdown'} %span = default_clone_protocol.upcase - = icon('angle-down') + = icon('caret-down') %ul.dropdown-menu.dropdown-menu-right.clone-options-dropdown %li = ssh_clone_button(project) diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml index c38d9313dba6e1..30055002213065 100644 --- a/app/views/shared/_event_filter.html.haml +++ b/app/views/shared/_event_filter.html.haml @@ -1,5 +1,7 @@ -%ul.nav-links.event-filter +%ul.nav-links.event-filter.scrolling-tabs + .fade-left = event_filter_link EventFilter.push, 'Push events' = event_filter_link EventFilter.merged, 'Merge events' = event_filter_link EventFilter.comments, 'Comments' = event_filter_link EventFilter.team, 'Team' + .fade-right diff --git a/app/views/shared/_sort_dropdown.html.haml b/app/views/shared/_sort_dropdown.html.haml index d327bd0a96f8f7..1e0f075b303d75 100644 --- a/app/views/shared/_sort_dropdown.html.haml +++ b/app/views/shared/_sort_dropdown.html.haml @@ -6,7 +6,7 @@ - else = sort_title_recently_created %b.caret - %ul.dropdown-menu.dropdown-menu-align-right + %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort %li = link_to page_filter_path(sort: sort_value_recently_created) do = sort_title_recently_created diff --git a/app/views/shared/groups/_list.html.haml b/app/views/shared/groups/_list.html.haml index 1aa7ed1f2eb920..427595c47a584b 100644 --- a/app/views/shared/groups/_list.html.haml +++ b/app/views/shared/groups/_list.html.haml @@ -3,4 +3,4 @@ - groups.each_with_index do |group, i| = render "shared/groups/group", group: group - else - %h3 No groups found + .nothing-here-block No groups found diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index 9474462cbd1195..cedff4af2e0879 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -1,6 +1,8 @@ .issues-filters .issues-details-filters.row-content-block.second-block - = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name]), method: :get, class: 'filter-form' do + = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name, :issue_search]), method: :get, class: 'filter-form js-filter-form' do + - if params[:issue_search].present? + = hidden_field_tag :issue_search, params[:issue_search] - if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project) .check-all-holder = check_box_tag "check_all_issues", nil, false, @@ -10,7 +12,7 @@ - if params[:author_id].present? = hidden_field_tag(:author_id, params[:author_id]) = dropdown_tag(user_dropdown_label(params[:author_id], "Author"), options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit", - placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: "author_id", default_label: "Author" } }) + placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author], field_name: "author_id", default_label: "Author" } }) .filter-item.inline - if params[:assignee_id].present? diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 5c52cc6d1daed5..b430251dbf695e 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -44,45 +44,53 @@ This issue is confidential and should only be visible to team members - if can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project) + - has_due_date = issuable.has_attribute?(:due_date) %hr - .form-group - .issue-assignee - = f.label :assignee_id, "Assignee", class: 'control-label' - .col-sm-10 - .issuable-form-select-holder - = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]", - placeholder: 'Select assignee', class: 'custom-form-control', null_user: true, - selected: issuable.assignee_id, project: @target_project || @project, - first_user: true, current_user: true, include_blank: true) -   - = link_to 'Assign to me', '#', class: 'btn assign-to-me-link' - .form-group - .issue-milestone - = f.label :milestone_id, "Milestone", class: 'control-label' - .col-sm-10 - - if milestone_options(issuable).present? + .row + %div{ class: (has_due_date ? "col-lg-6" : "col-sm-12") } + .form-group.issue-assignee + = f.label :assignee_id, "Assignee", class: "control-label #{"col-lg-4" if has_due_date}" + .col-sm-10{ class: ("col-lg-8" if has_due_date) } .issuable-form-select-holder - = f.select(:milestone_id, milestone_options(issuable), - { include_blank: true }, { class: 'select2', data: { placeholder: 'Select milestone' } }) - - else - .prepend-top-10 - %span.light No open milestones available. -   - - if can? current_user, :admin_milestone, issuable.project - = link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank - .form-group - - has_labels = issuable.project.labels.any? - = f.label :label_ids, "Labels", class: 'control-label' - .col-sm-10{ class: ('issuable-form-padding-top' if !has_labels) } - - if has_labels - .issuable-form-select-holder - = f.collection_select :label_ids, issuable.project.labels.all, :id, :name, - { selected: issuable.label_ids }, multiple: true, class: 'select2', data: { placeholder: "Select labels" } - - else - %span.light No labels yet. -   - - if can? current_user, :admin_label, issuable.project - = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank + = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]", + placeholder: 'Select assignee', class: 'custom-form-control', null_user: true, + selected: issuable.assignee_id, project: @target_project || @project, + first_user: true, current_user: true, include_blank: true) + %div + = link_to 'Assign to me', '#', class: 'assign-to-me-link prepend-top-5 inline' + .form-group.issue-milestone + = f.label :milestone_id, "Milestone", class: "control-label #{"col-lg-4" if has_due_date}" + .col-sm-10{ class: ("col-lg-8" if has_due_date) } + - if milestone_options(issuable).present? + .issuable-form-select-holder + = f.select(:milestone_id, milestone_options(issuable), + { include_blank: true }, { class: 'select2', data: { placeholder: 'Select milestone' } }) + - else + .prepend-top-10 + %span.light No open milestones available. + - if can? current_user, :admin_milestone, issuable.project + %div + = link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank, class: "prepend-top-5 inline" + .form-group + - has_labels = issuable.project.labels.any? + = f.label :label_ids, "Labels", class: "control-label #{"col-lg-4" if has_due_date}" + .col-sm-10{ class: "#{"col-lg-8" if has_due_date} #{'issuable-form-padding-top' if !has_labels}" } + - if has_labels + .issuable-form-select-holder + = f.collection_select :label_ids, issuable.project.labels.all, :id, :name, + { selected: issuable.label_ids }, multiple: true, class: 'select2', data: { placeholder: "Select labels" } + - else + %span.light No labels yet. + - if can? current_user, :admin_label, issuable.project + %div + = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank, class: "prepend-top-5 inline" + - if has_due_date + .col-lg-6 + .form-group + = f.label :due_date, "Due date", class: "control-label" + = f.hidden_field :due_date, id: "issuable-due-date" + .col-sm-10 + .datepicker - if issuable.can_move?(current_user) %hr @@ -90,9 +98,7 @@ = label_tag :move_to_project_id, 'Move', class: 'control-label' .col-sm-10 .issuable-form-select-holder - - projects = project_options(issuable, current_user, ability: :admin_issue) - = select_tag(:move_to_project_id, projects, include_blank: true, - class: 'select2', data: { placeholder: 'Select project' }) + = hidden_field_tag :move_to_project_id, nil, class: 'js-move-dropdown', data: { placeholder: 'Select project', projects_url: autocomplete_projects_path(project_id: @project.id) }   %span{ data: { toggle: 'tooltip', placement: 'auto top' }, style: 'cursor: default', title: 'Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location.' } @@ -114,6 +120,13 @@ - if @merge_request.new_record?   = link_to 'Change branches', mr_change_branches_path(@merge_request) + - if @merge_request.can_remove_source_branch?(current_user) + .form-group + .col-sm-10.col-sm-offset-2 + .checkbox + = label_tag 'merge_request[force_remove_source_branch]' do + = check_box_tag 'merge_request[force_remove_source_branch]', '1', @merge_request.force_remove_source_branch? + Remove source branch when merge request is accepted. - is_footer = !(issuable.is_a?(MergeRequest) && issuable.new_record?) .row-content-block{class: (is_footer ? "footer-block" : "middle-block")} diff --git a/app/views/shared/issuable/_search_form.html.haml b/app/views/shared/issuable/_search_form.html.haml index afad48499b7d7d..186963b32b87c5 100644 --- a/app/views/shared/issuable/_search_form.html.haml +++ b/app/views/shared/issuable/_search_form.html.haml @@ -1,8 +1,2 @@ = form_tag(path, method: :get, id: "issue_search_form", class: 'issue-search-form') do = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by name ...', class: 'form-control issue_search search-text-input input-short', spellcheck: false } - = hidden_field_tag :state, params['state'] - = hidden_field_tag :scope, params['scope'] - = hidden_field_tag :assignee_id, params['assignee_id'] - = hidden_field_tag :author_id, params['author_id'] - = hidden_field_tag :milestone_id, params['milestone_id'] - = hidden_field_tag :label_id, params['label_id'] diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index ed1b8a8da2adb4..d6552ae7f189a3 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -87,10 +87,16 @@ - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) = link_to 'Edit', '#', class: 'edit-link pull-right' .value.bold.hide-collapsed - - if issuable.due_date - = issuable.due_date.to_s(:medium) - - else - .light None + %span.value-content + - if issuable.due_date + = issuable.due_date.to_s(:medium) + - else + None + - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) + %span.light.js-remove-due-date-holder{ class: ("hidden" if issuable.due_date.nil?) } + \- + %a.js-remove-due-date{ href: "#", role: "button" } + remove due date - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) .selectbox.hide-collapsed = f.hidden_field :due_date, value: issuable.due_date @@ -108,20 +114,20 @@ .sidebar-collapsed-icon = icon('tags') %span - = issuable.labels.count + = issuable.labels_array.size .title.hide-collapsed Labels = icon('spinner spin', class: 'block-loading') - if can_edit_issuable = link_to 'Edit', '#', class: 'edit-link pull-right' - .value.bold.issuable-show-labels.hide-collapsed{ class: ("has-labels" if issuable.labels.any?) } - - if issuable.labels.any? - - issuable.labels.each do |label| + .value.bold.issuable-show-labels.hide-collapsed{ class: ("has-labels" if issuable.labels_array.any?) } + - if issuable.labels_array.any? + - issuable.labels_array.each do |label| = link_to_label(label, type: issuable.to_ability_name) - else .light None .selectbox.hide-collapsed - - issuable.labels.each do |label| + - issuable.labels_array.each do |label| = hidden_field_tag "#{issuable.to_ability_name}[label_names][]", label.id, id: nil .dropdown %button.dropdown-menu-toggle.js-label-select.js-multiselect{type: "button", data: {toggle: "dropdown", field_name: "#{issuable.to_ability_name}[label_names][]", ability_name: issuable.to_ability_name, show_no: "true", show_any: "true", project_id: (@project.id if @project), issue_update: issuable_json_path(issuable), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project)}} diff --git a/app/views/shared/milestones/_participants_tab.html.haml b/app/views/shared/milestones/_participants_tab.html.haml index 67ae85ac276fd5..549d2e2f61e0e8 100644 --- a/app/views/shared/milestones/_participants_tab.html.haml +++ b/app/views/shared/milestones/_participants_tab.html.haml @@ -3,6 +3,6 @@ %li = link_to user, title: user.name, class: "darken" do = image_tag avatar_icon(user, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) + %strong= truncate(user.name, length: 40) %br %small.cgray= user.username diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index ab8b022411d09c..b8b66d08db8585 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -12,12 +12,9 @@ %li.project-row{ class: css_class } = cache(cache_key) do .controls - - if project.main_language - %span - = project.main_language - if project.commit.try(:status) %span - = render_ci_status(project.commit) + = render_commit_status(project.commit) - if forks %span = icon('code-fork') diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml index e65b181487238d..af753496260b1c 100644 --- a/app/views/shared/snippets/_header.html.haml +++ b/app/views/shared/snippets/_header.html.haml @@ -1,25 +1,24 @@ -.detail-page-header - .snippet-box.has-tooltip{class: visibility_level_color(@snippet.visibility_level), title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: 'body' }} +.detail-page-header.clearfix + .snippet-box.has-tooltip.inline.append-right-5{ title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: "body" } } + %span.sr-only + = visibility_level_label(@snippet.visibility_level) = visibility_level_icon(@snippet.visibility_level, fw: false) - = visibility_level_label(@snippet.visibility_level) - %span.identifier - Snippet ##{@snippet.id} + %strong.item-title + Snippet #{@snippet.to_reference} %span.creator - · created by #{link_to_member(@project, @snippet.author, size: 24)} - · + created by #{link_to_member(@project, @snippet.author, size: 24, author_class: "author item-title")} = time_ago_with_tooltip(@snippet.created_at, placement: 'bottom', html_class: 'snippet_updated_ago') - if @snippet.updated_at != @snippet.created_at %span - · = icon('edit', title: 'edited') = time_ago_with_tooltip(@snippet.updated_at, placement: 'bottom', html_class: 'snippet_edited_ago') - .pull-right + .snippet-actions - if @snippet.project_id? = render "projects/snippets/actions" - else = render "snippets/actions" -.detail-page-description.row-content-block.second-block - %h2.title - = markdown escape_once(@snippet.title), pipeline: :single_line +.content-block.second-block + %h2.snippet-title.prepend-top-0.append-bottom-0 + = markdown escape_once(@snippet.title), pipeline: :single_line, author: @snippet.author diff --git a/app/views/snippets/_actions.html.haml b/app/views/snippets/_actions.html.haml index 1979ae6d5bc473..a7769654b61c28 100644 --- a/app/views/snippets/_actions.html.haml +++ b/app/views/snippets/_actions.html.haml @@ -1,11 +1,27 @@ -= link_to new_snippet_path, class: 'btn btn-grouped new-snippet-link', title: "New Snippet" do - = icon('plus') - New Snippet -- if can?(current_user, :update_personal_snippet, @snippet) - = link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do - = icon('pencil-square-o') - Edit -- if can?(current_user, :admin_personal_snippet, @snippet) - = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-remove", title: 'Delete Snippet' do - = icon('trash-o') - Delete +.hidden-xs + = link_to new_snippet_path, class: "btn btn-grouped btn-create new-snippet-link", title: "New Snippet" do + = icon('plus') + New Snippet + - if can?(current_user, :update_personal_snippet, @snippet) + = link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do + Edit + - if can?(current_user, :admin_personal_snippet, @snippet) + = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-warning", title: 'Delete Snippet' do + Delete +.visible-xs-block.dropdown + %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } } + Options + %span.caret + .dropdown-menu.dropdown-menu-full-width + %ul + %li + = link_to new_snippet_path, title: "New Snippet" do + New Snippet + - if can?(current_user, :update_personal_snippet, @snippet) + %li + = link_to edit_snippet_path(@snippet) do + Edit + - if can?(current_user, :admin_personal_snippet, @snippet) + %li + = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, title: 'Delete Snippet' do + Delete diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index a2b365687700d5..ed3992650d4a0c 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -3,11 +3,10 @@ .snippet-holder = render 'shared/snippets/header' - %article.file-holder - .file-title + %article.file-holder.file-holder-no-border.snippet-file-content + .file-title.file-title-clear = blob_icon 0, @snippet.file_name - %strong - = @snippet.file_name + = @snippet.file_name .file-actions.hidden-xs = clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']") = link_to 'Raw', raw_snippet_path(@snippet), class: "btn btn-sm", target: "_blank" diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml index 1de71f37d1a9dd..77f2ddefb1e28b 100644 --- a/app/views/users/calendar.html.haml +++ b/app/views/users/calendar.html.haml @@ -1,10 +1,9 @@ -#cal-heatmap.calendar - :javascript - new Calendar( - #{@timestamps.to_json}, - #{@starting_year}, - #{@starting_month}, - '#{user_calendar_activities_path}' - ); - -.calendar-hint Summary of issues, merge requests, and push events +.clearfix.calendar + .js-contrib-calendar + .calendar-hint + Summary of issues, merge requests, and push events +:javascript + new Calendar( + #{@timestamps.to_json}, + '#{user_calendar_activities_path}' + ); diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml index 027a93a75fcd9b..630d97e339db65 100644 --- a/app/views/users/calendar_activities.html.haml +++ b/app/views/users/calendar_activities.html.haml @@ -1,23 +1,27 @@ %h4.prepend-top-20 - %span.light Contributions for + Contributions for %strong #{@calendar_date.to_s(:short)} -%ul.bordered-list - - @events.sort_by(&:created_at).each do |event| - %li - %span.light - %i.fa.fa-clock-o - = event.created_at.to_s(:time) - - if event.push? - #{event.action_name} #{event.ref_type} #{event.ref_name} - - else - = event_action_name(event) - - if event.target - %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] - - at - %strong - - if event.project - = link_to_project event.project +- if @events.any? + %ul.bordered-list + - @events.sort_by(&:created_at).each do |event| + %li + %span.light + %i.fa.fa-clock-o + = event.created_at.to_s(:time) + - if event.push? + #{event.action_name} #{event.ref_type} #{event.ref_name} - else - = event.project_name + = event_action_name(event) + - if event.target + %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] + + at + %strong + - if event.project + = link_to_project event.project + - else + = event.project_name +- else + %p + No contributions found for #{@calendar_date.to_s(:short)} diff --git a/app/views/users/show.atom.builder b/app/views/users/show.atom.builder index e9e466c6350361..6c85e5f9fbd531 100644 --- a/app/views/users/show.atom.builder +++ b/app/views/users/show.atom.builder @@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear xml.id user_url(@user) xml.updated @events[0].updated_at.xmlschema if @events[0] - @events.each do |event| - event_to_atom(xml, event) - end + xml << render(@events) if @events.any? end diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 3c0b89c67416a4..8268380dafc4ec 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -1,5 +1,6 @@ - page_title @user.name - page_description @user.bio +- page_specific_javascripts asset_path("users/application.js") - header_title @user.name, user_path(@user) - @no_container = true @@ -81,15 +82,17 @@ %li.projects-tab = link_to user_projects_path, data: {target: 'div#projects', action: 'projects', toggle: 'tab'} do Personal projects + %li.snippets-tab + = link_to user_snippets_path, data: {target: 'div#snippets', action: 'snippets', toggle: 'tab'} do + Snippets %div{ class: container_class } .tab-content #activity.tab-pane .row-content-block.calender-block.white.second-block.hidden-xs - %div{ class: container_class } - .user-calendar{data: {href: user_calendar_path}} - %h4.center.light - %i.fa.fa-spinner.fa-spin + .user-calendar{data: {href: user_calendar_path}} + %h4.center.light + %i.fa.fa-spinner.fa-spin .user-calendar-activities .content_list{ data: {href: user_path} } @@ -104,6 +107,9 @@ #projects.tab-pane - # This tab is always loaded via AJAX + #snippets.tab-pane + - # This tab is always loaded via AJAX + .loading-status = spinner diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index c4d8595d45dc9f..971f969e25e594 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -1,6 +1,9 @@ class EmailsOnPushWorker include Sidekiq::Worker + sidekiq_options queue: :mailers + attr_reader :email, :skip_premailer + def perform(project_id, recipients, push_data, options = {}) options.symbolize_keys! options.reverse_merge!( @@ -25,15 +28,18 @@ def perform(project_id, recipients, push_data, options = {}) :push end + diff_refs = nil compare = nil reverse_compare = false if action == :push compare = Gitlab::Git::Compare.new(project.repository.raw_repository, before_sha, after_sha) + diff_refs = [project.merge_base_commit(before_sha, after_sha), project.commit(after_sha)] return false if compare.same if compare.commits.empty? compare = Gitlab::Git::Compare.new(project.repository.raw_repository, after_sha, before_sha) + diff_refs = [project.merge_base_commit(after_sha, before_sha), project.commit(before_sha)] reverse_compare = true @@ -41,26 +47,42 @@ def perform(project_id, recipients, push_data, options = {}) end end - recipients.split(" ").each do |recipient| + recipients.split.each do |recipient| begin - Notify.repository_push_email( - project_id, + send_email( recipient, - author_id: author_id, - ref: ref, - action: action, - compare: compare, - reverse_compare: reverse_compare, - send_from_committer_email: send_from_committer_email, - disable_diffs: disable_diffs - ).deliver_now + project_id, + author_id: author_id, + ref: ref, + action: action, + compare: compare, + reverse_compare: reverse_compare, + diff_refs: diff_refs, + send_from_committer_email: send_from_committer_email, + disable_diffs: disable_diffs + ) + # These are input errors and won't be corrected even if Sidekiq retries rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e logger.info("Failed to send e-mail for project '#{project.name_with_namespace}' to #{recipient}: #{e}") end end ensure + @email = nil compare = nil GC.start end + + private + + def send_email(recipient, project_id, options) + # Generating the body of this email can be expensive, so only do it once + @skip_premailer ||= email.present? + @email ||= Notify.repository_push_email(project_id, options) + + email.to = recipient + email.add_message_id + email.header[:skip_premailer] = true if skip_premailer + email.deliver_now + end end diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb index f9e32337983943..d947f1055160b7 100644 --- a/app/workers/repository_fork_worker.rb +++ b/app/workers/repository_fork_worker.rb @@ -15,8 +15,7 @@ def perform(project_id, source_path, target_path) result = gitlab_shell.fork_repository(source_path, target_path) unless result logger.error("Unable to fork project #{project_id} for repository #{source_path} -> #{target_path}") - project.update(import_error: "The project could not be forked.") - project.import_fail + project.mark_import_as_failed('The project could not be forked.') return end @@ -24,8 +23,7 @@ def perform(project_id, source_path, target_path) unless project.valid_repo? logger.error("Project #{project_id} had an invalid repository after fork") - project.update(import_error: "The forked repository is invalid.") - project.import_fail + project.mark_import_as_failed('The forked repository is invalid.') return end diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 2937493c614ac5..7d819fe78f83fc 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -13,8 +13,7 @@ def perform(project_id) result = Projects::ImportService.new(project, current_user).execute if result[:status] == :error - project.update(import_error: result[:message]) - project.import_fail + project.mark_import_as_failed(result[:message]) return end diff --git a/config/application.rb b/config/application.rb index b602e2b61689c0..49d4d3ba555264 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,23 +1,32 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' -require 'devise' -I18n.config.enforce_available_locales = false + Bundler.require(:default, Rails.env) -require_relative '../lib/gitlab/redis' module Gitlab class Application < Rails::Application + require_dependency Rails.root.join('lib/gitlab/redis') + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. - # Custom directories with classes and modules you want to be autoloadable. - config.autoload_paths.push(*%W(#{config.root}/lib - #{config.root}/app/models/hooks - #{config.root}/app/models/concerns - #{config.root}/app/models/project_services - #{config.root}/app/models/members)) + # Sidekiq uses eager loading, but directories not in the standard Rails + # directories must be added to the eager load paths: + # https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code + # Also, there is no need to add `lib` to autoload_paths since autoloading is + # configured to check for eager loaded paths: + # https://github.com/rails/rails/blob/v4.2.6/railties/lib/rails/engine.rb#L687 + # This is a nice reference article on autoloading/eager loading: + # http://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload + config.eager_load_paths.push(*%W(#{config.root}/lib + #{config.root}/app/models/ci + #{config.root}/app/models/hooks + #{config.root}/app/models/members + #{config.root}/app/models/project_services)) + + config.generators.templates.push("#{config.root}/generator_templates") # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. @@ -32,7 +41,7 @@ class Application < Rails::Application config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. - # + # # Parameters filtered: # - Password (:password, :password_confirmation) # - Private tokens (:private_token) @@ -71,6 +80,9 @@ class Application < Rails::Application config.assets.precompile << "*.png" config.assets.precompile << "print.css" config.assets.precompile << "notify.css" + config.assets.precompile << "mailers/*.css" + config.assets.precompile << "graphs/application.js" + config.assets.precompile << "users/application.js" # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' diff --git a/config/boot.rb b/config/boot.rb index 4489e58688ca64..f2830ae3166dc7 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -3,4 +3,4 @@ # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) -require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/config/environments/development.rb b/config/environments/development.rb index 4f39016bfa4354..8cca0039b4af0d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -39,6 +39,7 @@ config.action_mailer.delivery_method = :letter_opener_web # Don't make a mess when bootstrapping a development environment config.action_mailer.perform_deliveries = (ENV['BOOTSTRAP'] != '1') + config.action_mailer.preview_path = 'spec/mailers/previews' config.eager_load = false end diff --git a/config/environments/test.rb b/config/environments/test.rb index a703c0934f7ffe..fb25d3a8b14c8f 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -20,7 +20,7 @@ config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment - config.action_controller.allow_forgery_protection = false + config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index e682bcb976d198..0510e7df597091 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -98,6 +98,7 @@ production: &base wiki: true snippets: false builds: true + container_registry: true ## Webhook settings # Number of seconds to wait for HTTP response after sending webhook HTTP POST request (default: 10) @@ -175,6 +176,15 @@ production: &base repository_archive_cache_worker: cron: "0 * * * *" + registry: + # enabled: true + # host: registry.example.com + # port: 5005 + # api_url: http://localhost:5000/ # internal address to the registry, will be used by GitLab to directly communicate with API + # key_path: config/registry.key + # path: shared/registry + # issuer: gitlab-issuer + # # 2. GitLab CI settings # ========================== diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 8db2c05fe45859..436751b9d168f8 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -1,4 +1,4 @@ -require 'gitlab' # Load lib/gitlab.rb as soon as possible +require_dependency Rails.root.join('lib/gitlab') # Load Gitlab as soon as possible class Settings < Settingslogic source ENV.fetch('GITLAB_CONFIG') { "#{Rails.root}/config/gitlab.yml" } @@ -52,7 +52,7 @@ def build_gitlab_url # check that values in `current` (string or integer) is a contant in `modul`. def verify_constant_array(modul, current, default) values = default || [] - if !current.nil? + unless current.nil? values = [] current.each do |constant| values.push(verify_constant(modul, constant, nil)) @@ -126,7 +126,7 @@ def host(url) Settings['omniauth'] ||= Settingslogic.new({}) -Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil? +Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil? Settings.omniauth['auto_sign_in_with_provider'] = false if Settings.omniauth['auto_sign_in_with_provider'].nil? Settings.omniauth['allow_single_sign_on'] = false if Settings.omniauth['allow_single_sign_on'].nil? Settings.omniauth['external_providers'] = [] if Settings.omniauth['external_providers'].nil? @@ -134,7 +134,7 @@ def host(url) Settings.omniauth['auto_link_ldap_user'] = false if Settings.omniauth['auto_link_ldap_user'].nil? Settings.omniauth['auto_link_saml_user'] = false if Settings.omniauth['auto_link_saml_user'].nil? -Settings.omniauth['providers'] ||= [] +Settings.omniauth['providers'] ||= [] Settings.omniauth['cas3'] ||= Settingslogic.new({}) Settings.omniauth.cas3['session_duration'] ||= 8.hours Settings.omniauth['session_tickets'] ||= Settingslogic.new({}) @@ -168,7 +168,7 @@ def host(url) Settings['shared'] ||= Settingslogic.new({}) Settings.shared['path'] = File.expand_path(Settings.shared['path'] || "shared", Rails.root) -Settings['issues_tracker'] ||= {} +Settings['issues_tracker'] ||= {} # # GitLab @@ -183,7 +183,7 @@ def host(url) Settings.gitlab['https'] = false if Settings.gitlab['https'].nil? Settings.gitlab['port'] ||= Settings.gitlab.https ? 443 : 80 Settings.gitlab['relative_url_root'] ||= ENV['RAILS_RELATIVE_URL_ROOT'] || '' -Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http" +Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http" Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].nil? Settings.gitlab['email_from'] ||= ENV['GITLAB_EMAIL_FROM'] || "gitlab@#{Settings.gitlab.host}" Settings.gitlab['email_display_name'] ||= ENV['GITLAB_EMAIL_DISPLAY_NAME'] || 'GitLab' @@ -196,7 +196,7 @@ def host(url) rescue ArgumentError # no user configured '/home/' + Settings.gitlab['user'] end -Settings.gitlab['time_zone'] ||= nil +Settings.gitlab['time_zone'] ||= nil Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil? Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) @@ -206,12 +206,13 @@ def host(url) Settings.gitlab['webhook_timeout'] ||= 10 Settings.gitlab['max_attachment_size'] ||= 10 Settings.gitlab['session_expire_delay'] ||= 10080 -Settings.gitlab.default_projects_features['issues'] = true if Settings.gitlab.default_projects_features['issues'].nil? -Settings.gitlab.default_projects_features['merge_requests'] = true if Settings.gitlab.default_projects_features['merge_requests'].nil? -Settings.gitlab.default_projects_features['wiki'] = true if Settings.gitlab.default_projects_features['wiki'].nil? -Settings.gitlab.default_projects_features['snippets'] = false if Settings.gitlab.default_projects_features['snippets'].nil? -Settings.gitlab.default_projects_features['builds'] = true if Settings.gitlab.default_projects_features['builds'].nil? -Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) +Settings.gitlab.default_projects_features['issues'] = true if Settings.gitlab.default_projects_features['issues'].nil? +Settings.gitlab.default_projects_features['merge_requests'] = true if Settings.gitlab.default_projects_features['merge_requests'].nil? +Settings.gitlab.default_projects_features['wiki'] = true if Settings.gitlab.default_projects_features['wiki'].nil? +Settings.gitlab.default_projects_features['snippets'] = false if Settings.gitlab.default_projects_features['snippets'].nil? +Settings.gitlab.default_projects_features['builds'] = true if Settings.gitlab.default_projects_features['builds'].nil? +Settings.gitlab.default_projects_features['container_registry'] = true if Settings.gitlab.default_projects_features['container_registry'].nil? +Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) Settings.gitlab['repository_downloads_path'] = File.join(Settings.shared['path'], 'cache/archive') if Settings.gitlab['repository_downloads_path'].nil? Settings.gitlab['restricted_signup_domains'] ||= [] Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'] @@ -225,8 +226,8 @@ def host(url) Settings.gitlab_ci['shared_runners_enabled'] = true if Settings.gitlab_ci['shared_runners_enabled'].nil? Settings.gitlab_ci['all_broken_builds'] = true if Settings.gitlab_ci['all_broken_builds'].nil? Settings.gitlab_ci['add_pusher'] = false if Settings.gitlab_ci['add_pusher'].nil? -Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url) Settings.gitlab_ci['builds_path'] = File.expand_path(Settings.gitlab_ci['builds_path'] || "builds/", Rails.root) +Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url) # # Reply by email @@ -240,7 +241,20 @@ def host(url) Settings['artifacts'] ||= Settingslogic.new({}) Settings.artifacts['enabled'] = true if Settings.artifacts['enabled'].nil? Settings.artifacts['path'] = File.expand_path(Settings.artifacts['path'] || File.join(Settings.shared['path'], "artifacts"), Rails.root) -Settings.artifacts['max_size'] ||= 100 # in megabytes +Settings.artifacts['max_size'] ||= 100 # in megabytes + +# +# Registry +# +Settings['registry'] ||= Settingslogic.new({}) +Settings.registry['enabled'] ||= false +Settings.registry['host'] ||= "example.com" +Settings.registry['port'] ||= nil +Settings.registry['api_url'] ||= "http://localhost:5000/" +Settings.registry['key'] ||= nil +Settings.registry['issuer'] ||= nil +Settings.registry['host_port'] ||= [Settings.registry['host'], Settings.registry['port']].compact.join(':') +Settings.registry['path'] = File.expand_path(Settings.registry['path'] || File.join(Settings.shared['path'], 'registry'), Rails.root) # # Git LFS @@ -298,7 +312,7 @@ def host(url) Settings.backup['keep_time'] ||= 0 Settings.backup['pg_schema'] = nil Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root) -Settings.backup['archive_permissions'] ||= 0600 +Settings.backup['archive_permissions'] ||= 0600 Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil }) # Convert upload connection settings to use symbol keys, to make Fog happy if Settings.backup['upload']['connection'] diff --git a/config/initializers/5_backend.rb b/config/initializers/5_backend.rb index 80d641d73a37ae..e026151a03270c 100644 --- a/config/initializers/5_backend.rb +++ b/config/initializers/5_backend.rb @@ -1,11 +1,11 @@ # GIT over HTTP -require Rails.root.join("lib", "gitlab", "backend", "grack_auth") +require_dependency Rails.root.join('lib/gitlab/backend/grack_auth') # GIT over SSH -require Rails.root.join("lib", "gitlab", "backend", "shell") +require_dependency Rails.root.join('lib/gitlab/backend/shell') # GitLab shell adapter -require Rails.root.join("lib", "gitlab", "backend", "shell_adapter") +require_dependency Rails.root.join('lib/gitlab/backend/shell_adapter') required_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version_required) current_version = Gitlab::VersionInfo.parse(Gitlab::Shell.new.version) diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index df28d30d750946..1933afcbfb1e20 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -2,7 +2,7 @@ aws_file = Rails.root.join('config', 'aws.yml') -if File.exists?(aws_file) +if File.exist?(aws_file) AWS_CONFIG = YAML.load(File.read(aws_file))[Rails.env] CarrierWave.configure do |config| @@ -20,7 +20,7 @@ config.fog_public = false # optional, defaults to {} - config.fog_attributes = { 'Cache-Control'=>'max-age=315576000' } + config.fog_attributes = { 'Cache-Control' => 'max-age=315576000' } # optional time (in seconds) that authenticated urls will be valid. # when fog_public is false and provider is AWS or Google, defaults to 600 diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 31dceaebcadb5b..021bdb11251103 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -243,7 +243,7 @@ when Hash # Add procs for handling SLO if provider['name'] == 'cas3' - provider['args'][:on_single_sign_out] = lambda do |request| + provider['args'][:on_single_sign_out] = lambda do |request| ticket = request.params[:session_index] raise "Service Ticket not found." unless Gitlab::OAuth::Session.valid?(:cas3, ticket) Gitlab::OAuth::Session.destroy(:cas3, ticket) diff --git a/config/initializers/devise_async.rb b/config/initializers/devise_async.rb deleted file mode 100644 index 05a1852cdbd9d1..00000000000000 --- a/config/initializers/devise_async.rb +++ /dev/null @@ -1 +0,0 @@ -Devise::Async.backend = :sidekiq diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 66ac88e9f4af7d..7bd13105045d2f 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -52,7 +52,7 @@ # For more information go to # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes default_scopes :api - #optional_scopes :write, :update + # optional_scopes :write, :update # Change the way client credentials are retrieved from the request object. # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then @@ -71,7 +71,7 @@ # The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL # (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi) # - native_redirect_uri nil#'urn:ietf:wg:oauth:2.0:oob' + native_redirect_uri nil # 'urn:ietf:wg:oauth:2.0:oob' # Specify what grant flows are enabled in array of Strings. The valid # strings and the flows they enable are: diff --git a/config/initializers/health_check.rb b/config/initializers/health_check.rb new file mode 100644 index 00000000000000..79e2d23ab2eb9f --- /dev/null +++ b/config/initializers/health_check.rb @@ -0,0 +1,3 @@ +HealthCheck.setup do |config| + config.standard_checks = ['database', 'migrations', 'cache'] +end diff --git a/config/initializers/metrics.rb b/config/initializers/metrics.rb index b2d08d87bacb6c..0c7887147144fb 100644 --- a/config/initializers/metrics.rb +++ b/config/initializers/metrics.rb @@ -12,6 +12,7 @@ Gitlab::Application.configure do |config| config.middleware.use(Gitlab::Metrics::RackMiddleware) + config.middleware.use(Gitlab::Middleware::RailsQueueDuration) end Sidekiq.configure_server do |config| @@ -118,6 +119,8 @@ # Instrument the classes used for checking if somebody has push access. config.instrument_instance_methods(Gitlab::GitAccess) config.instrument_instance_methods(Gitlab::GitAccessWiki) + + config.instrument_instance_methods(API::Helpers) end GC::Profiler.enable diff --git a/config/initializers/monkey_patch.rb b/config/initializers/monkey_patch.rb deleted file mode 100644 index 62b05a55285486..00000000000000 --- a/config/initializers/monkey_patch.rb +++ /dev/null @@ -1,48 +0,0 @@ -## This patch is from rails 4.2-stable. Remove it when 4.2.6 is released -## https://github.com/rails/rails/issues/21108 - -module ActiveRecord - module ConnectionAdapters - class AbstractMysqlAdapter < AbstractAdapter - # SHOW VARIABLES LIKE 'name' - def show_variable(name) - variables = select_all("select @@#{name} as 'Value'", 'SCHEMA') - variables.first['Value'] unless variables.empty? - rescue ActiveRecord::StatementInvalid - nil - end - - - # MySQL is too stupid to create a temporary table for use subquery, so we have - # to give it some prompting in the form of a subsubquery. Ugh! - def subquery_for(key, select) - subsubselect = select.clone - subsubselect.projections = [key] - - subselect = Arel::SelectManager.new(select.engine) - subselect.project Arel.sql(key.name) - # Materialized subquery by adding distinct - # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on' - subselect.from subsubselect.distinct.as('__active_record_temp') - end - end - end -end - -module ActiveRecord - module ConnectionAdapters - class MysqlAdapter < AbstractMysqlAdapter - ADAPTER_NAME = 'MySQL'.freeze - - # Get the client encoding for this database - def client_encoding - return @client_encoding if @client_encoding - - result = exec_query( - "select @@character_set_client", - 'SCHEMA') - @client_encoding = ENCODINGS[result.rows.last.last] - end - end - end -end diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index 4c164119fff1db..26c30e523a765b 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -13,7 +13,7 @@ module OmniAuth::Strategies OmniAuth.config.full_host = Settings.gitlab['base_url'] OmniAuth.config.allowed_request_methods = [:post] -#In case of auto sign-in, the GET method is used (users don't get to click on a button) +# In case of auto sign-in, the GET method is used (users don't get to click on a button) OmniAuth.config.allowed_request_methods << :get if Gitlab.config.omniauth.auto_sign_in_with_provider.present? OmniAuth.config.before_request_phase do |env| OmniAuth::RequestForgeryProtection.call(env) diff --git a/config/initializers/premailer.rb b/config/initializers/premailer.rb index b9176688bc49e1..cb00d3cfe95be3 100644 --- a/config/initializers/premailer.rb +++ b/config/initializers/premailer.rb @@ -3,6 +3,6 @@ generate_text_part: false, preserve_styles: true, remove_comments: true, - remove_ids: true, + remove_ids: false, remove_scripts: false ) diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 599dabb9e50343..0d9d87bac00a31 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -23,6 +23,6 @@ secure: Gitlab.config.gitlab.https, httponly: true, expires_in: Settings.gitlab['session_expire_delay'] * 60, - path: (Rails.application.config.relative_url_root.nil?) ? '/' : Gitlab::Application.config.relative_url_root + path: Rails.application.config.relative_url_root.nil? ? '/' : Gitlab::Application.config.relative_url_root ) end diff --git a/config/routes.rb b/config/routes.rb index dafecc9464894f..428302d0fd7572 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -56,6 +56,7 @@ # Autocomplete get '/autocomplete/users' => 'autocomplete#users' get '/autocomplete/users/:id' => 'autocomplete#user' + get '/autocomplete/projects' => 'autocomplete#projects' # Emojis resources :emojis, only: :index @@ -64,6 +65,9 @@ get 'search' => 'search#show' get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete + # JSON Web Token + get 'jwt/auth' => 'jwt#auth' + # API API::API.logger Rails.logger mount API::API => '/api' @@ -73,6 +77,9 @@ mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq end + # Health check + get 'health_check(/:checks)' => 'health_check#index', as: :health_check + # Enable Grack support mount Grack::AuthSpawner, at: '/', constraints: lambda { |request| /[-\/\w\.]+\.git\//.match(request.path_info) }, via: [:get, :post, :put] @@ -80,7 +87,7 @@ get 'help' => 'help#index' get 'help/:category/:file' => 'help#show', as: :help_page, constraints: { category: /.*/, file: /[^\/\.]+/ } get 'help/shortcuts' - get 'help/ui' => 'help#ui' + get 'help/ui' => 'help#ui' # # Global snippets @@ -91,7 +98,8 @@ end end - get '/s/:username' => 'snippets#index', as: :user_snippets, constraints: { username: /.*/ } + get '/s/:username', to: redirect('/u/%{username}/snippets'), + constraints: { username: /[a-zA-Z.0-9_\-]+(? 'users#calendar', as: :user_calendar, - constraints: { username: /.*/ } - - get 'u/:username/calendar_activities' => 'users#calendar_activities', as: :user_calendar_activities, - constraints: { username: /.*/ } - - get 'u/:username/groups' => 'users#groups', as: :user_groups, - constraints: { username: /.*/ } - - get 'u/:username/projects' => 'users#projects', as: :user_projects, - constraints: { username: /.*/ } - - get 'u/:username/contributed' => 'users#contributed', as: :user_contributed_projects, - constraints: { username: /.*/ } - - get '/u/:username' => 'users#show', as: :user, - constraints: { username: /[a-zA-Z.0-9_\-]+(? 'omniauth_callbacks#omniauth_error', as: :omniauth_error @@ -659,9 +668,16 @@ end resources :protected_branches, only: [:index, :create, :update, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } - resource :variables, only: [:show, :update] + resources :variables, only: [:index, :show, :update, :create, :destroy] resources :triggers, only: [:index, :create, :destroy] + resources :pipelines, only: [:index, :new, :create, :show] do + member do + post :cancel + post :retry + end + end + resources :builds, only: [:index, :show], constraints: { id: /\d+/ } do collection do post :cancel_all @@ -672,6 +688,7 @@ post :cancel post :retry post :erase + get :trace get :raw end @@ -688,6 +705,8 @@ end end + resources :container_registry, only: [:index, :destroy], constraints: { id: Gitlab::Regex.container_registry_reference_regex } + resources :milestones, constraints: { id: /\d+/ } do member do put :sort_issues @@ -774,7 +793,7 @@ end # Get all keys of user - get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ } + get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: /.*/ } get ':id' => 'namespaces#show', constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } end diff --git a/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb b/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb index 8a351cf27a3991..6aed0fe03d2872 100644 --- a/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb +++ b/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb @@ -24,11 +24,11 @@ def up def process_projects_with_wrong_url projects_with_wrong_import_url.each do |project| begin - import_url = Gitlab::ImportUrl.new(project["import_url"]) + import_url = Gitlab::UrlSanitizer.new(project["import_url"]) update_import_url(import_url, project) update_import_data(import_url, project) - rescue URI::InvalidURIError + rescue Addressable::URI::InvalidURIError nullify_import_url(project) end end diff --git a/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb b/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb index 75de5f70fa299e..72b862d67d2fda 100644 --- a/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb +++ b/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb @@ -7,7 +7,9 @@ def up add_column :application_settings, :default_group_visibility, :integer # Unfortunately, this can't be a `default`, since we don't want the configuration specific # `allowed_visibility_level` to end up in schema.rb - execute("UPDATE application_settings SET default_group_visibility = #{allowed_visibility_level}") + + visibility_level = allowed_visibility_level || Gitlab::VisibilityLevel::PRIVATE + execute("UPDATE application_settings SET default_group_visibility = #{visibility_level}") end def down diff --git a/db/migrate/20160407120251_add_images_enabled_for_project.rb b/db/migrate/20160407120251_add_images_enabled_for_project.rb new file mode 100644 index 00000000000000..47f0ca8e8debdc --- /dev/null +++ b/db/migrate/20160407120251_add_images_enabled_for_project.rb @@ -0,0 +1,5 @@ +class AddImagesEnabledForProject < ActiveRecord::Migration + def change + add_column :projects, :container_registry_enabled, :boolean + end +end diff --git a/db/migrate/20160504091942_add_disabled_oauth_sign_in_sources_to_application_settings.rb b/db/migrate/20160504091942_add_disabled_oauth_sign_in_sources_to_application_settings.rb new file mode 100644 index 00000000000000..facd33875ba1ef --- /dev/null +++ b/db/migrate/20160504091942_add_disabled_oauth_sign_in_sources_to_application_settings.rb @@ -0,0 +1,5 @@ +class AddDisabledOauthSignInSourcesToApplicationSettings < ActiveRecord::Migration + def change + add_column :application_settings, :disabled_oauth_sign_in_sources, :text + end +end diff --git a/db/migrate/20160504112519_add_run_untagged_to_ci_runner.rb b/db/migrate/20160504112519_add_run_untagged_to_ci_runner.rb new file mode 100644 index 00000000000000..84e5e4eabe2765 --- /dev/null +++ b/db/migrate/20160504112519_add_run_untagged_to_ci_runner.rb @@ -0,0 +1,13 @@ +class AddRunUntaggedToCiRunner < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + disable_ddl_transaction! + + def up + add_column_with_default(:ci_runners, :run_untagged, :boolean, + default: true, allow_null: false) + end + + def down + remove_column(:ci_runners, :run_untagged) + end +end diff --git a/db/migrate/20160508215820_add_type_to_notes.rb b/db/migrate/20160508215820_add_type_to_notes.rb new file mode 100644 index 00000000000000..58944d4e651c4e --- /dev/null +++ b/db/migrate/20160508215820_add_type_to_notes.rb @@ -0,0 +1,5 @@ +class AddTypeToNotes < ActiveRecord::Migration + def change + add_column :notes, :type, :string + end +end diff --git a/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb b/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb new file mode 100644 index 00000000000000..c3f23d89d5a127 --- /dev/null +++ b/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb @@ -0,0 +1,5 @@ +class SetTypeOnLegacyDiffNotes < ActiveRecord::Migration + def change + execute "UPDATE notes SET type = 'LegacyDiffNote' WHERE line_code IS NOT NULL" + end +end diff --git a/db/migrate/20160509201028_add_health_check_access_token_to_application_settings.rb b/db/migrate/20160509201028_add_health_check_access_token_to_application_settings.rb new file mode 100644 index 00000000000000..9d729fec189874 --- /dev/null +++ b/db/migrate/20160509201028_add_health_check_access_token_to_application_settings.rb @@ -0,0 +1,5 @@ +class AddHealthCheckAccessTokenToApplicationSettings < ActiveRecord::Migration + def change + add_column :application_settings, :health_check_access_token, :string + end +end diff --git a/db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb b/db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb new file mode 100644 index 00000000000000..c34e7ba540951a --- /dev/null +++ b/db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb @@ -0,0 +1,12 @@ +class AddSendUserConfirmationEmailToApplicationSettings < ActiveRecord::Migration + def up + add_column :application_settings, :send_user_confirmation_email, :boolean, default: false + + #Sets confirmation email to true by default on existing installations. + execute "UPDATE application_settings SET send_user_confirmation_email=true" + end + + def down + remove_column :application_settings, :send_user_confirmation_email + end +end diff --git a/db/migrate/20160525205328_remove_main_language_from_projects.rb b/db/migrate/20160525205328_remove_main_language_from_projects.rb new file mode 100644 index 00000000000000..0f9d60c385f366 --- /dev/null +++ b/db/migrate/20160525205328_remove_main_language_from_projects.rb @@ -0,0 +1,21 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class RemoveMainLanguageFromProjects < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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 + # existing transaction. When using "add_concurrent_index" make sure that this + # method is the _only_ method called in the migration, any other changes + # should go in a separate migration. This ensures that upon failure _only_ the + # index creation fails and can be retried or reverted easily. + # + # To disable transactions uncomment the following line and remove these + # comments: + # disable_ddl_transaction! + + def change + remove_column :projects, :main_language + end +end diff --git a/db/migrate/20160527020117_remove_notification_settings_for_deleted_projects.rb b/db/migrate/20160527020117_remove_notification_settings_for_deleted_projects.rb new file mode 100644 index 00000000000000..7910120b4e06ca --- /dev/null +++ b/db/migrate/20160527020117_remove_notification_settings_for_deleted_projects.rb @@ -0,0 +1,13 @@ +class RemoveNotificationSettingsForDeletedProjects < ActiveRecord::Migration + def up + execute <<-SQL + DELETE FROM notification_settings + WHERE notification_settings.source_type = 'Project' + AND NOT EXISTS ( + SELECT * + FROM projects + WHERE projects.id = notification_settings.source_id + ) + SQL + end +end diff --git a/db/migrate/20160528043124_add_users_state_index.rb b/db/migrate/20160528043124_add_users_state_index.rb new file mode 100644 index 00000000000000..e77a54607373ea --- /dev/null +++ b/db/migrate/20160528043124_add_users_state_index.rb @@ -0,0 +1,9 @@ +class AddUsersStateIndex < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def change + add_concurrent_index :users, :state + end +end diff --git a/db/migrate/20160530150109_add_container_registry_token_expire_delay_to_application_settings.rb b/db/migrate/20160530150109_add_container_registry_token_expire_delay_to_application_settings.rb new file mode 100644 index 00000000000000..e21376bd571936 --- /dev/null +++ b/db/migrate/20160530150109_add_container_registry_token_expire_delay_to_application_settings.rb @@ -0,0 +1,9 @@ +# This is ONLINE migration + +class AddContainerRegistryTokenExpireDelayToApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + def change + add_column :application_settings, :container_registry_token_expire_delay, :integer, default: 5 + end +end diff --git a/db/schema.rb b/db/schema.rb index 71d953afe30ab9..b2af810f600ca2 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: 20160508194200) do +ActiveRecord::Schema.define(version: 20160530150109) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -43,43 +43,47 @@ t.datetime "created_at" t.datetime "updated_at" t.string "home_page_url" - t.integer "default_branch_protection", default: 2 + t.integer "default_branch_protection", default: 2 t.text "restricted_visibility_levels" - t.boolean "version_check_enabled", default: true - t.integer "max_attachment_size", default: 10, null: false + t.boolean "version_check_enabled", default: true + t.integer "max_attachment_size", default: 10, null: false t.integer "default_project_visibility" t.integer "default_snippet_visibility" t.text "restricted_signup_domains" - t.boolean "user_oauth_applications", default: true + t.boolean "user_oauth_applications", default: true t.string "after_sign_out_path" - t.integer "session_expire_delay", default: 10080, null: false + t.integer "session_expire_delay", default: 10080, null: false t.text "import_sources" t.text "help_page_text" t.string "admin_notification_email" - t.boolean "shared_runners_enabled", default: true, null: false - t.integer "max_artifacts_size", default: 100, null: false + t.boolean "shared_runners_enabled", default: true, null: false + t.integer "max_artifacts_size", default: 100, null: false t.string "runners_registration_token" - t.boolean "require_two_factor_authentication", default: false - t.integer "two_factor_grace_period", default: 48 - t.boolean "metrics_enabled", default: false - t.string "metrics_host", default: "localhost" - t.integer "metrics_pool_size", default: 16 - t.integer "metrics_timeout", default: 10 - t.integer "metrics_method_call_threshold", default: 10 - t.boolean "recaptcha_enabled", default: false + t.boolean "require_two_factor_authentication", default: false + t.integer "two_factor_grace_period", default: 48 + t.boolean "metrics_enabled", default: false + t.string "metrics_host", default: "localhost" + t.integer "metrics_pool_size", default: 16 + t.integer "metrics_timeout", default: 10 + t.integer "metrics_method_call_threshold", default: 10 + t.boolean "recaptcha_enabled", default: false t.string "recaptcha_site_key" t.string "recaptcha_private_key" - t.integer "metrics_port", default: 8089 - t.boolean "akismet_enabled", default: false + t.integer "metrics_port", default: 8089 + t.boolean "akismet_enabled", default: false t.string "akismet_api_key" - t.integer "metrics_sample_interval", default: 15 - t.boolean "sentry_enabled", default: false + t.integer "metrics_sample_interval", default: 15 + t.boolean "sentry_enabled", default: false t.string "sentry_dsn" - t.boolean "email_author_in_body", default: false + t.boolean "email_author_in_body", default: false t.integer "default_group_visibility" - t.boolean "repository_checks_enabled", default: false + t.boolean "repository_checks_enabled", default: false t.text "shared_runners_text" - t.integer "metrics_packet_size", default: 1 + t.integer "metrics_packet_size", default: 1 + t.text "disabled_oauth_sign_in_sources" + t.string "health_check_access_token" + t.boolean "send_user_confirmation_email", default: false + t.integer "container_registry_token_expire_delay", default: 5 end create_table "audit_events", force: :cascade do |t| @@ -267,6 +271,7 @@ t.string "revision" t.string "platform" t.string "architecture" + t.boolean "run_untagged", default: true, null: false end add_index "ci_runners", ["description"], name: "index_ci_runners_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"} @@ -634,6 +639,7 @@ t.text "st_diff" t.integer "updated_by_id" t.boolean "is_award", default: false, null: false + t.string "type" end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree @@ -755,10 +761,10 @@ t.integer "build_timeout", default: 3600, null: false t.boolean "pending_delete", default: false t.boolean "public_builds", default: true, null: false - t.string "main_language" t.integer "pushes_since_gc", default: 0 t.boolean "last_repository_check_failed" t.datetime "last_repository_check_at" + t.boolean "container_registry_enabled" end add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree @@ -995,6 +1001,7 @@ add_index "users", ["name"], name: "index_users_on_name", using: :btree add_index "users", ["name"], name: "index_users_on_name_trigram", using: :gin, opclasses: {"name"=>"gin_trgm_ops"} add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree + add_index "users", ["state"], name: "index_users_on_state", using: :btree add_index "users", ["username"], name: "index_users_on_username", using: :btree add_index "users", ["username"], name: "index_users_on_username_trigram", using: :gin, opclasses: {"username"=>"gin_trgm_ops"} diff --git a/doc/README.md b/doc/README.md index e358da1c4245cc..d1345ab2493d57 100644 --- a/doc/README.md +++ b/doc/README.md @@ -13,6 +13,7 @@ - [Profile Settings](profile/README.md) - [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat. - [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects. +- [Container Registry](container_registry/README.md) Learn how to use GitLab Container Registry. - [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. - [Webhooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. - [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. @@ -41,8 +42,10 @@ - [Git LFS configuration](workflow/lfs/lfs_administration.md) - [Housekeeping](administration/housekeeping.md) Keep your Git repository tidy and fast. - [GitLab Performance Monitoring](monitoring/performance/introduction.md) Configure GitLab and InfluxDB for measuring performance metrics +- [Monitoring uptime](monitoring/health_check.md) Check the server status using the health check endpoint - [Sidekiq Troubleshooting](administration/troubleshooting/sidekiq.md) Debug when Sidekiq appears hung and is not processing jobs - [High Availability](administration/high_availability/README.md) Configure multiple servers for scaling or high availability +- [Container Registry](administration/container_registry.md) Configure Docker Registry with GitLab ## Contributor documentation diff --git a/doc/administration/container_registry.md b/doc/administration/container_registry.md new file mode 100644 index 00000000000000..caf9a5bef2c454 --- /dev/null +++ b/doc/administration/container_registry.md @@ -0,0 +1,375 @@ +# GitLab Container Registry Administration + +> **Note:** +This feature was [introduced][ce-4040] in GitLab 8.8. + +With the Docker Container Registry integrated into GitLab, every project can +have its own space to store its Docker images. + +You can read more about Docker Registry at https://docs.docker.com/registry/introduction/. + +--- + + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Enable the Container Registry](#enable-the-container-registry) +- [Container Registry domain configuration](#container-registry-domain-configuration) + - [Configure Container Registry under an existing GitLab domain](#configure-container-registry-under-an-existing-gitlab-domain) + - [Configure Container Registry under its own domain](#configure-container-registry-under-its-own-domain) +- [Disable Container Registry site-wide](#disable-container-registry-site-wide) +- [Disable Container Registry per project](#disable-container-registry-per-project) +- [Disable Container Registry for new projects site-wide](#disable-container-registry-for-new-projects-site-wide) +- [Container Registry storage path](#container-registry-storage-path) +- [Storage limitations](#storage-limitations) +- [Changelog](#changelog) + + + +## Enable the Container Registry + +**Omnibus GitLab installations** + +All you have to do is configure the domain name under which the Container +Registry will listen to. Read [#container-registry-domain-configuration](#container-registry-domain-configuration) +and pick one of the two options that fits your case. + +>**Note:** +The container Registry works under HTTPS by default. Using HTTP is possible +but not recommended and out of the scope of this document. +Read the [insecure Registry documentation][docker-insecure] if you want to +implement this. + +--- + +**Installations from source** + +If you have installed GitLab from source: + +1. You will have to [install Docker Registry][registry-deploy] by yourself. +1. After the installation is complete, you will have to configure the Registry's + settings in `gitlab.yml` in order to enable it. +1. Use the sample NGINX configuration file that is found under + [`lib/support/nginx/registry-ssl`][registry-ssl] and edit it to match the + `host`, `port` and TLS certs paths. + +The contents of `gitlab.yml` are: + +``` +registry: + enabled: true + host: registry.gitlab.example.com + port: 5005 + api_url: http://localhost:5000/ + key_path: config/registry.key + path: shared/registry + issuer: gitlab-issuer +``` + +where: + +| Parameter | Description | +| --------- | ----------- | +| `enabled` | `true` or `false`. Enables the Registry in GitLab. By default this is `false`. | +| `host` | The host URL under which the Registry will run and the users will be able to use. | +| `port` | The port under which the external Registry domain will listen on. | +| `api_url` | The internal API URL under which the Registry is exposed to. It defaults to `http://localhost:5000`. | +| `key_path`| The private key location that is a pair of Registry's `rootcertbundle`. Read the [token auth configuration documentation][token-config]. | +| `path` | This should be the same directory like specified in Registry's `rootdirectory`. Read the [storage configuration documentation][storage-config]. This path needs to be readable by the GitLab user, the web-server user and the Registry user. Read more in [#container-registry-storage-path](#container-registry-storage-path). | +| `issuer` | This should be the same value as configured in Registry's `issuer`. Read the [token auth configuration documentation][token-config]. | + +>**Note:** +GitLab does not ship with a Registry init file. Hence, [restarting GitLab][restart gitlab] +will not restart the Registry should you modify its settings. Read the upstream +documentation on how to achieve that. + +## Container Registry domain configuration + +There are two ways you can configure the Registry's external domain. + +- Either [use the existing GitLab domain][existing-domain] where in that case + the Registry will have to listen on a port and reuse GitLab's TLS certificate, +- or [use a completely separate domain][new-domain] with a new TLS certificate + for that domain. + +Since the container Registry requires a TLS certificate, in the end it all boils +down to how easy or pricey is to get a new one. + +Please take this into consideration before configuring the Container Registry +for the first time. + +### Configure Container Registry under an existing GitLab domain + +If the Registry is configured to use the existing GitLab domain, you can +expose the Registry on a port so that you can reuse the existing GitLab TLS +certificate. + +Assuming that the GitLab domain is `https://gitlab.example.com` and the port the +Registry is exposed to the outside world is `4567`, here is what you need to set +in `gitlab.rb` or `gitlab.yml` if you are using Omnibus GitLab or installed +GitLab from source respectively. + +--- + +**Omnibus GitLab installations** + +1. Your `/etc/gitlab/gitlab.rb` should contain the Registry URL as well as the + path to the existing TLS certificate and key used by GitLab: + + ```ruby + registry_external_url 'https://gitlab.example.com:4567' + ``` + + Note how the `registry_external_url` is listening on HTTPS under the + existing GitLab URL, but on a different port. + + If your TLS certificate is not in `/etc/gitlab/ssl/gitlab.example.com.crt` + and key not in `/etc/gitlab/ssl/gitlab.example.com.key` uncomment the lines + below: + + ```ruby + registry_nginx['ssl_certificate'] = "/path/to/certificate.pem" + registry_nginx['ssl_certificate_key'] = "/path/to/certificate.key" + ``` + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +--- + +**Installations from source** + +1. Open `/home/git/gitlab/config/gitlab.yml`, find the `registry` entry and + configure it with the following settings: + + ``` + registry: + enabled: true + host: gitlab.example.com + port: 4567 + ``` + +1. Save the file and [restart GitLab][] for the changes to take effect. +1. Make the relevant changes in NGINX as well (domain, port, TLS certificates path). + +--- + +Users should now be able to login to the Container Registry with their GitLab +credentials using: + +```bash +docker login gitlab.example.com:4567 +``` + +### Configure Container Registry under its own domain + +If the Registry is configured to use its own domain, you will need a TLS +certificate for that specific domain (e.g., `registry.example.com`) or maybe +a wildcard certificate if hosted under a subdomain of your existing GitLab +domain (e.g., `registry.gitlab.example.com`). + +Let's assume that you want the container Registry to be accessible at +`https://registry.gitlab.example.com`. + +--- + +**Omnibus GitLab installations** + +1. Place your TLS certificate and key in + `/etc/gitlab/ssl/registry.gitlab.example.com.crt` and + `/etc/gitlab/ssl/registry.gitlab.example.com.key` and make sure they have + correct permissions: + + ```bash + chmod 600 /etc/gitlab/ssl/registry.gitlab.example.com.* + ``` + +1. Once the TLS certificate is in place, edit `/etc/gitlab/gitlab.rb` with: + + ```ruby + registry_external_url 'https://registry.gitlab.example.com' + ``` + + Note how the `registry_external_url` is listening on HTTPS. + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +> **Note:** +If you have a [wildcard certificate][], you need to specify the path to the +certificate in addition to the URL, in this case `/etc/gitlab/gitlab.rb` will +look like: +> +```ruby +registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/certificate.pem" +registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/certificate.key" +``` + +--- + +**Installations from source** + +1. Open `/home/git/gitlab/config/gitlab.yml`, find the `registry` entry and + configure it with the following settings: + + ``` + registry: + enabled: true + host: registry.gitlab.example.com + ``` + +1. Save the file and [restart GitLab][] for the changes to take effect. +1. Make the relevant changes in NGINX as well (domain, port, TLS certificates path). + +--- + +Users should now be able to login to the Container Registry using their GitLab +credentials: + +```bash +docker login registry.gitlab.example.com +``` + +## Disable Container Registry site-wide + +>**Note:** +Disabling the Registry in the Rails GitLab application as set by the following +steps, will not remove any existing Docker images. This is handled by the +Registry application itself. + +**Omnibus GitLab** + +1. Open `/etc/gitlab/gitlab.rb` and set `registry['enable']` to `false`: + + ```ruby + registry['enable'] = false + ``` + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +--- + +**Installations from source** + +1. Open `/home/git/gitlab/config/gitlab.yml`, find the `registry` entry and + set `enabled` to `false`: + + ``` + registry: + enabled: false + ``` + +1. Save the file and [restart GitLab][] for the changes to take effect. + +## Disable Container Registry per project + +If Registry is enabled in your GitLab instance, but you don't need it for your +project, you can disable it from your project's settings. Read the user guide +on how to achieve that. + +## Disable Container Registry for new projects site-wide + +If the Container Registry is enabled, then it will be available on all new +projects. To disable this function and let the owners of a project to enable +the Container Registry by themselves, follow the steps below. + +--- + +**Omnibus GitLab installations** + +1. Edit `/etc/gitlab/gitlab.rb` and add the following line: + + ```ruby + gitlab_rails['gitlab_default_projects_features_container_registry'] = false + ``` + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +--- + +**Installations from source** + +1. Open `/home/git/gitlab/config/gitlab.yml`, find the `default_projects_features` + entry and configure it so that `container_registry` is set to `false`: + + ``` + ## Default project features settings + default_projects_features: + issues: true + merge_requests: true + wiki: true + snippets: false + builds: true + container_registry: false + ``` + +1. Save the file and [restart GitLab][] for the changes to take effect. + +## Container Registry storage path + +To change the storage path where Docker images will be stored, follow the +steps below. + +This path is accessible to: + +- the user running the Container Registry daemon, +- the user running GitLab + +> **Warning** You should confirm that all GitLab, Registry and web server users +have access to this directory. + +--- + +**Omnibus GitLab installations** + +The default location where images are stored in Omnibus, is +`/var/opt/gitlab/gitlab-rails/shared/registry`. To change it: + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['registry_path'] = "/path/to/registry/storage" + ``` + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +--- + +**Installations from source** + +The default location where images are stored in source installations, is +`/home/git/gitlab/shared/registry`. To change it: + +1. Open `/home/git/gitlab/config/gitlab.yml`, find the `registry` entry and + change the `path` setting: + + ``` + registry: + path: shared/registry + ``` + +1. Save the file and [restart GitLab][] for the changes to take effect. + +## Storage limitations + +Currently, there is no storage limitation, which means a user can upload an +infinite amount of Docker images with arbitrary sizes. This setting will be +configurable in future releases. + +## Changelog + +**GitLab 8.8 ([source docs][8-8-docs])** + +- GitLab Container Registry feature was introduced. + +[reconfigure gitlab]: restart_gitlab.md#omnibus-gitlab-reconfigure +[restart gitlab]: restart_gitlab.md#installations-from-source +[wildcard certificate]: https://en.wikipedia.org/wiki/Wildcard_certificate +[ce-4040]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4040 +[docker-insecure]: https://docs.docker.com/registry/insecure/ +[registry-deploy]: https://docs.docker.com/registry/deploying/ +[storage-config]: https://docs.docker.com/registry/configuration/#storage +[token-config]: https://docs.docker.com/registry/configuration/#token +[8-8-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-8-stable/doc/administration/container_registry.md +[registry-ssl]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/support/nginx/registry-ssl +[existing-domain]: #configure-container-registry-under-an-existing-gitlab-domain +[new-domain]: #configure-container-registry-under-its-own-domain diff --git a/doc/administration/environment_variables.md b/doc/administration/environment_variables.md index 43ab153d76dc05..7f53915a4d7c86 100644 --- a/doc/administration/environment_variables.md +++ b/doc/administration/environment_variables.md @@ -58,4 +58,4 @@ to the naming scheme `GITLAB_#{name in 1_settings.rb in upper case}`. It's possible to preconfigure the GitLab docker image by adding the environment variable `GITLAB_OMNIBUS_CONFIG` to the `docker run` command. -For more information see the ['preconfigure-docker-container' section in the Omnibus documentation](http://doc.gitlab.com/omnibus/docker/#preconfigure-docker-container). +For more information see the ['preconfigure-docker-container' section in the Omnibus documentation](http://docs.gitlab.com/omnibus/docker/#preconfigure-docker-container). diff --git a/doc/administration/high_availability/README.md b/doc/administration/high_availability/README.md index 43d85ffb7752ce..d74a786ac24142 100644 --- a/doc/administration/high_availability/README.md +++ b/doc/administration/high_availability/README.md @@ -19,6 +19,8 @@ Components/Servers Required: - 2 servers/virtual machines (one active/one passive) +![Active/Passive HA Diagram](../img/high_availability/active-passive-diagram.png) + ### Active/Active This architecture scales easily because all application servers handle @@ -26,6 +28,8 @@ user requests simultaneously. The database, Redis, and GitLab application are all deployed on separate servers. The configuration is **only** highly-available if the database, Redis and storage are also configured as such. +![Active/Active HA Diagram](../img/high_availability/active-active-diagram.png) + **Steps to configure active/active:** 1. [Configure the database](database.md) diff --git a/doc/administration/high_availability/load_balancer.md b/doc/administration/high_availability/load_balancer.md index b1fe34ed9a1a30..136f570ac27243 100644 --- a/doc/administration/high_availability/load_balancer.md +++ b/doc/administration/high_availability/load_balancer.md @@ -60,4 +60,4 @@ Read more on high-availability configuration: configure custom domains with custom SSL, which would not be possible if SSL was terminated at the load balancer. -[gitlab-pages]: http://doc.gitlab.com/ee/pages/administration.html +[gitlab-pages]: http://docs.gitlab.com/ee/pages/administration.html diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md index e4e124e200a2cf..537f4f3501de53 100644 --- a/doc/administration/high_availability/nfs.md +++ b/doc/administration/high_availability/nfs.md @@ -2,8 +2,8 @@ ## Required NFS Server features -**File locking**: GitLab **requires** file locking which is only supported -natively in NFS version 4. NFSv3 also supports locking as long as +**File locking**: GitLab **requires** advisory file locking, which is only +supported natively in NFS version 4. NFSv3 also supports locking as long as Linux Kernel 2.6.5+ is used. We recommend using version 4 and do not specifically test NFSv3. @@ -113,4 +113,4 @@ Read more on high-availability configuration: 1. [Configure the GitLab application servers](gitlab.md) 1. [Configure the load balancers](load_balancer.md) -[udp-log-shipping]: http://doc.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only "UDP log shipping" +[udp-log-shipping]: http://docs.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only "UDP log shipping" diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md index d89a1e582cacaa..f6153216f333a9 100644 --- a/doc/administration/high_availability/redis.md +++ b/doc/administration/high_availability/redis.md @@ -26,7 +26,7 @@ that runs Redis. ```ruby external_url 'https://gitlab.example.com' - # Disable all components except PostgreSQL + # Disable all components except Redis redis['enable'] = true bootstrap['enable'] = false nginx['enable'] = false diff --git a/doc/administration/img/high_availability/active-active-diagram.png b/doc/administration/img/high_availability/active-active-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..81259e0ae9348a16e66407946719ddf3d75d974b GIT binary patch literal 29607 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 literal 0 HcmV?d00001 diff --git a/doc/administration/repository_checks.md b/doc/administration/repository_checks.md index 3411e4af6a7c7e..4172b604cec81e 100644 --- a/doc/administration/repository_checks.md +++ b/doc/administration/repository_checks.md @@ -5,7 +5,7 @@ This feature was [introduced][ce-3232] in GitLab 8.7. It is OFF by default because it still causes too many false alarms. Git has a built-in mechanism, [git fsck][git-fsck], to verify the -integrity of all data commited to a repository. GitLab administrators +integrity of all data committed to a repository. GitLab administrators can trigger such a check for a project via the project page under the admin panel. The checks run asynchronously so it may take a few minutes before the check result is visible on the project admin page. If the @@ -41,4 +41,4 @@ alarms you can choose to clear ALL repository check states from the --- [ce-3232]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3232 "Auto git fsck" -[git-fsck]: https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html "git fsck documentation" \ No newline at end of file +[git-fsck]: https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html "git fsck documentation" diff --git a/doc/administration/troubleshooting/sidekiq.md b/doc/administration/troubleshooting/sidekiq.md index 134a7583762dc0..a776cd3f05e2ea 100644 --- a/doc/administration/troubleshooting/sidekiq.md +++ b/doc/administration/troubleshooting/sidekiq.md @@ -150,6 +150,14 @@ To output a backtrace from all threads at once: apply all thread bt ``` +Once you're done debugging with `gdb`, be sure to detach from the process and +exit: + +``` +detach +exit +``` + ## Check for blocking queries Sometimes the speed at which Sidekiq processes jobs can be so fast that it can diff --git a/doc/api/README.md b/doc/api/README.md index ff039f1886f161..27c5962decfa3a 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -33,7 +33,7 @@ following locations: - [Build triggers](build_triggers.md) - [Build Variables](build_variables.md) - [Runners](runners.md) -- [Licenses](licenses.md) +- [Open source license templates](licenses.md) ## Authentication diff --git a/doc/api/build_triggers.md b/doc/api/build_triggers.md index 4a12e962b620de..0881a7d7a90408 100644 --- a/doc/api/build_triggers.md +++ b/doc/api/build_triggers.md @@ -101,8 +101,18 @@ DELETE /projects/:id/triggers/:token | Attribute | Type | required | Description | |-----------|---------|----------|--------------------------| | `id` | integer | yes | The ID of a project | -| `token` | string | yes | The `token` of a project | +| `token` | string | yes | The `token` of a trigger | ``` curl -X DELETE -H "PRIVATE_TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/triggers/7b9148c158980bbd9bcea92c17522d" ``` + +```json +{ + "created_at": "2015-12-23T16:25:56.760Z", + "deleted_at": "2015-12-24T12:32:20.100Z", + "last_used": null, + "token": "7b9148c158980bbd9bcea92c17522d", + "updated_at": "2015-12-24T12:32:20.100Z" +} +``` diff --git a/doc/api/groups.md b/doc/api/groups.md index 2821bc21b81e58..1ccb9715e96f91 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -265,7 +265,6 @@ GET /groups/:id/members { "id": 1, "username": "raymond_smith", - "email": "ray@smith.org", "name": "Raymond Smith", "state": "active", "created_at": "2012-10-22T14:13:35Z", @@ -274,7 +273,6 @@ GET /groups/:id/members { "id": 2, "username": "john_doe", - "email": "joh@doe.org", "name": "John Doe", "state": "active", "created_at": "2012-10-22T14:13:35Z", diff --git a/doc/api/issues.md b/doc/api/issues.md index 3e78149f442f9d..fc7a7ae0c0ce4b 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -77,7 +77,8 @@ Example response: "created_at" : "2016-01-04T15:31:51.081Z", "iid" : 6, "labels" : [], - "subscribed" : false + "subscribed" : false, + "user_notes_count": 1 } ] ``` @@ -154,7 +155,8 @@ Example response: "title" : "Ut commodi ullam eos dolores perferendis nihil sunt.", "updated_at" : "2016-01-04T15:31:46.176Z", "created_at" : "2016-01-04T15:31:46.176Z", - "subscribed" : false + "subscribed" : false, + "user_notes_count": 1 } ] ``` @@ -216,7 +218,8 @@ Example response: "title" : "Ut commodi ullam eos dolores perferendis nihil sunt.", "updated_at" : "2016-01-04T15:31:46.176Z", "created_at" : "2016-01-04T15:31:46.176Z", - "subscribed": false + "subscribed": false, + "user_notes_count": 1 } ``` @@ -271,7 +274,8 @@ Example response: "description" : null, "updated_at" : "2016-01-07T12:44:33.959Z", "milestone" : null, - "subscribed" : true + "subscribed" : true, + "user_notes_count": 0 } ``` @@ -329,7 +333,8 @@ Example response: "id" : 85, "assignee" : null, "milestone" : null, - "subscribed" : true + "subscribed" : true, + "user_notes_count": 0 } ``` diff --git a/doc/api/labels.md b/doc/api/labels.md index 3730c07c5a7a50..a181c0f57a2764 100644 --- a/doc/api/labels.md +++ b/doc/api/labels.md @@ -39,7 +39,7 @@ Example response: { "name" : "critical", "color" : "#d9534f", - "description": "Criticalissue. Need fix ASAP", + "description": "Critical issue. Need fix ASAP", "open_issues_count": 1, "closed_issues_count": 3, "open_merge_requests_count": 1 @@ -165,3 +165,73 @@ Example response: "description": "Documentation" } ``` + +## Subscribe to a label + +Subscribes the authenticated user to a label to receive notifications. If the +operation is successful, status code `201` together with the updated label is +returned. If the user is already subscribed to the label, the status code `304` +is returned. If the project or label is not found, status code `404` is +returned. + +``` +POST /projects/:id/labels/:label_id/subscription +``` + +| Attribute | Type | Required | Description | +| ---------- | ----------------- | -------- | ------------------------------------ | +| `id` | integer | yes | The ID of a project | +| `label_id` | integer or string | yes | The ID or title of a project's label | + +```bash +curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/labels/1/subscription +``` + +Example response: + +```json +{ + "name": "Docs", + "color": "#cc0033", + "description": "", + "open_issues_count": 0, + "closed_issues_count": 0, + "open_merge_requests_count": 0, + "subscribed": true +} +``` + +## Unsubscribe from a label + +Unsubscribes the authenticated user from a label to not receive notifications +from it. If the operation is successful, status code `200` together with the +updated label is returned. If the user is not subscribed to the label, the +status code `304` is returned. If the project or label is not found, status code +`404` is returned. + +``` +DELETE /projects/:id/labels/:label_id/subscription +``` + +| Attribute | Type | Required | Description | +| ---------- | ----------------- | -------- | ------------------------------------ | +| `id` | integer | yes | The ID of a project | +| `label_id` | integer or string | yes | The ID or title of a project's label | + +```bash +curl -X DELETE -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/labels/1/subscription +``` + +Example response: + +```json +{ + "name": "Docs", + "color": "#cc0033", + "description": "", + "open_issues_count": 0, + "closed_issues_count": 0, + "open_merge_requests_count": 0, + "subscribed": false +} +``` diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 2057f9d77aa486..8217e30fe256c8 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -67,7 +67,8 @@ Parameters: }, "merge_when_build_succeeds": true, "merge_status": "can_be_merged", - "subscribed" : false + "subscribed" : false, + "user_notes_count": 1 } ] ``` @@ -130,7 +131,8 @@ Parameters: }, "merge_when_build_succeeds": true, "merge_status": "can_be_merged", - "subscribed" : true + "subscribed" : true, + "user_notes_count": 1 } ``` @@ -230,6 +232,7 @@ Parameters: "merge_when_build_succeeds": true, "merge_status": "can_be_merged", "subscribed" : true, + "user_notes_count": 1, "changes": [ { "old_path": "VERSION", @@ -308,7 +311,8 @@ Parameters: }, "merge_when_build_succeeds": true, "merge_status": "can_be_merged", - "subscribed" : true + "subscribed" : true, + "user_notes_count": 0 } ``` @@ -378,7 +382,8 @@ Parameters: }, "merge_when_build_succeeds": true, "merge_status": "can_be_merged", - "subscribed" : true + "subscribed" : true, + "user_notes_count": 1 } ``` @@ -472,7 +477,8 @@ Parameters: }, "merge_when_build_succeeds": true, "merge_status": "can_be_merged", - "subscribed" : true + "subscribed" : true, + "user_notes_count": 1 } ``` @@ -537,7 +543,8 @@ Parameters: }, "merge_when_build_succeeds": true, "merge_status": "can_be_merged", - "subscribed" : true + "subscribed" : true, + "user_notes_count": 1 } ``` @@ -602,7 +609,8 @@ Example response: "title" : "Consequatur vero maxime deserunt laboriosam est voluptas dolorem.", "created_at" : "2016-01-04T15:31:51.081Z", "iid" : 6, - "labels" : [] + "labels" : [], + "user_notes_count": 1 }, ] ``` diff --git a/doc/api/notes.md b/doc/api/notes.md index a6b5b1787fdf90..7aa1c2155bfe8d 100644 --- a/doc/api/notes.md +++ b/doc/api/notes.md @@ -15,7 +15,7 @@ GET /projects/:id/issues/:issue_id/notes Parameters: - `id` (required) - The ID of a project -- `issue_id` (required) - The IID of an issue (not ID) +- `issue_id` (required) - The ID of an issue ```json [ @@ -73,7 +73,7 @@ GET /projects/:id/issues/:issue_id/notes/:note_id Parameters: - `id` (required) - The ID of a project -- `issue_id` (required) - The IID of a project issue (not ID) +- `issue_id` (required) - The ID of a project issue - `note_id` (required) - The ID of an issue note ### Create new issue note @@ -87,7 +87,7 @@ POST /projects/:id/issues/:issue_id/notes Parameters: - `id` (required) - The ID of a project -- `issue_id` (required) - The IID of an issue (not ID) +- `issue_id` (required) - The ID of an issue - `body` (required) - The content of a note - `created_at` (optional) - Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z @@ -102,7 +102,7 @@ PUT /projects/:id/issues/:issue_id/notes/:note_id Parameters: - `id` (required) - The ID of a project -- `issue_id` (required) - The IID of an issue (not ID) +- `issue_id` (required) - The ID of an issue - `note_id` (required) - The ID of a note - `body` (required) - The content of a note @@ -120,7 +120,7 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `issue_id` | integer | yes | The IID of an issue | +| `issue_id` | integer | yes | The ID of an issue | | `note_id` | integer | yes | The ID of a note | ```bash diff --git a/doc/api/projects.md b/doc/api/projects.md index de1faadebf58ec..f5f195b97df0c9 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -424,6 +424,7 @@ Parameters: - `builds_enabled` (optional) - `wiki_enabled` (optional) - `snippets_enabled` (optional) +- `container_registry_enabled` (optional) - `public` (optional) - if `true` same as setting visibility_level = 20 - `visibility_level` (optional) - `import_url` (optional) @@ -447,6 +448,7 @@ Parameters: - `builds_enabled` (optional) - `wiki_enabled` (optional) - `snippets_enabled` (optional) +- `container_registry_enabled` (optional) - `public` (optional) - if `true` same as setting visibility_level = 20 - `visibility_level` (optional) - `import_url` (optional) @@ -472,6 +474,7 @@ Parameters: - `builds_enabled` (optional) - `wiki_enabled` (optional) - `snippets_enabled` (optional) +- `container_registry_enabled` (optional) - `public` (optional) - if `true` same as setting visibility_level = 20 - `visibility_level` (optional) - `public_builds` (optional) diff --git a/doc/api/runners.md b/doc/api/runners.md index cc6c6b7cb2f20c..ddfa298f79d008 100644 --- a/doc/api/runners.md +++ b/doc/api/runners.md @@ -275,7 +275,7 @@ POST /projects/:id/runners | `runner_id` | integer | yes | The ID of a runner | ``` -curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/project/9/runners" -F "runner_id=9" +curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/9/runners" -F "runner_id=9" ``` Example response: @@ -306,7 +306,7 @@ DELETE /projects/:id/runners/:runner_id | `runner_id` | integer | yes | The ID of a runner | ``` -curl -X DELETE -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/project/9/runners/9" +curl -X DELETE -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/9/runners/9" ``` Example response: diff --git a/doc/api/services.md b/doc/api/services.md index 7d45b2cf463f60..ccfc0fccb7f20d 100644 --- a/doc/api/services.md +++ b/doc/api/services.md @@ -16,8 +16,8 @@ PUT /projects/:id/services/asana Parameters: -- `api_key` (**required**) - User API token. User must have access to task,all comments will be attributed to this user. -- `restrict_to_branch` (optional) - Comma-separated list of branches which will beautomatically inspected. Leave blank to include all branches. +- `api_key` (**required**) - User API token. User must have access to task, all comments will be attributed to this user. +- `restrict_to_branch` (optional) - Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches. ### Delete Asana service @@ -491,7 +491,7 @@ Jira issue tracker Set JIRA service for a project. -> Setting `project_url`, `issues_url` and `new_issue_url` will allow a user to easily navigate to the Jira issue tracker. See the [integration doc](http://doc.gitlab.com/ce/integration/external-issue-tracker.html) for details. Support for referencing commits and automatic closing of Jira issues directly from GitLab is [available in GitLab EE.](http://doc.gitlab.com/ee/integration/jira.html) +> Setting `project_url`, `issues_url` and `new_issue_url` will allow a user to easily navigate to the Jira issue tracker. See the [integration doc](http://docs.gitlab.com/ce/integration/external-issue-tracker.html) for details. Support for referencing commits and automatic closing of Jira issues directly from GitLab is [available in GitLab EE.](http://docs.gitlab.com/ee/integration/jira.html) ``` PUT /projects/:id/services/jira @@ -503,6 +503,8 @@ Parameters: - `project_url` (**required**) - Project url - `issues_url` (**required**) - Issue url - `description` (optional) - Jira issue tracker +- `username` (optional) - Jira username +- `password` (optional) - Jira password ### Delete JIRA service diff --git a/doc/api/settings.md b/doc/api/settings.md index 1e745115dc816a..43a0fe35e42dbc 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -37,7 +37,8 @@ Example response: "created_at" : "2016-01-04T15:44:55.176Z", "default_project_visibility" : 0, "gravatar_enabled" : true, - "sign_in_text" : null + "sign_in_text" : null, + "container_registry_token_expire_delay": 5 } ``` @@ -64,6 +65,7 @@ PUT /application/settings | `restricted_signup_domains` | array of strings | no | Force people to use only corporate emails for sign-up. Default is null, meaning there is no restriction. | | `user_oauth_applications` | boolean | no | Allow users to register any application to use GitLab as an OAuth provider | | `after_sign_out_path` | string | no | Where to redirect users after logout | +| `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes | ```bash curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/application/settings?signup_enabled=false&default_project_visibility=1 @@ -90,6 +92,7 @@ Example response: "default_snippet_visibility": 0, "restricted_signup_domains": [], "user_oauth_applications": true, - "after_sign_out_path": "" + "after_sign_out_path": "", + "container_registry_token_expire_delay": 5 } ``` diff --git a/doc/ci/deployment/README.md b/doc/ci/examples/deployment/README.md similarity index 100% rename from doc/ci/deployment/README.md rename to doc/ci/examples/deployment/README.md diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index 6a42a935abdfba..386b8e29fcfb7a 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -212,8 +212,8 @@ If you want to receive e-mail notifications about the result status of the builds, you should explicitly enable the **Builds Emails** service under your project's settings. -For more information read the [Builds emails service documentation] -(../../project_services/builds_emails.md). +For more information read the +[Builds emails service documentation](../../project_services/builds_emails.md). ## Builds badge diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index a06650b338742a..b42d7a62ebc906 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -125,7 +125,13 @@ shared runners will only run the jobs they are equipped to run. For instance, at GitLab we have runners tagged with "rails" if they contain the appropriate dependencies to run Rails test suites. -### Be Careful with Sensitive Information +### Prevent runner with tags from picking jobs without tags + +You can configure a runner to prevent it from picking jobs with tags when +the runnner does not have tags assigned. This setting is available on each +runner in *Project Settings* > *Runners*. + +### Be careful with sensitive information If you can run a build on a runner, you can get access to any code it runs and get the token of the runner. With shared runners, this means that anyone diff --git a/doc/ci/triggers/README.md b/doc/ci/triggers/README.md index 79ed512aabb83f..5c316510d0e7c4 100644 --- a/doc/ci/triggers/README.md +++ b/doc/ci/triggers/README.md @@ -33,7 +33,7 @@ POST /projects/:id/trigger/builds The required parameters are the trigger's `token` and the Git `ref` on which the trigger will be performed. Valid refs are the branch, the tag or the commit -SHA. The `:id` of a project can be found by [querying the API](../api/projects.md) +SHA. The `:id` of a project can be found by [querying the API](../../api/projects.md) or by visiting the **Triggers** page which provides self-explanatory examples. When a rebuild is triggered, the information is exposed in GitLab's UI under diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 7e9bced7616e52..a3481f58c6c586 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -128,7 +128,7 @@ builds, including deploy builds. This can be an array or a multi-line string. ### after_script >**Note:** -Introduced in GitLab 8.7 and GitLab Runner v1.2. +Introduced in GitLab 8.7 and requires Gitlab Runner v1.2 (not yet released) `after_script` is used to define the command that will be run after for all builds. This has to be an array or a multi-line string. @@ -348,7 +348,7 @@ job_name: | allow_failure | no | Allow build to fail. Failed build doesn't contribute to commit status | | when | no | Define when to run build. Can be `on_success`, `on_failure` or `always` | | dependencies | no | Define other builds that a build depends on so that you can pass artifacts between them| -| artifacts | no | Define list build artifacts | +| artifacts | no | Define list of build artifacts | | cache | no | Define list of files that should be cached between subsequent runs | | before_script | no | Override a set of commands that are executed before build | | after_script | no | Override a set of commands that are executed after build | diff --git a/doc/container_registry/README.md b/doc/container_registry/README.md new file mode 100644 index 00000000000000..4df24ef13cc104 --- /dev/null +++ b/doc/container_registry/README.md @@ -0,0 +1,113 @@ +# GitLab Container Registry + +> **Note:** +This feature was [introduced][ce-4040] in GitLab 8.8. + +> **Note:** +This document is about the user guide. To learn how to enable GitLab Container +Registry across your GitLab instance, visit the +[administrator documentation](../administration/container_registry.md). + +With the Docker Container Registry integrated into GitLab, every project can +have its own space to store its Docker images. + +You can read more about Docker Registry at https://docs.docker.com/registry/introduction/. + +--- + +## Enable the Container Registry for your project + +1. First, ask your system administrator to enable GitLab Container Registry + following the [administration documentation](../administration/container_registry.md). + If you are using GitLab.com, this is enabled by default so you can start using + the Registry immediately. + +1. Go to your project's settings and enable the **Container Registry** feature + on your project. For new projects this might be enabled by default. For + existing projects you will have to explicitly enable it. + + ![Enable Container Registry](img/project_feature.png) + +## Build and push images + +After you save your project's settings, you should see a new link in the +sidebar called **Container Registry**. Following this link will get you to +your project's Registry panel where you can see how to login to the Container +Registry using your GitLab credentials. + +For example if the Registry's URL is `registry.example.com`, the you should be +able to login with: + +``` +docker login registry.example.com +``` + +Building and publishing images should be a straightforward process. Just make +sure that you are using the Registry URL with the namespace and project name +that is hosted on GitLab: + +``` +docker build -t registry.example.com/group/project . +docker push registry.example.com/group/project +``` + +## Use images from GitLab Container Registry + +To download and run a container from images hosted in GitLab Container Registry, +use `docker run`: + +``` +docker run [options] registry.example.com/group/project [arguments] +``` + +For more information on running Docker containers, visit the +[Docker documentation][docker-docs]. + +## Control Container Registry from within GitLab + +GitLab offers a simple Container Registry management panel. Go to your project +and click **Container Registry** in the left sidebar. + +This view will show you all tags in your project and will easily allow you to +delete them. + +![Container Registry panel](img/container_registry.png) + +## Build and push images using GitLab CI + +> **Note:** +This feature requires GitLab 8.8 and GitLab Runner 1.2. + +Make sure that your GitLab Runner is configured to allow building docker images. +You have to check the [Using Docker Build documentation](../../ci/docker/using_docker_build.md). + +You can use [docker:dind](https://hub.docker.com/_/docker/) to build your images, +and this is how `.gitlab-ci.yml` should look like: + +``` + build_image: + image: docker:git + services: + - docker:dind + stage: build + script: + - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.example.com + - docker build -t registry.example.com/group/project:latest . + - docker push registry.example.com/group/project:latest +``` + +You have to use the credentials of the special `gitlab-ci-token` user with its +password stored in `$CI_BUILD_TOKEN` in order to push to the Registry connected +to your project. This allows you to automated building and deployment of your +Docker images. + +## Limitations + +In order to use a container image from your private project as an `image:` in +your `.gitlab-ci.yml`, you have to follow the +[Using a private Docker Registry][private-docker] +documentation. This workflow will be simplified in the future. + +[ce-4040]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4040 +[docker-docs]: https://docs.docker.com/engine/userguide/intro/ +[private-docker]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#using-a-private-docker-registry diff --git a/doc/container_registry/img/container_registry.png b/doc/container_registry/img/container_registry.png new file mode 100644 index 0000000000000000000000000000000000000000..e9505a73b408e29a78898014ccfc5b5f8eb80bf9 GIT binary patch literal 354050 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¿yocu6{nBG(zm&31W7 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%0DJI1P|T_ms|N|jrz2&pX6BcSQ@*RecwGT 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%0Dh#*9yidui)XgQ(dY-Yv;otVJoofv4-AQ{KntXJh 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 SJV^`;3=E#GelF{r5}E*RO%iAT literal 0 HcmV?d00001 diff --git a/doc/container_registry/img/project_feature.png b/doc/container_registry/img/project_feature.png new file mode 100644 index 0000000000000000000000000000000000000000..57a73d253c0b8ca6c92c80fca13068e5e764a69d GIT binary patch literal 392842 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 _V3}D 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

    +1Wl>#yHmRpzfcYsKgDUwWOk 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

     block' do
    +    create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world")
    +
    +    expect(current_path).to eq(
    +      namespace_project_tag_path(project.namespace, project, 'v3.0'))
    +    expect(page).to have_content 'v3.0'
    +    page.within 'pre.body' do
    +      expect(page).to have_content "Awesome tag message\n\n- hello\n- world"
    +    end
    +  end
    +
    +  scenario 'with multiline release notes parses the release note as Markdown' do
    +    create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world")
    +
    +    expect(current_path).to eq(
    +      namespace_project_tag_path(project.namespace, project, 'v4.0'))
    +    expect(page).to have_content 'v4.0'
    +    page.within '.description' do
    +      expect(page).to have_content 'Awesome release notes'
    +      expect(page).to have_selector('ul li', count: 2)
    +    end
    +  end
    +
    +  def create_tag_in_form(tag:, ref:, message: nil, desc: nil)
    +    click_link 'New tag'
    +    fill_in 'tag_name', with: tag
    +    fill_in 'ref', with: ref
    +    fill_in 'message', with: message unless message.nil?
    +    fill_in 'release_description', with: desc unless desc.nil?
    +    click_button 'Create tag'
    +  end
    +end
    diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb
    new file mode 100644
    index 00000000000000..f0990118e3c04a
    --- /dev/null
    +++ b/spec/features/tags/master_deletes_tag_spec.rb
    @@ -0,0 +1,41 @@
    +require 'spec_helper'
    +
    +feature 'Master deletes tag', feature: true do
    +  let(:user) { create(:user) }
    +  let(:project) { create(:project, namespace: user.namespace) }
    +
    +  before do
    +    project.team << [user, :master]
    +    login_with(user)
    +    visit namespace_project_tags_path(project.namespace, project)
    +  end
    +
    +  context 'from the tags list page' do
    +    scenario 'deletes the tag' do
    +      expect(page).to have_content 'v1.1.0'
    +
    +      page.within('.content') do
    +        first('.btn-remove').click
    +      end
    +
    +      expect(current_path).to eq(
    +        namespace_project_tags_path(project.namespace, project))
    +      expect(page).not_to have_content 'v1.1.0'
    +    end
    +
    +  end
    +
    +  context 'from a specific tag page' do
    +    scenario 'deletes the tag' do
    +      click_on 'v1.0.0'
    +      expect(current_path).to eq(
    +        namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
    +
    +      click_on 'Delete tag'
    +
    +      expect(current_path).to eq(
    +        namespace_project_tags_path(project.namespace, project))
    +      expect(page).not_to have_content 'v1.0.0'
    +    end
    +  end
    +end
    diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb
    new file mode 100644
    index 00000000000000..6b5b3122f72527
    --- /dev/null
    +++ b/spec/features/tags/master_updates_tag_spec.rb
    @@ -0,0 +1,42 @@
    +require 'spec_helper'
    +
    +feature 'Master updates tag', feature: true do
    +  let(:user) { create(:user) }
    +  let(:project) { create(:project, namespace: user.namespace) }
    +
    +  before do
    +    project.team << [user, :master]
    +    login_with(user)
    +    visit namespace_project_tags_path(project.namespace, project)
    +  end
    +
    +  context 'from the tags list page' do
    +    scenario 'updates the release notes' do
    +      page.within(first('.content-list .controls')) do
    +        click_link 'Edit release notes'
    +      end
    +
    +      fill_in 'release_description', with: 'Awesome release notes'
    +      click_button 'Save changes'
    +
    +      expect(current_path).to eq(
    +        namespace_project_tag_path(project.namespace, project, 'v1.1.0'))
    +      expect(page).to have_content 'v1.1.0'
    +      expect(page).to have_content 'Awesome release notes'
    +    end
    +  end
    +
    +  context 'from a specific tag page' do
    +    scenario 'updates the release notes' do
    +      click_on 'v1.1.0'
    +      click_link 'Edit release notes'
    +      fill_in 'release_description', with: 'Awesome release notes'
    +      click_button 'Save changes'
    +
    +      expect(current_path).to eq(
    +        namespace_project_tag_path(project.namespace, project, 'v1.1.0'))
    +      expect(page).to have_content 'v1.1.0'
    +      expect(page).to have_content 'Awesome release notes'
    +    end
    +  end
    +end
    diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb
    new file mode 100644
    index 00000000000000..29d2c244720563
    --- /dev/null
    +++ b/spec/features/tags/master_views_tags_spec.rb
    @@ -0,0 +1,73 @@
    +require 'spec_helper'
    +
    +feature 'Master views tags', feature: true do
    +  let(:user) { create(:user) }
    +
    +  before do
    +    project.team << [user, :master]
    +    login_with(user)
    +  end
    +
    +  context 'when project has no tags' do
    +    let(:project) { create(:project_empty_repo) }
    +    before do
    +      visit namespace_project_path(project.namespace, project)
    +      click_on 'README'
    +      fill_in :commit_message, with: 'Add a README file', visible: true
    +      # Remove pre-receive hook so we can push without auth
    +      FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive'))
    +      click_button 'Commit Changes'
    +      visit namespace_project_tags_path(project.namespace, project)
    +    end
    +
    +    scenario 'displays a specific message' do
    +      expect(page).to have_content 'Repository has no tags yet.'
    +    end
    +  end
    +
    +  context 'when project has tags' do
    +    let(:project) { create(:project, namespace: user.namespace) }
    +    before do
    +      visit namespace_project_tags_path(project.namespace, project)
    +    end
    +
    +    scenario 'views the tags list page' do
    +      expect(page).to have_content 'v1.0.0'
    +    end
    +
    +    scenario 'views a specific tag page' do
    +      click_on 'v1.0.0'
    +
    +      expect(current_path).to eq(
    +        namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
    +      expect(page).to have_content 'v1.0.0'
    +      expect(page).to have_content 'This tag has no release notes.'
    +    end
    +
    +    describe 'links on the tag page' do
    +      scenario 'has a button to browse files' do
    +        click_on 'v1.0.0'
    +
    +        expect(current_path).to eq(
    +          namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
    +
    +        click_on 'Browse files'
    +
    +        expect(current_path).to eq(
    +          namespace_project_tree_path(project.namespace, project, 'v1.0.0'))
    +      end
    +
    +      scenario 'has a button to browse commits' do
    +        click_on 'v1.0.0'
    +
    +        expect(current_path).to eq(
    +          namespace_project_tag_path(project.namespace, project, 'v1.0.0'))
    +
    +        click_on 'Browse commits'
    +
    +        expect(current_path).to eq(
    +          namespace_project_commits_path(project.namespace, project, 'v1.0.0'))
    +      end
    +    end
    +  end
    +end
    diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
    index b7368cca29d0cd..6ed279ef9be6f3 100644
    --- a/spec/features/task_lists_spec.rb
    +++ b/spec/features/task_lists_spec.rb
    @@ -75,7 +75,10 @@ def visit_issue(project, issue)
     
       describe 'for Notes' do
         let!(:issue) { create(:issue, author: user, project: project) }
    -    let!(:note)  { create(:note, note: markdown, noteable: issue, author: user) }
    +    let!(:note) do
    +      create(:note, note: markdown, noteable: issue,
    +                    project: project, author: user)
    +    end
     
         it 'renders for note body' do
           visit_issue(project, issue)
    diff --git a/spec/features/todos/target_state_spec.rb b/spec/features/todos/target_state_spec.rb
    new file mode 100644
    index 00000000000000..72491ac7e61f2b
    --- /dev/null
    +++ b/spec/features/todos/target_state_spec.rb
    @@ -0,0 +1,65 @@
    +require 'rails_helper'
    +
    +feature 'Todo target states', feature: true do
    +  let(:user)    { create(:user) }
    +  let(:author)  { create(:user) }
    +  let(:project) { create(:project) }
    +
    +  before do
    +    login_as user
    +  end
    +
    +  scenario 'on a closed issue todo has closed label' do
    +    issue_closed = create(:issue, state: 'closed')
    +    create_todo issue_closed
    +    visit dashboard_todos_path
    +
    +    page.within '.todos-list' do
    +      expect(page).to have_content('Closed')
    +    end
    +  end
    +
    +  scenario 'on an open issue todo does not have an open label' do
    +    issue_open = create(:issue)
    +    create_todo issue_open
    +    visit dashboard_todos_path
    +
    +    page.within '.todos-list' do
    +      expect(page).not_to have_content('Open')
    +    end
    +  end
    +
    +  scenario 'on a merged merge request todo has merged label' do
    +    mr_merged = create(:merge_request, :simple, author: user, state: 'merged')
    +    create_todo mr_merged
    +    visit dashboard_todos_path
    +
    +    page.within '.todos-list' do
    +      expect(page).to have_content('Merged')
    +    end
    +  end
    +
    +  scenario 'on a closed merge request todo has closed label' do
    +    mr_closed = create(:merge_request, :simple, author: user, state: 'closed')
    +    create_todo mr_closed
    +    visit dashboard_todos_path
    +
    +    page.within '.todos-list' do
    +      expect(page).to have_content('Closed')
    +    end
    +  end
    +
    +  scenario 'on an open merge request todo does not have an open label' do
    +    mr_open = create(:merge_request, :simple, author: user)
    +    create_todo mr_open
    +    visit dashboard_todos_path
    +
    +    page.within '.todos-list' do
    +      expect(page).not_to have_content('Open')
    +    end
    +  end
    +
    +  def create_todo(target)
    +    create(:todo, :mentioned, user: user, project: project, target: target, author: author)
    +  end
    +end
    diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb
    index 3354f529295656..4e627753cc7c3e 100644
    --- a/spec/features/todos/todos_spec.rb
    +++ b/spec/features/todos/todos_spec.rb
    @@ -43,6 +43,27 @@
           end
         end
     
    +    context 'User has Todos with labels spanning multiple projects' do
    +      before do
    +        label1 = create(:label, project: project)
    +        note1 = create(:note_on_issue, note: "Hello #{label1.to_reference(format: :name)}", noteable_id: issue.id, noteable_type: 'Issue', project: issue.project)
    +        create(:todo, :mentioned, project: project, target: issue, user: user, note_id: note1.id)
    +
    +        project2 = create(:project)
    +        label2 = create(:label, project: project2)
    +        issue2 = create(:issue, project: project2)
    +        note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2)
    +        create(:todo, :mentioned, project: project2, target: issue2, user: user, note_id: note2.id)
    +
    +        login_as(user)
    +        visit dashboard_todos_path
    +      end
    +
    +      it 'shows page with two Todos' do
    +        expect(page).to have_selector('.todos-list .todo', count: 2)
    +      end
    +    end
    +
         context 'User has multiple pages of Todos' do
           before do
             allow(Todo).to receive(:default_per_page).and_return(1)
    diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb
    index afea1840cd742d..a2b8f7b6931ffb 100644
    --- a/spec/features/variables_spec.rb
    +++ b/spec/features/variables_spec.rb
    @@ -1,24 +1,53 @@
     require 'spec_helper'
     
    -describe "Variables" do
    -  let(:user) { create(:user) }
    -  before { login_as(user) }
    -
    -  describe "specific runners" do
    -    before do
    -      @project = FactoryGirl.create :empty_project
    -      @project.team << [user, :master]
    +describe 'Project variables', js: true do
    +  let(:user)     { create(:user) }
    +  let(:project)  { create(:project) }
    +  let(:variable) { create(:ci_variable, key: 'test') }
    +
    +  before do
    +    login_as(user)
    +    project.team << [user, :master]
    +    project.variables << variable
    +
    +    visit namespace_project_variables_path(project.namespace, project)
    +  end
    +
    +  it 'should show list of variables' do
    +    page.within('.variables-table') do
    +      expect(page).to have_content(variable.key)
    +    end
    +  end
    +
    +  it 'should add new variable' do
    +    fill_in('variable_key', with: 'key')
    +    fill_in('variable_value', with: 'key value')
    +    click_button('Add new variable')
    +
    +    page.within('.variables-table') do
    +      expect(page).to have_content('key')
    +    end
    +  end
    +
    +  it 'should delete variable' do
    +    page.within('.variables-table') do
    +      find('.btn-variable-delete').click
    +    end
    +
    +    expect(page).not_to have_selector('variables-table')
    +  end
    +
    +  it 'should edit variable' do
    +    page.within('.variables-table') do
    +      find('.btn-variable-edit').click
         end
     
    -    it "creates variable", js: true do
    -      visit namespace_project_variables_path(@project.namespace, @project)
    -      click_on "Add a variable"
    -      fill_in "Key", with: "SECRET_KEY"
    -      fill_in "Value", with: "SECRET_VALUE"
    -      click_on "Save changes"
    +    fill_in('variable_key', with: 'key')
    +    fill_in('variable_value', with: 'key value')
    +    click_button('Save variable')
     
    -      expect(page).to have_content("Variables were successfully updated.")
    -      expect(@project.variables.count).to eq(1)
    +    page.within('.variables-table') do
    +      expect(page).to have_content('key')
         end
       end
     end
    diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
    index bc607a29751d85..ec8809e6926c39 100644
    --- a/spec/finders/issues_finder_spec.rb
    +++ b/spec/finders/issues_finder_spec.rb
    @@ -1,10 +1,10 @@
     require 'spec_helper'
     
     describe IssuesFinder do
    -  let(:user) { create :user }
    -  let(:user2) { create :user }
    -  let(:project1) { create(:project) }
    -  let(:project2) { create(:project) }
    +  let(:user) { create(:user) }
    +  let(:user2) { create(:user) }
    +  let(:project1) { create(:empty_project) }
    +  let(:project2) { create(:empty_project) }
       let(:milestone) { create(:milestone, project: project1) }
       let(:label) { create(:label, project: project2) }
       let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) }
    @@ -16,101 +16,147 @@
         project1.team << [user, :master]
         project2.team << [user, :developer]
         project2.team << [user2, :developer]
    +
    +    issue1
    +    issue2
    +    issue3
       end
     
    -  describe :execute do
    -    before :each do
    -      issue1
    -      issue2
    -      issue3
    -    end
    +  describe '#execute' do
    +    let(:search_user) { user }
    +    let(:params) { {} }
    +    let(:issues) { IssuesFinder.new(search_user, params.merge(scope: scope, state: 'opened')).execute }
     
         context 'scope: all' do
    -      it 'should filter by all' do
    -        params = { scope: "all", state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues.size).to eq(3)
    +      let(:scope) { 'all' }
    +
    +      it 'returns all issues' do
    +        expect(issues).to contain_exactly(issue1, issue2, issue3)
           end
     
    -      it 'should filter by assignee id' do
    -        params = { scope: "all", assignee_id: user.id, state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues.size).to eq(2)
    +      context 'filtering by assignee ID' do
    +        let(:params) { { assignee_id: user.id } }
    +
    +        it 'returns issues assigned to that user' do
    +          expect(issues).to contain_exactly(issue1, issue2)
    +        end
           end
     
    -      it 'should filter by author id' do
    -        params = { scope: "all", author_id: user2.id, state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues).to eq([issue3])
    +      context 'filtering by author ID' do
    +        let(:params) { { author_id: user2.id } }
    +
    +        it 'returns issues created by that user' do
    +          expect(issues).to contain_exactly(issue3)
    +        end
           end
     
    -      it 'should filter by milestone id' do
    -        params = { scope: "all", milestone_title: milestone.title, state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues).to eq([issue1])
    +      context 'filtering by milestone' do
    +        let(:params) { { milestone_title: milestone.title } }
    +
    +        it 'returns issues assigned to that milestone' do
    +          expect(issues).to contain_exactly(issue1)
    +        end
           end
     
    -      it 'should filter by no milestone id' do
    -        params = { scope: "all", milestone_title: Milestone::None.title, state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues).to match_array([issue2, issue3])
    +      context 'filtering by no milestone' do
    +        let(:params) { { milestone_title: Milestone::None.title } }
    +
    +        it 'returns issues with no milestone' do
    +          expect(issues).to contain_exactly(issue2, issue3)
    +        end
           end
     
    -      it 'should filter by label name' do
    -        params = { scope: "all", label_name: label.title, state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues).to eq([issue2])
    +      context 'filtering by upcoming milestone' do
    +        let(:params) { { milestone_title: Milestone::Upcoming.name } }
    +
    +        let(:project_no_upcoming_milestones) { create(:empty_project, :public) }
    +        let(:project_next_1_1) { create(:empty_project, :public) }
    +        let(:project_next_8_8) { create(:empty_project, :public) }
    +
    +        let(:yesterday) { Date.today - 1.day }
    +        let(:tomorrow) { Date.today + 1.day }
    +        let(:two_days_from_now) { Date.today + 2.days }
    +        let(:ten_days_from_now) { Date.today + 10.days }
    +
    +        let(:milestones) do
    +          [
    +            create(:milestone, :closed, project: project_no_upcoming_milestones),
    +            create(:milestone, project: project_next_1_1, title: '1.1', due_date: two_days_from_now),
    +            create(:milestone, project: project_next_1_1, title: '8.8', due_date: ten_days_from_now),
    +            create(:milestone, project: project_next_8_8, title: '1.1', due_date: yesterday),
    +            create(:milestone, project: project_next_8_8, title: '8.8', due_date: tomorrow)
    +          ]
    +        end
    +
    +        before do
    +          milestones.each do |milestone|
    +            create(:issue, project: milestone.project, milestone: milestone, author: user, assignee: user)
    +          end
    +        end
    +
    +        it 'returns issues in the upcoming milestone for each project' do
    +          expect(issues.map { |issue| issue.milestone.title }).to contain_exactly('1.1', '8.8')
    +          expect(issues.map { |issue| issue.milestone.due_date }).to contain_exactly(tomorrow, two_days_from_now)
    +        end
           end
     
    -      it 'returns unique issues when filtering by multiple labels' do
    -        label2 = create(:label, project: project2)
    +      context 'filtering by label' do
    +        let(:params) { { label_name: label.title } }
     
    -        create(:label_link, label: label2, target: issue2)
    +        it 'returns issues with that label' do
    +          expect(issues).to contain_exactly(issue2)
    +        end
    +      end
     
    -        params = {
    -          scope:      'all',
    -          label_name: [label.title, label2.title].join(','),
    -          state:      'opened'
    -        }
    +      context 'filtering by multiple labels' do
    +        let(:params) { { label_name: [label.title, label2.title].join(',') } }
    +        let(:label2) { create(:label, project: project2) }
     
    -        issues = IssuesFinder.new(user, params).execute
    +        before { create(:label_link, label: label2, target: issue2) }
     
    -        expect(issues).to eq([issue2])
    +        it 'returns the unique issues with any of those labels' do
    +          expect(issues).to contain_exactly(issue2)
    +        end
           end
     
    -      it 'should filter by no label name' do
    -        params = { scope: "all", label_name: Label::None.title, state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues).to match_array([issue1, issue3])
    +      context 'filtering by no label' do
    +        let(:params) { { label_name: Label::None.title } }
    +
    +        it 'returns issues with no labels' do
    +          expect(issues).to contain_exactly(issue1, issue3)
    +        end
           end
     
    -      it 'should be empty for unauthorized user' do
    -        params = { scope: "all", state: 'opened' }
    -        issues = IssuesFinder.new(nil, params).execute
    -        expect(issues.size).to be_zero
    +      context 'when the user is unauthorized' do
    +        let(:search_user) { nil }
    +
    +        it 'returns no results' do
    +          expect(issues).to be_empty
    +        end
           end
     
    -      it 'should not include unauthorized issues' do
    -        params = { scope: "all", state: 'opened' }
    -        issues = IssuesFinder.new(user2, params).execute
    -        expect(issues.size).to eq(2)
    -        expect(issues).not_to include(issue1)
    -        expect(issues).to include(issue2)
    -        expect(issues).to include(issue3)
    +      context 'when the user can see some, but not all, issues' do
    +        let(:search_user) { user2 }
    +
    +        it 'returns only issues they can see' do
    +          expect(issues).to contain_exactly(issue2, issue3)
    +        end
           end
         end
     
         context 'personal scope' do
    -      it 'should filter by assignee' do
    -        params = { scope: "assigned-to-me", state: 'opened' }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues.size).to eq(2)
    +      let(:scope) { 'assigned-to-me' }
    +
    +      it 'returns issue assigned to the user' do
    +        expect(issues).to contain_exactly(issue1, issue2)
           end
     
    -      it 'should filter by project' do
    -        params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id }
    -        issues = IssuesFinder.new(user, params).execute
    -        expect(issues.size).to eq(1)
    +      context 'filtering by project' do
    +        let(:params) { { project_id: project1.id } }
    +
    +        it 'returns issues assigned to the user in that project' do
    +          expect(issues).to contain_exactly(issue1)
    +        end
           end
         end
       end
    diff --git a/spec/fixtures/container_registry/config_blob.json b/spec/fixtures/container_registry/config_blob.json
    new file mode 100644
    index 00000000000000..1028c994a24b66
    --- /dev/null
    +++ b/spec/fixtures/container_registry/config_blob.json
    @@ -0,0 +1 @@
    +{"architecture":"amd64","config":{"Hostname":"b14cd8298755","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"b14cd82987550b01af9a666a2f4c996280a6152e66873134fae5a0f223dc5976","container_config":{"Hostname":"b14cd8298755","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh","-c","#(nop) ADD file:033ab063740d9ff4dcfb1c69eccf25f91d88729f57cd5a73050e014e3e094aa0 in /"],"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"created":"2016-04-01T20:53:00.160300546Z","docker_version":"1.9.1","history":[{"created":"2016-04-01T20:53:00.160300546Z","created_by":"/bin/sh -c #(nop) ADD file:033ab063740d9ff4dcfb1c69eccf25f91d88729f57cd5a73050e014e3e094aa0 in /"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:c56b7dabbc7aa730eeab07668bdcbd7e3d40855047ca9a0cc1bfed23a2486111"]}}
    diff --git a/spec/fixtures/container_registry/tag_manifest.json b/spec/fixtures/container_registry/tag_manifest.json
    new file mode 100644
    index 00000000000000..1b6008e2872606
    --- /dev/null
    +++ b/spec/fixtures/container_registry/tag_manifest.json
    @@ -0,0 +1 @@
    +{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/octet-stream","size":1145,"digest":"sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac"},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","size":2319870,"digest":"sha256:420890c9e918b6668faaedd9000e220190f2493b0693ee563ebd7b4cc754a57d"}]}
    diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb
    index 1772cc3f6a4a30..34ce7c4f033428 100644
    --- a/spec/fixtures/markdown.md.erb
    +++ b/spec/fixtures/markdown.md.erb
    @@ -216,10 +216,14 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e
     
     #### MilestoneReferenceFilter
     
    -- Milestone: <%= milestone.to_reference %>
    +- Milestone by ID: <%= simple_milestone.to_reference %>
    +- Milestone by name: <%= Milestone.reference_prefix %><%= simple_milestone.name %>
    +- Milestone by name in quotes: <%= milestone.to_reference(format: :name) %>
     - Milestone in another project: <%= xmilestone.to_reference(project) %>
    -- Ignored in code: `<%= milestone.to_reference %>`
    -- Link to milestone by URL: [Milestone](<%= urls.namespace_project_milestone_url(milestone.project.namespace, milestone.project, milestone) %>)
    +- Ignored in code: `<%= simple_milestone.to_reference %>`
    +- Ignored in links: [Link to <%= simple_milestone.to_reference %>](#milestone-link)
    +- Milestone by URL: <%= urls.namespace_project_milestone_url(milestone.project.namespace, milestone.project, milestone) %>
    +- Link to milestone by URL: [Milestone](<%= milestone.to_reference %>)
     
     ### Task Lists
     
    @@ -239,3 +243,16 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e
     - [[link-text|http://example.com/pdfs/gollum.pdf]]
     - [[images/example.jpg]]
     - [[http://example.com/images/example.jpg]]
    +
    +### Inline Diffs
    +
    +With inline diffs tags you can display {+ additions +} or [- deletions -].
    +
    +The wrapping tags can be either curly braces or square brackets [+ additions +] or {- deletions -}.
    +
    +However the wrapping tags can not be mixed as such -
    +
    +- {+ additions +]
    +- [+ additions +}
    +- {- delletions -]
    +- [- delletions -}
    diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb
    index e47a54fdac5e27..49ea4fa6d3e18c 100644
    --- a/spec/helpers/auth_helper_spec.rb
    +++ b/spec/helpers/auth_helper_spec.rb
    @@ -2,7 +2,7 @@
     
     describe AuthHelper do
       describe "button_based_providers" do
    -    it 'returns all enabled providers' do
    +    it 'returns all enabled providers from devise' do
           allow(helper).to receive(:auth_providers) { [:twitter, :github] }
           expect(helper.button_based_providers).to include(*[:twitter, :github])
         end
    @@ -17,4 +17,49 @@
           expect(helper.button_based_providers).to eq([])
         end
       end
    +
    +  describe 'enabled_button_based_providers' do
    +    before do
    +      allow(helper).to receive(:auth_providers) { [:twitter, :github] }
    +    end
    +
    +    context 'all providers are enabled to sign in' do
    +      it 'returns all the enabled providers from settings' do
    +        expect(helper.enabled_button_based_providers).to include('twitter', 'github')
    +      end
    +    end
    +
    +    context 'GitHub OAuth sign in is disabled from application setting' do
    +      it "doesn't return github as provider" do
    +        stub_application_setting(
    +          disabled_oauth_sign_in_sources: ['github']
    +        )
    +
    +        expect(helper.enabled_button_based_providers).to include('twitter')
    +        expect(helper.enabled_button_based_providers).not_to include('github')
    +      end
    +    end
    +  end
    +
    +  describe 'button_based_providers_enabled?' do
    +    before do
    +      allow(helper).to receive(:auth_providers) { [:twitter, :github] }
    +    end
    +
    +    context 'button based providers enabled' do
    +      it 'returns true' do
    +        expect(helper.button_based_providers_enabled?).to be true
    +      end
    +    end
    +
    +    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']
    +        )
    +
    +        expect(helper.button_based_providers_enabled?).to be false
    +      end
    +    end
    +  end
     end
    diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
    index b7810185d168bf..52764f41e0ddd8 100644
    --- a/spec/helpers/diff_helper_spec.rb
    +++ b/spec/helpers/diff_helper_spec.rb
    @@ -93,9 +93,9 @@
         it "returns strings with marked inline diffs" do
           marked_old_line, marked_new_line = mark_inline_diffs(old_line, new_line)
     
    -      expect(marked_old_line).to eq("abc 'def'")
    +      expect(marked_old_line).to eq("abc 'def'")
           expect(marked_old_line).to be_html_safe
    -      expect(marked_new_line).to eq("abc "def"")
    +      expect(marked_new_line).to eq("abc "def"")
           expect(marked_new_line).to be_html_safe
         end
       end
    diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb
    index e68a5ec29ab63b..c0d2be98e85e6d 100644
    --- a/spec/helpers/events_helper_spec.rb
    +++ b/spec/helpers/events_helper_spec.rb
    @@ -1,64 +1,65 @@
     require 'spec_helper'
     
     describe EventsHelper do
    -  include ApplicationHelper
    -  include GitlabMarkdownHelper
    +  describe '#event_note' do
    +    before do
    +      allow(helper).to receive(:current_user).and_return(double)
    +    end
     
    -  let(:current_user) { create(:user, email: "current@email.com") }
    +    it 'should display one line of plain text without alteration' do
    +      input = 'A short, plain note'
    +      expect(helper.event_note(input)).to match(input)
    +      expect(helper.event_note(input)).not_to match(/\.\.\.\z/)
    +    end
     
    -  it 'should display one line of plain text without alteration' do
    -    input = 'A short, plain note'
    -    expect(event_note(input)).to match(input)
    -    expect(event_note(input)).not_to match(/\.\.\.\z/)
    -  end
    +    it 'should display inline code' do
    +      input = 'A note with `inline code`'
    +      expected = 'A note with inline code'
     
    -  it 'should display inline code' do
    -    input = 'A note with `inline code`'
    -    expected = 'A note with inline code'
    +      expect(helper.event_note(input)).to match(expected)
    +    end
     
    -    expect(event_note(input)).to match(expected)
    -  end
    +    it 'should truncate a note with multiple paragraphs' do
    +      input = "Paragraph 1\n\nParagraph 2"
    +      expected = 'Paragraph 1...'
     
    -  it 'should truncate a note with multiple paragraphs' do
    -    input = "Paragraph 1\n\nParagraph 2"
    -    expected = 'Paragraph 1...'
    +      expect(helper.event_note(input)).to match(expected)
    +    end
     
    -    expect(event_note(input)).to match(expected)
    -  end
    +    it 'should display the first line of a code block' do
    +      input = "```\nCode block\nwith two lines\n```"
    +      expected = %r{Code block\.\.\.
    } - it 'should display the first line of a code block' do - input = "```\nCode block\nwith two lines\n```" - expected = %r{Code block\.\.\.} + expect(helper.event_note(input)).to match(expected) + end - expect(event_note(input)).to match(expected) - end + it 'should truncate a single long line of text' do + text = 'The quick brown fox jumped over the lazy dog twice' # 50 chars + input = text * 4 + expected = (text * 2).sub(/.{3}/, '...') - it 'should truncate a single long line of text' do - text = 'The quick brown fox jumped over the lazy dog twice' # 50 chars - input = "#{text}#{text}#{text}#{text}" # 200 chars - expected = "#{text}#{text}".sub(/.{3}/, '...') + expect(helper.event_note(input)).to match(expected) + end - expect(event_note(input)).to match(expected) - end - - it 'should preserve a link href when link text is truncated' do - text = 'The quick brown fox jumped over the lazy dog' # 44 chars - input = "#{text}#{text}#{text} " # 133 chars - link_url = 'http://example.com/foo/bar/baz' # 30 chars - input << link_url - expected_link_text = 'http://example...' + it 'should preserve a link href when link text is truncated' do + text = 'The quick brown fox jumped over the lazy dog' # 44 chars + input = "#{text}#{text}#{text} " # 133 chars + link_url = 'http://example.com/foo/bar/baz' # 30 chars + input << link_url + expected_link_text = 'http://example...' - expect(event_note(input)).to match(link_url) - expect(event_note(input)).to match(expected_link_text) - end + expect(helper.event_note(input)).to match(link_url) + expect(helper.event_note(input)).to match(expected_link_text) + end - it 'should preserve code color scheme' do - input = "```ruby\ndef test\n 'hello world'\nend\n```" - expected = '
    ' \
    -      "def test\n" \
    -      "  \'hello world\'\n" \
    -      "end" \
    -      '
    ' - expect(event_note(input)).to eq(expected) + it 'should preserve code color scheme' do + input = "```ruby\ndef test\n 'hello world'\nend\n```" + expected = '
    ' \
    +        "def test\n" \
    +        "  \'hello world\'\n" \
    +        "end" \
    +        '
    ' + expect(helper.event_note(input)).to eq(expected) + end end end diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index 600e1c4e9ecf17..8e7ed42e883a05 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -17,7 +17,7 @@ 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") - expect(helper.ci_build_details_path(merge_request)).to_not match("secret") + expect(helper.ci_build_details_path(merge_request)).not_to match("secret") end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 29bcb8c58924de..ac5af8740dc142 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -88,18 +88,18 @@ end describe 'default_clone_protocol' do - describe 'using HTTP' do + context 'when user is not logged in and gitlab protocol is HTTP' do it 'returns HTTP' do - expect(helper).to receive(:current_user).and_return(nil) + allow(helper).to receive(:current_user).and_return(nil) expect(helper.send(:default_clone_protocol)).to eq('http') end end - describe 'using HTTPS' do + context 'when user is not logged in and gitlab protocol is HTTPS' do it 'returns HTTPS' do - allow(Gitlab.config.gitlab).to receive(:protocol).and_return('https') - expect(helper).to receive(:current_user).and_return(nil) + stub_config_setting(protocol: 'https') + allow(helper).to receive(:current_user).and_return(nil) expect(helper.send(:default_clone_protocol)).to eq('https') end diff --git a/spec/javascripts/fixtures/right_sidebar.html.haml b/spec/javascripts/fixtures/right_sidebar.html.haml new file mode 100644 index 00000000000000..95efaff4b694cb --- /dev/null +++ b/spec/javascripts/fixtures/right_sidebar.html.haml @@ -0,0 +1,13 @@ +%div + %div.page-gutter.page-with-sidebar + + %aside.right-sidebar + %div.block.issuable-sidebar-header + %a.gutter-toggle.pull-right.js-sidebar-toggle + %i.fa.fa-angle-double-left + + %form.issuable-context-form + %div.block.labels + %div.sidebar-collapsed-icon + %i.fa.fa-tags + %span 1 diff --git a/spec/javascripts/stat_graph_contributors_graph_spec.js b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js similarity index 98% rename from spec/javascripts/stat_graph_contributors_graph_spec.js rename to spec/javascripts/graphs/stat_graph_contributors_graph_spec.js index 78d39f1b4280d6..82ee1954a597e4 100644 --- a/spec/javascripts/stat_graph_contributors_graph_spec.js +++ b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js @@ -1,4 +1,4 @@ -//= require stat_graph_contributors_graph +//= require graphs/stat_graph_contributors_graph describe("ContributorsGraph", function () { describe("#set_x_domain", function () { diff --git a/spec/javascripts/stat_graph_contributors_util_spec.js b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js similarity index 99% rename from spec/javascripts/stat_graph_contributors_util_spec.js rename to spec/javascripts/graphs/stat_graph_contributors_util_spec.js index dbafe782b77332..5b992447473e09 100644 --- a/spec/javascripts/stat_graph_contributors_util_spec.js +++ b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js @@ -1,4 +1,4 @@ -//= require stat_graph_contributors_util +//= require graphs/stat_graph_contributors_util describe("ContributorsStatGraphUtil", function () { diff --git a/spec/javascripts/stat_graph_spec.js b/spec/javascripts/graphs/stat_graph_spec.js similarity index 92% rename from spec/javascripts/stat_graph_spec.js rename to spec/javascripts/graphs/stat_graph_spec.js index 4c652910cd6f43..4b05d401a428fb 100644 --- a/spec/javascripts/stat_graph_spec.js +++ b/spec/javascripts/graphs/stat_graph_spec.js @@ -1,4 +1,4 @@ -//= require stat_graph +//= require graphs/stat_graph describe("StatGraph", function () { diff --git a/spec/javascripts/project_title_spec.js.coffee b/spec/javascripts/project_title_spec.js.coffee index 3d8de2ff989bde..1cf34d4d2d3343 100644 --- a/spec/javascripts/project_title_spec.js.coffee +++ b/spec/javascripts/project_title_spec.js.coffee @@ -1,5 +1,6 @@ #= require bootstrap #= require select2 +#= require lib/type_utility #= require gl_dropdown #= require api #= require project_select diff --git a/spec/javascripts/right_sidebar_spec.js.coffee b/spec/javascripts/right_sidebar_spec.js.coffee new file mode 100644 index 00000000000000..2075cacdb67414 --- /dev/null +++ b/spec/javascripts/right_sidebar_spec.js.coffee @@ -0,0 +1,69 @@ +#= require right_sidebar +#= require jquery +#= require jquery.cookie + +@sidebar = null +$aside = null +$toggle = null +$icon = null +$page = null +$labelsIcon = null + + +assertSidebarState = (state) -> + + shouldBeExpanded = state is 'expanded' + shouldBeCollapsed = state is 'collapsed' + + expect($aside.hasClass('right-sidebar-expanded')).toBe shouldBeExpanded + expect($page.hasClass('right-sidebar-expanded')).toBe shouldBeExpanded + expect($icon.hasClass('fa-angle-double-right')).toBe shouldBeExpanded + + expect($aside.hasClass('right-sidebar-collapsed')).toBe shouldBeCollapsed + expect($page.hasClass('right-sidebar-collapsed')).toBe shouldBeCollapsed + expect($icon.hasClass('fa-angle-double-left')).toBe shouldBeCollapsed + + +describe 'RightSidebar', -> + + fixture.preload 'right_sidebar.html' + + beforeEach -> + fixture.load 'right_sidebar.html' + + @sidebar = new Sidebar + $aside = $ '.right-sidebar' + $page = $ '.page-with-sidebar' + $icon = $aside.find 'i' + $toggle = $aside.find '.js-sidebar-toggle' + $labelsIcon = $aside.find '.sidebar-collapsed-icon' + + + it 'should expand the sidebar when arrow is clicked', -> + + $toggle.click() + assertSidebarState 'expanded' + + + it 'should collapse the sidebar when arrow is clicked', -> + + $toggle.click() + assertSidebarState 'expanded' + + $toggle.click() + assertSidebarState 'collapsed' + + + it 'should float over the page and when sidebar icons clicked', -> + + $labelsIcon.click() + assertSidebarState 'expanded' + + + it 'should collapse when the icon arrow clicked while it is floating on page', -> + + $labelsIcon.click() + assertSidebarState 'expanded' + + $toggle.click() + assertSidebarState 'collapsed' diff --git a/spec/lib/award_emoji_spec.rb b/spec/lib/award_emoji_spec.rb index 88c22912950610..c309857429225f 100644 --- a/spec/lib/award_emoji_spec.rb +++ b/spec/lib/award_emoji_spec.rb @@ -5,7 +5,7 @@ subject { AwardEmoji.urls } it { is_expected.to be_an_instance_of(Array) } - it { is_expected.to_not be_empty } + it { is_expected.not_to be_empty } context 'every Hash in the Array' do it 'has the correct keys and values' do 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 c2a8ad36c3057f..593bd6d5cac994 100644 --- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb @@ -98,11 +98,6 @@ expect(link).not_to match %r(https?://) expect(link).to eq urls.namespace_project_compare_url(project.namespace, project, from: commit1.id, to: commit2.id, only_path: true) end - - it 'adds to the results hash' do - result = reference_pipeline_result("See #{reference}") - expect(result[:references][:commit_range]).not_to be_empty - end end context 'cross-project reference' do @@ -135,11 +130,6 @@ exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}" expect(reference_filter(act).to_html).to eq exp end - - it 'adds to the results hash' do - result = reference_pipeline_result("See #{reference}") - expect(result[:references][:commit_range]).not_to be_empty - end end context 'cross-project URL reference' do @@ -173,10 +163,5 @@ exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}" expect(reference_filter(act).to_html).to eq exp end - - it 'adds to the results hash' do - result = reference_pipeline_result("See #{reference}") - expect(result[:references][:commit_range]).not_to be_empty - end end end diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb index 63a32d9d455ea9..d46d3f1489e40a 100644 --- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb @@ -93,11 +93,6 @@ expect(link).not_to match %r(https?://) expect(link).to eq urls.namespace_project_commit_url(project.namespace, project, reference, only_path: true) end - - it 'adds to the results hash' do - result = reference_pipeline_result("See #{reference}") - expect(result[:references][:commit]).not_to be_empty - end end context 'cross-project reference' do @@ -124,11 +119,6 @@ exp = act = "Committed #{invalidate_reference(reference)}" expect(reference_filter(act).to_html).to eq exp end - - it 'adds to the results hash' do - result = reference_pipeline_result("See #{reference}") - expect(result[:references][:commit]).not_to be_empty - end end context 'cross-project URL reference' do @@ -154,10 +144,5 @@ act = "Committed #{invalidate_reference(reference)}" expect(reference_filter(act).to_html).to match(/#{Regexp.escape(invalidate_reference(reference))}<\/a>/) end - - it 'adds to the results hash' do - result = reference_pipeline_result("See #{reference}") - expect(result[:references][:commit]).not_to be_empty - end end end diff --git a/spec/lib/banzai/filter/inline_diff_filter_spec.rb b/spec/lib/banzai/filter/inline_diff_filter_spec.rb new file mode 100644 index 00000000000000..9e526371294667 --- /dev/null +++ b/spec/lib/banzai/filter/inline_diff_filter_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe Banzai::Filter::InlineDiffFilter, lib: true do + include FilterSpecHelper + + it 'adds inline diff span tags for deletions when using square brackets' do + doc = "START [-something deleted-] END" + expect(filter(doc).to_html).to eq('START something deleted END') + end + + it 'adds inline diff span tags for deletions when using curley braces' do + doc = "START {-something deleted-} END" + expect(filter(doc).to_html).to eq('START something deleted END') + end + + it 'does not add inline diff span tags when a closing tag is not provided' do + doc = "START [- END" + expect(filter(doc).to_html).to eq(doc) + end + + it 'adds inline span tags for additions when using square brackets' do + doc = "START [+something added+] END" + expect(filter(doc).to_html).to eq('START something added END') + end + + it 'adds inline span tags for additions when using curley braces' do + doc = "START {+something added+} END" + expect(filter(doc).to_html).to eq('START something added END') + end + + it 'does not add inline diff span tags when a closing addition tag is not provided' do + doc = "START {+ END" + expect(filter(doc).to_html).to eq(doc) + end + + it 'does not add inline diff span tags when the tags do not match' do + examples = [ + "{+ additions +]", + "[+ additions +}", + "{- delletions -]", + "[- delletions -}" + ] + + examples.each do |doc| + expect(filter(doc).to_html).to eq(doc) + end + end + + it 'prevents user-land html being injected' do + doc = "START {+<script>alert('I steal cookies')</script>+} END" + expect(filter(doc).to_html).to eq("START <script>alert('I steal cookies')</script> END") + end + + it 'preserves content inside pre tags' do + doc = "
    START {+something added+} END
    " + expect(filter(doc).to_html).to eq(doc) + end + + it 'preserves content inside code tags' do + doc = "START {+something added+} END" + expect(filter(doc).to_html).to eq(doc) + end + + it 'preserves content inside tt tags' do + doc = "START {+something added+} END" + expect(filter(doc).to_html).to eq(doc) + end +end diff --git a/spec/lib/banzai/filter/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/issue_reference_filter_spec.rb index 266ebef33d6154..8e6a264970d0c6 100644 --- a/spec/lib/banzai/filter/issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/issue_reference_filter_spec.rb @@ -91,11 +91,6 @@ def helper expect(link).to eq helper.url_for_issue(issue.iid, project, only_path: true) end - it 'adds to the results hash' do - result = reference_pipeline_result("Fixed #{reference}") - expect(result[:references][:issue]).to eq [issue] - end - it 'does not process links containing issue numbers followed by text' do href = "#{reference}st" doc = reference_filter("") @@ -136,11 +131,6 @@ def helper expect(reference_filter(act).to_html).to eq exp end - - it 'adds to the results hash' do - result = reference_pipeline_result("Fixed #{reference}") - expect(result[:references][:issue]).to eq [issue] - end end context 'cross-project URL reference' do @@ -160,11 +150,6 @@ def helper doc = reference_filter("Fixed (#{reference}.)") expect(doc.to_html).to match(/\(#{Regexp.escape(issue.to_reference(project))} \(comment 123\)<\/a>\.\)/) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Fixed #{reference}") - expect(result[:references][:issue]).to eq [issue] - end end context 'cross-project reference in link href' do @@ -184,11 +169,6 @@ def helper doc = reference_filter("Fixed (#{reference}.)") expect(doc.to_html).to match(/\(Reference<\/a>\.\)/) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Fixed #{reference}") - expect(result[:references][:issue]).to eq [issue] - end end context 'cross-project URL in link href' do @@ -208,10 +188,5 @@ def helper doc = reference_filter("Fixed (#{reference}.)") expect(doc.to_html).to match(/\(Reference<\/a>\.\)/) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Fixed #{reference}") - expect(result[:references][:issue]).to eq [issue] - 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 b0a38e7c2510b8..f1064a701d8ca2 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -48,11 +48,6 @@ expect(link).to eq urls.namespace_project_issues_path(project.namespace, project, label_name: label.name) end - it 'adds to the results hash' do - result = reference_pipeline_result("Label #{reference}") - expect(result[:references][:label]).to eq [label] - end - describe 'label span element' do it 'includes default classes' do doc = reference_filter("Label #{reference}") @@ -170,11 +165,6 @@ expect(link).to have_attribute('data-label') expect(link.attr('data-label')).to eq label.id.to_s end - - it 'adds to the results hash' do - result = reference_pipeline_result("Label #{reference}") - expect(result[:references][:label]).to eq [label] - end end describe 'cross project label references' 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 352710df3071fc..3185e41fe5c2d2 100644 --- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb @@ -78,11 +78,6 @@ expect(link).not_to match %r(https?://) expect(link).to eq urls.namespace_project_merge_request_url(project.namespace, project, merge, only_path: true) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Merge #{reference}") - expect(result[:references][:merge_request]).to eq [merge] - end end context 'cross-project reference' do @@ -109,11 +104,6 @@ expect(reference_filter(act).to_html).to eq exp end - - it 'adds to the results hash' do - result = reference_pipeline_result("Merge #{reference}") - expect(result[:references][:merge_request]).to eq [merge] - end end context 'cross-project URL reference' do @@ -133,10 +123,5 @@ doc = reference_filter("Merge (#{reference}.)") expect(doc.to_html).to match(/\(#{Regexp.escape(merge.to_reference(project))} \(diffs, comment 123\)<\/a>\.\)/) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Merge #{reference}") - expect(result[:references][:merge_request]).to eq [merge] - end end end diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index ebf3d7489b53ad..9424f2363e1c4d 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -3,8 +3,9 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do include FilterSpecHelper - let(:project) { create(:project, :public) } - let(:milestone) { create(:milestone, project: project) } + let(:project) { create(:project, :public) } + let(:milestone) { create(:milestone, project: project) } + let(:reference) { milestone.to_reference } it 'requires project context' do expect { described_class.call('') }.to raise_error(ArgumentError, /:project/) @@ -17,11 +18,37 @@ end end - context 'internal reference' do - # Convert the Markdown link to only the URL, since these tests aren't run through the regular Markdown pipeline. - # Milestone reference behavior in the full Markdown pipeline is tested elsewhere. - let(:reference) { milestone.to_reference.gsub(/\[([^\]]+)\]\(([^)]+)\)/, '\2') } + it 'includes default classes' do + doc = reference_filter("Milestone #{reference}") + expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-milestone' + end + + it 'includes a data-project attribute' do + doc = reference_filter("Milestone #{reference}") + link = doc.css('a').first + + expect(link).to have_attribute('data-project') + expect(link.attr('data-project')).to eq project.id.to_s + end + + it 'includes a data-milestone attribute' do + doc = reference_filter("See #{reference}") + link = doc.css('a').first + + expect(link).to have_attribute('data-milestone') + expect(link.attr('data-milestone')).to eq milestone.id.to_s + end + + it 'supports an :only_path context' do + doc = reference_filter("Milestone #{reference}", only_path: true) + 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) + end + + context 'Integer-based references' do it 'links to a valid reference' do doc = reference_filter("See #{reference}") @@ -30,29 +57,82 @@ end it 'links with adjacent text' do - doc = reference_filter("milestone (#{reference}.)") - expect(doc.to_html).to match(/\(#{Regexp.escape(milestone.title)}<\/a>\.\)/) + doc = reference_filter("Milestone (#{reference}.)") + expect(doc.to_html).to match(%r(\(#{milestone.name}\.\))) end - it 'includes a title attribute' do - doc = reference_filter("milestone #{reference}") - expect(doc.css('a').first.attr('title')).to eq "Milestone: #{milestone.title}" + it 'ignores invalid milestone IIDs' do + exp = act = "Milestone #{invalidate_reference(reference)}" + + expect(reference_filter(act).to_html).to eq exp end + end + + context 'String-based single-word references' do + let(:milestone) { create(:milestone, name: 'gfm', project: project) } + let(:reference) { "#{Milestone.reference_prefix}#{milestone.name}" } + + it 'links to a valid reference' do + doc = reference_filter("See #{reference}") - it 'escapes the title attribute' do - milestone.update_attribute(:title, %{">whatever#{milestone.name}\.\))) end - it 'includes default classes' do - doc = reference_filter("milestone #{reference}") - expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-milestone' + it 'ignores invalid milestone names' do + exp = act = "Milestone #{Milestone.reference_prefix}#{milestone.name.reverse}" + + expect(reference_filter(act).to_html).to eq exp + end + end + + context 'String-based multi-word references in quotes' do + let(:milestone) { create(:milestone, name: 'gfm references', project: project) } + let(:reference) { milestone.to_reference(format: :name) } + + 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.text).to eq 'See gfm references' + end + + it 'links with adjacent text' do + doc = reference_filter("Milestone (#{reference}.)") + expect(doc.to_html).to match(%r(\(#{milestone.name}\.\))) + end + + it 'ignores invalid milestone names' do + exp = act = %(Milestone #{Milestone.reference_prefix}"#{milestone.name.reverse}") + + expect(reference_filter(act).to_html).to eq exp + end + end + + describe 'referencing a milestone in a link href' do + let(:reference) { %Q{Milestone} } + + 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) + end + + it 'links with adjacent text' do + doc = reference_filter("Milestone (#{reference}.)") + expect(doc.to_html).to match(%r(\(Milestone\.\))) end it 'includes a data-project attribute' do - doc = reference_filter("milestone #{reference}") + doc = reference_filter("Milestone #{reference}") link = doc.css('a').first expect(link).to have_attribute('data-project') @@ -66,10 +146,31 @@ expect(link).to have_attribute('data-milestone') expect(link.attr('data-milestone')).to eq milestone.id.to_s end + end + + describe 'cross project milestone references' do + let(:another_project) { create(:empty_project, :public) } + let(:project_path) { another_project.path_with_namespace } + let(:milestone) { create(:milestone, project: another_project) } + let(:reference) { milestone.to_reference(project) } + + 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, + another_project, + milestone) + end - it 'adds to the results hash' do - result = reference_pipeline_result("milestone #{reference}") - expect(result[:references][:milestone]).to eq [milestone] + it 'contains cross project content' do + expect(result.css('a').first.text).to eq "#{milestone.name} in #{project_path}" + end + + it 'escapes the name attribute' do + allow_any_instance_of(Milestone).to receive(:title).and_return(%{">whateverText) + exp = 'Text' + expect(filter(act).to_html).to eq exp + end + it 'allows whitelisted HTML tags from the user' do exp = act = "
    \n
    Term
    \n
    Definition
    \n
    " expect(filter(act).to_html).to eq exp diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb index 26466fbb180138..5068ddd7faa5c9 100644 --- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb @@ -77,11 +77,6 @@ expect(link).not_to match %r(https?://) expect(link).to eq urls.namespace_project_snippet_url(project.namespace, project, snippet, only_path: true) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Snippet #{reference}") - expect(result[:references][:snippet]).to eq [snippet] - end end context 'cross-project reference' do @@ -107,11 +102,6 @@ expect(reference_filter(act).to_html).to eq exp end - - it 'adds to the results hash' do - result = reference_pipeline_result("Snippet #{reference}") - expect(result[:references][:snippet]).to eq [snippet] - end end context 'cross-project URL reference' do @@ -137,10 +127,5 @@ expect(reference_filter(act).to_html).to match(/#{Regexp.escape(invalidate_reference(reference))}<\/a>/) end - - it 'adds to the results hash' do - result = reference_pipeline_result("Snippet #{reference}") - expect(result[:references][:snippet]).to eq [snippet] - end end end diff --git a/spec/lib/banzai/filter/upload_link_filter_spec.rb b/spec/lib/banzai/filter/upload_link_filter_spec.rb index 3b073a90a95739..b83be54746c913 100644 --- a/spec/lib/banzai/filter/upload_link_filter_spec.rb +++ b/spec/lib/banzai/filter/upload_link_filter_spec.rb @@ -8,6 +8,10 @@ def filter(doc, contexts = {}) project: project }) + raw_filter(doc, contexts) + end + + def raw_filter(doc, contexts = {}) described_class.call(doc, contexts) end @@ -70,4 +74,18 @@ def link(path) expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png" end end + + context 'when project context does not exist' do + let(:upload_link) { link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg') } + + it 'does not raise error' do + expect { raw_filter(upload_link, project: nil) }.not_to raise_error + end + + it 'does not rewrite link' do + doc = raw_filter(upload_link, project: nil) + + expect(doc.to_html).to eq upload_link + end + end end diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index 8bdebae1841bdf..d7dfd6699ef460 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -31,28 +31,22 @@ end it 'supports a special @all mention' do - doc = reference_filter("Hey #{reference}") + 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) end - context "when the author is a member of the project" do + it 'includes a data-author attribute when there is an author' do + doc = reference_filter(reference, author: user) - it 'adds to the results hash' do - result = reference_pipeline_result("Hey #{reference}", author: project.creator) - expect(result[:references][:user]).to eq [project.creator] - end + expect(doc.css('a').first.attr('data-author')).to eq(user.id.to_s) end - context "when the author is not a member of the project" do - - let(:other_user) { create(:user) } + it 'does not include a data-author attribute when there is no author' do + doc = reference_filter(reference) - it "doesn't add to the results hash" do - result = reference_pipeline_result("Hey #{reference}", author: other_user) - expect(result[:references][:user]).to eq [] - end + expect(doc.css('a').first.has_attribute?('data-author')).to eq(false) end end @@ -83,11 +77,6 @@ expect(link).to have_attribute('data-user') expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s end - - it 'adds to the results hash' do - result = reference_pipeline_result("Hey #{reference}") - expect(result[:references][:user]).to eq [user] - end end context 'mentioning a group' do @@ -106,11 +95,6 @@ expect(link).to have_attribute('data-group') expect(link.attr('data-group')).to eq group.id.to_s end - - it 'adds to the results hash' do - result = reference_pipeline_result("Hey #{reference}") - expect(result[:references][:user]).to eq group.users - end end it 'links with adjacent text' do @@ -151,10 +135,5 @@ expect(link).to have_attribute('data-user') expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s end - - it 'adds to the results hash' do - result = reference_pipeline_result("Hey #{reference}") - expect(result[:references][:user]).to eq [user] - end end end diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb new file mode 100644 index 00000000000000..185abbb2108041 --- /dev/null +++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb @@ -0,0 +1,85 @@ +require 'spec_helper' + +describe Banzai::Filter::WikiLinkFilter, lib: true do + include FilterSpecHelper + + let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") } + let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) } + let(:user) { double } + let(:project_wiki) { ProjectWiki.new(project, user) } + + describe "links within the wiki (relative)" do + describe "hierarchical links to the current directory" do + it "doesn't rewrite non-file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('./page') + end + + it "doesn't rewrite file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('./page.md') + end + end + + describe "hierarchical links to the parent directory" do + it "doesn't rewrite non-file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('../page') + end + + it "doesn't rewrite file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('../page.md') + end + end + + describe "hierarchical links to a sub-directory" do + it "doesn't rewrite non-file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('./subdirectory/page') + end + + it "doesn't rewrite file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('./subdirectory/page.md') + end + end + + describe "non-hierarchical links" do + it 'rewrites non-file links to be at the scope of the wiki root' do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to match('/wiki_link_ns/wiki_link_project/wikis/page') + end + + it "doesn't rewrite file links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('page.md') + end + end + end + + describe "links outside the wiki (absolute)" do + it "doesn't rewrite links" do + link = "Link to Page" + filtered_link = filter(link, project_wiki: project_wiki).children[0] + + expect(filtered_link.attribute('href').value).to eq('http://example.com/page') + end + end +end diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb new file mode 100644 index 00000000000000..543b4786d84219 --- /dev/null +++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb @@ -0,0 +1,237 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::BaseParser, lib: true do + include ReferenceParserHelpers + + let(:user) { create(:user) } + let(:project) { create(:empty_project, :public) } + + subject do + klass = Class.new(described_class) do + self.reference_type = :foo + end + + klass.new(project, user) + end + + describe '.reference_type=' do + it 'sets the reference type' do + dummy = Class.new(described_class) + dummy.reference_type = :foo + + expect(dummy.reference_type).to eq(:foo) + end + end + + describe '#nodes_visible_to_user' do + let(:link) { empty_html_link } + + context 'when the link has a data-project attribute' do + it 'returns the nodes if the attribute value equals the current project ID' do + link['data-project'] = project.id.to_s + + expect(Ability.abilities).not_to receive(:allowed?) + expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) + end + + it 'returns the nodes if the user can read the project' do + other_project = create(:empty_project, :public) + + link['data-project'] = other_project.id.to_s + + expect(Ability.abilities).to receive(:allowed?). + with(user, :read_project, other_project). + and_return(true) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) + end + + it 'returns an empty Array when the attribute value is empty' do + link['data-project'] = '' + + expect(subject.nodes_visible_to_user(user, [link])).to eq([]) + end + + it 'returns an empty Array when the user can not read the project' do + other_project = create(:empty_project, :public) + + link['data-project'] = other_project.id.to_s + + expect(Ability.abilities).to receive(:allowed?). + with(user, :read_project, other_project). + and_return(false) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([]) + end + end + + context 'when the link does not have a data-project attribute' do + it 'returns the nodes' do + expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) + end + end + end + + describe '#nodes_user_can_reference' do + it 'returns the nodes' do + link = double(:link) + + expect(subject.nodes_user_can_reference(user, [link])).to eq([link]) + end + end + + describe '#referenced_by' do + context 'when references_relation is implemented' do + it 'returns a collection of objects' do + links = Nokogiri::HTML.fragment(""). + children + + expect(subject).to receive(:references_relation).and_return(User) + expect(subject.referenced_by(links)).to eq([user]) + end + end + + context 'when references_relation is not implemented' do + it 'raises NotImplementedError' do + links = Nokogiri::HTML.fragment('').children + + expect { subject.referenced_by(links) }. + to raise_error(NotImplementedError) + end + end + end + + describe '#references_relation' do + it 'raises NotImplementedError' do + expect { subject.references_relation }.to raise_error(NotImplementedError) + end + end + + describe '#gather_attributes_per_project' do + it 'returns a Hash containing attribute values per project' do + link = Nokogiri::HTML.fragment(''). + children[0] + + hash = subject.gather_attributes_per_project([link], 'data-foo') + + expect(hash).to be_an_instance_of(Hash) + + expect(hash[1].to_a).to eq(['2']) + end + end + + describe '#grouped_objects_for_nodes' 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]) + + hash = subject.grouped_objects_for_nodes(nodes, User, 'data-user') + + expect(hash).to eq({ user.id => user }) + end + + it 'returns an empty Hash when the list of nodes is empty' do + expect(subject.grouped_objects_for_nodes([], User, 'data-user')).to eq({}) + end + end + + describe '#unique_attribute_values' 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(:attr). + with('data-foo'). + twice. + and_return('1') + + nodes = [link, link] + + expect(subject.unique_attribute_values(nodes, 'data-foo')).to eq(['1']) + end + end + + describe '#process' do + it 'gathers the references for every node matching the reference type' do + dummy = Class.new(described_class) do + self.reference_type = :test + end + + instance = dummy.new(project, user) + document = Nokogiri::HTML.fragment('') + + expect(instance).to receive(:gather_references). + with([document.children[1]]). + and_return([user]) + + expect(instance.process([document])).to eq([user]) + end + end + + describe '#gather_references' 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(:referenced_by).with([]) + + subject.gather_references([link]) + 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_visible_to_user). + with(user, [link]). + and_return([]) + + expect(subject).to receive(:referenced_by).with([]) + + subject.gather_references([link]) + 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_visible_to_user). + with(user, [link]). + and_return([link]) + + expect(subject).to receive(:referenced_by).with([link]) + + subject.gather_references([link]) + end + end + + describe '#can?' do + it 'delegates the permissions check to the Ability class' do + user = double(:user) + + expect(Ability.abilities).to receive(:allowed?). + with(user, :read_project, project) + + subject.can?(user, :read_project, project) + end + end + + 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]) + 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 new file mode 100644 index 00000000000000..0b76d29fce019d --- /dev/null +++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb @@ -0,0 +1,113 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::CommitParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + context 'when the link has a data-project attribute' do + before do + link['data-project'] = project.id.to_s + end + + context 'when the link has a data-commit attribute' do + before do + link['data-commit'] = '123' + end + + it 'returns an Array of commits' do + commit = double(:commit) + + 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.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) + + 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) + + expect(subject.referenced_by([link])).to eq([]) + end + end + + 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) + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + 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) + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + describe '#commit_ids_per_project' do + before do + link['data-project'] = project.id.to_s + end + + it 'returns a Hash containing commit IDs per project' do + link['data-commit'] = '123' + + hash = subject.commit_ids_per_project([link]) + + expect(hash).to be_an_instance_of(Hash) + + expect(hash[project.id].to_a).to eq(['123']) + end + + it 'does not add a project when the data-commit attribute is empty' do + hash = subject.commit_ids_per_project([link]) + + expect(hash).to be_empty + end + end + + describe '#find_commits' do + it 'returns an Array of commit objects' do + commit = double(:commit) + + expect(project).to receive(:commit).with('123').and_return(commit) + expect(project).to receive(:valid_repo?).and_return(true) + + expect(subject.find_commits(project, %w{123})).to eq([commit]) + end + + it 'skips commit IDs for which no commit could be found' do + expect(project).to receive(:commit).with('123').and_return(nil) + expect(project).to receive(:valid_repo?).and_return(true) + + expect(subject.find_commits(project, %w{123})).to eq([]) + end + end +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 new file mode 100644 index 00000000000000..ba982f38542745 --- /dev/null +++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb @@ -0,0 +1,120 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::CommitRangeParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + context 'when the link has a data-project attribute' do + before do + link['data-project'] = project.id.to_s + end + + context 'when the link as a data-commit-range attribute' do + before do + link['data-commit-range'] = '123..456' + end + + 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.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.referenced_by([link])).to eq([]) + end + end + + context 'when the link does not have a data-commit-range attribute' do + it 'returns an empty Array' do + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + context 'when the link does not have a data-project attribute' do + it 'returns an empty Array' do + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + describe '#commit_range_ids_per_project' do + before do + link['data-project'] = project.id.to_s + end + + it 'returns a Hash containing range IDs per project' do + link['data-commit-range'] = '123..456' + + hash = subject.commit_range_ids_per_project([link]) + + expect(hash).to be_an_instance_of(Hash) + + expect(hash[project.id].to_a).to eq(['123..456']) + end + + it 'does not add a project when the data-commit-range attribute is empty' do + hash = subject.commit_range_ids_per_project([link]) + + expect(hash).to be_empty + end + end + + describe '#find_ranges' 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.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.find_ranges(project, ['123..456'])).to eq([]) + end + end + + describe '#find_object' do + let(:range) { double(:range) } + + before do + expect(CommitRange).to receive(:new).and_return(range) + end + + context 'when the range has valid commits' do + it 'returns the commit range' do + expect(range).to receive(:valid_commits?).and_return(true) + + expect(subject.find_object(project, '123..456')).to eq(range) + end + end + + context 'when the range does not have any valid commits' do + it 'returns nil' do + expect(range).to receive(:valid_commits?).and_return(false) + + expect(subject.find_object(project, '123..456')).to be_nil + end + end + end +end diff --git a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb new file mode 100644 index 00000000000000..a6ef8394fe7a98 --- /dev/null +++ b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::ExternalIssueParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + context 'when the link has a data-project attribute' do + before do + link['data-project'] = project.id.to_s + end + + context 'when the link has a data-external-issue attribute' do + it 'returns an Array of ExternalIssue instances' do + link['data-external-issue'] = '123' + + refs = subject.referenced_by([link]) + + expect(refs).to eq([ExternalIssue.new('123', project)]) + end + end + + context 'when the link does not have a data-external-issue attribute' do + it 'returns an empty Array' do + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + context 'when the link does not have a data-project attribute' do + it 'returns an empty Array' do + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + describe '#issue_ids_per_project' do + before do + link['data-project'] = project.id.to_s + end + + it 'returns a Hash containing range IDs per project' do + link['data-external-issue'] = '123' + + hash = subject.issue_ids_per_project([link]) + + expect(hash).to be_an_instance_of(Hash) + + expect(hash[project.id].to_a).to eq(['123']) + end + + it 'does not add a project when the data-external-issue attribute is empty' do + hash = subject.issue_ids_per_project([link]) + + expect(hash).to be_empty + end + end +end diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb new file mode 100644 index 00000000000000..514c752546d83f --- /dev/null +++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb @@ -0,0 +1,79 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::IssueParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + let(:issue) { create(:issue, project: project) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#nodes_visible_to_user' do + context 'when the link has a data-issue attribute' do + before do + link['data-issue'] = issue.id.to_s + end + + it 'returns the nodes when the user can read the issue' do + expect(Ability.abilities).to receive(:allowed?). + with(user, :read_issue, issue). + and_return(true) + + 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.abilities).to receive(:allowed?). + with(user, :read_issue, issue). + and_return(false) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([]) + end + end + + context 'when the link does not have a data-issue attribute' do + it 'returns an empty Array' do + expect(subject.nodes_visible_to_user(user, [link])).to eq([]) + end + end + + context 'when the project uses an external issue tracker' do + it 'returns all nodes' do + link = double(:link) + + expect(project).to receive(:external_issue_tracker).and_return(true) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) + end + end + end + + describe '#referenced_by' do + context 'when the link has a data-issue attribute' do + context 'using an existing issue ID' do + before do + link['data-issue'] = issue.id.to_s + end + + it 'returns an Array of issues' do + expect(subject.referenced_by([link])).to eq([issue]) + end + + it 'returns an empty Array when the list of nodes is empty' do + expect(subject.referenced_by([link])).to eq([issue]) + expect(subject.referenced_by([])).to eq([]) + end + end + end + end + + describe '#issues_for_nodes' do + it 'returns a Hash containing the issues for a list of nodes' do + link['data-issue'] = issue.id.to_s + nodes = [link] + + expect(subject.issues_for_nodes(nodes)).to eq({ issue.id => issue }) + end + end +end diff --git a/spec/lib/banzai/reference_parser/label_parser_spec.rb b/spec/lib/banzai/reference_parser/label_parser_spec.rb new file mode 100644 index 00000000000000..77fda47f0e7c9f --- /dev/null +++ b/spec/lib/banzai/reference_parser/label_parser_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::LabelParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + let(:label) { create(:label, project: project) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + describe 'when the link has a data-label attribute' do + context 'using an existing label ID' do + it 'returns an Array of labels' do + link['data-label'] = label.id.to_s + + expect(subject.referenced_by([link])).to eq([label]) + end + end + + context 'using a non-existing label ID' do + it 'returns an empty Array' do + link['data-label'] = '' + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + end +end diff --git a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb new file mode 100644 index 00000000000000..cf89ad598ea520 --- /dev/null +++ b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::MergeRequestParser, lib: true do + include ReferenceParserHelpers + + let(:user) { create(:user) } + let(:merge_request) { create(:merge_request) } + subject { described_class.new(merge_request.target_project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + describe 'when the link has a data-merge-request attribute' do + context 'using an existing merge request ID' do + it 'returns an Array of merge requests' do + link['data-merge-request'] = merge_request.id.to_s + + expect(subject.referenced_by([link])).to eq([merge_request]) + end + end + + context 'using a non-existing merge request ID' do + it 'returns an empty Array' do + link['data-merge-request'] = '' + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + end +end diff --git a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb new file mode 100644 index 00000000000000..6aa45a22cc4816 --- /dev/null +++ b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::MilestoneParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + let(:milestone) { create(:milestone, project: project) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + describe 'when the link has a data-milestone attribute' do + context 'using an existing milestone ID' do + it 'returns an Array of milestones' do + link['data-milestone'] = milestone.id.to_s + + expect(subject.referenced_by([link])).to eq([milestone]) + end + end + + context 'using a non-existing milestone ID' do + it 'returns an empty Array' do + link['data-milestone'] = '' + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + end +end diff --git a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb new file mode 100644 index 00000000000000..59127b7c5d182e --- /dev/null +++ b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::SnippetParser, lib: true do + include ReferenceParserHelpers + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + let(:snippet) { create(:snippet, project: project) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + describe 'when the link has a data-snippet attribute' do + context 'using an existing snippet ID' do + it 'returns an Array of snippets' do + link['data-snippet'] = snippet.id.to_s + + expect(subject.referenced_by([link])).to eq([snippet]) + end + end + + context 'using a non-existing snippet ID' do + it 'returns an empty Array' do + link['data-snippet'] = '' + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + end +end diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb new file mode 100644 index 00000000000000..9a82891297d3f2 --- /dev/null +++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb @@ -0,0 +1,189 @@ +require 'spec_helper' + +describe Banzai::ReferenceParser::UserParser, lib: true do + include ReferenceParserHelpers + + let(:group) { create(:group) } + let(:user) { create(:user) } + let(:project) { create(:empty_project, :public, group: group, creator: user) } + subject { described_class.new(project, user) } + let(:link) { empty_html_link } + + describe '#referenced_by' do + context 'when the link has a data-group attribute' do + context 'using an existing group ID' do + before do + link['data-group'] = project.group.id.to_s + end + + it 'returns the users of the group' do + create(:group_member, group: group, user: user) + + expect(subject.referenced_by([link])).to eq([user]) + end + + it 'returns an empty Array when the group has no users' do + expect(subject.referenced_by([link])).to eq([]) + end + end + + context 'using a non-existing group ID' do + it 'returns an empty Array' do + link['data-group'] = '' + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + + context 'when the link has a data-user attribute' do + it 'returns an Array of users' do + link['data-user'] = user.id.to_s + + expect(subject.referenced_by([link])).to eq([user]) + end + end + + context 'when the link has a data-project attribute' do + context 'using an existing project ID' do + let(:contributor) { create(:user) } + + before do + project.team << [user, :developer] + project.team << [contributor, :developer] + end + + it 'returns the members of a project' do + link['data-project'] = project.id.to_s + + # This uses an explicit sort to make sure this spec doesn't randomly + # fail when objects are returned in a different order. + refs = subject.referenced_by([link]).sort_by(&:id) + + expect(refs).to eq([user, contributor]) + end + end + + context 'using a non-existing project ID' do + it 'returns an empty Array' do + link['data-project'] = '' + + expect(subject.referenced_by([link])).to eq([]) + end + end + end + end + + describe '#nodes_visible_to_use?' do + context 'when the link has a data-group attribute' do + context 'using an existing group ID' do + before do + link['data-group'] = group.id.to_s + end + + it 'returns the nodes if the user can read the group' do + expect(Ability.abilities).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.abilities).to receive(:allowed?). + with(user, :read_group, group). + and_return(false) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([]) + end + end + + context 'when the link does not have a data-group attribute' do + context 'with a data-project attribute' do + it 'returns the nodes if the attribute value equals the current project ID' do + link['data-project'] = project.id.to_s + + expect(Ability.abilities).not_to receive(:allowed?) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) + end + + it 'returns the nodes if the user can read the project' do + other_project = create(:empty_project, :public) + + link['data-project'] = other_project.id.to_s + + expect(Ability.abilities).to receive(:allowed?). + with(user, :read_project, other_project). + 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 project' do + other_project = create(:empty_project, :public) + + link['data-project'] = other_project.id.to_s + + expect(Ability.abilities).to receive(:allowed?). + with(user, :read_project, other_project). + and_return(false) + + expect(subject.nodes_visible_to_user(user, [link])).to eq([]) + end + end + + context 'without a data-project attribute' do + it 'returns the nodes' do + expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) + end + end + end + end + end + + describe '#nodes_user_can_reference' do + context 'when the link has a data-author attribute' do + it 'returns the nodes when the user is a member of the project' do + other_project = create(:project) + other_project.team << [user, :developer] + + link['data-project'] = other_project.id.to_s + link['data-author'] = user.id.to_s + + expect(subject.nodes_user_can_reference(user, [link])).to eq([link]) + end + + it 'returns an empty Array when the project could not be found' do + link['data-project'] = '' + link['data-author'] = user.id.to_s + + expect(subject.nodes_user_can_reference(user, [link])).to eq([]) + end + + it 'returns an empty Array when the user could not be found' do + other_project = create(:project) + + link['data-project'] = other_project.id.to_s + link['data-author'] = '' + + expect(subject.nodes_user_can_reference(user, [link])).to eq([]) + end + + it 'returns an empty Array when the user is not a team member' do + other_project = create(:project) + + link['data-project'] = other_project.id.to_s + link['data-author'] = user.id.to_s + + expect(subject.nodes_user_can_reference(user, [link])).to eq([]) + end + end + + context 'when the link does not have a data-author attribute' do + it 'returns the nodes' do + expect(subject.nodes_user_can_reference(user, [link])).to eq([link]) + end + end + end +end diff --git a/spec/lib/ci/ansi2html_spec.rb b/spec/lib/ci/ansi2html_spec.rb index 3a2b568f4c7ca2..898f1e84ab0679 100644 --- a/spec/lib/ci/ansi2html_spec.rb +++ b/spec/lib/ci/ansi2html_spec.rb @@ -4,131 +4,185 @@ subject { Ci::Ansi2html } it "prints non-ansi as-is" do - expect(subject.convert("Hello")).to eq('Hello') + expect(subject.convert("Hello")[:html]).to eq('Hello') end it "strips non-color-changing controll sequences" do - expect(subject.convert("Hello \e[2Kworld")).to eq('Hello world') + expect(subject.convert("Hello \e[2Kworld")[:html]).to eq('Hello world') end it "prints simply red" do - expect(subject.convert("\e[31mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[31mHello\e[0m")[:html]).to eq('Hello') end it "prints simply red without trailing reset" do - expect(subject.convert("\e[31mHello")).to eq('Hello') + expect(subject.convert("\e[31mHello")[:html]).to eq('Hello') end it "prints simply yellow" do - expect(subject.convert("\e[33mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[33mHello\e[0m")[:html]).to eq('Hello') end it "prints default on blue" do - expect(subject.convert("\e[39;44mHello")).to eq('Hello') + expect(subject.convert("\e[39;44mHello")[:html]).to eq('Hello') end it "prints red on blue" do - expect(subject.convert("\e[31;44mHello")).to eq('Hello') + expect(subject.convert("\e[31;44mHello")[:html]).to eq('Hello') end it "resets colors after red on blue" do - expect(subject.convert("\e[31;44mHello\e[0m world")).to eq('Hello world') + expect(subject.convert("\e[31;44mHello\e[0m world")[:html]).to eq('Hello world') end it "performs color change from red/blue to yellow/blue" do - expect(subject.convert("\e[31;44mHello \e[33mworld")).to eq('Hello world') + expect(subject.convert("\e[31;44mHello \e[33mworld")[:html]).to eq('Hello world') end it "performs color change from red/blue to yellow/green" do - expect(subject.convert("\e[31;44mHello \e[33;42mworld")).to eq('Hello world') + expect(subject.convert("\e[31;44mHello \e[33;42mworld")[:html]).to eq('Hello world') end it "performs color change from red/blue to reset to yellow/green" do - expect(subject.convert("\e[31;44mHello\e[0m \e[33;42mworld")).to eq('Hello world') + expect(subject.convert("\e[31;44mHello\e[0m \e[33;42mworld")[:html]).to eq('Hello world') end it "ignores unsupported codes" do - expect(subject.convert("\e[51mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[51mHello\e[0m")[:html]).to eq('Hello') end it "prints light red" do - expect(subject.convert("\e[91mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[91mHello\e[0m")[:html]).to eq('Hello') end it "prints default on light red" do - expect(subject.convert("\e[101mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[101mHello\e[0m")[:html]).to eq('Hello') end it "performs color change from red/blue to default/blue" do - expect(subject.convert("\e[31;44mHello \e[39mworld")).to eq('Hello world') + expect(subject.convert("\e[31;44mHello \e[39mworld")[:html]).to eq('Hello world') end it "performs color change from light red/blue to default/blue" do - expect(subject.convert("\e[91;44mHello \e[39mworld")).to eq('Hello world') + expect(subject.convert("\e[91;44mHello \e[39mworld")[:html]).to eq('Hello world') end it "prints bold text" do - expect(subject.convert("\e[1mHello")).to eq('Hello') + expect(subject.convert("\e[1mHello")[:html]).to eq('Hello') end it "resets bold text" do - expect(subject.convert("\e[1mHello\e[21m world")).to eq('Hello world') - expect(subject.convert("\e[1mHello\e[22m world")).to eq('Hello world') + expect(subject.convert("\e[1mHello\e[21m world")[:html]).to eq('Hello world') + expect(subject.convert("\e[1mHello\e[22m world")[:html]).to eq('Hello world') end it "prints italic text" do - expect(subject.convert("\e[3mHello")).to eq('Hello') + expect(subject.convert("\e[3mHello")[:html]).to eq('Hello') end it "resets italic text" do - expect(subject.convert("\e[3mHello\e[23m world")).to eq('Hello world') + expect(subject.convert("\e[3mHello\e[23m world")[:html]).to eq('Hello world') end it "prints underlined text" do - expect(subject.convert("\e[4mHello")).to eq('Hello') + expect(subject.convert("\e[4mHello")[:html]).to eq('Hello') end it "resets underlined text" do - expect(subject.convert("\e[4mHello\e[24m world")).to eq('Hello world') + expect(subject.convert("\e[4mHello\e[24m world")[:html]).to eq('Hello world') end it "prints concealed text" do - expect(subject.convert("\e[8mHello")).to eq('Hello') + expect(subject.convert("\e[8mHello")[:html]).to eq('Hello') end it "resets concealed text" do - expect(subject.convert("\e[8mHello\e[28m world")).to eq('Hello world') + expect(subject.convert("\e[8mHello\e[28m world")[:html]).to eq('Hello world') end it "prints crossed-out text" do - expect(subject.convert("\e[9mHello")).to eq('Hello') + expect(subject.convert("\e[9mHello")[:html]).to eq('Hello') end it "resets crossed-out text" do - expect(subject.convert("\e[9mHello\e[29m world")).to eq('Hello world') + expect(subject.convert("\e[9mHello\e[29m world")[:html]).to eq('Hello world') end it "can print 256 xterm fg colors" do - expect(subject.convert("\e[38;5;16mHello")).to eq('Hello') + expect(subject.convert("\e[38;5;16mHello")[:html]).to eq('Hello') end it "can print 256 xterm fg colors on normal magenta background" do - expect(subject.convert("\e[38;5;16;45mHello")).to eq('Hello') + expect(subject.convert("\e[38;5;16;45mHello")[:html]).to eq('Hello') end it "can print 256 xterm bg colors" do - expect(subject.convert("\e[48;5;240mHello")).to eq('Hello') + expect(subject.convert("\e[48;5;240mHello")[:html]).to eq('Hello') end it "can print 256 xterm bg colors on normal magenta foreground" do - expect(subject.convert("\e[48;5;16;35mHello")).to eq('Hello') + expect(subject.convert("\e[48;5;16;35mHello")[:html]).to eq('Hello') end it "prints bold colored text vividly" do - expect(subject.convert("\e[1;31mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[1;31mHello\e[0m")[:html]).to eq('Hello') end it "prints bold light colored text correctly" do - expect(subject.convert("\e[1;91mHello\e[0m")).to eq('Hello') + expect(subject.convert("\e[1;91mHello\e[0m")[:html]).to eq('Hello') + end + + it "prints <" do + expect(subject.convert("<")[:html]).to eq('<') + end + + describe "incremental update" do + shared_examples 'stateable converter' do + let(:pass1) { subject.convert(pre_text) } + let(:pass2) { subject.convert(pre_text + text, pass1[:state]) } + + it "to returns html to append" do + expect(pass2[:append]).to be_truthy + expect(pass2[:html]).to eq(html) + expect(pass1[:text] + pass2[:text]).to eq(pre_text + text) + expect(pass1[:html] + pass2[:html]).to eq(pre_html + html) + end + end + + context "with split word" do + let(:pre_text) { "\e[1mHello" } + let(:pre_html) { "Hello" } + let(:text) { "\e[1mWorld" } + let(:html) { "World" } + + it_behaves_like 'stateable converter' + end + + context "with split sequence" do + let(:pre_text) { "\e[1m" } + let(:pre_html) { "" } + let(:text) { "Hello" } + let(:html) { "Hello" } + + it_behaves_like 'stateable converter' + end + + context "with partial sequence" do + let(:pre_text) { "Hello\e" } + let(:pre_html) { "Hello" } + let(:text) { "[1m World" } + let(:html) { " World" } + + it_behaves_like 'stateable converter' + end + + context 'with new line' do + let(:pre_text) { "Hello\r" } + let(:pre_html) { "Hello\r" } + let(:text) { "\nWorld" } + let(:html) { "
    World" } + + it_behaves_like 'stateable converter' + end end end diff --git a/spec/lib/ci/charts_spec.rb b/spec/lib/ci/charts_spec.rb index 50a77308cde81d..9d1215a57609c6 100644 --- a/spec/lib/ci/charts_spec.rb +++ b/spec/lib/ci/charts_spec.rb @@ -12,5 +12,12 @@ chart = Ci::Charts::BuildTime.new(@commit.project) expect(chart.build_times).to eq([2]) end + + it 'should handle nil build times' do + create(:ci_commit, duration: nil, project: @commit.project) + + chart = Ci::Charts::BuildTime.new(@commit.project) + expect(chart.build_times).to eq([2, 0]) + end 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 c7ab3185378f2c..7375539cf17355 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -443,12 +443,12 @@ module Ci context 'when job variables are defined' do context 'when syntax is correct' do it 'returns job variables' do - variables = { + variables = { KEY1: 'value1', SOME_KEY_2: 'value2' } - config = YAML.dump( + config = YAML.dump( { before_script: ['pwd'], rspec: { variables: variables, @@ -619,19 +619,19 @@ module Ci context 'no dependencies' do let(:dependencies) { } - it { expect { subject }.to_not raise_error } + it { expect { subject }.not_to raise_error } end context 'dependencies to builds' do let(:dependencies) { ['build1', 'build2'] } - it { expect { subject }.to_not raise_error } + it { expect { subject }.not_to raise_error } end context 'dependencies to builds defined as symbols' do let(:dependencies) { [:build1, :build2] } - it { expect { subject }.to_not raise_error } + it { expect { subject }.not_to raise_error } end context 'undefined dependency' do diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb new file mode 100644 index 00000000000000..4d8cb787ddeef5 --- /dev/null +++ b/spec/lib/container_registry/blob_spec.rb @@ -0,0 +1,61 @@ +require 'spec_helper' + +describe ContainerRegistry::Blob do + let(:digest) { 'sha256:0123456789012345' } + let(:config) do + { + 'digest' => digest, + 'mediaType' => 'binary', + 'size' => 1000 + } + end + + let(:registry) { ContainerRegistry::Registry.new('http://example.com') } + let(:repository) { registry.repository('group/test') } + let(:blob) { repository.blob(config) } + + it { expect(blob).to respond_to(:repository) } + it { expect(blob).to delegate_method(:registry).to(:repository) } + it { expect(blob).to delegate_method(:client).to(:repository) } + + context '#path' do + subject { blob.path } + + it { is_expected.to eq('example.com/group/test@sha256:0123456789012345') } + end + + context '#digest' do + subject { blob.digest } + + it { is_expected.to eq(digest) } + end + + context '#type' do + subject { blob.type } + + it { is_expected.to eq('binary') } + end + + context '#revision' do + subject { blob.revision } + + it { is_expected.to eq('0123456789012345') } + end + + context '#short_revision' do + subject { blob.short_revision } + + it { is_expected.to eq('012345678') } + end + + context '#delete' do + before do + stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345'). + to_return(status: 200) + end + + subject { blob.delete } + + it { is_expected.to be_truthy } + end +end diff --git a/spec/lib/container_registry/registry_spec.rb b/spec/lib/container_registry/registry_spec.rb new file mode 100644 index 00000000000000..4f3f8b24fc43b7 --- /dev/null +++ b/spec/lib/container_registry/registry_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe ContainerRegistry::Registry do + let(:path) { nil } + let(:registry) { described_class.new('http://example.com', path: path) } + + subject { registry } + + it { is_expected.to respond_to(:client) } + it { is_expected.to respond_to(:uri) } + it { is_expected.to respond_to(:path) } + + it { expect(subject.repository('test')).not_to be_nil } + + context '#path' do + subject { registry.path } + + context 'path from URL' do + it { is_expected.to eq('example.com') } + end + + context 'custom path' do + let(:path) { 'registry.example.com' } + + it { is_expected.to eq(path) } + end + end +end diff --git a/spec/lib/container_registry/repository_spec.rb b/spec/lib/container_registry/repository_spec.rb new file mode 100644 index 00000000000000..279709521c9743 --- /dev/null +++ b/spec/lib/container_registry/repository_spec.rb @@ -0,0 +1,65 @@ +require 'spec_helper' + +describe ContainerRegistry::Repository do + let(:registry) { ContainerRegistry::Registry.new('http://example.com') } + let(:repository) { registry.repository('group/test') } + + it { expect(repository).to respond_to(:registry) } + it { expect(repository).to delegate_method(:client).to(:registry) } + it { expect(repository.tag('test')).not_to be_nil } + + context '#path' do + subject { repository.path } + + it { is_expected.to eq('example.com/group/test') } + end + + 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( + status: 200, + body: JSON.dump(tags: ['test']), + headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json' }) + end + + context '#manifest' do + subject { repository.manifest } + + it { is_expected.not_to be_nil } + end + + context '#valid?' do + subject { repository.valid? } + + it { is_expected.to be_truthy } + end + + context '#tags' do + subject { repository.tags } + + it { is_expected.not_to be_empty } + end + end + + context '#delete_tags' do + let(:tag) { ContainerRegistry::Tag.new(repository, 'tag') } + + before { expect(repository).to receive(:tags).twice.and_return([tag]) } + + subject { repository.delete_tags } + + context 'succeeds' do + before { expect(tag).to receive(:delete).and_return(true) } + + it { is_expected.to be_truthy } + end + + context 'any fails' do + before { expect(tag).to receive(:delete).and_return(false) } + + it { is_expected.to be_falsey } + end + end +end diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb new file mode 100644 index 00000000000000..858cb0bb134d38 --- /dev/null +++ b/spec/lib/container_registry/tag_spec.rb @@ -0,0 +1,89 @@ +require 'spec_helper' + +describe ContainerRegistry::Tag do + let(:registry) { ContainerRegistry::Registry.new('http://example.com') } + let(:repository) { registry.repository('group/test') } + let(:tag) { repository.tag('tag') } + let(:headers) { { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' } } + + it { expect(tag).to respond_to(:repository) } + it { expect(tag).to delegate_method(:registry).to(:repository) } + it { expect(tag).to delegate_method(:client).to(:repository) } + + context '#path' do + subject { tag.path } + + it { is_expected.to eq('example.com/group/test:tag') } + end + + context 'manifest processing' do + before do + 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' }) + end + + context '#layers' do + subject { tag.layers } + + it { expect(subject.length).to eq(1) } + end + + context '#total_size' do + subject { tag.total_size } + + it { is_expected.to eq(2319870) } + end + + context 'config processing' do + before do + 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 + + context '#config' do + subject { tag.config } + + it { is_expected.not_to be_nil } + end + + context '#created_at' do + subject { tag.created_at } + + it { is_expected.not_to be_nil } + end + end + end + + 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' }) + end + + context '#digest' do + subject { tag.digest } + + it { is_expected.to eq('sha256:digest') } + end + + context '#delete' do + before do + stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest'). + with(headers: headers). + to_return(status: 200) + end + + subject { tag.delete } + + it { is_expected.to be_truthy } + end + end +end diff --git a/spec/lib/gitlab/akismet_helper_spec.rb b/spec/lib/gitlab/akismet_helper_spec.rb index 53f5d6c5c80dd6..88a71528867c2d 100644 --- a/spec/lib/gitlab/akismet_helper_spec.rb +++ b/spec/lib/gitlab/akismet_helper_spec.rb @@ -6,8 +6,8 @@ before do allow(Gitlab.config.gitlab).to receive(:url).and_return(Settings.send(:build_gitlab_url)) - current_application_settings.akismet_enabled = true - current_application_settings.akismet_api_key = '12345' + allow_any_instance_of(ApplicationSetting).to receive(:akismet_enabled).and_return(true) + allow_any_instance_of(ApplicationSetting).to receive(:akismet_api_key).and_return('12345') end describe '#check_for_spam?' do diff --git a/spec/lib/gitlab/bitbucket_import/client_spec.rb b/spec/lib/gitlab/bitbucket_import/client_spec.rb index af839f4242155a..7718689e6d4b01 100644 --- a/spec/lib/gitlab/bitbucket_import/client_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/client_spec.rb @@ -59,7 +59,7 @@ bitbucket_access_token_secret: "test" } }) project.import_url = "ssh://git@bitbucket.org/test/test.git" - expect { described_class.from_project(project) }.to_not raise_error + expect { described_class.from_project(project) }.not_to raise_error end end end diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb index acca0b08bab349..711a3e1c7d41a4 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb @@ -10,8 +10,8 @@ 'path/dir_1/subdir/subfile' => { size: 10 }, 'path/second_dir' => {}, 'path/second_dir/dir_3/file_2' => { size: 10 }, - 'path/second_dir/dir_3/file_3'=> { size: 10 }, - 'another_directory/'=> {}, + 'path/second_dir/dir_3/file_3' => { size: 10 }, + 'another_directory/' => {}, 'another_file' => {}, '/file/with/absolute_path' => {} } end @@ -122,7 +122,7 @@ def entry(path) describe 'empty path', path: '' do subject { |example| path(example) } - it { is_expected.to_not have_parent } + it { is_expected.not_to have_parent } describe '#children' do subject { |example| path(example).children } diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb new file mode 100644 index 00000000000000..35ade7a2be052c --- /dev/null +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -0,0 +1,128 @@ +require 'spec_helper' + +describe Gitlab::Database::MigrationHelpers, lib: true do + let(:model) do + ActiveRecord::Migration.new.extend( + Gitlab::Database::MigrationHelpers + ) + end + + before { allow(model).to receive(:puts) } + + describe '#add_concurrent_index' do + context 'outside a transaction' do + before do + expect(model).to receive(:transaction_open?).and_return(false) + end + + context 'using PostgreSQL' do + it 'creates the index concurrently' do + expect(Gitlab::Database).to receive(:postgresql?).and_return(true) + + expect(model).to receive(:add_index). + with(:users, :foo, algorithm: :concurrently) + + model.add_concurrent_index(:users, :foo) + end + end + + context 'using MySQL' 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) + + model.add_concurrent_index(:users, :foo) + end + end + end + + context 'inside a transaction' 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) + end + end + end + + describe '#update_column_in_batches' do + before do + create_list(:empty_project, 5) + end + + it 'updates all the rows in a table' do + model.update_column_in_batches(:projects, :import_error, 'foo') + + expect(Project.where(import_error: 'foo').count).to eq(5) + end + + it 'updates boolean values correctly' do + model.update_column_in_batches(:projects, :archived, true) + + expect(Project.where(archived: true).count).to eq(5) + end + end + + describe '#add_column_with_default' do + context 'outside of a transaction' do + before do + expect(model).to receive(:transaction_open?).and_return(false) + + expect(model).to receive(:transaction).twice.and_yield + + expect(model).to receive(:add_column). + with(:projects, :foo, :integer, default: nil) + + 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).not_to receive(:change_column_null) + + model.add_column_with_default(:projects, :foo, :integer, + default: 10, + allow_null: true) + 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(: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(:remove_column). + with(:projects, :foo) + + expect do + model.add_column_with_default(:projects, :foo, :integer, default: 10) + end.to raise_error(RuntimeError) + end + end + + context 'inside a transaction' do + it 'raises RuntimeError' do + expect(model).to receive(:transaction_open?).and_return(true) + + expect do + model.add_column_with_default(:projects, :foo, :integer, default: 10) + end.to raise_error(RuntimeError) + end + end + end +end diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb index b2d7a799810d17..c19f33e22241d1 100644 --- a/spec/lib/gitlab/email/message/repository_push_spec.rb +++ b/spec/lib/gitlab/email/message/repository_push_spec.rb @@ -8,7 +8,7 @@ let!(:author) { create(:author, name: 'Author') } let(:message) do - described_class.new(Notify, project.id, 'recipient@example.com', opts) + described_class.new(Notify, project.id, opts) end context 'new commits have been pushed to repository' do @@ -57,7 +57,7 @@ describe '#diffs' do subject { message.diffs } - it { is_expected.to all(be_an_instance_of Gitlab::Git::Diff) } + it { is_expected.to all(be_an_instance_of Gitlab::Diff::File) } end describe '#diffs_count' do diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb index 0a7ca3ec848be1..0af249d8690edb 100644 --- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb @@ -33,8 +33,8 @@ end it { is_expected.to include issue_first.to_reference(new_project) } - it { is_expected.to_not include issue_second.to_reference(new_project) } - it { is_expected.to_not include merge_request.to_reference(new_project) } + it { is_expected.not_to include issue_second.to_reference(new_project) } + it { is_expected.not_to include merge_request.to_reference(new_project) } end context 'description ambigous elements' do diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb index eda956e6f0a92c..6eca33f9fee300 100644 --- a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb @@ -32,13 +32,13 @@ let(:new_paths) { new_files.map(&:path) } it 'rewrites content' do - expect(new_text).to_not eq text + expect(new_text).not_to eq text expect(new_text.length).to eq text.length end it 'copies files' do expect(new_files).to all(exist) - expect(old_paths).to_not match_array new_paths + expect(old_paths).not_to match_array new_paths expect(old_paths).to all(include(old_project.path_with_namespace)) expect(new_paths).to all(include(new_project.path_with_namespace)) end @@ -48,8 +48,8 @@ end it 'generates a new secret for each file' do - expect(new_paths).to_not include image_uploader.secret - expect(new_paths).to_not include zip_uploader.secret + expect(new_paths).not_to include image_uploader.secret + expect(new_paths).not_to include zip_uploader.secret end end diff --git a/spec/lib/gitlab/github_import/branch_formatter_spec.rb b/spec/lib/gitlab/github_import/branch_formatter_spec.rb new file mode 100644 index 00000000000000..3cb634ba010bb5 --- /dev/null +++ b/spec/lib/gitlab/github_import/branch_formatter_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe Gitlab::GithubImport::BranchFormatter, lib: true do + let(:project) { create(:project) } + let(:repo) { double } + let(:raw) do + { + ref: 'feature', + repo: repo, + sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b' + } + end + + describe '#exists?' do + it 'returns true when branch exists' do + branch = described_class.new(project, double(raw)) + + expect(branch.exists?).to eq true + end + + it 'returns false when branch does not exist' do + branch = described_class.new(project, double(raw.merge(ref: 'removed-branch'))) + + expect(branch.exists?).to eq false + end + end + + describe '#name' do + it 'returns raw ref when branch exists' do + branch = described_class.new(project, double(raw)) + + expect(branch.name).to eq 'feature' + end + + it 'returns formatted ref when branch does not exist' do + branch = described_class.new(project, double(raw.merge(ref: 'removed-branch'))) + + expect(branch.name).to eq 'removed-branch-2e5d3239' + end + end + + describe '#repo' do + it 'returns raw repo' do + branch = described_class.new(project, double(raw)) + + expect(branch.repo).to eq repo + end + end + + describe '#sha' do + it 'returns raw sha' do + branch = described_class.new(project, double(raw)) + + expect(branch.sha).to eq '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b' + end + end + + describe '#valid?' do + it 'returns true when repository exists' do + branch = described_class.new(project, double(raw)) + + expect(branch.valid?).to eq true + end + + it 'returns false when repository does not exist' do + branch = described_class.new(project, double(raw.merge(repo: nil))) + + expect(branch.valid?).to eq false + end + end +end diff --git a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb index e59c0ca110e66b..120f59e6e71fd4 100644 --- a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb +++ b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb @@ -4,9 +4,9 @@ let(:project) { create(:project) } let(:repository) { double(id: 1, fork: false) } let(:source_repo) { repository } - let(:source_branch) { double(ref: 'feature', repo: source_repo) } + let(:source_branch) { double(ref: 'feature', repo: source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b') } let(:target_repo) { repository } - let(:target_branch) { double(ref: 'master', repo: target_repo) } + let(:target_branch) { double(ref: 'master', repo: target_repo, sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7') } let(:octocat) { double(id: 123456, login: 'octocat') } let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') } let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') } @@ -41,8 +41,10 @@ description: "*Created by: octocat*\n\nPlease pull these awesome changes", source_project: project, source_branch: 'feature', + head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', target_project: project, target_branch: 'master', + base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7', state: 'opened', milestone: nil, author_id: project.creator_id, @@ -66,8 +68,10 @@ description: "*Created by: octocat*\n\nPlease pull these awesome changes", source_project: project, source_branch: 'feature', + head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', target_project: project, target_branch: 'master', + base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7', state: 'closed', milestone: nil, author_id: project.creator_id, @@ -91,8 +95,10 @@ description: "*Created by: octocat*\n\nPlease pull these awesome changes", source_project: project, source_branch: 'feature', + head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b', target_project: project, target_branch: 'master', + base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7', state: 'merged', milestone: nil, author_id: project.creator_id, @@ -137,11 +143,11 @@ let(:milestone) { double(number: 45) } let(:raw_data) { double(base_data.merge(milestone: milestone)) } - it 'returns nil when milestone does not exists' do + it 'returns nil when milestone does not exist' do expect(pull_request.attributes.fetch(:milestone)).to be_nil end - it 'returns milestone when is exists' do + it 'returns milestone when it exists' do milestone = create(:milestone, project: project, iid: 45) expect(pull_request.attributes.fetch(:milestone)).to eq milestone @@ -158,36 +164,16 @@ end describe '#valid?' do - let(:invalid_branch) { double(ref: 'invalid-branch').as_null_object } - - context 'when source, and target repositories are the same' do - context 'and source and target branches exists' do - let(:raw_data) { double(base_data.merge(head: source_branch, base: target_branch)) } - - it 'returns true' do - expect(pull_request.valid?).to eq true - end - end - - context 'and source branch doesn not exists' do - let(:raw_data) { double(base_data.merge(head: invalid_branch, base: target_branch)) } - - it 'returns false' do - expect(pull_request.valid?).to eq false - end - end - - context 'and target branch doesn not exists' do - let(:raw_data) { double(base_data.merge(head: source_branch, base: invalid_branch)) } + context 'when source, and target repos are not a fork' do + let(:raw_data) { double(base_data) } - it 'returns false' do - expect(pull_request.valid?).to eq false - end + it 'returns true' do + expect(pull_request.valid?).to eq true end end context 'when source repo is a fork' do - let(:source_repo) { double(id: 2, fork: true) } + let(:source_repo) { double(id: 2) } let(:raw_data) { double(base_data) } it 'returns false' do @@ -196,7 +182,7 @@ end context 'when target repo is a fork' do - let(:target_repo) { double(id: 2, fork: true) } + let(:target_repo) { double(id: 2) } let(:raw_data) { double(base_data) } it 'returns false' do diff --git a/spec/lib/gitlab/gitignore_spec.rb b/spec/lib/gitlab/gitignore_spec.rb new file mode 100644 index 00000000000000..72baa516cc4ddd --- /dev/null +++ b/spec/lib/gitlab/gitignore_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe Gitlab::Gitignore do + subject { Gitlab::Gitignore } + + describe '.all' do + it 'strips the gitignore suffix' do + expect(subject.all.first.name).not_to end_with('.gitignore') + end + + it 'combines the globals and rest' do + all = subject.all.map(&:name) + + expect(all).to include('Vim') + expect(all).to include('Ruby') + end + end + + describe '.find' do + it 'returns nil if the file does not exist' do + expect(subject.find('mepmep-yadida')).to be nil + end + + it 'returns the Gitignore object of a valid file' do + ruby = subject.find('Ruby') + + expect(ruby).to be_a Gitlab::Gitignore + expect(ruby.name).to eq('Ruby') + end + end + + describe '#content' do + it 'loads the full file' do + gitignore = subject.new(Rails.root.join('vendor/gitignore/Ruby.gitignore')) + + expect(gitignore.name).to eq 'Ruby' + expect(gitignore.content).to start_with('*.gem') + end + end +end diff --git a/spec/lib/gitlab/import_url_spec.rb b/spec/lib/gitlab/import_url_spec.rb deleted file mode 100644 index f758cb8693c45f..00000000000000 --- a/spec/lib/gitlab/import_url_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe Gitlab::ImportUrl do - - let(:credentials) { { user: 'blah', password: 'password' } } - let(:import_url) do - Gitlab::ImportUrl.new("https://github.com/me/project.git", credentials: credentials) - end - - describe :full_url do - it { expect(import_url.full_url).to eq("https://blah:password@github.com/me/project.git") } - end - - describe :sanitized_url do - it { expect(import_url.sanitized_url).to eq("https://github.com/me/project.git") } - end - - describe :credentials do - it { expect(import_url.credentials).to eq(credentials) } - end -end diff --git a/spec/lib/gitlab/lazy_spec.rb b/spec/lib/gitlab/lazy_spec.rb new file mode 100644 index 00000000000000..b5ca89dd242390 --- /dev/null +++ b/spec/lib/gitlab/lazy_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe Gitlab::Lazy, lib: true do + let(:dummy) { double(:dummy) } + + context 'when not calling any methods' do + it 'does not call the supplied block' do + expect(dummy).not_to receive(:foo) + + described_class.new { dummy.foo } + end + end + + context 'when calling a method on the object' do + it 'lazy loads the value returned by the block' do + expect(dummy).to receive(:foo).and_return('foo') + + lazy = described_class.new { dummy.foo } + + expect(lazy.to_s).to eq('foo') + end + end + + describe '#respond_to?' do + it 'returns true for a method defined on the wrapped object' do + lazy = described_class.new { 'foo' } + + expect(lazy).to respond_to(:downcase) + end + + it 'returns false for a method not defined on the wrapped object' do + lazy = described_class.new { 'foo' } + + expect(lazy).not_to respond_to(:quack) + end + end +end diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb index 5852b31ab3a5ff..88814bc474d15c 100644 --- a/spec/lib/gitlab/lfs/lfs_router_spec.rb +++ b/spec/lib/gitlab/lfs/lfs_router_spec.rb @@ -26,8 +26,8 @@ let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" } let(:sample_size) { 499013 } - let(:respond_with_deprecated) {[ 501, { "Content-Type"=>"application/json; charset=utf-8" }, ["{\"message\":\"Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]} - let(:respond_with_disabled) {[ 501, { "Content-Type"=>"application/json; charset=utf-8" }, ["{\"message\":\"Git LFS is not enabled on this GitLab server, contact your admin.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]} + let(:respond_with_deprecated) {[ 501, { "Content-Type" => "application/json; charset=utf-8" }, ["{\"message\":\"Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]} + let(:respond_with_disabled) {[ 501, { "Content-Type" => "application/json; charset=utf-8" }, ["{\"message\":\"Git LFS is not enabled on this GitLab server, contact your admin.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]} describe 'when lfs is disabled' do before do @@ -368,7 +368,7 @@ expect(response['objects']).to be_kind_of(Array) expect(response['objects'].first['oid']).to eq(sample_oid) expect(response['objects'].first['size']).to eq(sample_size) - expect(lfs_object.projects.pluck(:id)).to_not include(project.id) + expect(lfs_object.projects.pluck(:id)).not_to include(project.id) expect(lfs_object.projects.pluck(:id)).to include(public_project.id) expect(response['objects'].first['actions']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}") expect(response['objects'].first['actions']['upload']['header']).to eq('Authorization' => @auth) @@ -430,7 +430,7 @@ expect(response_body['objects'].last['oid']).to eq(sample_oid) expect(response_body['objects'].last['size']).to eq(sample_size) - expect(response_body['objects'].last).to_not have_key('actions') + expect(response_body['objects'].last).not_to have_key('actions') end end end diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb index 5c885a7a982a36..220e86924a2c78 100644 --- a/spec/lib/gitlab/metrics/instrumentation_spec.rb +++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb @@ -56,9 +56,6 @@ def bar(text = 'bar') allow(described_class).to receive(:transaction). and_return(transaction) - expect(transaction).to receive(:increment). - with(:method_duration, a_kind_of(Numeric)) - expect(transaction).to receive(:add_metric). with(described_class::SERIES, an_instance_of(Hash), method: 'Dummy.foo') @@ -70,7 +67,7 @@ def bar(text = 'bar') allow(Gitlab::Metrics).to receive(:method_call_threshold). and_return(100) - expect(transaction).to_not receive(:add_metric) + expect(transaction).not_to receive(:add_metric) @dummy.foo end @@ -139,9 +136,6 @@ def self.test; end allow(described_class).to receive(:transaction). and_return(transaction) - expect(transaction).to receive(:increment). - with(:method_duration, a_kind_of(Numeric)) - expect(transaction).to receive(:add_metric). with(described_class::SERIES, an_instance_of(Hash), method: 'Dummy#bar') @@ -153,7 +147,7 @@ def self.test; end allow(Gitlab::Metrics).to receive(:method_call_threshold). and_return(100) - expect(transaction).to_not receive(:add_metric) + expect(transaction).not_to receive(:add_metric) @dummy.new.bar end @@ -226,7 +220,7 @@ def kittens described_class.instrument_methods(@dummy) - expect(@dummy).to_not respond_to(:_original_kittens) + expect(@dummy).not_to respond_to(:_original_kittens) end it 'can take a block to determine if a method should be instrumented' do @@ -234,7 +228,7 @@ def kittens false end - expect(@dummy).to_not respond_to(:_original_foo) + expect(@dummy).not_to respond_to(:_original_foo) end end diff --git a/spec/lib/gitlab/metrics/sampler_spec.rb b/spec/lib/gitlab/metrics/sampler_spec.rb index 38da77adc9f17f..59db127674a1c9 100644 --- a/spec/lib/gitlab/metrics/sampler_spec.rb +++ b/spec/lib/gitlab/metrics/sampler_spec.rb @@ -130,7 +130,7 @@ 100.times do interval = sampler.sleep_interval - expect(interval).to_not eq(last) + expect(interval).not_to eq(last) last = interval end diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb index e3293a012078ad..49699ffe28f0a1 100644 --- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb @@ -13,7 +13,7 @@ describe 'without a current transaction' do it 'simply returns' do expect_any_instance_of(Gitlab::Metrics::Transaction). - to_not receive(:increment) + not_to receive(:increment) 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 e01b0b4bd21b1e..d824dc54438bb1 100644 --- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb @@ -9,7 +9,7 @@ describe '#cache_read' do it 'increments the cache_read duration' do expect(subscriber).to receive(:increment). - with(:cache_read_duration, event.duration) + with(:cache_read, event.duration) subscriber.cache_read(event) end @@ -18,7 +18,7 @@ describe '#cache_write' do it 'increments the cache_write duration' do expect(subscriber).to receive(:increment). - with(:cache_write_duration, event.duration) + with(:cache_write, event.duration) subscriber.cache_write(event) end @@ -27,7 +27,7 @@ describe '#cache_delete' do it 'increments the cache_delete duration' do expect(subscriber).to receive(:increment). - with(:cache_delete_duration, event.duration) + with(:cache_delete, event.duration) subscriber.cache_delete(event) end @@ -36,7 +36,7 @@ describe '#cache_exist?' do it 'increments the cache_exists duration' do expect(subscriber).to receive(:increment). - with(:cache_exists_duration, event.duration) + with(:cache_exists, event.duration) subscriber.cache_exist?(event) end @@ -61,10 +61,16 @@ 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_delete_duration, event.duration) - subscriber.increment(:cache_delete_duration, event.duration) + expect(transaction).to receive(:increment). + with(:cache_delete_count, 1) + + subscriber.increment(:cache_delete, event.duration) end end end diff --git a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb new file mode 100644 index 00000000000000..fd6f684db0c17b --- /dev/null +++ b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Gitlab::Middleware::RailsQueueDuration do + let(:app) { double(:app) } + let(:middleware) { described_class.new(app) } + let(:env) { {} } + let(:transaction) { double(:transaction) } + + before { expect(app).to receive(:call).with(env).and_return('yay') } + + describe '#call' do + it 'calls the app when metrics are disabled' do + expect(Gitlab::Metrics).to receive(:current_transaction).and_return(nil) + expect(middleware.call(env)).to eq('yay') + end + + context 'when metrics are enabled' do + before { allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction) } + + it 'calls the app when metrics are enabled but no timing header is found' do + expect(middleware.call(env)).to eq('yay') + end + + it 'sets proxy_flight_time and calls the app when the header is present' do + env['HTTP_GITLAB_WORHORSE_PROXY_START'] = '123' + expect(transaction).to receive(:set).with(:rails_queue_duration, an_instance_of(Float)) + expect(middleware.call(env)).to eq('yay') + end + end + end +end diff --git a/spec/lib/gitlab/note_data_builder_spec.rb b/spec/lib/gitlab/note_data_builder_spec.rb index f093d0a0d8b3a7..e848d88182fb07 100644 --- a/spec/lib/gitlab/note_data_builder_spec.rb +++ b/spec/lib/gitlab/note_data_builder_spec.rb @@ -9,7 +9,8 @@ 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 @@ -37,13 +38,21 @@ end describe 'When asking for a note on issue' do - let(:issue) { create(:issue, created_at: fixed_time, updated_at: fixed_time) } - let(:note) { create(:note_on_issue, noteable_id: issue.id, project: project) } + let(:issue) do + create(:issue, created_at: fixed_time, updated_at: fixed_time, + project: project) + end + + let(:note) do + create(:note_on_issue, noteable: issue, project: project) + end it 'returns the note and issue-specific data' do expect(data).to have_key(:issue) - expect(data[:issue].except('updated_at')).to eq(issue.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' @@ -51,13 +60,23 @@ end describe 'When asking for a note on merge request' do - let(:merge_request) { create(:merge_request, created_at: fixed_time, updated_at: fixed_time) } - let(:note) { create(:note_on_merge_request, noteable_id: merge_request.id, project: project) } + let(:merge_request) do + create(:merge_request, created_at: fixed_time, + updated_at: fixed_time, + source_project: project) + end + + let(:note) do + create(:note_on_merge_request, noteable: merge_request, + project: project) + end 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.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' @@ -65,13 +84,22 @@ end describe 'When asking for a note on merge request diff' do - let(:merge_request) { create(:merge_request, created_at: fixed_time, updated_at: fixed_time) } - let(:note) { create(:note_on_merge_request_diff, noteable_id: merge_request.id, project: project) } + let(:merge_request) do + create(:merge_request, created_at: fixed_time, updated_at: fixed_time, + source_project: project) + end + + let(:note) do + create(:note_on_merge_request_diff, noteable: merge_request, + project: project) + end 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.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' @@ -79,13 +107,22 @@ end describe 'When asking for a note on project snippet' do - let!(:snippet) { create(:project_snippet, created_at: fixed_time, updated_at: fixed_time) } - let!(:note) { create(:note_on_project_snippet, noteable_id: snippet.id, project: project) } + let!(:snippet) do + create(:project_snippet, created_at: fixed_time, updated_at: fixed_time, + project: project) + end + + let!(:note) do + create(:note_on_project_snippet, noteable: snippet, + project: project) + end it 'returns the note and project snippet data' do expect(data).to have_key(:snippet) - expect(data[:snippet].except('updated_at')).to eq(snippet.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/sherlock/collection_spec.rb b/spec/lib/gitlab/sherlock/collection_spec.rb index de6bb86c5ddd8a..2ae79b50e77ca3 100644 --- a/spec/lib/gitlab/sherlock/collection_spec.rb +++ b/spec/lib/gitlab/sherlock/collection_spec.rb @@ -11,13 +11,13 @@ it 'adds a new transaction' do collection.add(transaction) - expect(collection).to_not be_empty + expect(collection).not_to be_empty end it 'is aliased as <<' do collection << transaction - expect(collection).to_not be_empty + expect(collection).not_to be_empty end end @@ -47,7 +47,7 @@ it 'returns false for a collection with a transaction' do collection.add(transaction) - expect(collection).to_not be_empty + expect(collection).not_to be_empty end end diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb index 05da915ccfd827..0a620428138832 100644 --- a/spec/lib/gitlab/sherlock/query_spec.rb +++ b/spec/lib/gitlab/sherlock/query_spec.rb @@ -85,7 +85,7 @@ frames = query.application_backtrace expect(frames).to be_an_instance_of(Array) - expect(frames).to_not be_empty + expect(frames).not_to be_empty frames.each do |frame| expect(frame.path).to start_with(Rails.root.to_s) diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb index 7553f2a045fc6c..9fe18f253f0bc3 100644 --- a/spec/lib/gitlab/sherlock/transaction_spec.rb +++ b/spec/lib/gitlab/sherlock/transaction_spec.rb @@ -203,7 +203,7 @@ end it 'only tracks queries triggered from the transaction thread' do - expect(transaction).to_not receive(:track_query) + expect(transaction).not_to receive(:track_query) Thread.new { subscription.publish('test', time, time, nil, query_data) }. join @@ -226,7 +226,7 @@ end it 'only tracks views rendered from the transaction thread' do - expect(transaction).to_not receive(:track_view) + expect(transaction).not_to receive(:track_view) Thread.new { subscription.publish('test', time, time, nil, view_data) }. join diff --git a/spec/lib/gitlab/url_sanitizer_spec.rb b/spec/lib/gitlab/url_sanitizer_spec.rb new file mode 100644 index 00000000000000..de55334118f659 --- /dev/null +++ b/spec/lib/gitlab/url_sanitizer_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe Gitlab::UrlSanitizer, lib: true do + let(:credentials) { { user: 'blah', password: 'password' } } + let(:url_sanitizer) do + described_class.new("https://github.com/me/project.git", credentials: credentials) + end + + 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{ + remote: Not Found + fatal: repository '#{url}' not found + }) + end + + it 'mask the credentials from HTTP URLs' do + filtered_content = sanitize_url('http://user:pass@test.com/root/repoC.git/') + + expect(filtered_content).to include("http://*****:*****@test.com/root/repoC.git/") + end + + it 'mask the credentials from HTTPS URLs' do + filtered_content = sanitize_url('https://user:pass@test.com/root/repoA.git/') + + expect(filtered_content).to include("https://*****:*****@test.com/root/repoA.git/") + end + + it 'mask credentials from SSH URLs' do + filtered_content = sanitize_url('ssh://user@host.test/path/to/repo.git') + + expect(filtered_content).to include("ssh://*****@host.test/path/to/repo.git") + end + + it 'does not modify Git URLs' do + # git protocol does not support authentication + filtered_content = sanitize_url('git://host.test/path/to/repo.git') + + expect(filtered_content).to include("git://host.test/path/to/repo.git") + end + + it 'does not modify scp-like URLs' do + filtered_content = sanitize_url('user@server:project.git') + + expect(filtered_content).to include("user@server:project.git") + end + end + + describe '#sanitized_url' do + it { expect(url_sanitizer.sanitized_url).to eq("https://github.com/me/project.git") } + end + + describe '#credentials' do + it { expect(url_sanitizer.credentials).to eq(credentials) } + end + + describe '#full_url' do + it { expect(url_sanitizer.full_url).to eq("https://blah:password@github.com/me/project.git") } + + it 'supports scp-like URLs' do + sanitizer = described_class.new('user@server:project.git') + + expect(sanitizer.full_url).to eq('user@server:project.git') + end + end + +end diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb new file mode 100644 index 00000000000000..1872675451721c --- /dev/null +++ b/spec/lib/json_web_token/rsa_token_spec.rb @@ -0,0 +1,43 @@ +describe JSONWebToken::RSAToken do + let(:rsa_key) do + OpenSSL::PKey::RSA.new <<-eos.strip_heredoc + -----BEGIN RSA PRIVATE KEY----- + MIIBOgIBAAJBAMA5sXIBE0HwgIB40iNidN4PGWzOyLQK0bsdOBNgpEXkDlZBvnak + OUgAPF+rME4PB0Yl415DabUI40T5UNmlwxcCAwEAAQJAZtY2pSwIFm3JAXIh0cZZ + iXcAfiJ+YzuqinUOS+eW2sBCAEzjcARlU/o6sFQgtsOi4FOMczAd1Yx8UDMXMmrw + 2QIhAPBgVhJiTF09pdmeFWutCvTJDlFFAQNbrbo2X2x/9WF9AiEAzLgqMKeStSRu + H9N16TuDrUoO8R+DPqriCwkKrSHaWyMCIFzMhE4inuKcSywBaLmiG4m3GQzs++Al + A6PRG/PSTpQtAiBxtBg6zdf+JC3GH3zt/dA0/10tL4OF2wORfYQghRzyYQIhAL2l + 0ZQW+yLIZAGrdBFWYEAa52GZosncmzBNlsoTgwE4 + -----END RSA PRIVATE KEY----- + eos + end + let(:rsa_token) { described_class.new(nil) } + let(:rsa_encoded) { rsa_token.encoded } + + before { allow_any_instance_of(described_class).to receive(:key).and_return(rsa_key) } + + context 'token' do + context 'for valid key to be validated' do + before { rsa_token['key'] = 'value' } + + subject { JWT.decode(rsa_encoded, rsa_key) } + + it { expect{subject}.not_to raise_error } + it { expect(subject.first).to include('key' => 'value') } + it do + expect(subject.second).to eq( + "typ" => "JWT", + "alg" => "RS256", + "kid" => "OGXY:4TR7:FAVO:WEM2:XXEW:E4FP:TKL7:7ACK:TZAF:D54P:SUIA:P3B2") + end + end + + context 'for invalid key to raise an exception' do + let(:new_key) { OpenSSL::PKey::RSA.generate(512) } + subject { JWT.decode(rsa_encoded, new_key) } + + it { expect{subject}.to raise_error(JWT::DecodeError) } + end + end +end diff --git a/spec/lib/json_web_token/token_spec.rb b/spec/lib/json_web_token/token_spec.rb new file mode 100644 index 00000000000000..3d955e4d7747bd --- /dev/null +++ b/spec/lib/json_web_token/token_spec.rb @@ -0,0 +1,18 @@ +describe JSONWebToken::Token do + let(:token) { described_class.new } + + context 'custom parameters' do + let(:value) { 'value' } + before { token[:key] = value } + + it { expect(token[:key]).to eq(value) } + it { expect(token.payload).to include(key: value) } + end + + context 'embeds default payload' do + subject { token.payload } + let(:default) { token.send(:default_payload) } + + it { is_expected.to include(default) } + end +end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 495c5cbac00836..818825b1477e24 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -51,7 +51,7 @@ context 'when enabled email_author_in_body' do before do - allow(current_application_settings).to receive(:email_author_in_body).and_return(true) + allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true) end it 'contains a link to note author' do @@ -230,7 +230,7 @@ context 'when enabled email_author_in_body' do before do - allow(current_application_settings).to receive(:email_author_in_body).and_return(true) + allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true) end it 'contains a link to note author' do @@ -454,7 +454,7 @@ context 'when enabled email_author_in_body' do before do - allow(current_application_settings).to receive(:email_author_in_body).and_return(true) + allow_any_instance_of(ApplicationSetting).to receive(:email_author_in_body).and_return(true) end it 'contains a link to note author' do @@ -593,7 +593,7 @@ let(:user) { create(:user) } let(:tree_path) { namespace_project_tree_path(project.namespace, project, "master") } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :create) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :create) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -606,10 +606,6 @@ expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Pushed new branch master/ end @@ -624,7 +620,7 @@ let(:user) { create(:user) } let(:tree_path) { namespace_project_tree_path(project.namespace, project, "v1.0") } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/tags/v1.0', action: :create) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :create) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -637,10 +633,6 @@ expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Pushed new tag v1\.0/ end @@ -654,7 +646,7 @@ let(:example_site_path) { root_path } let(:user) { create(:user) } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :delete) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :delete) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -667,10 +659,6 @@ expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Deleted branch master/ end @@ -680,7 +668,7 @@ let(:example_site_path) { root_path } let(:user) { create(:user) } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -693,10 +681,6 @@ expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /Deleted tag v1\.0/ end @@ -709,8 +693,9 @@ let(:commits) { Commit.decorate(compare.commits, nil) } let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) } let(:send_from_committer_email) { false } + let(:diff_refs) { [project.merge_base_commit(sample_image_commit.id, sample_commit.id), project.commit(sample_commit.id)] } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, send_from_committer_email: send_from_committer_email) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, diff_refs: diff_refs, send_from_committer_email: send_from_committer_email) } it_behaves_like 'it should not have Gmail Actions links' it_behaves_like "a user cannot unsubscribe through footer link" @@ -723,10 +708,6 @@ expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/ end @@ -735,15 +716,15 @@ is_expected.to have_body_text /Change some files/ end - it 'includes diffs' do - is_expected.to have_body_text /def archive_formats_regex/ + it 'includes diffs with character-level highlighting' do + is_expected.to have_body_text /def<\/span> archive_formats_regex/ end it 'contains a link to the diff' do is_expected.to have_body_text /#{diff_path}/ end - it 'doesn not contain the misleading footer' do + it 'does not contain the misleading footer' do is_expected.not_to have_body_text /you are a member of/ end @@ -817,8 +798,9 @@ let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) } let(:commits) { Commit.decorate(compare.commits, nil) } let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) } + let(:diff_refs) { [project.merge_base_commit(sample_commit.parent_id, sample_commit.id), project.commit(sample_commit.id)] } - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare) } + subject { Notify.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, diff_refs: diff_refs) } it_behaves_like 'it should show Gmail Actions View Commit link' it_behaves_like "a user cannot unsubscribe through footer link" @@ -831,10 +813,6 @@ expect(sender.address).to eq(gitlab_sender) end - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - it 'has the correct subject' do is_expected.to have_subject /#{commits.first.title}/ end @@ -843,8 +821,8 @@ is_expected.to have_body_text /Change some files/ end - it 'includes diffs' do - is_expected.to have_body_text /def archive_formats_regex/ + it 'includes diffs with character-level highlighting' do + is_expected.to have_body_text /def<\/span> archive_formats_regex/ end it 'contains a link to the diff' do diff --git a/spec/mailers/previews/devise_mailer_preview.rb b/spec/mailers/previews/devise_mailer_preview.rb new file mode 100644 index 00000000000000..dc3062a43327c2 --- /dev/null +++ b/spec/mailers/previews/devise_mailer_preview.rb @@ -0,0 +1,11 @@ +class DeviseMailerPreview < ActionMailer::Preview + def confirmation_instructions_for_signup + user = User.new(name: 'Jane Doe', email: 'signup@example.com') + DeviseMailer.confirmation_instructions(user, 'faketoken', {}) + end + + def confirmation_instructions_for_new_email + user = User.last + DeviseMailer.confirmation_instructions(user, 'faketoken', {}) + end +end diff --git a/spec/mailers/shared/notify.rb b/spec/mailers/shared/notify.rb index 5a85cb501dd276..93de5850ba28aa 100644 --- a/spec/mailers/shared/notify.rb +++ b/spec/mailers/shared/notify.rb @@ -146,8 +146,8 @@ end shared_examples 'it should not have Gmail Actions links' do - it { is_expected.to_not have_body_text '

    (@X2 ztu8%-I_1H_wAFZdn#?6juen7Z7To3advfLS7rjD9p@0cHp6pZc_-JW3xBQBtd`enT z*1@|^#B?<*Zl0Q{kbZUl|2fXT_HW*6I@d+RDD>RC>7D|o<7~7)YwljnkuIv<`+0YG zNSe^YJ4e>d$bPkF-{K>cXEIk-PvX;?9Q^8U@@2)1T923PIu&_FGI-`s2dlNr;cx5y z-#t?;Z(~(f^x<#8e&f!n4ReLHg3pKWzPfun=>D8dT+h$dtljkRV(6#O&*LXQ+jg#T zH$#{ctOi9ingkpYQn`Sp5#=WG13IPW2`PJWAFbA{qJ$Nt^y-SS6t zH=Cezpaqs}nrjo8wZ!n}j#J4-qF=mLV(rVX&)+|pr*zVsC+BZ!6X~{O(lQyrmZ4H$BHT~G0?)Nu^ZI*@2pB){f zK3&h&{onP;vxAFEPOb}|=e_5c?;O?ix-ZH``BiJ}cN)IeV!@sUvRJrIp1gR&>CtcI z!VTBo_h-MlI_Hkyy6~K4s}BD63qEZ|ISu`Z$cw7@H_w9ip1k|%9*a+KRoA3HQ;MIT zJh#p)Q=ZHGyjJ1AyxbSha*i^nE=g#-S5r9W%C=3vHb425tv7k+C4Wr)bn(Huyt(o}x_Cq4Ax>+y6!K8Sf9qo&Wo2%DG8PPunS7nrUsldDS+% z?CYwJm!EPyy>4p%cGJ_}boEcZmnu)$w|K4flaubJpI*LRd#17{>so;y#03s$NlYR7 zKvB)6=)dVw(H?uOz4MQYR`ZqbOAM7?yWj6Rzuz5}Eiw5S`Oh};=PJH#zrNA3=xwhZ zN~15qfran={kfG>lEceiJ z^6RT_cYn&;xa7?dAD`@k>3bjKY>>Y`>*j?QYfE>}@94O{V#<&FYzgVLYqIvdxYBt( zF0->|{o1#shoU?~*Pe;4DEttmV?94!{dN4!`FGrZi)G%a-By#MHGkEOd>*XhjEj90 z=FAqhJO6y)$JV}!met0`wogww`*?QsiESSQ z4_fE%d7S(H<_*=gZ*A>ERMmYad@)~MJ3Hsx$9v!B7_VCDlQwU^&$KgM=XGN5+FtLI z^0h|E>adi#*h9fj&+pEjdG|IQz3H6)T<+pyw`ippLpzO{8SY=go4QeE#pgS`-gf`g zw`cSE(`$a;+`4J)UAHNxX3EdZQV+UckQe53{#N?7NQE*OyI64~U$5X5Ng>o7?_P z|5SF%^6I_2I_K>^o<5_jZ~XAeFV6*8hdf`-yj{LmYxicmpu3ws-#niBciWx$9X`Jz zcfYCE&u)5hCpGx#ou4oH=jBB258GB{w_EDYruCk;jD*?B4Ra>VxBoK1X7^spz5d%T z-FjBjai=g(pcEzQ;K{s0JD|sA$%?IAQ|DiqU)^)-_kykNHYbuVe7hXa{d#uPiNzkj zv*q_yzGW6quXp}wRdd}9<*xP~k;Zj@KYdBIpK?qx{lp*5$Ej~_2;KbrO6_Ku!sLix ztH(^1dynlbjyYQL)8(*B<))7gP770SU;dO|z5Vne*YuO^e(NSByWgK~dpmxb`1Tiz zL)A~E&fgicY}!}h8SnmIWcn^|(^FCu+nST<8~3;|{MxCQ*y1eS?gLURlj)s@* zYZEP)p%~J|B*5?(mZZbQ|hOOt?4J8ZC$_Q*Ti=piR0g^ zzb78FzGknfUjNDI=Y<<)H+L?MTsD7qz^kVB2fh^BD++J7(Oj9|m&0MV+xmQjO8WWV z6GBcIR{lRAS6TVFdy{p=mjd6zK|8AwYm;_fpZ9C!n=JlsAHF1ST3a|Rrr=%8%%Esx z^_ma+-rV>yXU~TF-^~4%@mzEl{e3qBsUrxFEQf>(EIRAe@3Wcc<>l<#`D<~##{0Dy z*R7+39(J*b6)XMzaKtn3v}x+P$~F4eD}JFAX^o4xw!Eowop<}`%%VFnJO50ow6%IA z{%@m>-JU43Hy*b3TS~Xvd=L5XO0d%5Ud3|XW#`s-ecxfers(y{h8ofH3!J{&|6MFE zc=MxE)l%l$aTB)QzO-CPbaKkE9nPChdvcUiHCvaY&P|;gGRH>KW7Vx`KC3Rd>^1d2 zapQc9`sLu04Why4r~A*_=s&MYbta#x}yEwzgKaUAb%Jd>N8c6NfZ zb=lHMPw&XBoqpoZW-*q>(!sL2n|`h|-DFu>mU2rn$b7F-g--rno!v$y)Rl`nanbyHD#-Yr2s|2h6SKU&V5thu_!&;;u+ zxj`4}qN1WLwyV|)tV=o@d}7vOrLraVQd=YB_wA5pvs+QPv;(<3X-rf#$h%g#X-8sP z`FY{zdXxO)t0!Kms6L%?@96bYqVqE*%u?8YynIUEY?bFaJDv23COt4o%&3|A_ifn9 zDHi6lKA(M$;Qs z&#mw)y_GdHqMU!}(}mp<_U>ZmE*(*|zLlE);^XGa=l9!enEgI>|CY42nopPKPdxo> z`IBnBeBt&}ceYu6&oQ3b>#Gu{>Zg5d*}J6lx&MsL?NL4F6RQ6E%I4>Gg>P=GX}gpC zWMAIw6>pCCv_(`FJU{$qv5VjSH~vrNtbF%7P4MxP9@X&Eo4V~MRjO=wZmYREUgNa* z*-eg-Ppf@r9$z)>%DKte_QkCxXA0&`oGluwHTl^*1A*6(>X;y(ZS>({cUOPC9vpAdcintS`s=RaTV ztIPg8HE(wG_Scuqs(;?PV<@(KshZTT=T>HS(*91H^5QlB_LupOzM6kt9$WTw>;0>q zmXI7H;mKql`**S9-Z{3_-&C&6H%dLV;9c`kK?jD$gJK!?|E{swQs$i`{rFj&+VwaQ zl}V-BJd2CFx5&PpHfdvMP;j(%D67r6Eq@C(Z`pHSGgVaGqxwV5$;nxMd_woQW-M5* zarfZA`?flFQ`Jwf&vi@+x%0PtyZ7aHYA@HUm^A5}-^vv$r_NG(yF2xMUZy^`&~&Ta zOP@`7aB=p-JFAbFZukDYFD-NOCI!uR%$h4#O}zCn@T6a@Yf_C&C z?3R_4CA75ab>%|$iZdS{|BKmlxSd~p*}AoB|IS|U$?ZcHcigW8PVcbGpPDc1+{$|P zp51o)`!-hX(#fUqySGNJ+_-Po)}NaFi}{6*_ZV0FGrK8m zen(1l=?DM%_v?-BSAA1^dMkLH<)O!K_k6cbQ$eZl1131Ua-5VJ8Wb(Rhf8WU=Q@da z?XQoGpEJj4d%oNMpwwHd$vwl*ed4<+C?YOrq{ru5LLl&*9SE;-H zn{|9##=pHNl#HS+8Fuw?+kczS^DjduIv+F%; zelO|J=Wov|_t}1be(SH<_PecX?u$vZ35$R3J@?)5+}5ylcFDcM$s2K))_`g_m@A+w zpf0W+?z3-S%-@Ta@gn-(KnI+44tcI6v3FX0!8~mpn>f zgB^y0SnRnV!qW2S4E1+1g^%67{Ps|a`O~uL->(BN_5>FH{)ufE;=l@NQ*;Z35#wHM+0Cr;qF9<5OO`PZyFY4Q#G&Mm$^AzSZ$+}5?$5?94y zSpU0vu|kU!NWWsi3ntOfKgEk*tnfk1W}*e2!4sA~dHZ`}IbQ$G?i5wrvHf*xOZ@G{ zzwUf2e06lz>WJT+o1ZI+8cWIdN_{_jPJH_6_}?{u_ibCj-=cpl_qT$?jhk1m?zGQh zx`i@gf*OEmzEjxmke$8y*@F@`{j(=G9zJ{Zgm z%y-?zqSpEGzLk3`H-9=iclG`2%X0(YKK$!?bXTF&;`m*C%DHQO^Vo5;G$BENYPE(> z!t--;XEk3I++(7CeERdpeiBpfKb8*nShM!w?Bl<-oVot~m{?T*t^9?bc`E)C__n;} z4cTbN5cv6r9m_tmyVW7pKX%m=-dfgvuj^xmckyTIPUAXIipHKp(L%bxVLc0I-_Y5E zmQs66)ZO_{U-X>!Rrmh!XWA*}3f8<`d|^|>XOUg+8jklbbJ_9li0%_+;l8V%3!*F5 zKa{Y&{^qiBb@~3kk2dywTlKpIQUj<$*+9K;E^6Lzr6?~UX zw=;Kp{ch*Er`s~wR@u$2_&;rW{co0&1*Z<F@&%UgA z`0c*p-tNu&`mP@C-MVevg1uYc{{6l^_t)3U{JI$yzaK1FDIaC9ZBJ5M5{o^g?SL(n zql+o%Ubu2)OX=5FSJ(f0d;i~C|7MjPwT|xDA1=wroISpA&YT6aENXJEiR;yF-1qa) z<1aQc;#Z$ZXXoy-T$6uf`eIW-zxyTTE6>y}Ui_=(ZD6j|{Ilx~tB%;I&x_e{-u8Sb|M!=bA+x{kT>8#YJ~b=% zVR82L8SfsH>QroH*Y~Z-=8pTNapl~DrM2&Dtn_N~iX-C%CPkQs&#_huzx%8xxoGRo z+OX|G&o@-9nw9$MTVzhi9O-Psu(spRy3SrtFBTI5t$c6)B>RwO%?wW$tMqk0KYf*+ zqkryt+Q-%@R{e6j{I}1`D5={~8+Cnpo#EOm`m6WtpQf<<^G~6NTlSi-Pl)I*d}wC9 z{nE9KpDj|?NxZ%6{Cw--wb{`>Y*w8;7X4B>y*5wM{G6;a>Yy8X>V(Jr2hIq)j`inr zyM>>3b8g@HJTLb8rq2a4SL@5He*TTCpL_f5ozui#Z~M9}?_}1r56jByFYlUrd(XRB zQT+0Sj}JZmH23wMhlj6=^QI%gp1y@9#dw$vc{G4@l@$+ws zgrI)cHhyXGyzg_fbMpD_ zTf|3Sxzl>&*RvO|EAG!>zGoIB^iag_{)81Ri(_g7U+k3>Hl4ohHoM#R7uVM6XT86b z-~RTbS9ZDg>&rp$f$eoGOV57LzO(M}THn`IH>BRp1EsjDrEAtczqa-MxwTsi_w7q5 zDbnk{Y}UQiQs>;cyLH){XB5oe8vQbE_12@hzm3e^NgcsH1B#Zm4_pvCF@5%g?C-5T zUyrukKJ|f86Ok8@jzv>~XaB??Z)R@23SO-<5bpRF-XUxFgdXQ`q`t=f=F)`<&MN(|7** zbadC>uPQp)|xG4+IP#g=l$Im^!Uq$+N`^`wybNvJw4~- zpOWO_qp5BI$YTO{N?tnC-ULJG1diZ12J8K=k-*+Uozmpcv<32AeCvW$?mw$WVI}V=jE*5_oc6fT8TdKNh z=da?gt&1K!&FWox4^xN)ssmR$^YxCai5qp1bacTLSqY=?p zcAiblzP<`G?1zzPh}l=I^^0=XG{>gdbKhugagH zZ+P?O|QrbI01e-+teE)8h5@OV76MnzoZ~?)AP8TX)t<3BTK3NMwJ_ zL8dY3ncS0Er>{THzHGbuZP@lp>rS3qTXH-ydf%mEI|?7}n)mxwj(nb^sC3?TL$mdB zqch){o%4FT-L8AW&TxmIec?#|73x!UffH0NOZGe zwVy?^^=>y?FORp#pFFo3F`^%kg0`u&(uH9PvE%k5f6tnPkhC9Da z&z7krE^2qNJbET^r1SI9mfJ;hqvuckHAgY_+=7T=}2B=3a2Q`fO|2_d9E&>*G%+or^rP^H)i% zv#Q`ae{sR$4U3NZMsXeAnS8fu-BMjYZ`(t~YSG-kGmCdFE{TgioqK)P*4q~5*KXzX zygh#`V)xwNkM5e?uh<^{eDl}bclWmZe751|Ay9(&JXPwo+{3-QYp)PhMKCn}6L^uk zuPJ}ddf)FddFAKt?vl=a8}{qhnzKoFz-jhcTB+@Jv(?d=hEcZ?H&*2phDFVuDwe%; z+wS(Qw=1@nJg$n~{u#4Y)``NXxcQ+MlKi(F(XIkD}+4rm4AKxwR-F_HUm}k$H%X@jPw)SD= zp^u%M)gP7L*@!)Vw^sagDsSQQEqyz3#q8glnmCQ)`fYQE`x)jRPul8l$*bN_81?Gm zx%oLK|6Z2OKN(y2{Di4l-u(RXZTqTy!@eJFzx~GQ&bNJAUfS&Y`14u$@8418lVd)M zBu&YdL!D^ARjnnYa348qctSMXBi`bg?f0vXw?y_t?<%cj|9U6)^W59kxwQ{3Ju7^C z$87ff>(9R3{ITLv(&5yQJ?mqSKab zd%8Yujh?Mq(dzyBd}!P881MTy;}JDyR6vq+B{pC?AowhAMvMSo-UiHe%U@VQtqr=Kp?F zlWV27>h7;CTWT|G?=Sp(Gw_6kv@_~%B%C83UtAZM|KtixUUaLpK5u^X`K#%LVY@b7 z6I;GTqI}QQwf^4Kne(e7c1Q2}yKmRASAu$z*B<>ZnJ(L{dF|D{pO3b^l&jfz^w#Z$ zGsZGP4@GYJ2E5Xr5%YRSZC>p6NAq@n{b0BD{HcQd)$0rc+g0l$Uv_WaSMaiXt66U; z|9!a}JM(jEcmK`1+k0`>*GS2C@;#pyZkc{?N8L4|0>1H}_=l(2M{Z8dpR@k#v!dU3 zc75CZd|#DfuGnksyJl-|pZ+FrHUF(tdV6oLmg%`;JD2L)$-M5~Xqi(RpJ^EOtgG<) z7K`#Z(c9~^i@!$t7@lg3T7JD+mans*s*r1Cr`KNFn#Z-dt>@mKdwA_`<(63f`~TMJ zOHTaxvU_V>^l@-YoqM{NaNhOL9|WgLJlnSW>xYW_l_7i9+vd$)w|HaKk9Ep7C;xmo z+x)UO?t_X@GK7Rpqs31CeRo}ZwU^vYTDzt6%^k1Y?YpM#Gkbmc(%R@Xx5fHCe*KxW z=4|iwpIf&m$L~LyDcM*0`_8W2+oH>p*W~>zdpB*{ylp#6&6iEsmCqL+9sgV>f>VKufIH7abF_$^5OEcJAX}DY-FFCSMIYzS6Fs^+R226MmD$Z?q0jz z@S0q?{5HRee;;=0pSvz5C;t4--QqbvR!Gb~{wr2IdofYb!^qO5C}6Iy7$394zGhwZ zRx|C~|L=BQUHheXvt9hlZLU}EmYN=WRP#1(|IwXGzlsO7tv@;U{I?0Kw`{F346NPO zmhTf1oqudc@z>Hl*5T`ZIjmJ?p2;!&brbt0|H8v3eYWkp{ruYFZ@(YiFBdHCbIc{PRG`af9Mmj7P#%Iw_R?c1EZ=Q{J>x0`Hx^uMJGZqy<3ls+?Ll|f=FPvl_KfMZ z-i&=5g+twes`)f8VVv`g%L&-HZar*8kYwzp8GOel3+dM&zbLXU7B6 zuRnaZ+WhZB!@%cxyVuWKefHO#OKV@7zSz0R$8Ou778KPv5_n$J$?; z<$rncCcE%)&bk%b3hIBv9RGQ%XzTOWm;VVC_e^oIsGj^-rS0ppvzLF?7Vm!haM#+$ zeciW~_in9|eciWt=bA4^qvLm6sk~EReO^5M@3#IA_ukmtuQBuAXOtx;J$?QCN558= ztlz%>T0$K5#T4kt>wxHn8rJP+!_SL9f6c%BsnvEn?Na`IyS5(HygMVN^z~-buXk?U zxpZsomLCO~e*>3FuP?p-u(eKzpaW0nqfVE+ii)}*)QcD z7K-I(@A!Ky?eSXuS9fl;J7r$KDqsC^=a=JFXFAaa3b1n*`zy?uE)cG8e+MW`uY(4I z!nPa9F@sMTxzJ!-^c0Su&r(L{OR9(&Hp82us%O0<> zjd44>vhdwQwbiZbEoD|e*130T#m+T%#h;%`E-XB~;^(72bv~ltoo9eCFd*id~TH)QbD^w5NJSOTjc}Z98k(t+%4lUg+ z{`&H^n9{f9>z$Lo7To@FC%620@$W5p?Wz-8&n6ec8{Vwdt$BeBGJ*aMydARcCXz@6DS1e(B$L z5BqqJKkourn|$|M!R)oEAH`m8Yrnnbyw~gRQwx)79)H^U_4=Nl*UsLw4-tM?Gu!My z!Kdl^W`48Jg`bEK%TKM~-F|m%bj%Ll^KUucD~HeTEBu|yr+fHw#%$@;f2;Be^X4CO z+nPOJ)~tPQ`{|m$Qu69*Hu;9<-d4S}x@#FLzJ0D0%1j&D7%PHn5WqC;cEE`$aKj`o zK7Pkp+wHriKD4ZPdn@hjPOt6f*WQ-8m8QSl_jOgo{HZ6ez1e!WR_w8~y!o}c$~OJC zmw*2I|Lxt|MXxO;XYc|MCBSCu5Ek?Tgt!6*z1*Z zwyryWX7jeb(zx$^KQyjC-u-&b>gsP1d-mIz&aX9<|GZ}9$2D(vUflKVX@|DrhC8gm?p1JTIIx-Jlip$3-|}xw zPxn8v-4=EI&PAKgrE5MHtaxp8KBo6*O?vF>S9UjVC-1fU^f6^mU;NDa=SI_#YyFSB zvig4Nmesdi_oB0Z+f*07`DwrL-)r%Q@BU1B+&*Rcx>q*$Hg4|Q_2&FMx$aV%zwWbZ zZRNHuzM~rKvmd-*Zq|ElNaf5aa?I=y!K#$Uf8<8QpM zH5L0@@hQiBXO#5kd-5AAjO0G=Dqr*3_*8Gw*5{$0x12D%S6z0m+U<4E(HZk?pZ)C7 zF}{90D!O=aZT7u6`0^SgI5%h;?4Dn6rT&Wf>F+YA$^4yx&!Pe)+qv=foch8S59_WfZJ_ zR#&=jcloy`7O!6K+%@lP^86D|gZ1Y>tyB)rPMW*3=Xq6#^v0S^dcTeAq!-t1FWYu} z^P|Fbe{4SX*`)VgtvFM??s>YY;Cugl>yN*#`m%49xjI3g)a^fTPPRF=b?)9U)5UiJ z*F5WgHuJopUHCco$1@|=_EyF(PkdHocYW`=^_%S<8(xbz=l(m@|LoPucT-Di&)kx! zuG_lKwshaCn`iItz5lLy`>T6DmF`?)zoF5k|KMD=N9q1K&m;PUH&%SQyLH+5?ASBz zKcgmByX(xWIIbbKv!_2xY5w`Ze>t(&jz`%0_r5=uT|f8zxA>L2Kih7c-cC5V6to|B zXWJ5bSL1qeY3%cllCP>v&PT{+=byb=xqju&8Q)8<^%pI^6?Z@TmEB&mYadh2Uw@Sy zo4mU6?A3q!-mlPmy}qaXefd)!|F=KS^X`7`x?Vf_?U%l+vZSqPX8p$L>-ty6tX=#0 zp773j=VwW+FP+(MIB#C`(SMl{e_mF9EzRw{v-tcu`vppW^+h-1 zU#I=P5>-rGQMc~!IoY-~vU5|XNxzLw4u5|0`f-cs-m5>g!e1xFUB4*q-+R4u?b%s@ zZ|3`+vWpD<{_69s;O94IC!c*PCwcngifzwd+bxcH7kxbL`t_~f-uyYY*KhCd<^Q`2 zeja?kt7PkD|2@T_zRqKf9~36 zB>(k^wXyi?ilo@&THDo~6*hbKy_@>e>ewE;$oZg}-TkZk&pXxI^-@3XF^ z{9FBNw_UYy-1V)?-&?PK|99)UXH|RFz22QwV`d+1fBX5;kN$f(#61}I?Mm2k>Uzvv z^?w@Ec3OSgwQt>4!~PnZ!go>8k0;una`m;@dH(vV{r|7k%zgjm+pK&4@8|#SyYji- z{d?N#d-GnuzAC-QZ2k|Ozbk*9=*_C?HwBeHI9e=Fsf6$a_kC}?mA?A+P3h8Q-`8B* z9Mk)}#_U*n_Z^-1$KlUb&pRRe^l{C{E4O0)PmXv}<$vwE;r;m=_noVdcP}*!dv3jV zYueT5*Z1=NofLm~F6r3xl9HX7p_6yoJ+m~DdwsD+toxTu_?08VudVuTWZf;^yYE@C zoay^dM`m7HFh6r@_pN#7&zs*~|K2|Ox!uhAl>Pg{-({*0EQvVYaK!Aa-tbEDXgy>or~0a^z+HSjq7S> zu1{Wnwzlk1>HP4sub;nvAM-RT_ivA>+~?4B*PmHc7tKw+_579x;e4<|3shyL?Y}CQ zUbJ`Hy4N=6!mcl_JoanGUR%2;`J-8Nrt(kSo_FjD&HZvD_;pe2ajW%Pca}eS{POks z7vJwM{!{++-Pt=EvmU z>rc78kGpzWkU%?^k!inw!t=g^SN&_ZeAlu+_4P)U?dhu(=YC7fH&3#)i<;kg_14ur z&o0>|N%lv~fBtJl-WBPMzpm_c`zUp~^4k+DQ1*zr{JJV{YuwwNuc|ZO1?wF;8^HAQ zjOyaKzoI68wtH4-H1D;H`^Uu*XTMjzk)Ch-=;M{2;ZI)YNAz&4B zX);&kj%L-FoHy<*5|lo=S^ZeWre){-+ujc zr#`Rh@#5)iWxvu*p(Vlb^{+45BwJpa*K_t*U~d1{d$Z)vrhk=`|LU^Feyd&a?u~2q zTb=uN@yw&m-+NvuZ|mwWTKuXO`P(W}esAVh!*A-vi+=>Jc^Cft z;`G-t*=x=j*Qd&SJ(IM#VxH>f+Pz)rddIB#Z6B@NXm$RM#- z_1FI$*;Uu){eJ)J{T$-#lCg_+m8?)VkF|ZhxOS`kbHii8Ws==rGv;lbcwYT%`p%x~ ze~qVAADQuUam3mCrv0CvJbzLBEhgUmuf{fzEjO!`ug|YI|H5+f@fGnsglpjmOq+jm z&b%+#|82%o_m6VXYqQ^F%=_tnEHJ;`%B|k>?aC~>_qB^_j-BiI`Onxk zuzKtJH`VV}?0>qZJho+Z#r!fu4TaBVO6SF2(wesO=8Wnq8?U>qJC-E-yfebaQhu&s z_CBrue=W1}pQUd!{u#B~`26{8!P2ICC+C~@F)--od%8G={L8R?b+Y{Hy`JY1KWi?T zU*Da4H~Cs|>HC{?j|fJ^f#;lW?ilX)wX*E{ysN#BY|GMOvy0~?*BqO3-|(94E1Ub9 zyUu1A$tByA_TT)o`qTZblCP8RDi>`oeS3OVWX_cJTi;vk|9a;9o(09J@8`}7JnOgS z`jxLUE3bVstkba-dmXsu`n6eB=XXh2Tg$&KG@JG{{MfC{*6~+e_2!lQh^qZ7d(>$E zsZ?Lt^VhD&5z}-qW<3|D5OuY`$bI9y^{7^{n*D+1tIyWRXV;#+ z`qR&MZT#8lye)RZ-M4-{iOhbJQMdGY#`*s{Kkw%#|FJ1PNFd%NX40$2ZyvwBlIr_r z;%6&2oBKOwxv#U|s$Xn6?X%40WqmVWC$Fu1W~2Mcx-9vo@YkP5o?BF9)n0k`Mdq!h zKM@6_(uMbiZ{BRYY`p4b=hs=g?2OOfvOD(t^~Q+)q`lj&U8%fwHDa#(Q}?YGh5euH z3;X|X_D-4qbN|Mr?(4rVn&#d3UuSc_>iQU&TQ4QA#`Ip@XZ(51S;HkobtdPs!fQ># zpa0}to3!|Q>V4y57wwPrti5+VyYJe@@bxEeXvE!@{keEnRQ&g|_hhQ)5>anHSmkif z{l(*%e>at1HD29WQD61uj8%4V&)(vBkMne1ZB93R_sp%-Htc-Z^VPd%t^OQZf6djm zKI`2Zn{TUZYv0Fj{iplib;qAWpPVArE86V}zB4@K{^r%a z&3}&&F;pQ8Zo&k=eYba&^wX+0uXcTVYIFR@8O!s9BHc01%8!Mf)d){6otG|ow6AF5 zd;fQrA8$Mt)3vmrJlcV$cb;R?Bo1^-R7DrfpzmxSpG;hoK z6?XTnrHkiB?t3@W)Y>-k_Hp;B-*Nhp^^g9WW*s=Ar`h|+_S*H@{j=oHopT!$~t2c3fZ4tcwWbwI2H-&$O`o6pTy1Y7Tza=BV z2KxiO#yy`WJU+KCa`&$92B(n;Ib9U{k&vUFzBdw*@AIb8cf4u6; z6HE7<{r!7y*9+=x_#AXi^v>LWb7x)M?f%z#W8CHIAJ6riJr?PEhNQ4PL@BZGU-dYD1KgN`p5OF*6+71+p_NW z`fn?D&aJF}zao8k+Lh@W-G3L)k3Lqun?qb)tMT2g7?Iy|Z?3*3f7bn{)amoV_v1es z_N#xAjPG52>%`N`-(P=>*kQ|NIpI{&)W3kS-040&#aEsWa%aCJoix}>~pQ$ z>&46WJzw!nqyBlE`}b_s>m7aNW?_a-I zxzQ^AX;$pH;x)CBuOIvQe)+O*?pMFFFa8R4r*Hqi`q%6HZ&z--+w=X~*LQY--#y;X z{C+3yx3vBt)}Xjos}f*^_}gUL@bj^;@i#ZmTJx-OS?JlhJLlHBY@XF|zNqrp8p~DE zSKoh2SwE3*m0YmgVej`1)%^>$b&+3Fj9df9T4@-KN0NB%!$ zUY+&--JbW+-%s7i(|K)QR3iB9eth)aKcUY9L$6z&|EOWV>hz7pkN4Xjyq>k~`HF8E z)2d~!zJ22Ue??gB;$ML}-y@!GQaiTd_S&=i-bnUFCKJ)fj}eu)>v`hFOxyEcT;9Hs zd|H;Yb=kScwxzbS=J%%ly%=#nHv4r=Sh0J}R`(}v{_}K;O7CTd?~MDs`g(a>(W`*| zcY81IUj^3otgrIj#p54dZJZzXe$L8kS1RZ2J@#wQ`fUFvk8bv!&H8^cWt0Cix5qE` zF19ixn711a?B<-amuKs$`A^+GE{-^V{cDC@S8M69^v8Z@*L;usIM?{F|#_^)?8w%I-9 zvbKNkx_|9|CjU2Z{V(P1r@n7aukEwV_a&T-E5sZ3+@J9H-Oj#O%J$W6JLRl5uiI*Q z-te5kto2DVXZMz#k31Xu@#=1+>HholucbfV>E5^1J~{pPT-&m&bNjwe`&GW5LtNfS zKmDxT2QB+kZ;xd8&i(%R%AJgP8)dTVj}^r{-L$OVcyb^pb*@MkIlV9NUEhrt@~1Vn z{a*KC@1^;*mhblY%MwvO<~8owKjHDszvaId<$dXSWW6yi`1<0?-lLX9caI0=iM+1e z{aU-))!*)~tz>`Ul+&Qjz?#>=)meMaxtlJIcpG_E{$=djYVUXEF)iF3H=nM#`(wqr zW3Tq?%U7RgYI*LL@qX*RZzjXt+EgdssZ1+f{6jNp} zyo+{%r`69-d@WPGXWeU?*S~iJ2UnlFcKzP=8TOx*VrmX7?hdi$u&!Q{<+gJ!Xb5%n z=fL=5MQidTPj9SBeUlOM^-9dSV$gto*VRADpN;=_q-_XJwd$(y&YDej z$2*?e9G5!1PbS;#iM-#qYu)D` zIiY2tP|nx58QL?)t>9u?_8`gw_kNSLjHASmEQH$vjW#0dsVX~{_OY4 z`0M}Xb(h-geWq>IzrJcy`SxYkzW;m^v-jPlUpN1|?xDM{wud~+^Q?bjkoV!L*c@LR zarXVW>bvKvLWDO~yo%hfbiY1)=bBq9Pu{v(aouip`3b_q1T1b$<*^;NZl;GC!%XfZF&k39T^VhkauZ7E(eZTT`@!!(* zFaK=+EB^3N^Ey49vqiS|t}m|5K704`;=gV`rB3Vb0S$A!F#dXD&9-BoV>f^Fd7IPk z{^%qB%f5P_o&NIjmb2ps23~`M=!@?{MX}lI&YXWEymfQ>H0h)LNw)i=uHVV9>pGf# zqN1<-Xy3P$KkfRzzL1=2_&Q53xpvOgGmkFrKlSzR{kp%N;tz#Bzeu{OWe@Y@Ya2V~ zb;WBo-mD3+?z;Lf(k|M&MehFhzpwb0^)K}O&Z>R& zU;iHKF8Ih8K7AuNg3qnVew!0_-fFevQTL6Tt6ght+^g4SRq0)G_piMl_;&8kAMG>$ z?=HT7HEw;~{Z~3ggo~K-Tzh`WIquUxcK7*;vT65wzwa`B9aU{&f2!U6+LMUn(z+@0 zue$BAv;OT;yY_Zuf0mM%|NYn6zrL1FU0o_~T>o_GlHK>V?moXN57d+gH8<>v>q_6x z-S@-r{HwkqTl*+?oq50dKt)NUO?Ka>$nfLZwp;HLF)Q@p9aFfTmF(9upLTx?jP1Qz z`QuvY-1S9~(;xfguHAVn{QC~0_qNur1AUJ?S~>r*_NTw)Q-80EdLQ_@@7eD6*0<7U z{y*|xDW+z@+-{%Mvy68J=Jv0>wtMHA(}w$Z>^fK3clVLco@>u`yCtt({rTU!#rFd3 zl56kxyzdGBx6tMM)O~Y5uTUgBc=>0^fveSm*5#U@X%xRT*VkM#HJ{yH`>bfq#?7B^ z%9YNK^zFU=%kF-pyKnukf42Wm{F+&9U$idsy|(_Lql$7nKZMvHd1tqJS7e?DxV<~? z?Cz6m-ev9i_O<-1O}78s>%T6>t-f_Hn~3&;!Uvhg)#5YCeu12FHRA2+&jPDoZ~lC% ze%tq)+W%$gf4}xQHPOANK<^060izA-(5KK%Aj78?CdV+tUSJS#a!FIthAqjdyfCI zvWxD$T6z9!>DslQ@9w%)T(+;u{d{a>f0dG$zwPVrBk_cb0*1!bOyT>#Ra>90F#8_+b?(}gUl;$pXz6ClfBfGe*BuU4 zyK+oV^(QUf>joMXcmKQk)~wlQfB##(YsK00(D35G`Yq>d%a82~e{Xrp{jZbr$#Q0Qv@7H}-cRhP$v+wz?d1uRCXZ>Hb{Q0k4?=OE|TzVw!e8&E$ z>M85D%3J>b(p}KFuUPQainM9=!tb}P{<^vN{EhmQyZ4P(%{;2Kuga}@{VT%r9E?mX z|7u^pUUU3i>dMf&I_6#Pk5rw_s&#+YXM1SxyWr=x=27R9R#!ZctNmpufA{^;zx7X* zViw57u9@|;{PE&la?xw=Ynp$GnyX*GWpCP+^Q+8?cRzknyL;~|g5#WwO#1^LTs-Y# z{ny=e^B;|U!mmx!udTin{`}GRYxgaG@t(^%cdYn*Wc;)Gqd%ne4jmQWSgrU9oDA0= ztGb`{wHSZ}ZT;loo8G_rf1d57-|y$HAtDUsD{iP3%=(g9Ruyi# z`3~G*>1poO{aNRZq-_;EzkI&ptFWJec_Q8CuRTt`UfaL< z@78_i(%)Zlg92d;VtTGzUpF8-q-c5QJ* z|J>N`wdcQG|7CUlzFYs?*z@0BK0mi>_wl-WtAF3$dVcA5`B=YQTVA#<+kI~1?(>0n zA+_SQ>yB5G-*3BTnOyhu?;H1z7w_E+K7MoG)@A3{fB9m&hKLsU{=f&PT9?k97kXA_ zyR`h(uQztDeZ0N6WLco^zh_nX$HHwRH@`YNYi@1U+pK-R_g$6ae|qmBs2}s-oVWMx zYT2u6KW)CFaWA>n_Sc`i%hrQz?Yp+P92`CK{Oz5Oz1|W0*`xMt?X^E|(krf6zVRm5 z(fTvzK!3c5RLz&o>9-&+>FK4}*?{fN=o^NxHhJ9Ro$ImXS?&)V~{X<8^ zOP?*e6!;b#CE>}|wR@MXcUQAEUA(X3=;qu1Lv7cckLg=%Yiurc{#yUH8As>s{QhPx z;h}JbM%l)?$n53m+n>F;XZ>~cEKvIU-2cdWqqb>ym7HaAo&DnP@1CT+KX=b=-M!1% z_DO&9rq{l+IX`o6Usm|f$UKq##@jYu_w)S|Aiwgo{I87uoA+*Rp1gi*_^ayr*z@ON zvd<8aKIW?wJZD|Lxmxz>`A?fGcJvpOA1nKIYh~q^HJkr+95=Q)9RBR}`@nx$xo@S< zp5Ie`r9S#i?7!}UpN;SK%qS^azxY>Z-85@q`K#}alw}?I{%+UJdAsjFePMI+_HpB_ zd(E%)f9wAyLc~Iknn?#1i%&cEMgHnKP=fpS=EmLM$KR)Jd9GDA<@QPUv+L{YKD+Mt z@#$P#gVn0|r|CP5Ki<6+c=ztcsrO&RuKso6sPXIHr|SOSUHkjp4^T<5w_B2kp7eL_ zGkU3SYd+n*w|H0NKTsN2y)iJ}qW96_8*9o$?N7aZvUr)@=FL}U_0ReLt-Ijk(m8u2 zN<;Raia*&~6(>0RX3ss_)x8xqo98XQV}JJl@AR$iYgd2Pw%z)_@2B;ghkfT0`3csY z51zB$dpPORRO2__*1THx#LaebM9t>KKeUrJmp@;hThcc7&c%H@-DShyuPT+dtl!>U z&{^^Q=_2FbZ?DK*J@cvjhCQ+x>O* zuE;zw{=k{{i16h&rPp?XLtMN-@aGtpQYE9 zA36V~aG6=X+2(mC))!g-jhy`WTwUaDsrR?izw%iU^nb$vb&flwlCRF#S#MoEOM7SF zc@44qH#O|K&St&uIUe`%%)S3pZO^60_PPH~z5A}>d)@B$vDfy#t{2qftNqTpZ1eB8 zSLCm*`Ly|t>__WwC*;rNte^Wny{GCZ5mg4ux%hRj(soZ@45|mT zcSfGqujR^U^8y z(bKR zdHJ}uZEgRqebxJSeRuxszvE5ucggi{wqGs|*?j7J(dLSpmz(e0{E@YO@g2Xq?P{++ z&8%%ZGhg!ko!4iouM#old(Zd5Id7lz@1XKG^6B~~X||gyYUXdgqqFbT$@|AwefROb z_H4)I{A=%e%HMDQeD3Y6@_+l?&hmfk>Glc#cITz#s>rAB&)wY{Un9TTc708}_3x+q zHh=81O{?xE+%IGKH|c<^_}p`EHU{rrwbQ!%d)>#|k#BcSzQ49}*Dsm9+pqoW`nfzt zsp^>J`ZqgoZ(bGs^pX44Q~QJU{xhyQH^tO_{_1OAf4=*-_x;7M{(HY)EPhSY;w%5y zqFul4-Q72LSLj*mr;oxbzS?{h-*ap6wW~j;&bwtl%Rc%1#cI9db}u)b-+ZpB?Ec+f zi+8zyT77Tz&L4tntI9w9bhf#r{<_E}dVcNVkLUKf{q82N5ioc9>~rt7M%RaY_o%yC zZ7ROMH}t)qU46X!@08fS^w*o;XVhHV=li?Gi*;oEJoZs`Hr0o6OUm$mCiR-QY zqg8%oH#lr6`p$h0HU0lPZhfxr z{JsBgDz6X`uW`Bs-;%E0{2Y6;etY`zcPpOV{e1QJi#1!n&HP+$dHh;BXw=&$T+iq2 zw>MX0ugW}qd|BqI%`E?oi)%OO9pC)*X83XIZ!3P!B*G?+HLUM;@RXMIgJbEl;^!{g zPtq1u;n%Ky^zwiE-}JNp-iR+}isNto_BrqOR@SuqjiCLPxwW6Zxjyj0xzhpR-)_CVxw1Od z_fJ^az4B%2{{Jic{=Rm9+25DbyXIB?TU|Z>)JYUY7FDQM#xpwzg>r!jekB4urwT_-`f6DlG`uVIq)%&mRenLzUyN~tV zKAFPtw}Q-3+!{T7Rr+iBx2OMIt@!G*+BSaL?<@bauW)^N!yVNBrheIX$*t#a z7{5LLX0ENJ-KE*pF_QJK_J*HZ)lN9p3fd3&$L3W%*_&Q{{>uAn@2(v!|FY)RzrXV< z{onun`ucv6;S16Ek6&4z`!;uFefzCn{ZGzRX5G)J`(C&Cdj~No@D1mkTFKY1>e7GR zTWD5te$L`L>G0pLS+Cbs; zvCBK4f8XPr|GTd)|9-PL^?t^l;`JB*5wR|Yk?FkXj?Ye4ukJnfZEtk#|F(1U)_?!M z@@xK{hA*qme>qXT?%TY#*3t6z|Fmtt%AW;|D_;C_^LPI}O(Ld6e{?gQ-`DZ=#lP@h z=fBNad;b2(tNUKmFEPKr-+13ETkG`79nZGMX;oc)UiHN`{P+4Vu`fI2Z(QB?@A01O z`TO3-zAm@FA3OiD9l?+~@Lss$JGXE7-1o2S!hfy%azy`iR{TFL`M2k5`;LY0ef~mb z`_uZ*Pv?i%ZnM5uT-qQ0{VD(ZSJj*A&Fr%8-~3H@(w~uuMNYWlTI(wJ?|X0kf3iDYfyWOVa z{$HQvKb-jex!mr@pmee<`qjTfs*A$wk6GXQ{zA_F?)~~X{qvT;|Gw_^{!fz0LUGD$_ve>R zTmJ0dBiBXqf1D}b_j%pkcej@RcbLC5zy7@Sn*W#5YuWSD3C@_*J3crc6Z7kT{Ikt= zuVa7T+v@)(4^%|oKj^=w_wm9y+t`2I`M&P`+~0S1UVqj8Yt{EP=M>xt_G|?d zKGZaZ#~#`B*|z+h=%MoW+kdb9d!@Ske0lZV_K-$t$t;FmWa+Ii(UMKQ1Kn}e$GpOxA!ye|1ZDG&;7U}HGTTOv%fFP zov-`9`TPIv&%VD}e(!fJlQChhGc?W@`LVJ)>U`b%&EM^RovZux*Zp~QLL*IKozxabMU1IKQ_ar^Jvp4S_ zeRlPE#n<1@?jNXoCVYO+|Cb>|w4~?hf9RaPDz5ff`2PHFYxkeFOnd%&;tp~H0t zf3E!e=SubU`+Yh@IP5^Y;E$E3Yt`}My^m*p+n+g=V3Eqe$aG$; z;&^xL`-){h$?Sl?FBdLVyK$5+nzFNM$j=(>M@W%-Vf zlCJECKb~##ORgz?o6WX!-%Ihw5rjPVpqVA6uIk+Mub%7Xmt1>Z6V3nT71MdAgRRaPz|9K|goRE7wi_w%?=w-ic}2_5byclFR<~|Nq`!Axlg?xfl50vi^kH zUqA1^GJkmK^5=bh_tSpgwmbiMU!^rM&5t{pA8zaQ{M~lG_<4D4rT+BUdY5y}|FJ&a z|3Py5{(@FQVE`)0mb3ml^mN1i50d`%AInX594MLo3BYm+NmnT{6As|NYZD{>vYI*m6~IA`=k?c(cU3x|N=`HNVt*skhs91G_Dq z?;j}cTWm_I5JLOBgaw`wEO*2&kfeMcfHxX_{%P-`^R6e+1p7(EH)fi z%%r#9R;wa-e|NaKqg|r({ji(%# zzhDUwbqh<~+y?Lb{qMA8>lMToAJePXeO3P9`o6;X(+S7ShuthO6~ANeKY!`}nCVL9 zCi|NY%0H>^FOw%`;>V0hZ`aW= z`)B>*hwzR)Up~e^T>pciu6_Tb>@SK0z1(Q8^T6n~{J&54A1>bA@P+SwlkuL#4fWFR zf2_3-CRk1iFzLS1_lNOPgg&e IbxsLQ01|avtN;K2 literal 0 HcmV?d00001 diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md index 187ec9e7b75c14..8292b393757ada 100644 --- a/doc/development/doc_styleguide.md +++ b/doc/development/doc_styleguide.md @@ -127,7 +127,7 @@ Inside the document: ``` If the document you are editing resides in a place other than the GitLab CE/EE `doc/` directory, instead of the relative link, use the full path: - `http://doc.gitlab.com/ce/administration/restart_gitlab.html`. + `http://docs.gitlab.com/ce/administration/restart_gitlab.html`. Replace `reconfigure` with `restart` where appropriate. ## Installation guide @@ -266,5 +266,5 @@ curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -d "restricted_signup_domai [cURL]: http://curl.haxx.se/ "cURL website" [single spaces]: http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html -[gfm]: http://doc.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation" +[gfm]: http://docs.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation" [doc-restart]: ../administration/restart_gitlab.md "GitLab restart documentation" diff --git a/doc/development/instrumentation.md b/doc/development/instrumentation.md index c1cf2e77c2689e..9168c70945aafb 100644 --- a/doc/development/instrumentation.md +++ b/doc/development/instrumentation.md @@ -1,12 +1,125 @@ # Instrumenting Ruby Code -GitLab Performance Monitoring allows instrumenting of custom blocks of Ruby -code. This can be used to measure the time spent in a specific part of a larger -chunk of code. The resulting data is stored as a field in the transaction that -executed the block. +GitLab Performance Monitoring allows instrumenting of both methods and custom +blocks of Ruby code. Method instrumentation is the primary form of +instrumentation with block-based instrumentation only being used when we want to +drill down to specific regions of code within a method. -To start measuring a block of Ruby code you should use `Gitlab::Metrics.measure` -and give it a name: +## Instrumenting Methods + +Instrumenting methods is done by using the `Gitlab::Metrics::Instrumentation` +module. This module offers a few different methods that can be used to +instrument code: + +* `instrument_method`: instruments a single class method. +* `instrument_instance_method`: instruments a single instance method. +* `instrument_class_hierarchy`: given a Class this method will recursively + instrument all sub-classes (both class and instance methods). +* `instrument_methods`: instruments all public class methods of a Module. +* `instrument_instance_methods`: instruments all public instance methods of a + Module. + +To remove the need for typing the full `Gitlab::Metrics::Instrumentation` +namespace you can use the `configure` class method. This method simply yields +the supplied block while passing `Gitlab::Metrics::Instrumentation` as its +argument. An example: + +``` +Gitlab::Metrics::Instrumentation.configure do |conf| + conf.instrument_method(Foo, :bar) + conf.instrument_method(Foo, :baz) +end +``` + +Using this method is in general preferred over directly calling the various +instrumentation methods. + +Method instrumentation should be added in the initializer +`config/initializers/metrics.rb`. + +### Examples + +Instrumenting a single method: + +``` +Gitlab::Metrics::Instrumentation.configure do |conf| + conf.instrument_method(User, :find_by) +end +``` + +Instrumenting an entire class hierarchy: + +``` +Gitlab::Metrics::Instrumentation.configure do |conf| + conf.instrument_class_hierarchy(ActiveRecord::Base) +end +``` + +Instrumenting all public class methods: + +``` +Gitlab::Metrics::Instrumentation.configure do |conf| + conf.instrument_methods(User) +end +``` + +### Checking Instrumented Methods + +The easiest way to check if a method has been instrumented is to check its +source location. For example: + +``` +method = Rugged::TagCollection.instance_method(:[]) + +method.source_location +``` + +If the source location points to `lib/gitlab/metrics/instrumentation.rb` you +know the method has been instrumented. + +If you're using Pry you can use the `$` command to display the source code of a +method (along with its source location), this is easier than running the above +Ruby code. In case of the above snippet you'd run the following: + +``` +$ Rugged::TagCollection#[] +``` + +This will print out something along the lines of: + +``` +From: /path/to/your/gitlab/lib/gitlab/metrics/instrumentation.rb @ line 148: +Owner: # +Visibility: public +Number of lines: 21 + +def #{name}(#{args_signature}) + trans = Gitlab::Metrics::Instrumentation.transaction + + if trans + start = Time.now + retval = super + duration = (Time.now - start) * 1000.0 + + if duration >= Gitlab::Metrics.method_call_threshold + trans.increment(:method_duration, duration) + + trans.add_metric(Gitlab::Metrics::Instrumentation::SERIES, + { duration: duration }, + method: #{label.inspect}) + end + + retval + else + super + end +end +``` + +## Instrumenting Ruby Blocks + +Measuring blocks of Ruby code is done by calling `Gitlab::Metrics.measure` and +passing it a block. For example: ```ruby Gitlab::Metrics.measure(:foo) do @@ -14,6 +127,10 @@ Gitlab::Metrics.measure(:foo) do end ``` +The block is executed and the execution time is stored as a set of fields in the +currently running transaction. If no transaction is present the block is yielded +without measuring anything. + 3 values are measured for a block: 1. The real time elapsed, stored in NAME_real_time. diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md index 28dedf3978cd8f..02e024ca15aa92 100644 --- a/doc/development/migration_style_guide.md +++ b/doc/development/migration_style_guide.md @@ -8,7 +8,10 @@ In addition, having to take a server offline for a an upgrade small or big is a big burden for most organizations. For this reason it is important that your migrations are written carefully, can be applied online and adhere to the style guide below. -It's advised to have offline migrations only in major GitLab releases. +Migrations should not require GitLab installations to be taken offline unless +_absolutely_ necessary. If a migration requires downtime this should be +clearly mentioned during the review process as well as being documented in the +monthly release post. When writing your migrations, also consider that databases might have stale data or inconsistencies and guard for that. Try to make as little assumptions as possible @@ -58,6 +61,45 @@ remove_index :namespaces, column: :name if index_exists?(:namespaces, :name) If you need to add an unique index please keep in mind there is possibility of existing duplicates. If it is possible write a separate migration for handling this situation. It can be just removing or removing with overwriting all references to these duplicates depend on situation. +When adding an index make sure to use the method `add_concurrent_index` instead +of the regular `add_index` method. The `add_concurrent_index` method +automatically creates concurrent indexes when using PostgreSQL, removing the +need for downtime. To use this method you must disable transactions by calling +the method `disable_ddl_transaction!` in the body of your migration class like +so: + +``` +class MyMigration < ActiveRecord::Migration + disable_ddl_transaction! + + def change + + end +end +``` + +## Adding Columns With Default Values + +When adding columns with default values you should use the method +`add_column_with_default`. This method ensures the table is updated without +requiring downtime. This method is not reversible so you must manually define +the `up` and `down` methods in your migration class. + +For example, to add the column `foo` to the `projects` table with a default +value of `10` you'd write the following: + +``` +class MyMigration < ActiveRecord::Migration + def up + add_column_with_default(:projects, :foo, :integer, 10) + end + + def down + remove_column(:projects, :foo) + end +end +``` + ## Testing Make sure that your migration works with MySQL and PostgreSQL with data. An empty database does not guarantee that your migration is correct. @@ -74,7 +116,7 @@ Example with Arel: users = Arel::Table.new(:users) users.group(users[:user_id]).having(users[:id].count.gt(5)) -#updtae other tables with this results +#update other tables with these results ``` Example with plain SQL and `quote_string` helper: @@ -89,4 +131,4 @@ select_all("SELECT name, COUNT(id) as cnt FROM tags GROUP BY name HAVING COUNT(i execute("UPDATE taggings SET tag_id = #{origin_tag_id} WHERE tag_id IN(#{duplicate_ids.join(",")})") execute("DELETE FROM tags WHERE id IN(#{duplicate_ids.join(",")})") end -``` \ No newline at end of file +``` diff --git a/doc/development/testing.md b/doc/development/testing.md index 33eed29ba5c4a0..513457d203a487 100644 --- a/doc/development/testing.md +++ b/doc/development/testing.md @@ -65,7 +65,7 @@ the command line via `bundle exec teaspoon`, or via a web browser at - Use `context` to test branching logic. - Don't `describe` symbols (see [Gotchas](gotchas.md#dont-describe-symbols)). - Don't supply the `:each` argument to hooks since it's the default. -- Prefer `not_to` to `to_not`. +- Prefer `not_to` to `to_not` (_this is enforced by Rubocop_). - Try to match the ordering of tests to the ordering within the class. - Try to follow the [Four-Phase Test][four-phase-test] pattern, using newlines to separate phases. diff --git a/doc/development/ui_guide.md b/doc/development/ui_guide.md index a3e260a5f89d2f..23760a14b39dd7 100644 --- a/doc/development/ui_guide.md +++ b/doc/development/ui_guide.md @@ -6,3 +6,51 @@ We created a page inside GitLab where you can check commonly used html and css e When you run GitLab instance locally - just visit http://localhost:3000/help/ui page to see UI examples you can use during GitLab development. + +## Design repository + +All design files are stored in the [gitlab-design](https://gitlab.com/gitlab-org/gitlab-design) +repository and maintained by GitLab UX designers. + +## Navigation + +GitLab's layout contains 2 sections: the left sidebar and the content. The left sidebar contains a static navigation menu. +This menu will be visible regardless of what page you visit. The left sidebar also contains the GitLab logo +and the current user's profile picture. The content section contains a header and the content itself. +The header describes the current GitLab page and what navigation is +available to user in this area. Depending on the area (project, group, profile setting) the header name and navigation may change. For example when user visits one of the +project pages the header will contain a project name and navigation for that project. When the user visits a group page it will contain a group name and navigation related to this group. + +### Adding new tab to header navigation + +We try to keep the amount of tabs in the header navigation between 5 and 10 so that it fits on a typical laptop screen. We also try not to confuse the user with too many options. Ideally each +tab should represent separate functionality. Everything related to the issue +tracker should be under the 'Issues' tab while everything related to the wiki should +be under 'Wiki' tab and so on and so forth. + +## Mobile screen size + +We want GitLab to work well on small mobile screens as well. Size limitations make it is impossible to fit everything on a mobile screen. In this case it is OK to hide +part of the UI for smaller resolutions in favor of a better user experience. +However core functionality like browsing files, creating issues, writing comments, should +be available on all resolutions. + +## Icons + +* `trash` icon for button or link that does destructive action like removing +information from database or file system +* `x` icon for closing/hiding UI element. For example close modal window +* `pencil` icon for edit button or link +* `eye` icon for subscribe action +* `rss` for rss/atom feed +* `plus` for link or dropdown that lead to page where you create new object (For example new issue page) + + +## Buttons + +* Button should contain icon or text. Exceptions should be approved by UX designer. +* Use gray button on white background or white button on gray background. +* Use red button for destructive actions (not revertable). For example removing issue. +* Use green or blue button for primary action. Primary button should be only one. +Do not use both green and blue button in one form. + diff --git a/doc/gitlab-basics/create-issue.md b/doc/gitlab-basics/create-issue.md index 87f078def0422b..5221d85b661027 100644 --- a/doc/gitlab-basics/create-issue.md +++ b/doc/gitlab-basics/create-issue.md @@ -24,4 +24,4 @@ You may assign the Issue to a user, add a milestone and add labels (they are all ![Submit new issue](basicsimages/submit_new_issue.png) -Your Issue will now be added to the Issue Tracker and will be ready to be reviewed. You can comment on it and mention the people involved. You can also link Issues to the Merge Requests where the Issues are solved. To do this, you can use an [Issue closing pattern](http://doc.gitlab.com/ce/customization/issue_closing.html). +Your Issue will now be added to the Issue Tracker and will be ready to be reviewed. You can comment on it and mention the people involved. You can also link Issues to the Merge Requests where the Issues are solved. To do this, you can use an [Issue closing pattern](http://docs.gitlab.com/ce/customization/issue_closing.html). diff --git a/doc/gitlab-basics/create-project.md b/doc/gitlab-basics/create-project.md index b545d62549d803..f737dffc0248ae 100644 --- a/doc/gitlab-basics/create-project.md +++ b/doc/gitlab-basics/create-project.md @@ -14,7 +14,7 @@ Fill out the required information: 1. Select a [visibility level](https://gitlab.com/help/public_access/public_access) -1. You can also [import your existing projects](http://doc.gitlab.com/ce/workflow/importing/README.html) +1. You can also [import your existing projects](http://docs.gitlab.com/ce/workflow/importing/README.html) 1. Click on "create project" diff --git a/doc/hooks/custom_hooks.md b/doc/hooks/custom_hooks.md index dcdf49d3379702..820934f97f1188 100644 --- a/doc/hooks/custom_hooks.md +++ b/doc/hooks/custom_hooks.md @@ -2,7 +2,7 @@ **Note: Custom git hooks must be configured on the filesystem of the GitLab server. Only GitLab server administrators will be able to complete these tasks. -Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://doc.gitlab.com/ee/git_hooks/git_hooks.html).** +Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://docs.gitlab.com/ee/git_hooks/git_hooks.html).** Git natively supports hooks that are executed on different actions. Examples of server-side git hooks include pre-receive, post-receive, and update. diff --git a/doc/install/installation.md b/doc/install/installation.md index e3af302226253b..1318b3d1fa5594 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -6,7 +6,7 @@ Since an installation from source is a lot of work and error prone we strongly r One reason the Omnibus package is more reliable is its use of Runit to restart any of the GitLab processes in case one crashes. On heavily used GitLab instances the memory usage of the Sidekiq background worker will grow over time. -Omnibus packages solve this by [letting the Sidekiq terminate gracefully](http://doc.gitlab.com/ce/operations/sidekiq_memory_killer.html) if it uses too much memory. +Omnibus packages solve this by [letting the Sidekiq terminate gracefully](http://docs.gitlab.com/ce/operations/sidekiq_memory_killer.html) if it uses too much memory. After this termination Runit will detect Sidekiq is not running and will start it. Since installations from source don't have Runit, Sidekiq can't be terminated and its memory usage will grow over time. @@ -269,9 +269,9 @@ sudo usermod -aG redis git ### Clone the Source # Clone GitLab repository - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 8-7-stable gitlab + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 8-8-stable gitlab -**Note:** You can change `8-7-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! +**Note:** You can change `8-8-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! ### Configure It @@ -394,7 +394,7 @@ GitLab Shell is an SSH access and repository management software developed speci cd /home/git sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git cd gitlab-workhorse - sudo -u git -H git checkout v0.7.1 + sudo -u git -H git checkout v0.7.4 sudo -u git -H make ### Initialize Database and Activate Advanced Features diff --git a/doc/install/relative_url.md b/doc/install/relative_url.md index 0245febfcd878c..44d2a14f3666ed 100644 --- a/doc/install/relative_url.md +++ b/doc/install/relative_url.md @@ -132,5 +132,5 @@ To disable the relative URL: 1. Follow the same as above starting from 2. and set up the GitLab URL to one that doesn't contain a relative path. -[omnibus-rel]: http://doc.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab" +[omnibus-rel]: http://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab" [restart gitlab]: ../administration/restart_gitlab.md#installations-from-source "How to restart GitLab" diff --git a/doc/install/requirements.md b/doc/install/requirements.md index df8e8bdc476b90..09c6211b3ab80b 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -81,7 +81,7 @@ errors during usage. - More users? Run it on [multiple application servers](https://about.gitlab.com/high-availability/) We recommend having at least 1GB of swap on your server, even if you currently have -enough available RAM. Having swap will help reduce the chance of errors occuring +enough available RAM. Having swap will help reduce the chance of errors occurring if your available memory changes. Notice: The 25 workers of Sidekiq will show up as separate processes in your process overview (such as top or htop) but they share the same RAM allocation since Sidekiq is a multithreaded application. Please see the section below about Unicorn workers for information about many you need of those. @@ -150,3 +150,4 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o - Safari 7+ (known problem: required fields in html5 do not work) - Opera (Latest released version) - Internet Explorer (IE) 11+ but please make sure that you have the `Compatibility View` mode disabled. +- Edge (Latest stable version) diff --git a/doc/integration/README.md b/doc/integration/README.md index 6fe04aa2a0639f..fd330dd7a7deae 100644 --- a/doc/integration/README.md +++ b/doc/integration/README.md @@ -19,7 +19,7 @@ See the documentation below for details on how to configure these services. GitLab Enterprise Edition contains [advanced Jenkins support][jenkins]. -[jenkins]: http://doc.gitlab.com/ee/integration/jenkins.html +[jenkins]: http://docs.gitlab.com/ee/integration/jenkins.html ## Project services diff --git a/doc/integration/cas.md b/doc/integration/cas.md index e6b2071f193cd5..e34e306f9acdef 100644 --- a/doc/integration/cas.md +++ b/doc/integration/cas.md @@ -27,17 +27,18 @@ To enable the CAS OmniAuth provider you must register your application with your ```ruby gitlab_rails['omniauth_providers'] = [ { - name: "cas3", - label: "cas", - args: { - url: 'CAS_SERVER', - login_url: '/CAS_PATH/login', - service_validate_url: '/CAS_PATH/p3/serviceValidate', - logout_url: '/CAS_PATH/logout'} } - } + "name"=> "cas3", + "label"=> "cas", + "args"=> { + "url"=> 'CAS_SERVER', + "login_url"=> '/CAS_PATH/login', + "service_validate_url"=> '/CAS_PATH/p3/serviceValidate', + "logout_url"=> '/CAS_PATH/logout' + } } ] ``` + For installations from source: @@ -57,6 +58,8 @@ To enable the CAS OmniAuth provider you must register your application with your 1. Save the configuration file. +1. Run `gitlab-ctl reconfigure` for the omnibus package. + 1. Restart GitLab for the changes to take effect. On the sign in page there should now be a CAS tab in the sign in form. diff --git a/doc/integration/google.md b/doc/integration/google.md index f9a20dd840d46f..82978b68a34820 100644 --- a/doc/integration/google.md +++ b/doc/integration/google.md @@ -11,9 +11,9 @@ To enable the Google OAuth2 OmniAuth provider you must register your application - Project ID: Must be unique to all Google Developer registered applications. Google provides a randomly generated Project ID by default. You can use the randomly generated ID or choose a new one. 1. Refresh the page. You should now see your new project in the list. Click on the project. -1. Select "APIs & auth" in the left menu. +1. Select the "Google APIs" tab in the Overview. -1. Select "APIs" in the submenu. +1. Select and enable the following Google APIs - listed under "Popular APIs" - Enable `Contacts API` - Enable `Google+ API` diff --git a/doc/integration/img/enabled-oauth-sign-in-sources.png b/doc/integration/img/enabled-oauth-sign-in-sources.png new file mode 100644 index 0000000000000000000000000000000000000000..95f8bbdcd2489c4eb14c100c92dffadf3a1a65fc GIT binary patch literal 49081 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:** +This setting was introduced with version 8.8 of GitLab. + +Administrators are able to enable or disable Sign In via some OmniAuth providers. + +>**Note:** +By default Sign In is enabled via all the OAuth Providers that have been configured in `config/gitlab.yml`. + +In order to enable/disable an OmniAuth provider, go to Admin Area -> Settings -> Sign-in Restrictions section -> Enabled OAuth Sign-In sources and select the providers you want to enable or disable. + +![Enabled OAuth Sign-In sources](img/enabled-oauth-sign-in-sources.png) diff --git a/doc/intro/README.md b/doc/intro/README.md index ab298d3808e251..382d10aaf40f5b 100644 --- a/doc/intro/README.md +++ b/doc/intro/README.md @@ -39,4 +39,4 @@ Install and update your GitLab installation. - [Install GitLab](https://about.gitlab.com/installation/) - [Update GitLab](https://about.gitlab.com/update/) -- [Explore Omnibus GitLab configuration options](http://doc.gitlab.com/omnibus/settings/configuration.html) +- [Explore Omnibus GitLab configuration options](http://docs.gitlab.com/omnibus/settings/configuration.html) diff --git a/doc/logs/logs.md b/doc/logs/logs.md index 27937e51764492..f84060b8d070ed 100644 --- a/doc/logs/logs.md +++ b/doc/logs/logs.md @@ -1,6 +1,6 @@ ## Log system -GitLab has advanced log system so everything is logging and you can analize your instance using various system log files. -In addition to system log files, GitLab Enterprise Edition comes with Audit Events. Find more about them [in Audit Events documentation](http://doc.gitlab.com/ee/administration/audit_events.html) +GitLab has an advanced log system where everything is logged so that you can analyze your instance using various system log files. +In addition to system log files, GitLab Enterprise Edition comes with Audit Events. Find more about them [in Audit Events documentation](http://docs.gitlab.com/ee/administration/audit_events.html) System log files are typically plain text in a standard log file format. This guide talks about how to read and use these system log files. @@ -67,13 +67,13 @@ gitlab-shell is using by Gitlab for executing git commands and provide ssh acces ``` I, [2015-02-13T06:17:00.671315 #9291] INFO -- : Adding project root/example.git at . -I, [2015-02-13T06:17:00.679433 #9291] INFO -- : Moving existing hooks directory and simlinking global hooks directory for /var/opt/gitlab/git-data/repositories/root/example.git. +I, [2015-02-13T06:17:00.679433 #9291] INFO -- : Moving existing hooks directory and symlinking global hooks directory for /var/opt/gitlab/git-data/repositories/root/example.git. ``` #### unicorn_stderr.log This file lives in `/var/log/gitlab/unicorn/unicorn_stderr.log` for omnibus package or in `/home/git/gitlab/log/unicorn_stderr.log` for installations from the source. -Unicorn is a high-performance forking Web server which is used for serving GitLab application. You can look at this log, for example, if your application does not respond. This log cantains all information about state of unicorn processes at any given time. +Unicorn is a high-performance forking Web server which is used for serving the GitLab application. You can look at this log if, for example, your application does not respond. This log contains all information about the state of unicorn processes at any given time. ``` I, [2015-02-13T06:14:46.680381 #9047] INFO -- : Refreshing Gem list diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index 4f199b6af6fc53..236eb7b12c42b1 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -8,6 +8,7 @@ * [Multiple underscores in words](#multiple-underscores-in-words) * [URL auto-linking](#url-auto-linking) * [Code and Syntax Highlighting](#code-and-syntax-highlighting) +* [Inline Diff](#inline-diff) * [Emoji](#emoji) * [Special GitLab references](#special-gitlab-references) * [Task lists](#task-lists) @@ -153,6 +154,19 @@ s = "There is no highlighting for this." But let's throw in a tag. ``` +## Inline Diff + +With inline diffs tags you can display {+ additions +} or [- deletions -]. + +The wrapping tags can be either curly braces or square brackets [+ additions +] or {- deletions -}. + +However the wrapping tags cannot be mixed as such: + +- {+ additions +] +- [+ additions +} +- {- deletions -] +- [- deletions -} + ## Emoji Sometimes you want to :monkey: around a bit and add some :star2: to your :speech_balloon:. Well we have a gift for you: @@ -185,20 +199,23 @@ GFM will turn that reference into a link so you can navigate between them easily GFM will recognize the following: -| input | references | -|:-----------------------|:---------------------------| -| `@user_name` | specific user | -| `@group_name` | specific group | -| `@all` | entire team | -| `#123` | issue | -| `!123` | merge request | -| `$123` | snippet | -| `~123` | label by ID | -| `~bug` | one-word label by name | -| `~"feature request"` | multi-word label by name | -| `9ba12248` | specific commit | -| `9ba12248...b19a04f5` | commit range comparison | -| `[README](doc/README)` | repository file references | +| input | references | +|:-----------------------|:--------------------------- | +| `@user_name` | specific user | +| `@group_name` | specific group | +| `@all` | entire team | +| `#123` | issue | +| `!123` | merge request | +| `$123` | snippet | +| `~123` | label by ID | +| `~bug` | one-word label by name | +| `~"feature request"` | multi-word label by name | +| `%123` | milestone by ID | +| `%v1.23` | one-word milestone by name | +| `%"release candidate"` | multi-word milestone by name | +| `9ba12248` | specific commit | +| `9ba12248...b19a04f5` | commit range comparison | +| `[README](doc/README)` | repository file references | GFM also recognizes certain cross-project references: @@ -206,6 +223,7 @@ GFM also recognizes certain cross-project references: |:----------------------------------------|:------------------------| | `namespace/project#123` | issue | | `namespace/project!123` | merge request | +| `namespace/project%123` | milestone | | `namespace/project$123` | snippet | | `namespace/project@9ba12248` | specific commit | | `namespace/project@9ba12248...b19a04f5` | commit range comparison | @@ -402,7 +420,7 @@ There are two ways to create links, inline-style and reference-style. [I'm a reference-style link][Arbitrary case-insensitive reference text] -[I'm a relative reference to a repository file](LICENSE) +[I'm a relative reference to a repository file](LICENSE)[^1] [You can use numbers for reference-style link definitions][1] @@ -594,3 +612,4 @@ By including colons in the header row, you can align the text within that column [rouge]: http://rouge.jneen.net/ "Rouge website" [redcarpet]: https://github.com/vmg/redcarpet "Redcarpet website" +[^1]: This link will be broken if you see this document from the Help page or docs.gitlab.com diff --git a/doc/migrate_ci_to_ce/README.md b/doc/migrate_ci_to_ce/README.md index 5ec0a2069b59cc..8f9ef05494927a 100644 --- a/doc/migrate_ci_to_ce/README.md +++ b/doc/migrate_ci_to_ce/README.md @@ -355,7 +355,7 @@ sudo chown git:git /var/opt/gitlab/gitlab-ci/builds ``` #### Problems when importing CI database to GitLab -If you were migrating CI database from MySQL to PostgreSQL manually you can see errros during import about missing sequences: +If you were migrating CI database from MySQL to PostgreSQL manually you can see errors during import about missing sequences: ``` ALTER SEQUENCE ERROR: relation "ci_builds_id_seq" does not exist diff --git a/doc/monitoring/health_check.md b/doc/monitoring/health_check.md new file mode 100644 index 00000000000000..0d17799372f473 --- /dev/null +++ b/doc/monitoring/health_check.md @@ -0,0 +1,66 @@ +# Health Check + +>**Note:** This feature was [introduced][ce-3888] in GitLab 8.8. + +GitLab provides a health check endpoint for uptime monitoring on the `health_check` web +endpoint. The health check reports on the overall system status based on the status of +the database connection, the state of the database migrations, and the ability to write +and access the cache. This endpoint can be provided to uptime monitoring services like +[Pingdom][pingdom], [Nagios][nagios-health], and [NewRelic][newrelic-health]. + +## Access Token + +An access token needs to be provided while accessing the health check endpoint. The current +accepted token can be found on the `admin/health_check` page of your GitLab instance. + +![access token](img/health_check_token.png) + +The access token can be passed as a URL parameter: + +``` +https://gitlab.example.com/health_check.json?token=ACCESS_TOKEN +``` + +or as an HTTP header: + +```bash +curl -H "TOKEN: ACCESS_TOKEN" https://gitlab.example.com/health_check.json +``` + +## Using the Endpoint + +Once you have the access token, health information can be retrieved as plain text, JSON, +or XML using the `health_check` endpoint: + +- `https://gitlab.example.com/health_check?token=ACCESS_TOKEN` +- `https://gitlab.example.com/health_check.json?token=ACCESS_TOKEN` +- `https://gitlab.example.com/health_check.xml?token=ACCESS_TOKEN` + +You can also ask for the status of specific services: + +- `https://gitlab.example.com/health_check/cache.json?token=ACCESS_TOKEN` +- `https://gitlab.example.com/health_check/database.json?token=ACCESS_TOKEN` +- `https://gitlab.example.com/health_check/migrations.json?token=ACCESS_TOKEN` + +For example, the JSON output of the following health check: + +```bash +curl -H "TOKEN: ACCESS_TOKEN" https://gitlab.example.com/health_check.json +``` + +would be like: + +``` +{"healthy":true,"message":"success"} +``` + +## Status + +On failure, the endpoint will return a `500` HTTP status code. On success, the endpoint +will return a valid successful HTTP status code, and a `success` message. Ideally your +uptime monitoring should look for the success message. + +[ce-3888]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3888 +[pingdom]: https://www.pingdom.com +[nagios-health]: https://nagios-plugins.org/doc/man/check_http.html +[newrelic-health]: https://docs.newrelic.com/docs/alerts/alert-policies/downtime-alerts/availability-monitoring diff --git a/doc/monitoring/img/health_check_token.png b/doc/monitoring/img/health_check_token.png new file mode 100644 index 0000000000000000000000000000000000000000..2daf8606b009aedda120af03baa13c36a195f07d GIT binary patch literal 10884 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 V7{3}jmV(w}db;|#taD0e0syE<(}4g0 literal 0 HcmV?d00001 diff --git a/doc/operations/moving_repositories.md b/doc/operations/moving_repositories.md index 39086b7a2519e2..54adb99386a48f 100644 --- a/doc/operations/moving_repositories.md +++ b/doc/operations/moving_repositories.md @@ -134,7 +134,7 @@ sudo -u git sh -c ' cat /var/opt/gitlab/transfer-logs/* | sort | uniq -u |\ /usr/bin/env JOBS=10 \ /opt/gitlab/embedded/service/gitlab-rails/bin/parallel-rsync-repos \ - /var/opt/gitlab/transfer-logs/succes-$(date +%s).log \ + /var/opt/gitlab/transfer-logs/success-$(date +%s).log \ /var/opt/gitlab/git-data/repositories \ /mnt/gitlab/repositories ' @@ -145,7 +145,7 @@ sudo -u git -H sh -c ' cat /home/git/transfer-logs/* | sort | uniq -u |\ /usr/bin/env JOBS=10 \ bin/parallel-rsync-repos \ - /home/git/transfer-logs/succes-$(date +%s).log \ + /home/git/transfer-logs/success-$(date +%s).log \ /home/git/repositories \ /mnt/gitlab/repositories ` @@ -164,7 +164,7 @@ sudo gitlab-rake gitlab:list_repos SINCE='2015-10-1 12:00 UTC' |\ sudo -u git \ /usr/bin/env JOBS=10 \ /opt/gitlab/embedded/service/gitlab-rails/bin/parallel-rsync-repos \ - succes-$(date +%s).log \ + success-$(date +%s).log \ /var/opt/gitlab/git-data/repositories \ /mnt/gitlab/repositories @@ -174,7 +174,7 @@ sudo -u git -H bundle exec rake gitlab:list_repos SINCE='2015-10-1 12:00 UTC' |\ sudo -u git -H \ /usr/bin/env JOBS=10 \ bin/parallel-rsync-repos \ - succes-$(date +%s).log \ + success-$(date +%s).log \ /home/git/repositories \ /mnt/gitlab/repositories ``` diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md index 6219693b8a8d63..b76ce31cbade73 100644 --- a/doc/permissions/permissions.md +++ b/doc/permissions/permissions.md @@ -27,6 +27,7 @@ documentation](../workflow/add-user/add-user.md). | Manage issue tracker | | ✓ | ✓ | ✓ | ✓ | | Manage labels | | ✓ | ✓ | ✓ | ✓ | | See a commit status | | ✓ | ✓ | ✓ | ✓ | +| See a container registry | | ✓ | ✓ | ✓ | ✓ | | Manage merge requests | | | ✓ | ✓ | ✓ | | Create new merge request | | | ✓ | ✓ | ✓ | | Create new branches | | | ✓ | ✓ | ✓ | @@ -37,6 +38,8 @@ documentation](../workflow/add-user/add-user.md). | Write a wiki | | | ✓ | ✓ | ✓ | | Cancel and retry builds | | | ✓ | ✓ | ✓ | | Create or update commit status | | | ✓ | ✓ | ✓ | +| Update a container registry | | | ✓ | ✓ | ✓ | +| Remove a container registry image | | | ✓ | ✓ | ✓ | | Create new milestones | | | | ✓ | ✓ | | Add new team members | | | | ✓ | ✓ | | Push to protected branches | | | | ✓ | ✓ | diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md index 6be954ad68ba65..a49c43b8ef2bd0 100644 --- a/doc/raketasks/README.md +++ b/doc/raketasks/README.md @@ -8,4 +8,4 @@ - [User management](user_management.md) - [Webhooks](web_hooks.md) - [Import](import.md) of git repositories in bulk -- [Rebuild authorized_keys file](http://doc.gitlab.com/ce/raketasks/maintenance.html#rebuild-authorized_keys-file) task for administrators +- [Rebuild authorized_keys file](http://docs.gitlab.com/ce/raketasks/maintenance.html#rebuild-authorized_keys-file) task for administrators diff --git a/doc/security/README.md b/doc/security/README.md index 4cd0fdd409443e..38706e48ec5713 100644 --- a/doc/security/README.md +++ b/doc/security/README.md @@ -8,3 +8,4 @@ - [User File Uploads](user_file_uploads.md) - [How we manage the CRIME vulnerability](crime_vulnerability.md) - [Enforce Two-factor authentication](two_factor_authentication.md) +- [Send email confirmation on sign-up](user_email_confirmation.md) diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md new file mode 100644 index 00000000000000..4293944ae8b75e --- /dev/null +++ b/doc/security/user_email_confirmation.md @@ -0,0 +1,7 @@ +# User email confirmation at sign-up + +Gitlab admin can enable email confirmation on sign-up, if you want to confirm all +user emails before they are able to sign-in. + +In the Admin area under **Settings** (`/admin/application_settings`), go to section +**Sign-in Restrictions** and look for **Send confirmation email on sign-up** option. diff --git a/doc/update/8.6-to-8.7.md b/doc/update/8.6-to-8.7.md index 4a2c6ea91d2557..bb463d43a7c22b 100644 --- a/doc/update/8.6-to-8.7.md +++ b/doc/update/8.6-to-8.7.md @@ -86,6 +86,14 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS ### 7. Update configuration files +#### New configuration options for `gitlab.yml` + +There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them manually to your current `gitlab.yml`: + +```sh +git diff origin/8-6-stable:config/gitlab.yml.example origin/8-7-stable:config/gitlab.yml.example +``` + #### Git configuration Disable `git gc --auto` because GitLab runs `git gc` for us already. diff --git a/doc/update/8.7-to-8.8.md b/doc/update/8.7-to-8.8.md new file mode 100644 index 00000000000000..32906650f6f1fd --- /dev/null +++ b/doc/update/8.7-to-8.8.md @@ -0,0 +1,162 @@ +# From 8.7 to 8.8 + +Make sure you view this update guide from the tag (version) of GitLab you would +like to install. In most cases this should be the highest numbered production +tag (without rc in it). You can select the tag in the version dropdown at the +top left corner of GitLab (below the menu bar). + +If the highest number stable branch is unclear please check the +[GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation +guide links by version. + +### 1. Stop server + + sudo service gitlab stop + +### 2. Backup + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production +``` + +### 3. Get latest code + +```bash +sudo -u git -H git fetch --all +sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically +``` + +For GitLab Community Edition: + +```bash +sudo -u git -H git checkout 8-8-stable +``` + +OR + +For GitLab Enterprise Edition: + +```bash +sudo -u git -H git checkout 8-8-stable-ee +``` + +### 4. Update gitlab-shell + +```bash +cd /home/git/gitlab-shell +sudo -u git -H git fetch --all --tags +sudo -u git -H git checkout v2.7.2 +``` + +### 5. Update gitlab-workhorse + +Install and compile gitlab-workhorse. This requires +[Go 1.5](https://golang.org/dl) which should already be on your system from +GitLab 8.1. + +```bash +cd /home/git/gitlab-workhorse +sudo -u git -H git fetch --all +sudo -u git -H git checkout v0.7.1 +sudo -u git -H make +``` + +### 6. Install libs, migrations, etc. + +```bash +cd /home/git/gitlab + +# MySQL installations (note: the line below states '--without postgres') +sudo -u git -H bundle install --without postgres development test --deployment + +# PostgreSQL installations (note: the line below states '--without mysql') +sudo -u git -H bundle install --without mysql development test --deployment + +# Optional: clean up old gems +sudo -u git -H bundle clean + +# Run database migrations +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production + +# Clean up assets and cache +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production + +``` + +### 7. Update configuration files + +#### New configuration options for `gitlab.yml` + +There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them manually to your current `gitlab.yml`: + +```sh +git diff origin/8-7-stable:config/gitlab.yml.example origin/8-8-stable:config/gitlab.yml.example +``` + +#### Git configuration + +Disable `git gc --auto` because GitLab runs `git gc` for us already. + +```sh +sudo -u git -H git config --global gc.auto 0 +``` + +#### Nginx configuration + +Ensure you're still up-to-date with the latest NGINX configuration changes: + +```sh +# For HTTPS configurations +git diff origin/8-7-stable:lib/support/nginx/gitlab-ssl origin/8-8-stable:lib/support/nginx/gitlab-ssl + +# For HTTP configurations +git diff origin/8-7-stable:lib/support/nginx/gitlab origin/8-8-stable:lib/support/nginx/gitlab +``` + +If you are using Apache instead of NGINX please see the updated [Apache templates]. +Also note that because Apache does not support upstreams behind Unix sockets you +will need to let gitlab-workhorse listen on a TCP port. You can do this +via [/etc/default/gitlab]. + +[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache +[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-8-stable/lib/support/init.d/gitlab.default.example#L37 + +#### Init script + +Ensure you're still up-to-date with the latest init script changes: + + sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab + +### 8. Start application + + sudo service gitlab start + sudo service nginx restart + +### 9. Check application status + +Check if GitLab and its environment are configured correctly: + + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production + +To make sure you didn't miss anything run a more thorough check: + + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production + +If all items are green, then congratulations, the upgrade is complete! + +## Things went south? Revert to previous version (8.7) + +### 1. Revert the code to the previous version + +Follow the [upgrade guide from 8.6 to 8.7](8.6-to-8.7.md), except for the +database migration (the backup is already migrated to the previous version). + +### 2. Restore from the backup + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production +``` + +If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/README.md b/doc/update/README.md index a770633c9b8f9a..975d72164b4eb0 100644 --- a/doc/update/README.md +++ b/doc/update/README.md @@ -29,7 +29,7 @@ Based on your installation, choose a section below that fits your needs. ## Omnibus Packages -- The [Omnibus update guide](http://doc.gitlab.com/omnibus/update/README.html) +- The [Omnibus update guide](http://docs.gitlab.com/omnibus/update/README.html) contains the steps needed to update an Omnibus GitLab package. ## Installation from source @@ -86,10 +86,10 @@ possible. information about configuring GitLab to work with a MySQL database. - [Restoring from backup after a failed upgrade](restore_after_failure.md) -[omnidocker]: http://doc.gitlab.com/omnibus/docker/README.html +[omnidocker]: http://docs.gitlab.com/omnibus/docker/README.html [source-ee]: https://gitlab.com/gitlab-org/gitlab-ee/tree/master/doc/update [source-ce]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update [ee-ce]: ../downgrade_ee_to_ce/README.md [ce]: https://about.gitlab.com/features/#community [ee]: https://about.gitlab.com/features/#enterprise -[omni-ce-ee]: http://doc.gitlab.com/omnibus/update/README.html#from-community-edition-to-enterprise-edition +[omni-ce-ee]: http://docs.gitlab.com/omnibus/update/README.html#from-community-edition-to-enterprise-edition diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md index b4283a526f3d68..60729316cde315 100644 --- a/doc/update/patch_versions.md +++ b/doc/update/patch_versions.md @@ -57,10 +57,10 @@ sudo -u git -H make cd /home/git/gitlab # PostgreSQL -sudo -u git -H bundle install --without development test mysql --with postgres --deployment +sudo -u git -H bundle install --without development test mysql --deployment # MySQL -sudo -u git -H bundle install --without development test postgres --with mysql --deployment +sudo -u git -H bundle install --without development test postgres --deployment # Optional: clean up old gems sudo -u git -H bundle clean diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md index c1c51302e79be8..8559b67af04656 100644 --- a/doc/web_hooks/web_hooks.md +++ b/doc/web_hooks/web_hooks.md @@ -13,6 +13,19 @@ You can configure webhooks to listen for specific events like pushes, issues or Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. +## Webhook endpoint tips + +If you are writing your own endpoint (web server) that will receive +GitLab webhooks keep in mind the following things: + +- Your endpoint should send its HTTP response as fast as possible. If + you wait too long, GitLab may decide the hook failed and retry it. +- Your endpoint should ALWAYS return a valid HTTP response. If you do + not do this then GitLab will think the hook failed and retry it. + Most HTTP libraries take care of this for you automatically but if + you are writing a low-level hook this is important to remember. +- GitLab ignores the HTTP status code returned by your endpoint. + ## SSL Verification By default, the SSL certificate of the webhook endpoint is verified based on @@ -682,6 +695,61 @@ X-Gitlab-Event: Merge Request Hook } ``` +## Wiki Page events + +Triggered when a wiki page is created or edited. + +**Request Header**: + +``` +X-Gitlab-Event: Wiki Page Hook +``` + +**Request Body**: + +```json +{ + "object_kind": "wiki_page", + "user": { + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon" + }, + "project": { + "name": "awesome-project", + "description": "This is awesome", + "web_url": "http://example.com/root/awesome-project", + "avatar_url": null, + "git_ssh_url": "git@example.com:root/awesome-project.git", + "git_http_url": "http://example.com/root/awesome-project.git", + "namespace": "root", + "visibility_level": 0, + "path_with_namespace": "root/awesome-project", + "default_branch": "master", + "homepage": "http://example.com/root/awesome-project", + "url": "git@example.com:root/awesome-project.git", + "ssh_url": "git@example.com:root/awesome-project.git", + "http_url": "http://example.com/root/awesome-project.git" + }, + "wiki": { + "web_url": "http://example.com/root/awesome-project/wikis/home", + "git_ssh_url": "git@example.com:root/awesome-project.wiki.git", + "git_http_url": "http://example.com/root/awesome-project.wiki.git", + "path_with_namespace": "root/awesome-project.wiki", + "default_branch": "master" + }, + "object_attributes": { + "title": "Awesome", + "content": "awesome content goes here", + "format": "markdown", + "message": "adding an awesome page to the wiki", + "slug": "awesome", + "url": "http://example.com/root/awesome-project/wikis/awesome", + "action": "create" + } +} +``` + #### Example webhook receiver If you want to see GitLab's webhooks in action for testing purposes you can use diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md index 1b354bcc0f1c87..2b2f140f8bf195 100644 --- a/doc/workflow/gitlab_flow.md +++ b/doc/workflow/gitlab_flow.md @@ -131,7 +131,7 @@ When you feel comfortable with it to be merged you assign it to the person that There is room for more feedback and after the assigned person feels comfortable with the result the branch is merged. If the assigned person does not feel comfortable they can close the merge request without merging. -In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](http://doc.gitlab.com/ce/permissions/permissions.html). +In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](http://docs.gitlab.com/ce/permissions/permissions.html). So if you want to merge it into a protected branch you assign it to someone with master authorizations. ## Issues with GitLab flow @@ -187,7 +187,7 @@ If you have an issue that spans across multiple repositories, the best thing is ![Vim screen showing the rebase view](rebase.png) With git you can use an interactive rebase (`rebase -i`) to squash multiple commits into one and reorder them. -In GitLab EE and .com you can also [rebase before merge](http://doc.gitlab.com/ee/workflow/rebase_before_merge.html) from the web interface. +In GitLab EE and .com you can also [rebase before merge](http://docs.gitlab.com/ee/workflow/rebase_before_merge.html) from the web interface. This functionality is useful if you made a couple of commits for small changes during development and want to replace them with a single commit or if you want to make the order more logical. However you should never rebase commits you have pushed to a remote server. Somebody can have referred to the commits or cherry-picked them. diff --git a/doc/workflow/groups.md b/doc/workflow/groups.md index 52bf611dc5e2a8..34ada1774d8721 100644 --- a/doc/workflow/groups.md +++ b/doc/workflow/groups.md @@ -54,7 +54,7 @@ If necessary, you can increase the access level of an individual user for a spec ## Managing group memberships via LDAP In GitLab Enterprise Edition it is possible to manage GitLab group memberships using LDAP groups. -See [the GitLab Enterprise Edition documentation](http://doc.gitlab.com/ee/integration/ldap.html) for more information. +See [the GitLab Enterprise Edition documentation](http://docs.gitlab.com/ee/integration/ldap.html) for more information. ## Allowing only admins to create groups diff --git a/doc/workflow/importing/import_projects_from_github.md b/doc/workflow/importing/import_projects_from_github.md index e670e415c7151a..a7dfac2c120661 100644 --- a/doc/workflow/importing/import_projects_from_github.md +++ b/doc/workflow/importing/import_projects_from_github.md @@ -44,5 +44,5 @@ case the namespace is taken, the project will be imported on the user's namespace. [gh-import]: ../../integration/github.md "GitHub integration" -[ee-gh]: http://doc.gitlab.com/ee/integration/github.html "GitHub integration for GitLab EE" +[ee-gh]: http://docs.gitlab.com/ee/integration/github.html "GitHub integration for GitLab EE" [new-project]: ../../gitlab-basics/create-project.md "How to create a new project in GitLab" diff --git a/doc/workflow/importing/import_projects_from_gitlab_com.md b/doc/workflow/importing/import_projects_from_gitlab_com.md index 1117db98e7e40d..dcc00074b750e3 100644 --- a/doc/workflow/importing/import_projects_from_gitlab_com.md +++ b/doc/workflow/importing/import_projects_from_gitlab_com.md @@ -2,7 +2,7 @@ You can import your existing GitLab.com projects to your GitLab instance. But keep in mind that it is possible only if GitLab support is enabled on your GitLab instance. -You can read more about GitLab support [here](http://doc.gitlab.com/ce/integration/gitlab.html) +You can read more about GitLab support [here](http://docs.gitlab.com/ce/integration/gitlab.html) To get to the importer page you need to go to "New project" page. ![New project page](gitlab_importer/new_project_page.png) diff --git a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md index 31620044b1501d..9fe065fa680038 100644 --- a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md +++ b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md @@ -4,7 +4,7 @@ Managing large files such as audio, video and graphics files has always been one of the shortcomings of Git. The general recommendation is to not have Git repositories larger than 1GB to preserve performance. -GitLab already supports [managing large files with git annex](http://doc.gitlab.com/ee/workflow/git_annex.html) +GitLab already supports [managing large files with git annex](http://docs.gitlab.com/ee/workflow/git_annex.html) (EE only), however in certain environments it is not always convenient to use different commands to differentiate between the large files and regular ones. @@ -127,7 +127,7 @@ To prevent this from happening, set the lfs url in project Git config: ```bash -git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs/objects/batch" +git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs" ``` ### Credentials are always required when pushing an object @@ -152,4 +152,4 @@ If you are using OS X you can use `osxkeychain` to store and encrypt your creden For Windows, you can use `wincred` or Microsoft's [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases). More details about various methods of storing the user credentials can be found -on [Git Credential Storage documentation](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage). \ No newline at end of file +on [Git Credential Storage documentation](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage). diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md index 80817c98d22f30..cbca94c0b5eacb 100644 --- a/doc/workflow/notifications.md +++ b/doc/workflow/notifications.md @@ -69,7 +69,7 @@ In all of the below cases, the notification will be sent to: ...with notification level "Participating" or higher -- Watchers: project members with notification level "Watch" +- Watchers: users with notification level "Watch" - Subscribers: anyone who manually subscribed to the issue/merge request | Event | Sent to | diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index 2fd097d100bc72..26e6750302190c 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -10,14 +10,9 @@ Feature: Project Active Tab Then the active main tab should be Home And no other main tabs should be active - Scenario: On Project Files + Scenario: On Project Code Given I visit my project's files page - Then the active main tab should be Files - And no other main tabs should be active - - Scenario: On Project Commits - Given I visit my project's commits page - Then the active main tab should be Commits + Then the active main tab should be Code And no other main tabs should be active Scenario: On Project Issues @@ -30,11 +25,6 @@ Feature: Project Active Tab Then the active main tab should be Merge Requests And no other main tabs should be active - Scenario: On Project Members - Given I visit my project's members page - Then the active main tab should be Members - And no other main tabs should be active - Scenario: On Project Wiki Given I visit my project's wiki page Then the active main tab should be Wiki @@ -49,13 +39,6 @@ Feature: Project Active Tab # Sub Tabs: Settings - Scenario: On Project Settings/Edit - Given I visit my project's settings page - And I click the "Edit" tab - Then the active sub nav should be Edit - And no other sub navs should be active - And the active main tab should be Settings - Scenario: On Project Settings/Hooks Given I visit my project's settings page And I click the "Hooks" tab @@ -70,40 +53,52 @@ Feature: Project Active Tab And no other sub navs should be active And the active main tab should be Settings - # Sub Tabs: Commits + Scenario: On Project Members + Given I visit my project's members page + Then the active sub nav should be Members + And no other sub navs should be active + And the active main tab should be Settings + + # Sub Tabs: Code + + Scenario: On Project Code/Files + Given I visit my project's files page + Then the active sub tab should be Files + And no other sub tabs should be active + And the active main tab should be Code - Scenario: On Project Commits/Commits + Scenario: On Project Code/Commits Given I visit my project's commits page Then the active sub tab should be Commits And no other sub tabs should be active - And the active main tab should be Commits + And the active main tab should be Code - Scenario: On Project Commits/Network + Scenario: On Project Code/Network Given I visit my project's network page Then the active sub tab should be Network And no other sub tabs should be active - And the active main tab should be Commits + And the active main tab should be Code - Scenario: On Project Commits/Compare + Scenario: On Project Code/Compare Given I visit my project's commits page And I click the "Compare" tab Then the active sub tab should be Compare And no other sub tabs should be active - And the active main tab should be Commits + And the active main tab should be Code - Scenario: On Project Commits/Branches + Scenario: On Project Code/Branches Given I visit my project's commits page And I click the "Branches" tab Then the active sub tab should be Branches And no other sub tabs should be active - And the active main tab should be Commits + And the active main tab should be Code - Scenario: On Project Commits/Tags + Scenario: On Project Code/Tags Given I visit my project's commits page And I click the "Tags" tab Then the active sub tab should be Tags And no other sub tabs should be active - And the active main tab should be Commits + And the active main tab should be Code Scenario: On Project Issues/Browse Given I visit my project's issues page diff --git a/features/project/builds/summary.feature b/features/project/builds/summary.feature index 3c029a973df4c9..550ebccf0d7c39 100644 --- a/features/project/builds/summary.feature +++ b/features/project/builds/summary.feature @@ -24,3 +24,4 @@ Feature: Project Builds Summary Then recent build has been erased And recent build summary does not have artifacts widget And recent build summary contains information saying that build has been erased + And the build count cache is updated diff --git a/features/project/commits/tags.feature b/features/project/commits/tags.feature deleted file mode 100644 index a4be39b2d40899..00000000000000 --- a/features/project/commits/tags.feature +++ /dev/null @@ -1,46 +0,0 @@ -@project_commits -Feature: Project Commits Tags - Background: - Given I sign in as a user - And I own project "Shop" - Given I visit project tags page - - Scenario: I can see all git tags - Then I should see "Shop" all tags list - - Scenario: I create a tag - And I click new tag link - And I submit new tag form - Then I should see new tag created - - Scenario: I create a tag with release notes - Given I click new tag link - And I submit new tag form with release notes - Then I should see new tag created - And I should see tag release notes - - Scenario: I create a tag with invalid name - And I click new tag link - And I submit new tag form with invalid name - Then I should see new an error that tag is invalid - - Scenario: I create a tag with invalid reference - And I click new tag link - And I submit new tag form with invalid reference - Then I should see new an error that tag ref is invalid - - Scenario: I create a tag that already exists - And I click new tag link - And I submit new tag form with tag that already exists - Then I should see new an error that tag already exists - - Scenario: I delete a tag - Given I visit tag 'v1.1.0' page - Given I delete tag 'v1.1.0' - Then I should not see tag 'v1.1.0' - - Scenario: I add release notes to the tag - Given I visit tag 'v1.1.0' page - When I click edit tag link - And I fill release notes and submit form - Then I should see tag release notes diff --git a/features/project/create.feature b/features/project/create.feature index 27136798e36d14..67336d73bf729a 100644 --- a/features/project/create.feature +++ b/features/project/create.feature @@ -6,21 +6,9 @@ Feature: Project Create @javascript Scenario: User create a project - Given I sign in as a user - When I visit new project page - And I have an ssh key - And fill project form with valid data - Then I should see project page - And I should see empty project instuctions - - @javascript - Scenario: Empty project instructions Given I sign in as a user And I have an ssh key When I visit new project page And fill project form with valid data - Then I see empty project instuctions - And I click on HTTP - Then Remote url should update to http link - And If I click on SSH - Then Remote url should update to ssh link + Then I should see project page + And I should see empty project instructions diff --git a/features/project/project.feature b/features/project/project.feature index f1f3ed26065eb9..aa22401c88ec34 100644 --- a/features/project/project.feature +++ b/features/project/project.feature @@ -18,15 +18,6 @@ Feature: Project Then I should see the default project avatar And I should not see the "Remove avatar" button - Scenario: I should have back to group button - And project "Shop" belongs to group - And I visit project "Shop" page - Then I should see back to group button - - Scenario: I should have back to group button - And I visit project "Shop" page - Then I should see back to dashboard button - Scenario: I should have readme on page And I visit project "Shop" page Then I should see project "Shop" README diff --git a/features/project/shortcuts.feature b/features/project/shortcuts.feature index 10e7c23461057d..c73d0b32337689 100644 --- a/features/project/shortcuts.feature +++ b/features/project/shortcuts.feature @@ -8,19 +8,21 @@ Feature: Project Shortcuts @javascript Scenario: Navigate to files tab Given I press "g" and "f" - Then the active main tab should be Files + Then the active main tab should be Code + Then the active sub tab should be Files @javascript Scenario: Navigate to commits tab Given I visit my project's files page Given I press "g" and "c" - Then the active main tab should be Commits + Then the active main tab should be Code + Then the active sub tab should be Commits @javascript Scenario: Navigate to network tab Given I press "g" and "n" Then the active sub tab should be Network - And the active main tab should be Commits + And the active main tab should be Code @javascript Scenario: Navigate to graphs tab diff --git a/features/steps/admin/active_tab.rb b/features/steps/admin/active_tab.rb index 90d13abdb13173..f2db180138981d 100644 --- a/features/steps/admin/active_tab.rb +++ b/features/steps/admin/active_tab.rb @@ -1,7 +1,7 @@ class Spinach::Features::AdminActiveTab < Spinach::FeatureSteps include SharedAuthentication include SharedPaths - include SharedActiveTab + include SharedSidebarActiveTab step 'the active main tab should be Home' do ensure_active_main_tab('Overview') @@ -34,4 +34,12 @@ class Spinach::Features::AdminActiveTab < Spinach::FeatureSteps step 'the active main tab should be Messages' do ensure_active_main_tab('Messages') end + + step 'no other main tabs should be active' do + expect(page).to have_selector('.nav-sidebar > li.active', count: 1) + end + + def ensure_active_main_tab(content) + expect(find('.nav-sidebar > li.active')).to have_content(content) + end end diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb index 4bc290b6bdfe70..8fb8a86d58b1f8 100644 --- a/features/steps/admin/users.rb +++ b/features/steps/admin/users.rb @@ -158,7 +158,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps step 'I should not see twitter details' do expect(page).to have_content 'Pete' - expect(page).to_not have_content 'twitter' + expect(page).not_to have_content 'twitter' end step 'click on ssh keys tab' do diff --git a/features/steps/dashboard/active_tab.rb b/features/steps/dashboard/active_tab.rb index 0e2c04fb29994c..04fe96cef22bc6 100644 --- a/features/steps/dashboard/active_tab.rb +++ b/features/steps/dashboard/active_tab.rb @@ -1,9 +1,5 @@ class Spinach::Features::DashboardActiveTab < Spinach::FeatureSteps include SharedAuthentication include SharedPaths - include SharedActiveTab - - step 'the active main tab should be Help' do - ensure_active_main_tab('Help') - end + include SharedSidebarActiveTab end diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index b5980b3510297f..80ed4c6d64cad9 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -13,7 +13,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps end step 'I should see "Shop" project CI status' do - expect(page).to have_link "Build skipped" + expect(page).to have_link "Commit: skipped" end step 'I should see last push widget' do diff --git a/features/steps/dashboard/issues.rb b/features/steps/dashboard/issues.rb index e21af72a777ba3..8706f0e8e789fb 100644 --- a/features/steps/dashboard/issues.rb +++ b/features/steps/dashboard/issues.rb @@ -74,7 +74,7 @@ def authored_issue_on_public_project def project @project ||= begin - project =create :project + project = create :project project.team << [current_user, :master] project end diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb index a2adc87f8efa93..06db36c7014076 100644 --- a/features/steps/dashboard/merge_requests.rb +++ b/features/steps/dashboard/merge_requests.rb @@ -100,7 +100,7 @@ def assigned_merge_request_from_fork def project @project ||= begin - project =create :project + project = create :project project.team << [current_user, :master] project end diff --git a/features/steps/dashboard/shortcuts.rb b/features/steps/dashboard/shortcuts.rb index a9083850b523fc..118d27888df461 100644 --- a/features/steps/dashboard/shortcuts.rb +++ b/features/steps/dashboard/shortcuts.rb @@ -2,5 +2,6 @@ class Spinach::Features::DashboardShortcuts < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject - include SharedActiveTab + include SharedSidebarActiveTab + include SharedShortcuts end diff --git a/features/steps/dashboard/todos.rb b/features/steps/dashboard/todos.rb index 2b23df6764b7bf..bd8a270202ee75 100644 --- a/features/steps/dashboard/todos.rb +++ b/features/steps/dashboard/todos.rb @@ -20,7 +20,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps step 'I have todos' do create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED) create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::ASSIGNED) - note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?") + note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?", project: project) create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::MENTIONED, note: note) create(:todo, user: current_user, project: project, author: john_doe, target: merge_request, action: Todo::ASSIGNED) end @@ -106,7 +106,7 @@ def should_see_todo(position, title, body, pending = true) if pending expect(page).to have_link 'Done' else - expect(page).to_not have_link 'Done' + expect(page).not_to have_link 'Done' end end end diff --git a/features/steps/profile/active_tab.rb b/features/steps/profile/active_tab.rb index 3b59089a093e02..4724a326277783 100644 --- a/features/steps/profile/active_tab.rb +++ b/features/steps/profile/active_tab.rb @@ -22,8 +22,4 @@ class Spinach::Features::ProfileActiveTab < Spinach::FeatureSteps step 'the active main tab should be Audit Log' do ensure_active_main_tab('Audit Log') end - - def ensure_active_main_tab(content) - expect(find('.layout-nav li.active')).to have_content(content) - end end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 909de31a479892..b1a87b96efd115 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -166,7 +166,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I have group with projects' do - @group = create(:group) + @group = create(:group) @group.add_owner(current_user) @project = create(:project, namespace: @group) @event = create(:closed_issue_event, project: @project) diff --git a/features/steps/project/active_tab.rb b/features/steps/project/active_tab.rb index 19d81453d8cd7f..745fd3471c4953 100644 --- a/features/steps/project/active_tab.rb +++ b/features/steps/project/active_tab.rb @@ -16,12 +16,14 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps end step 'I click the "Snippets" tab' do - click_link('Snippets') + page.within('.layout-nav') do + click_link('Snippets') + end end - step 'I click the "Edit" tab' do - page.within '.sidebar-subnav' do - click_link('Project Settings') + step 'I click the "Edit Project"' do + page.within '.layout-nav .controls' do + click_link('Edit Project') end end @@ -33,14 +35,10 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps click_link('Deploy Keys') end - step 'the active sub nav should be Team' do + step 'the active sub nav should be Members' do ensure_active_sub_nav('Members') end - step 'the active sub nav should be Edit' do - ensure_active_sub_nav('Project') - end - step 'the active sub nav should be Hooks' do ensure_active_sub_nav('Webhooks') end @@ -56,17 +54,15 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps end step 'I click the "Branches" tab' do - click_link('Branches') + page.within '.content' do + click_link('Branches') + end end step 'I click the "Tags" tab' do click_link('Tags') end - step 'the active sub tab should be Commits' do - ensure_active_sub_tab('Commits') - end - step 'the active sub tab should be Compare' do ensure_active_sub_tab('Compare') end @@ -82,11 +78,15 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps # Sub Tabs: Issues step 'I click the "Milestones" tab' do - click_link('Milestones') + page.within('.layout-nav') do + click_link('Milestones') + end end step 'I click the "Labels" tab' do - click_link('Labels') + page.within('.layout-nav') do + click_link('Labels') + end end step 'the active sub tab should be Issues' do diff --git a/features/steps/project/builds/summary.rb b/features/steps/project/builds/summary.rb index e9e2359146e4b3..374eb0b0e07b7f 100644 --- a/features/steps/project/builds/summary.rb +++ b/features/steps/project/builds/summary.rb @@ -36,4 +36,8 @@ class Spinach::Features::ProjectBuildsSummary < Spinach::FeatureSteps expect(page).to have_content 'Build has been erased' end end + + step 'the build count cache is updated' do + expect(@build.project.running_or_pending_build_count).to eq @build.project.builds.running_or_pending.count(:all) + end end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index 93c37bf507f7dd..e1b29f1e57a99c 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -105,7 +105,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I should not see button to create a new merge request' do - expect(page).to_not have_link 'Create Merge Request' + expect(page).not_to have_link 'Create Merge Request' end step 'I should see button to the merge request' do @@ -173,7 +173,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I see commit ci info' do - expect(page).to have_content "build: pending" + expect(page).to have_content "Builds for 1 pipeline pending" end step 'I click status link' do @@ -181,7 +181,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I see builds list' do - expect(page).to have_content "build: pending" + expect(page).to have_content "Builds for 1 pipeline pending" expect(page).to have_content "1 build" end diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb deleted file mode 100644 index 912ba580efd7a3..00000000000000 --- a/features/steps/project/commits/tags.rb +++ /dev/null @@ -1,90 +0,0 @@ -class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I should see "Shop" all tags list' do - expect(page).to have_content "Tags" - expect(page).to have_content "v1.0.0" - end - - step 'I click new tag link' do - click_link 'New tag' - end - - step 'I submit new tag form' do - fill_in 'tag_name', with: 'v7.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I submit new tag form with release notes' do - fill_in 'tag_name', with: 'v7.0' - fill_in 'ref', with: 'master' - fill_in 'release_description', with: 'Awesome release notes' - click_button 'Create tag' - end - - step 'I fill release notes and submit form' do - fill_in 'release_description', with: 'Awesome release notes' - click_button 'Save changes' - end - - step 'I submit new tag form with invalid name' do - fill_in 'tag_name', with: 'v 1.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I submit new tag form with invalid reference' do - fill_in 'tag_name', with: 'foo' - fill_in 'ref', with: 'foo' - click_button 'Create tag' - end - - step 'I submit new tag form with tag that already exists' do - fill_in 'tag_name', with: 'v1.0.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I should see new tag created' do - expect(page).to have_content 'v7.0' - end - - step 'I should see new an error that tag is invalid' do - expect(page).to have_content 'Tag name invalid' - end - - step 'I should see new an error that tag ref is invalid' do - expect(page).to have_content 'Target foo is invalid' - end - - step 'I should see new an error that tag already exists' do - expect(page).to have_content 'Tag v1.0.0 already exists' - end - - step "I visit tag 'v1.1.0' page" do - click_link 'v1.1.0' - end - - step "I delete tag 'v1.1.0'" do - page.within('.content') do - first('.btn-remove').click - end - end - - step "I should not see tag 'v1.1.0'" do - page.within '.tags' do - expect(page).not_to have_link 'v1.1.0' - end - end - - step 'I click edit tag link' do - click_link 'Edit release notes' - end - - step 'I should see tag release notes' do - expect(page).to have_content 'Awesome release notes' - end -end diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb index 422b151eaa2418..5f5f806df36c8c 100644 --- a/features/steps/project/create.rb +++ b/features/steps/project/create.rb @@ -13,33 +13,9 @@ class Spinach::Features::ProjectCreate < Spinach::FeatureSteps expect(current_path).to eq namespace_project_path(Project.last.namespace, Project.last) end - step 'I should see empty project instuctions' do + step 'I should see empty project instructions' do expect(page).to have_content "git init" expect(page).to have_content "git remote" expect(page).to have_content Project.last.url_to_repo end - - step 'I see empty project instuctions' do - expect(page).to have_content "git init" - expect(page).to have_content "git remote" - expect(page).to have_content Project.last.url_to_repo - end - - step 'I click on HTTP' do - find('#clone-dropdown').click - find('.http-selector').click - end - - step 'Remote url should update to http link' do - expect(page).to have_content "git remote add origin #{Project.last.http_url_to_repo}" - end - - step 'If I click on SSH' do - find('#clone-dropdown').click - find('.ssh-selector').click - end - - step 'Remote url should update to ssh link' do - expect(page).to have_content "git remote add origin #{Project.last.url_to_repo}" - end end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 527f7853da9f09..8abeb5ee242020 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -36,7 +36,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps end step 'I goto the Merge Requests page' do - page.within '.page-sidebar-expanded' do + page.within '.layout-nav' do click_link "Merge Requests" end end diff --git a/features/steps/project/hooks.rb b/features/steps/project/hooks.rb index b1ffe7f7b4c88d..13c0713669a03a 100644 --- a/features/steps/project/hooks.rb +++ b/features/steps/project/hooks.rb @@ -59,7 +59,7 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps step 'hook should be triggered' do expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project) expect(page).to have_selector '.flash-notice', - text: 'Hook successfully executed.' + text: 'Hook executed successfully: HTTP 200' end step 'I should see hook error message' do diff --git a/features/steps/project/issues/award_emoji.rb b/features/steps/project/issues/award_emoji.rb index c5d45709b44567..1b14659b4dfb7c 100644 --- a/features/steps/project/issues/award_emoji.rb +++ b/features/steps/project/issues/award_emoji.rb @@ -39,8 +39,8 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps step 'I can see the activity and food categories' do page.within '.emoji-menu' do - expect(page).to_not have_selector 'Activity' - expect(page).to_not have_selector 'Food' + expect(page).not_to have_selector 'Activity' + expect(page).not_to have_selector 'Food' end end diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index fc12843ea5ca4a..5cd431e05d5802 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -216,7 +216,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps page.within 'li.issue:nth-child(3)' do expect(page).to have_content 'Bugfix' - expect(page).to_not have_content '0 0' + expect(page).not_to have_content '0 0' end end end @@ -235,7 +235,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps page.within 'li.issue:nth-child(3)' do expect(page).to have_content 'Bugfix' - expect(page).to_not have_content '0 0' + expect(page).not_to have_content '0 0' end end end @@ -348,7 +348,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'another user adds a comment with text "Yay!" to issue "Release 0.4"' do issue = Issue.find_by!(title: 'Release 0.4') - create(:note_on_issue, noteable: issue, note: 'Yay!') + create(:note_on_issue, noteable: issue, project: project, note: 'Yay!') end step 'I should see a new comment with text "Yay!"' do diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index 0ca2d6257c3bc8..8d87f6a7a58229 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -24,8 +24,8 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I should see labels help message' do page.within '.labels' do - expect(page).to have_content 'Create first label or generate default set of '\ - 'labels' + expect(page).to have_content 'Create a label or generate a default set '\ + 'of labels' end end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 3b1a00f628af07..b30346790eb58d 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -203,7 +203,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps page.within 'li.merge-request:nth-child(3)' do expect(page).to have_content 'Bug NS-05' - expect(page).to_not have_content '0 0' + expect(page).not_to have_content '0 0' end end end @@ -222,7 +222,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps page.within 'li.merge-request:nth-child(3)' do expect(page).to have_content 'Bug NS-05' - expect(page).to_not have_content '0 0' + expect(page).not_to have_content '0 0' end end end @@ -273,7 +273,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'user "John Doe" leaves a comment like "Line is wrong" on diff' do mr = MergeRequest.find_by(title: "Bug NS-05") create(:note_on_merge_request_diff, project: project, - noteable_id: mr.id, + noteable: mr, author: user_exists("John Doe"), line_code: sample_commit.line_code, note: 'Line is wrong') @@ -525,7 +525,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should see merge request "Bug NS-05" with CI status' do page.within ".mr-list" do - expect(page).to have_link "Build pending" + expect(page).to have_link "Pipeline: pending" end end @@ -567,7 +567,7 @@ def init_diff_note_second_file click_diff_line(sample_compare.changes[1][:line_code]) end - def have_visible_content (text) + def have_visible_content(text) have_css("*", text: text, visible: true) end diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index ef185861e00e85..a1785311c2b8ae 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -114,7 +114,9 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should not see "Snippets" button' do - expect(page).not_to have_link 'Snippets' + page.within '.content' do + expect(page).not_to have_link 'Snippets' + end end step 'project "Shop" belongs to group' do @@ -123,14 +125,6 @@ class Spinach::Features::Project < Spinach::FeatureSteps @project.save! end - step 'I should see back to dashboard button' do - expect(page).to have_content 'Go to dashboard' - end - - step 'I should see back to group button' do - expect(page).to have_content 'Go to group' - end - step 'I click notifications drop down button' do click_link 'notifications-button' end diff --git a/features/steps/project/project_find_file.rb b/features/steps/project/project_find_file.rb index 8c1d09d6cc6aae..47de4b91df1eba 100644 --- a/features/steps/project/project_find_file.rb +++ b/features/steps/project/project_find_file.rb @@ -13,12 +13,12 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps end step 'I should see "find file" page' do - ensure_active_main_tab('Files') + ensure_active_main_tab('Code') expect(page).to have_selector('.file-finder-holder', count: 1) end step 'I fill in Find by path with "git"' do - ensure_active_main_tab('Files') + ensure_active_main_tab('Code') expect(page).to have_selector('.file-finder-holder', count: 1) end diff --git a/features/steps/project/project_milestone.rb b/features/steps/project/project_milestone.rb index 2508c09e36d861..1864b3a2b52df7 100644 --- a/features/steps/project/project_milestone.rb +++ b/features/steps/project/project_milestone.rb @@ -52,7 +52,7 @@ class Spinach::Features::ProjectMilestone < Spinach::FeatureSteps end step 'I click link "Labels"' do - page.within('.nav-links') do + page.within('.layout-nav .nav-links') do page.find(:xpath, "//a[@href='#tab-labels']").click end end diff --git a/features/steps/project/project_shortcuts.rb b/features/steps/project/project_shortcuts.rb index 49e9c5520bb603..8143b01ca4070f 100644 --- a/features/steps/project/project_shortcuts.rb +++ b/features/steps/project/project_shortcuts.rb @@ -3,6 +3,7 @@ class Spinach::Features::ProjectShortcuts < Spinach::FeatureSteps include SharedPaths include SharedProject include SharedProjectTab + include SharedShortcuts step 'I press "g" and "f"' do find('body').native.send_key('g') diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index 786a0cad975715..beb8ecfc799254 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -43,12 +43,12 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps step 'I click link "Edit"' do page.within ".detail-page-header" do - click_link "Edit" + first(:link, "Edit").click end end step 'I click link "Delete"' do - click_link "Delete" + first(:link, "Delete").click end step 'I submit new snippet "Snippet three"' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index c26d7a1521214c..2c0498de3b92f1 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -337,13 +337,15 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I should see buttons for allowed commands' do - expect(page).to have_content 'Raw' - expect(page).to have_content 'History' - expect(page).to have_content 'Permalink' - expect(page).not_to have_content 'Edit' - expect(page).not_to have_content 'Blame' - expect(page).to have_content 'Delete' - expect(page).to have_content 'Replace' + page.within '.content' do + expect(page).to have_content 'Raw' + expect(page).to have_content 'History' + expect(page).to have_content 'Permalink' + expect(page).not_to have_content 'Edit' + expect(page).not_to have_content 'Blame' + expect(page).to have_content 'Delete' + expect(page).to have_content 'Replace' + end end step 'I should see a notice about a new fork having been created' do diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index 3fbcf770b62bea..c6ced747370c3c 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -126,7 +126,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps step 'I share project with group "OpenSource"' do project = Project.find_by(name: 'Shop') - os_group = create(:group, name: 'OpenSource') + os_group = create(:group, name: 'OpenSource') create(:project, group: os_group) @os_user1 = create(:user) @os_user2 = create(:user) diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb index 0bee91d758d685..ace717b99094d8 100644 --- a/features/steps/shared/active_tab.rb +++ b/features/steps/shared/active_tab.rb @@ -2,7 +2,7 @@ module SharedActiveTab include Spinach::DSL def ensure_active_main_tab(content) - expect(find('.nav-sidebar > li.active')).to have_content(content) + expect(find('.layout-nav li.active')).to have_content(content) end def ensure_active_sub_tab(content) @@ -10,11 +10,11 @@ def ensure_active_sub_tab(content) end def ensure_active_sub_nav(content) - expect(find('.sidebar-subnav > li.active')).to have_content(content) + expect(find('.layout-nav .controls li.active')).to have_content(content) end step 'no other main tabs should be active' do - expect(page).to have_selector('.nav-sidebar > li.active', count: 1) + expect(page).to have_selector('.layout-nav .nav-links > li.active', count: 1) end step 'no other sub tabs should be active' do @@ -22,26 +22,6 @@ def ensure_active_sub_nav(content) end step 'no other sub navs should be active' do - expect(page).to have_selector('.sidebar-subnav > li.active', count: 1) - end - - step 'the active main tab should be Home' do - ensure_active_main_tab('Projects') - end - - step 'the active main tab should be Projects' do - ensure_active_main_tab('Projects') - end - - step 'the active main tab should be Issues' do - ensure_active_main_tab('Issues') - end - - step 'the active main tab should be Merge Requests' do - ensure_active_main_tab('Merge Requests') - end - - step 'the active main tab should be Help' do - ensure_active_main_tab('Help') + expect(page).to have_selector('.layout-nav .controls li.active', count: 1) end end diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index e846c52d474ecd..e8b1e4b4879baa 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -23,7 +23,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.line_code) - page.within("form[id$='#{sample_commit.line_code}']") do + page.within("form[id$='#{sample_commit.line_code}-true']") do fill_in "note[note]", with: "Typo, please fix" find(".js-comment-button").trigger("click") sleep 0.05 @@ -33,7 +33,7 @@ module SharedDiffNote step 'I leave a diff comment in a parallel view on the left side like "Old comment"' do click_parallel_diff_line(sample_commit.line_code, 'old') - page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}']") do + page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}-true']") do fill_in "note[note]", with: "Old comment" find(".js-comment-button").trigger("click") end @@ -41,7 +41,7 @@ module SharedDiffNote step 'I leave a diff comment in a parallel view on the right side like "New comment"' do click_parallel_diff_line(sample_commit.line_code, 'new') - page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}']") do + page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}-true']") do fill_in "note[note]", with: "New comment" find(".js-comment-button").trigger("click") end @@ -51,7 +51,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.line_code) - page.within("form[id$='#{sample_commit.line_code}']") do + page.within("form[id$='#{sample_commit.line_code}-true']") do fill_in "note[note]", with: "Should fix it :smile:" find('.js-md-preview-button').click end @@ -62,7 +62,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.del_line_code) - page.within("form[id$='#{sample_commit.del_line_code}']") do + page.within("form[id$='#{sample_commit.del_line_code}-true']") do fill_in "note[note]", with: "DRY this up" find('.js-md-preview-button').click end @@ -91,7 +91,7 @@ module SharedDiffNote page.within(diff_file_selector) do click_diff_line(sample_commit.line_code) - page.within("form[id$='#{sample_commit.line_code}']") do + page.within("form[id$='#{sample_commit.line_code}-true']") do fill_in 'note[note]', with: ':smile:' click_button('Comment') end diff --git a/features/steps/shared/issuable.rb b/features/steps/shared/issuable.rb index a58b3cb7e16042..733e80b7279cc4 100644 --- a/features/steps/shared/issuable.rb +++ b/features/steps/shared/issuable.rb @@ -111,7 +111,7 @@ def edit_issuable step 'I sort the list by "Oldest updated"' do find('button.dropdown-toggle.btn').click - page.within('ul.dropdown-menu.dropdown-menu-align-right li') do + page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do click_link "Oldest updated" end end @@ -119,7 +119,7 @@ def edit_issuable step 'I sort the list by "Least popular"' do find('button.dropdown-toggle.btn').click - page.within('ul.dropdown-menu.dropdown-menu-align-right li') do + page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do click_link 'Least popular' end end @@ -127,13 +127,13 @@ def edit_issuable step 'I sort the list by "Most popular"' do find('button.dropdown-toggle.btn').click - page.within('ul.dropdown-menu.dropdown-menu-align-right li') do + page.within('.content ul.dropdown-menu.dropdown-menu-align-right li') do click_link 'Most popular' end end step 'The list should be sorted by "Oldest updated"' do - page.within('div.dropdown.inline.prepend-left-10') do + page.within('.content div.dropdown.inline.prepend-left-10') do expect(page.find('button.dropdown-toggle.btn')).to have_content('Oldest updated') end end diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb index a3c3887ab4600e..3d7c6ef9d2db06 100644 --- a/features/steps/shared/note.rb +++ b/features/steps/shared/note.rb @@ -107,7 +107,7 @@ module SharedNote end step 'I should see no notes at all' do - expect(page).to_not have_css('.note') + expect(page).not_to have_css('.note') end # Markdown diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index ea5f9580308e05..ce9ea7ee18af74 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -95,7 +95,7 @@ module SharedProject step 'I should see project settings' do expect(current_path).to eq edit_namespace_project_path(@project.namespace, @project) expect(page).to have_content("Project name") - expect(page).to have_content("Features:") + expect(page).to have_content("Features") end def current_project diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index 4fc2ece79ff927..bfee87933010d2 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -8,12 +8,8 @@ module SharedProjectTab ensure_active_main_tab('Project') end - step 'the active main tab should be Files' do - ensure_active_main_tab('Files') - end - - step 'the active main tab should be Commits' do - ensure_active_main_tab('Commits') + step 'the active main tab should be Code' do + ensure_active_main_tab('Code') end step 'the active main tab should be Graphs' do @@ -41,9 +37,7 @@ module SharedProjectTab end step 'the active main tab should be Settings' do - page.within '.nav-sidebar' do - expect(page).to have_content('Go to project') - end + expect(page).to have_selector('.layout-nav .nav-links > li.active', count: 0) end step 'the active main tab should be Activity' do @@ -53,4 +47,12 @@ module SharedProjectTab step 'the active sub tab should be Network' do ensure_active_sub_tab('Network') end + + step 'the active sub tab should be Files' do + ensure_active_sub_tab('Files') + end + + step 'the active sub tab should be Commits' do + ensure_active_sub_tab('Commits') + end end diff --git a/features/steps/shared/shortcuts.rb b/features/steps/shared/shortcuts.rb index bbb7afec0ad33e..a75a8474d26a7f 100644 --- a/features/steps/shared/shortcuts.rb +++ b/features/steps/shared/shortcuts.rb @@ -1,4 +1,4 @@ -module SharedActiveTab +module SharedShortcuts include Spinach::DSL step 'I press "g" and "p"' do diff --git a/features/steps/shared/sidebar_active_tab.rb b/features/steps/shared/sidebar_active_tab.rb new file mode 100644 index 00000000000000..5c47238777fd77 --- /dev/null +++ b/features/steps/shared/sidebar_active_tab.rb @@ -0,0 +1,35 @@ +module SharedSidebarActiveTab + include Spinach::DSL + + step 'the active main tab should be Help' do + ensure_active_main_tab('Help') + end + + step 'no other main tabs should be active' do + expect(page).to have_selector('.nav-sidebar > li.active', count: 1) + end + + def ensure_active_main_tab(content) + expect(find('.nav-sidebar li.active')).to have_content(content) + end + + step 'the active main tab should be Home' do + ensure_active_main_tab('Projects') + end + + step 'the active main tab should be Projects' do + ensure_active_main_tab('Projects') + end + + step 'the active main tab should be Issues' do + ensure_active_main_tab('Issues') + end + + step 'the active main tab should be Merge Requests' do + ensure_active_main_tab('Merge Requests') + end + + step 'the active main tab should be Help' do + ensure_active_main_tab('Help') + end +end diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index 023032e679f219..19366b11071d71 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -14,12 +14,12 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps step 'I click link "Edit"' do page.within ".detail-page-header" do - click_link "Edit" + first(:link, "Edit").click end end step 'I click link "Delete"' do - click_link "Delete" + first(:link, "Delete").click end step 'I submit new snippet "Personal snippet three"' do diff --git a/features/steps/user.rb b/features/steps/user.rb index b1d088f07f992e..59385a6ab59d03 100644 --- a/features/steps/user.rb +++ b/features/steps/user.rb @@ -34,7 +34,7 @@ class Spinach::Features::User < Spinach::FeatureSteps end step 'I should see contributions calendar' do - expect(page).to have_css('.cal-heatmap-container') + expect(page).to have_css('.js-contrib-calendar') end def contributed_project diff --git a/generator_templates/active_record/migration/create_table_migration.rb b/generator_templates/active_record/migration/create_table_migration.rb new file mode 100644 index 00000000000000..27acc75dcc433d --- /dev/null +++ b/generator_templates/active_record/migration/create_table_migration.rb @@ -0,0 +1,35 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class <%= migration_class_name %> < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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 + # existing transaction. When using "add_concurrent_index" make sure that this + # method is the _only_ method called in the migration, any other changes + # should go in a separate migration. This ensures that upon failure _only_ the + # index creation fails and can be retried or reverted easily. + # + # To disable transactions uncomment the following line and remove these + # comments: + # disable_ddl_transaction! + + def change + create_table :<%= table_name %> do |t| +<% attributes.each do |attribute| -%> +<% if attribute.password_digest? -%> + t.string :password_digest<%= attribute.inject_options %> +<% else -%> + t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %> +<% end -%> +<% end -%> +<% if options[:timestamps] %> + t.timestamps null: false +<% end -%> + end +<% attributes_with_index.each do |attribute| -%> + add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> +<% end -%> + end +end diff --git a/generator_templates/active_record/migration/migration.rb b/generator_templates/active_record/migration/migration.rb new file mode 100644 index 00000000000000..06bdea113670ab --- /dev/null +++ b/generator_templates/active_record/migration/migration.rb @@ -0,0 +1,55 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class <%= migration_class_name %> < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # 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 + # existing transaction. When using "add_concurrent_index" make sure that this + # method is the _only_ method called in the migration, any other changes + # should go in a separate migration. This ensures that upon failure _only_ the + # index creation fails and can be retried or reverted easily. + # + # To disable transactions uncomment the following line and remove these + # comments: + # disable_ddl_transaction! + +<%- if migration_action == 'add' -%> + def change +<% attributes.each do |attribute| -%> + <%- if attribute.reference? -%> + add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %> + <%- else -%> + add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %> + <%- if attribute.has_index? -%> + add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> + <%- end -%> + <%- end -%> +<%- end -%> + end +<%- elsif migration_action == 'join' -%> + def change + create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t| + <%- attributes.each do |attribute| -%> + <%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %> + <%- end -%> + end + end +<%- else -%> + def change +<% attributes.each do |attribute| -%> +<%- if migration_action -%> + <%- if attribute.reference? -%> + remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %> + <%- else -%> + <%- if attribute.has_index? -%> + remove_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %> + <%- end -%> + remove_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %> + <%- end -%> +<%- end -%> +<%- end -%> + end +<%- end -%> +end diff --git a/lib/api/api.rb b/lib/api/api.rb index cc1004f80059e8..6cd909f6115402 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -1,5 +1,3 @@ -Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file} - module API class API < Grape::API include APIGuard @@ -25,38 +23,41 @@ class API < Grape::API format :json content_type :txt, "text/plain" - helpers Helpers - - mount Groups - mount GroupMembers - mount Users - mount Projects - mount Repositories - mount Issues - mount Milestones - mount Session - mount MergeRequests - mount Notes - mount Internal - mount SystemHooks - mount ProjectSnippets - mount ProjectMembers - mount DeployKeys - mount ProjectHooks - mount Services - mount Files - mount Commits - mount CommitStatus - mount Namespaces - mount Branches - mount Labels - mount Settings - mount Keys - mount Tags - mount Triggers - mount Builds - mount Variables - mount Runners - mount Licenses + # Ensure the namespace is right, otherwise we might load Grape::API::Helpers + helpers ::API::Helpers + + mount ::API::Groups + mount ::API::GroupMembers + mount ::API::Users + mount ::API::Projects + mount ::API::Repositories + mount ::API::Issues + mount ::API::Milestones + mount ::API::Session + mount ::API::MergeRequests + mount ::API::Notes + mount ::API::Internal + mount ::API::SystemHooks + mount ::API::ProjectSnippets + mount ::API::ProjectMembers + mount ::API::DeployKeys + mount ::API::ProjectHooks + mount ::API::Services + mount ::API::Files + mount ::API::Commits + mount ::API::CommitStatuses + mount ::API::Namespaces + mount ::API::Branches + mount ::API::Labels + mount ::API::Settings + mount ::API::Keys + mount ::API::Tags + mount ::API::Triggers + mount ::API::Builds + mount ::API::Variables + mount ::API::Runners + mount ::API::Licenses + mount ::API::Subscriptions + mount ::API::Gitignores end end diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index b9994fcefdaba0..7e67edb203ac73 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -2,171 +2,175 @@ require 'rack/oauth2' -module APIGuard - extend ActiveSupport::Concern +module API + module APIGuard + extend ActiveSupport::Concern - included do |base| - # OAuth2 Resource Server Authentication - use Rack::OAuth2::Server::Resource::Bearer, 'The API' do |request| - # The authenticator only fetches the raw token string + included do |base| + # OAuth2 Resource Server Authentication + use Rack::OAuth2::Server::Resource::Bearer, 'The API' do |request| + # The authenticator only fetches the raw token string - # Must yield access token to store it in the env - request.access_token - end + # Must yield access token to store it in the env + request.access_token + end - helpers HelperMethods + helpers HelperMethods - install_error_responders(base) - end + install_error_responders(base) + end - # Helper Methods for Grape Endpoint - module HelperMethods - # Invokes the doorkeeper guard. - # - # If token is presented and valid, then it sets @current_user. - # - # If the token does not have sufficient scopes to cover the requred scopes, - # then it raises InsufficientScopeError. - # - # If the token is expired, then it raises ExpiredError. - # - # If the token is revoked, then it raises RevokedError. - # - # If the token is not found (nil), then it raises TokenNotFoundError. - # - # Arguments: - # - # scopes: (optional) scopes required for this guard. - # Defaults to empty array. - # - def doorkeeper_guard!(scopes: []) - if (access_token = find_access_token).nil? - raise TokenNotFoundError - - else - case validate_access_token(access_token, scopes) - when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE - raise InsufficientScopeError.new(scopes) - when Oauth2::AccessTokenValidationService::EXPIRED - raise ExpiredError - when Oauth2::AccessTokenValidationService::REVOKED - raise RevokedError - when Oauth2::AccessTokenValidationService::VALID - @current_user = User.find(access_token.resource_owner_id) + # Helper Methods for Grape Endpoint + module HelperMethods + # Invokes the doorkeeper guard. + # + # If token is presented and valid, then it sets @current_user. + # + # If the token does not have sufficient scopes to cover the requred scopes, + # then it raises InsufficientScopeError. + # + # If the token is expired, then it raises ExpiredError. + # + # If the token is revoked, then it raises RevokedError. + # + # If the token is not found (nil), then it raises TokenNotFoundError. + # + # Arguments: + # + # scopes: (optional) scopes required for this guard. + # Defaults to empty array. + # + def doorkeeper_guard!(scopes: []) + if (access_token = find_access_token).nil? + raise TokenNotFoundError + + else + case validate_access_token(access_token, scopes) + when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE + raise InsufficientScopeError.new(scopes) + when Oauth2::AccessTokenValidationService::EXPIRED + raise ExpiredError + when Oauth2::AccessTokenValidationService::REVOKED + raise RevokedError + when Oauth2::AccessTokenValidationService::VALID + @current_user = User.find(access_token.resource_owner_id) + end end end - end - def doorkeeper_guard(scopes: []) - if access_token = find_access_token - case validate_access_token(access_token, scopes) - when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE - raise InsufficientScopeError.new(scopes) + def doorkeeper_guard(scopes: []) + if access_token = find_access_token + case validate_access_token(access_token, scopes) + when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE + raise InsufficientScopeError.new(scopes) - when Oauth2::AccessTokenValidationService::EXPIRED - raise ExpiredError + when Oauth2::AccessTokenValidationService::EXPIRED + raise ExpiredError - when Oauth2::AccessTokenValidationService::REVOKED - raise RevokedError + when Oauth2::AccessTokenValidationService::REVOKED + raise RevokedError - when Oauth2::AccessTokenValidationService::VALID - @current_user = User.find(access_token.resource_owner_id) + when Oauth2::AccessTokenValidationService::VALID + @current_user = User.find(access_token.resource_owner_id) + end end end - end - def current_user - @current_user - end + def current_user + @current_user + end - private - def find_access_token - @access_token ||= Doorkeeper.authenticate(doorkeeper_request, Doorkeeper.configuration.access_token_methods) - end + private - def doorkeeper_request - @doorkeeper_request ||= ActionDispatch::Request.new(env) - end + def find_access_token + @access_token ||= Doorkeeper.authenticate(doorkeeper_request, Doorkeeper.configuration.access_token_methods) + end - def validate_access_token(access_token, scopes) - Oauth2::AccessTokenValidationService.validate(access_token, scopes: scopes) - end - end + def doorkeeper_request + @doorkeeper_request ||= ActionDispatch::Request.new(env) + end - module ClassMethods - # Installs the doorkeeper guard on the whole Grape API endpoint. - # - # Arguments: - # - # scopes: (optional) scopes required for this guard. - # Defaults to empty array. - # - def guard_all!(scopes: []) - before do - guard! scopes: scopes + def validate_access_token(access_token, scopes) + Oauth2::AccessTokenValidationService.validate(access_token, scopes: scopes) end end - private - def install_error_responders(base) - error_classes = [ MissingTokenError, TokenNotFoundError, - ExpiredError, RevokedError, InsufficientScopeError] + module ClassMethods + # Installs the doorkeeper guard on the whole Grape API endpoint. + # + # Arguments: + # + # scopes: (optional) scopes required for this guard. + # Defaults to empty array. + # + def guard_all!(scopes: []) + before do + guard! scopes: scopes + end + end - base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler - end + private - def oauth2_bearer_token_error_handler - Proc.new do |e| - response = - case e - when MissingTokenError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new - - when TokenNotFoundError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( - :invalid_token, - "Bad Access Token.") - - when ExpiredError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( - :invalid_token, - "Token is expired. You can either do re-authorization or token refresh.") - - when RevokedError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( - :invalid_token, - "Token was revoked. You have to re-authorize from the user.") - - when InsufficientScopeError - # FIXME: ForbiddenError (inherited from Bearer::Forbidden of Rack::Oauth2) - # does not include WWW-Authenticate header, which breaks the standard. - Rack::OAuth2::Server::Resource::Bearer::Forbidden.new( - :insufficient_scope, - Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION[:insufficient_scope], - { scope: e.scopes }) - end + def install_error_responders(base) + error_classes = [ MissingTokenError, TokenNotFoundError, + ExpiredError, RevokedError, InsufficientScopeError] - response.finish + base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler + end + + def oauth2_bearer_token_error_handler + Proc.new do |e| + response = + case e + when MissingTokenError + Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new + + when TokenNotFoundError + Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( + :invalid_token, + "Bad Access Token.") + + when ExpiredError + Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( + :invalid_token, + "Token is expired. You can either do re-authorization or token refresh.") + + when RevokedError + Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( + :invalid_token, + "Token was revoked. You have to re-authorize from the user.") + + when InsufficientScopeError + # FIXME: ForbiddenError (inherited from Bearer::Forbidden of Rack::Oauth2) + # does not include WWW-Authenticate header, which breaks the standard. + Rack::OAuth2::Server::Resource::Bearer::Forbidden.new( + :insufficient_scope, + Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION[:insufficient_scope], + { scope: e.scopes }) + end + + response.finish + end end end - end - # - # Exceptions - # + # + # Exceptions + # - class MissingTokenError < StandardError; end + class MissingTokenError < StandardError; end - class TokenNotFoundError < StandardError; end + class TokenNotFoundError < StandardError; end - class ExpiredError < StandardError; end + class ExpiredError < StandardError; end - class RevokedError < StandardError; end + class RevokedError < StandardError; end - class InsufficientScopeError < StandardError - attr_reader :scopes - def initialize(scopes) - @scopes = scopes + class InsufficientScopeError < StandardError + attr_reader :scopes + def initialize(scopes) + @scopes = scopes + end end end end diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 7388ed2f4eaf60..9bcd33ff19ebb1 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -2,7 +2,7 @@ module API # Project commit statuses API - class CommitStatus < Grape::API + class CommitStatuses < Grape::API resource :projects do before { authenticate! } diff --git a/lib/api/commits.rb b/lib/api/commits.rb index 93a3a5ce08908c..4a11c8e3620cc2 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -107,6 +107,8 @@ class Commits < Grape::API 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 diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 716ca6f7ed9a0d..790a1869f7364e 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -66,7 +66,8 @@ class Project < Grape::Entity expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } expose :name, :name_with_namespace expose :path, :path_with_namespace - expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :created_at, :last_activity_at + expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :container_registry_enabled + expose :created_at, :last_activity_at expose :shared_runners_enabled expose :creator_id expose :namespace @@ -170,10 +171,10 @@ class Issue < ProjectEntity expose :label_names, as: :labels expose :milestone, using: Entities::Milestone expose :assignee, :author, using: Entities::UserBasic - expose :subscribed do |issue, options| issue.subscribed?(options[:current_user]) end + expose :user_notes_count end class MergeRequest < ProjectEntity @@ -187,10 +188,10 @@ class MergeRequest < ProjectEntity expose :milestone, using: Entities::Milestone expose :merge_when_build_succeeds expose :merge_status - expose :subscribed do |merge_request, options| merge_request.subscribed?(options[:current_user]) end + expose :user_notes_count end class MergeRequestChanges < MergeRequest @@ -227,9 +228,9 @@ class MRNote < Grape::Entity class CommitNote < Grape::Entity expose :note - expose(:path) { |note| note.diff_file_name } - expose(:line) { |note| note.diff_new_line } - expose(:line_type) { |note| note.diff_line_type } + expose(:path) { |note| note.diff_file_path if note.legacy_diff_note? } + expose(:line) { |note| note.diff_new_line if note.legacy_diff_note? } + expose(:line_type) { |note| note.diff_line_type if note.legacy_diff_note? } expose :author, using: Entities::UserBasic expose :created_at end @@ -307,6 +308,10 @@ class ProjectWithAccess < Project class Label < Grape::Entity expose :name, :color, :description expose :open_issues_count, :closed_issues_count, :open_merge_requests_count + + expose :subscribed do |label, options| + label.subscribed?(options[:current_user]) + end end class Compare < Grape::Entity @@ -357,6 +362,7 @@ class ApplicationSetting < Grape::Entity expose :restricted_signup_domains expose :user_oauth_applications expose :after_sign_out_path + expose :container_registry_token_expire_delay end class Release < Grape::Entity @@ -403,6 +409,7 @@ class Runner < Grape::Entity class RunnerDetails < Runner expose :tag_list + expose :run_untagged expose :version, :revision, :platform, :architecture expose :contacted_at expose :token, if: lambda { |runner, options| options[:current_user].is_admin? || !runner.is_shared? } @@ -451,5 +458,13 @@ class RepoLicense < Grape::Entity expose(:limitations) { |license| license.meta['limitations'] } expose :content end + + class GitignoresList < Grape::Entity + expose :name + end + + class Gitignore < Grape::Entity + expose :name, :content + end end end diff --git a/lib/api/gitignores.rb b/lib/api/gitignores.rb new file mode 100644 index 00000000000000..270c9501dd2271 --- /dev/null +++ b/lib/api/gitignores.rb @@ -0,0 +1,29 @@ +module API + class Gitignores < Grape::API + + # Get the list of the available gitignore templates + # + # Example Request: + # GET /gitignores + get 'gitignores' do + present Gitlab::Gitignore.all, with: Entities::GitignoresList + end + + # Get the text for a specific gitignore + # + # Parameters: + # name (required) - The name of a license + # + # Example Request: + # GET /gitignores/Elixir + # + get 'gitignores/:name' do + required_attributes! [:name] + + gitignore = Gitlab::Gitignore.find(params[:name]) + not_found!('.gitignore') unless gitignore + + present gitignore, with: Entities::Gitignore + end + end +end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 91e420832f388d..9d8b8d737a9b06 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -95,8 +95,7 @@ class Groups < Grape::API # GET /groups/:id/projects get ":id/projects" do group = find_group(params[:id]) - projects = group.projects - projects = filter_projects(projects) + projects = GroupProjectsFinder.new(group).execute(current_user) projects = paginate projects present projects, with: Entities::Project end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 40c967453fb778..2aaa0557ea30fc 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -2,7 +2,7 @@ module API module Helpers PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" PRIVATE_TOKEN_PARAM = :private_token - SUDO_HEADER ="HTTP_SUDO" + SUDO_HEADER = "HTTP_SUDO" SUDO_PARAM = :sudo def parse_boolean(value) @@ -29,7 +29,7 @@ def current_user @current_user end - def sudo_identifier() + def sudo_identifier identifier ||= params[SUDO_PARAM] || env[SUDO_HEADER] # Regex for integers @@ -95,6 +95,17 @@ def find_group(id) end end + def find_project_label(id) + label = user_project.labels.find_by_id(id) || user_project.labels.find_by_title(id) + label || not_found!('Label') + end + + def find_project_issue(id) + issue = user_project.issues.find(id) + not_found! unless can?(current_user, :read_issue, issue) + issue + end + def paginate(relation) relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| add_pagination_headers(data) diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 409287494814a7..f59a4d6c012df1 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -103,8 +103,7 @@ def create_spam_log(project, current_user, attrs) # Example Request: # GET /projects/:id/issues/:issue_id get ":id/issues/:issue_id" do - @issue = user_project.issues.find(params[:issue_id]) - not_found! unless can?(current_user, :read_issue, @issue) + @issue = find_project_issue(params[:issue_id]) present @issue, with: Entities::Issue, current_user: current_user end @@ -234,42 +233,6 @@ def create_spam_log(project, current_user, attrs) authorize!(:destroy_issue, issue) issue.destroy end - - # Subscribes to a project issue - # - # Parameters: - # id (required) - The ID of a project - # issue_id (required) - The ID of a project issue - # Example Request: - # POST /projects/:id/issues/:issue_id/subscription - post ':id/issues/:issue_id/subscription' do - issue = user_project.issues.find(params[:issue_id]) - - if issue.subscribed?(current_user) - not_modified! - else - issue.toggle_subscription(current_user) - present issue, with: Entities::Issue, current_user: current_user - end - end - - # Unsubscribes from a project issue - # - # Parameters: - # id (required) - The ID of a project - # issue_id (required) - The ID of a project issue - # Example Request: - # DELETE /projects/:id/issues/:issue_id/subscription - delete ':id/issues/:issue_id/subscription' do - issue = user_project.issues.find(params[:issue_id]) - - if issue.subscribed?(current_user) - issue.unsubscribe(current_user) - present issue, with: Entities::Issue, current_user: current_user - else - not_modified! - end - end end end end diff --git a/lib/api/labels.rb b/lib/api/labels.rb index 4af6bef0fa71b5..c806829d69e526 100644 --- a/lib/api/labels.rb +++ b/lib/api/labels.rb @@ -11,7 +11,7 @@ class Labels < Grape::API # Example Request: # GET /projects/:id/labels get ':id/labels' do - present user_project.labels, with: Entities::Label + present user_project.labels, with: Entities::Label, current_user: current_user end # Creates a new label @@ -36,7 +36,7 @@ class Labels < Grape::API label = user_project.labels.create(attrs) if label.valid? - present label, with: Entities::Label + present label, with: Entities::Label, current_user: current_user else render_validation_error!(label) end @@ -90,7 +90,7 @@ class Labels < Grape::API attrs[:name] = attrs.delete(:new_name) if attrs.key?(:new_name) if label.update(attrs) - present label, with: Entities::Label + present label, with: Entities::Label, current_user: current_user else render_validation_error!(label) end diff --git a/lib/api/licenses.rb b/lib/api/licenses.rb index 187d2c047036bb..be0e113fbcb851 100644 --- a/lib/api/licenses.rb +++ b/lib/api/licenses.rb @@ -2,15 +2,15 @@ module API # Licenses API class Licenses < Grape::API PROJECT_TEMPLATE_REGEX = - /[\<\{\[] - (project|description| - one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here - [\>\}\]]/xi.freeze + /[\<\{\[] + (project|description| + one\sline\s.+\swhat\sit\sdoes\.) # matching the start and end is enough here + [\>\}\]]/xi.freeze YEAR_TEMPLATE_REGEX = /[<{\[](year|yyyy)[>}\]]/i.freeze FULLNAME_TEMPLATE_REGEX = - /[\<\{\[] - (fullname|name\sof\s(author|copyright\sowner)) - [\>\}\]]/xi.freeze + /[\<\{\[] + (fullname|name\sof\s(author|copyright\sowner)) + [\>\}\]]/xi.freeze # Get the list of the available license templates # diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 7e78609ecb9853..4e7de8867b43ae 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -327,42 +327,6 @@ def handle_merge_request_errors!(errors) issues = ::Kaminari.paginate_array(merge_request.closes_issues(current_user)) present paginate(issues), with: Entities::Issue, current_user: current_user end - - # Subscribes to a merge request - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - The ID of a merge request - # Example Request: - # POST /projects/:id/issues/:merge_request_id/subscription - post "#{path}/subscription" do - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - - if merge_request.subscribed?(current_user) - not_modified! - else - merge_request.toggle_subscription(current_user) - present merge_request, with: Entities::MergeRequest, current_user: current_user - end - end - - # Unsubscribes from a merge request - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - The ID of a merge request - # Example Request: - # DELETE /projects/:id/merge_requests/:merge_request_id/subscription - delete "#{path}/subscription" do - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - - if merge_request.subscribed?(current_user) - merge_request.unsubscribe(current_user) - present merge_request, with: Entities::MergeRequest, current_user: current_user - else - not_modified! - end - end end end end diff --git a/lib/api/notes.rb b/lib/api/notes.rb index 71a53e6f0d6f9d..d4fcfd3d4d3b46 100644 --- a/lib/api/notes.rb +++ b/lib/api/notes.rb @@ -19,20 +19,24 @@ class Notes < Grape::API # GET /projects/:id/issues/:noteable_id/notes # GET /projects/:id/snippets/:noteable_id/notes get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do - @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) - - # 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: Entities::Note + @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym]) + + 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: Entities::Note + else + not_found!("Notes") + end end # Get a single +noteable+ note @@ -45,13 +49,14 @@ class Notes < Grape::API # GET /projects/:id/issues/:noteable_id/notes/:note_id # GET /projects/:id/snippets/:noteable_id/notes/:note_id get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do - @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) + @noteable = user_project.send(noteables_str.to_sym).find(params[noteable_id_str.to_sym]) @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 @note.cross_reference_not_visible_for?(current_user) - not_found!("Note") - else + if can_read_note present @note, with: Entities::Note + else + not_found!("Note") end end @@ -136,5 +141,11 @@ class Notes < Grape::API end end end + + helpers do + def noteable_read_ability_name(noteable) + "read_#{noteable.class.to_s.underscore.downcase}".to_sym + end + end end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index cc2c7a0c5032ec..5a22d14988f4a0 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -44,7 +44,7 @@ def map_public_to_visibility_level(attrs) # Example Request: # GET /projects/starred get '/starred' do - @projects = current_user.starred_projects + @projects = current_user.viewable_starred_projects @projects = filter_projects(@projects) @projects = paginate @projects present @projects, with: Entities::Project @@ -94,6 +94,7 @@ def map_public_to_visibility_level(attrs) # builds_enabled (optional) # wiki_enabled (optional) # snippets_enabled (optional) + # container_registry_enabled (optional) # shared_runners_enabled (optional) # namespace_id (optional) - defaults to user namespace # public (optional) - if true same as setting visibility_level = 20 @@ -112,6 +113,7 @@ def map_public_to_visibility_level(attrs) :builds_enabled, :wiki_enabled, :snippets_enabled, + :container_registry_enabled, :shared_runners_enabled, :namespace_id, :public, @@ -143,6 +145,7 @@ def map_public_to_visibility_level(attrs) # builds_enabled (optional) # wiki_enabled (optional) # snippets_enabled (optional) + # container_registry_enabled (optional) # shared_runners_enabled (optional) # public (optional) - if true same as setting visibility_level = 20 # visibility_level (optional) @@ -206,6 +209,7 @@ def map_public_to_visibility_level(attrs) # builds_enabled (optional) # wiki_enabled (optional) # snippets_enabled (optional) + # container_registry_enabled (optional) # shared_runners_enabled (optional) # public (optional) - if true same as setting visibility_level = 20 # visibility_level (optional) - visibility level of a project @@ -222,6 +226,7 @@ def map_public_to_visibility_level(attrs) :builds_enabled, :wiki_enabled, :snippets_enabled, + :container_registry_enabled, :shared_runners_enabled, :public, :visibility_level, diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 8ec91485b26b7b..4faba9dc87ba63 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -49,7 +49,7 @@ class Runners < Grape::API runner = get_runner(params[:id]) authenticate_update_runner!(runner) - attrs = attributes_for_keys [:description, :active, :tag_list] + attrs = attributes_for_keys [:description, :active, :tag_list, :run_untagged] if runner.update(attrs) present runner, with: Entities::RunnerDetails, current_user: current_user else diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb new file mode 100644 index 00000000000000..c49e2a21b82b4c --- /dev/null +++ b/lib/api/subscriptions.rb @@ -0,0 +1,60 @@ +module API + class Subscriptions < Grape::API + before { authenticate! } + + subscribable_types = { + 'merge_request' => proc { |id| user_project.merge_requests.find(id) }, + 'merge_requests' => proc { |id| user_project.merge_requests.find(id) }, + 'issues' => proc { |id| find_project_issue(id) }, + 'labels' => proc { |id| find_project_label(id) }, + } + + resource :projects do + subscribable_types.each do |type, finder| + type_singularized = type.singularize + type_id_str = :"#{type_singularized}_id" + entity_class = Entities.const_get(type_singularized.camelcase) + + # Subscribe to a resource + # + # Parameters: + # id (required) - The ID of a project + # subscribable_id (required) - The ID of a resource + # Example Request: + # POST /projects/:id/labels/:subscribable_id/subscription + # POST /projects/:id/issues/:subscribable_id/subscription + # POST /projects/:id/merge_requests/:subscribable_id/subscription + post ":id/#{type}/:#{type_id_str}/subscription" do + resource = instance_exec(params[type_id_str], &finder) + + if resource.subscribed?(current_user) + not_modified! + else + resource.subscribe(current_user) + present resource, with: entity_class, current_user: current_user + end + end + + # Unsubscribe from a resource + # + # Parameters: + # id (required) - The ID of a project + # subscribable_id (required) - The ID of a resource + # Example Request: + # DELETE /projects/:id/labels/:subscribable_id/subscription + # DELETE /projects/:id/issues/:subscribable_id/subscription + # DELETE /projects/:id/merge_requests/:subscribable_id/subscription + delete ":id/#{type}/:#{type_id_str}/subscription" do + resource = instance_exec(params[type_id_str], &finder) + + if !resource.subscribed?(current_user) + not_modified! + else + resource.unsubscribe(current_user) + present resource, with: entity_class, current_user: current_user + end + end + end + end + end +end diff --git a/lib/api/users.rb b/lib/api/users.rb index ea6fa2dc8a84cc..8a376d3c2a3220 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -76,7 +76,7 @@ class Users < Grape::API required_attributes! [:email, :password, :name, :username] attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :bio, :location, :can_create_group, :admin, :confirm, :external] admin = attrs.delete(:admin) - confirm = !(attrs.delete(:confirm) =~ (/(false|f|no|0)$/i)) + confirm = !(attrs.delete(:confirm) =~ /(false|f|no|0)$/i) user = User.build_user(attrs) user.admin = admin unless admin.nil? user.skip_confirmation! unless confirm diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index 4962f5e53cebca..660ca8c2923a95 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -1,5 +1,8 @@ module Backup class Manager + ARCHIVES_TO_BACKUP = %w[uploads builds artifacts lfs registry] + FOLDERS_TO_BACKUP = %w[repositories db] + def pack # Make sure there is a connection ActiveRecord::Base.connection.reconnect! @@ -45,7 +48,7 @@ def upload(tar_file) end connection = ::Fog::Storage.new(connection_settings) - directory = connection.directories.get(remote_directory) + directory = connection.directories.create(key: remote_directory) if directory.files.create(key: tar_file, body: File.open(tar_file), public: false, multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size, @@ -147,7 +150,7 @@ def tar_version end def skipped?(item) - settings[:skipped] && settings[:skipped].include?(item) + settings[:skipped] && settings[:skipped].include?(item) || disabled_features.include?(item) end private @@ -157,11 +160,17 @@ def backup_contents end def archives_to_backup - %w{uploads builds artifacts lfs}.map{ |name| (name + ".tar.gz") unless skipped?(name) }.compact + ARCHIVES_TO_BACKUP.map{ |name| (name + ".tar.gz") unless skipped?(name) }.compact end def folders_to_backup - %w{repositories db}.reject{ |name| skipped?(name) } + FOLDERS_TO_BACKUP.reject{ |name| skipped?(name) } + end + + def disabled_features + features = [] + features << 'registry' unless Gitlab.config.registry.enabled + features end def settings diff --git a/lib/backup/registry.rb b/lib/backup/registry.rb new file mode 100644 index 00000000000000..67fe023108726b --- /dev/null +++ b/lib/backup/registry.rb @@ -0,0 +1,13 @@ +require 'backup/files' + +module Backup + class Registry < Files + def initialize + super('registry', Settings.registry.path) + end + + def create_files_dir + Dir.mkdir(app_files_dir, 0700) + end + end +end diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb index b8962379cb5712..db95d7c908b523 100644 --- a/lib/banzai/filter/abstract_reference_filter.rb +++ b/lib/banzai/filter/abstract_reference_filter.rb @@ -18,10 +18,6 @@ def self.object_sym @object_sym ||= object_name.to_sym end - def self.data_reference - @data_reference ||= "data-#{object_name.dasherize}" - end - def self.object_class_title @object_title ||= object_class.name.titleize end @@ -45,10 +41,6 @@ def self.references_in(text, pattern = object_class.reference_pattern) end end - def self.referenced_by(node) - { object_sym => LazyReference.new(object_class, node.attr(data_reference)) } - end - def object_class self.class.object_class end @@ -236,7 +228,9 @@ def get_or_set_cache(cache, key) if cache.key?(key) cache[key] else - cache[key] = yield + value = yield + cache[key] = value if key.present? + value end end end diff --git a/lib/banzai/filter/commit_range_reference_filter.rb b/lib/banzai/filter/commit_range_reference_filter.rb index b469ea0f626651..bbb88c979cc3f3 100644 --- a/lib/banzai/filter/commit_range_reference_filter.rb +++ b/lib/banzai/filter/commit_range_reference_filter.rb @@ -4,6 +4,8 @@ module Filter # # This filter supports cross-project references. class CommitRangeReferenceFilter < AbstractReferenceFilter + self.reference_type = :commit_range + def self.object_class CommitRange end @@ -14,34 +16,18 @@ def self.references_in(text, pattern = CommitRange.reference_pattern) end end - def self.referenced_by(node) - project = Project.find(node.attr("data-project")) rescue nil - return unless project - - id = node.attr("data-commit-range") - range = find_object(project, id) - - return unless range - - { commit_range: range } - end - def initialize(*args) super @commit_map = {} end - def self.find_object(project, id) + def find_object(project, id) range = CommitRange.new(id, project) range.valid_commits? ? range : nil end - def find_object(*args) - self.class.find_object(*args) - end - def url_for_object(range, project) h = Gitlab::Routing.url_helpers h.namespace_project_compare_url(project.namespace, project, diff --git a/lib/banzai/filter/commit_reference_filter.rb b/lib/banzai/filter/commit_reference_filter.rb index bd88207326ca31..2ce1816672b93e 100644 --- a/lib/banzai/filter/commit_reference_filter.rb +++ b/lib/banzai/filter/commit_reference_filter.rb @@ -4,6 +4,8 @@ module Filter # # This filter supports cross-project references. class CommitReferenceFilter < AbstractReferenceFilter + self.reference_type = :commit + def self.object_class Commit end @@ -14,28 +16,12 @@ def self.references_in(text, pattern = Commit.reference_pattern) end end - def self.referenced_by(node) - project = Project.find(node.attr("data-project")) rescue nil - return unless project - - id = node.attr("data-commit") - commit = find_object(project, id) - - return unless commit - - { commit: commit } - end - - def self.find_object(project, id) + def find_object(project, id) if project && project.valid_repo? project.commit(id) end end - def find_object(*args) - self.class.find_object(*args) - end - def url_for_object(commit, project) h = Gitlab::Routing.url_helpers h.namespace_project_commit_url(project.namespace, project, commit, diff --git a/lib/banzai/filter/external_issue_reference_filter.rb b/lib/banzai/filter/external_issue_reference_filter.rb index 37344b9057658b..eaa702952ccbec 100644 --- a/lib/banzai/filter/external_issue_reference_filter.rb +++ b/lib/banzai/filter/external_issue_reference_filter.rb @@ -4,6 +4,8 @@ module Filter # References are ignored if the project doesn't use an external issue # tracker. class ExternalIssueReferenceFilter < ReferenceFilter + self.reference_type = :external_issue + # Public: Find `JIRA-123` issue references in text # # ExternalIssueReferenceFilter.references_in(text) do |match, issue| @@ -21,18 +23,6 @@ def self.references_in(text) end end - def self.referenced_by(node) - project = Project.find(node.attr("data-project")) rescue nil - return unless project - - id = node.attr("data-external-issue") - external_issue = ExternalIssue.new(id, project) - - return unless external_issue - - { external_issue: external_issue } - end - def call # Early return if the project isn't using an external tracker return doc if project.nil? || default_issues_tracker? diff --git a/lib/banzai/filter/inline_diff_filter.rb b/lib/banzai/filter/inline_diff_filter.rb new file mode 100644 index 00000000000000..beb21b19ab3b60 --- /dev/null +++ b/lib/banzai/filter/inline_diff_filter.rb @@ -0,0 +1,26 @@ +module Banzai + module Filter + class InlineDiffFilter < HTML::Pipeline::Filter + IGNORED_ANCESTOR_TAGS = %w(pre code tt).to_set + + def call + search_text_nodes(doc).each do |node| + next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS) + + content = node.to_html + html_content = inline_diff_filter(content) + + next if content == html_content + + node.replace(html_content) + end + doc + end + + def inline_diff_filter(text) + html_content = text.gsub(/(?:\[\-(.*?)\-\]|\{\-(.*?)\-\})/, '\1\2') + html_content.gsub(/(?:\[\+(.*?)\+\]|\{\+(.*?)\+\})/, '\1\2') + end + end + end +end diff --git a/lib/banzai/filter/issue_reference_filter.rb b/lib/banzai/filter/issue_reference_filter.rb index 2732e0b51455ca..2496e704002a29 100644 --- a/lib/banzai/filter/issue_reference_filter.rb +++ b/lib/banzai/filter/issue_reference_filter.rb @@ -5,15 +5,12 @@ module Filter # # This filter supports cross-project references. class IssueReferenceFilter < AbstractReferenceFilter + self.reference_type = :issue + def self.object_class Issue end - def self.user_can_see_reference?(user, node, context) - issue = Issue.find(node.attr('data-issue')) rescue nil - Ability.abilities.allowed?(user, :read_issue, issue) - end - def find_object(project, id) project.get_issue(id) end diff --git a/lib/banzai/filter/label_reference_filter.rb b/lib/banzai/filter/label_reference_filter.rb index 8488a493b55cfd..e4d3f87d0aa77d 100644 --- a/lib/banzai/filter/label_reference_filter.rb +++ b/lib/banzai/filter/label_reference_filter.rb @@ -2,6 +2,8 @@ module Banzai module Filter # HTML filter that replaces label references with links. class LabelReferenceFilter < AbstractReferenceFilter + self.reference_type = :label + def self.object_class Label end diff --git a/lib/banzai/filter/merge_request_reference_filter.rb b/lib/banzai/filter/merge_request_reference_filter.rb index cad38a51851f6b..ac5216d9cfb3d7 100644 --- a/lib/banzai/filter/merge_request_reference_filter.rb +++ b/lib/banzai/filter/merge_request_reference_filter.rb @@ -5,6 +5,8 @@ module Filter # # This filter supports cross-project references. class MergeRequestReferenceFilter < AbstractReferenceFilter + self.reference_type = :merge_request + def self.object_class MergeRequest end diff --git a/lib/banzai/filter/milestone_reference_filter.rb b/lib/banzai/filter/milestone_reference_filter.rb index 4cb82178024ac7..ca686c87d97bd9 100644 --- a/lib/banzai/filter/milestone_reference_filter.rb +++ b/lib/banzai/filter/milestone_reference_filter.rb @@ -2,6 +2,8 @@ module Banzai module Filter # HTML filter that replaces milestone references with links. class MilestoneReferenceFilter < AbstractReferenceFilter + self.reference_type = :milestone + def self.object_class Milestone end @@ -10,11 +12,53 @@ def find_object(project, id) project.milestones.find_by(iid: id) end - def url_for_object(issue, project) + def references_in(text, pattern = Milestone.reference_pattern) + # We'll handle here the references that follow the `reference_pattern`. + # Other patterns (for example, the link pattern) are handled by the + # default implementation. + return super(text, pattern) if pattern != Milestone.reference_pattern + + text.gsub(pattern) do |match| + milestone = find_milestone($~[:project], $~[:milestone_iid], $~[:milestone_name]) + + if milestone + yield match, milestone.iid, $~[:project], $~ + else + match + end + end + end + + def find_milestone(project_ref, milestone_id, milestone_name) + project = project_from_ref(project_ref) + return unless project + + milestone_params = milestone_params(milestone_id, milestone_name) + project.milestones.find_by(milestone_params) + end + + def milestone_params(iid, name) + if name + { name: name.tr('"', '') } + else + { iid: iid.to_i } + end + end + + def url_for_object(milestone, project) h = Gitlab::Routing.url_helpers h.namespace_project_milestone_url(project.namespace, project, milestone, only_path: context[:only_path]) end + + def object_link_text(object, matches) + if context[:project] == object.project + super + else + "#{escape_once(super)} in #{escape_once(object.project.path_with_namespace)}". + html_safe + end + end end end end diff --git a/lib/banzai/filter/redactor_filter.rb b/lib/banzai/filter/redactor_filter.rb index e589b5df6ec626..c753a84a20d9a2 100644 --- a/lib/banzai/filter/redactor_filter.rb +++ b/lib/banzai/filter/redactor_filter.rb @@ -7,8 +7,11 @@ module Filter # class RedactorFilter < HTML::Pipeline::Filter def call - Querying.css(doc, 'a.gfm').each do |node| - unless user_can_see_reference?(node) + nodes = Querying.css(doc, 'a.gfm[data-reference-type]') + visible = nodes_visible_to_user(nodes) + + nodes.each do |node| + unless visible.include?(node) # The reference should be replaced by the original text, # which is not always the same as the rendered text. text = node.attr('data-original') || node.text @@ -21,20 +24,30 @@ def call private - def user_can_see_reference?(node) - if node.has_attribute?('data-reference-filter') - reference_type = node.attr('data-reference-filter') - reference_filter = Banzai::Filter.const_get(reference_type) + def nodes_visible_to_user(nodes) + per_type = Hash.new { |h, k| h[k] = [] } + visible = Set.new + + nodes.each do |node| + per_type[node.attr('data-reference-type')] << node + end + + per_type.each do |type, nodes| + parser = Banzai::ReferenceParser[type].new(project, current_user) - reference_filter.user_can_see_reference?(current_user, node, context) - else - true + visible.merge(parser.nodes_visible_to_user(current_user, nodes)) end + + visible end def current_user context[:current_user] end + + def project + context[:project] + end end end end diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb index 31386cf851c700..41ae0e1f9cc36e 100644 --- a/lib/banzai/filter/reference_filter.rb +++ b/lib/banzai/filter/reference_filter.rb @@ -8,24 +8,8 @@ module Filter # :project (required) - Current project, ignored if reference is cross-project. # :only_path - Generate path-only links. class ReferenceFilter < HTML::Pipeline::Filter - def self.user_can_see_reference?(user, node, context) - if node.has_attribute?('data-project') - project_id = node.attr('data-project').to_i - return true if project_id == context[:project].try(:id) - - project = Project.find(project_id) rescue nil - Ability.abilities.allowed?(user, :read_project, project) - else - true - end - end - - def self.user_can_reference?(user, node, context) - true - end - - def self.referenced_by(node) - raise NotImplementedError, "#{self} does not implement #{__method__}" + class << self + attr_accessor :reference_type end # Returns a data attribute String to attach to a reference link @@ -43,7 +27,9 @@ def self.referenced_by(node) # # Returns a String def data_attribute(attributes = {}) - attributes[:reference_filter] = self.class.name.demodulize + attributes = attributes.reject { |_, v| v.nil? } + + attributes[:reference_type] = self.class.reference_type attributes.delete(:original) if context[:no_original_data] attributes.map { |key, value| %Q(data-#{key.to_s.dasherize}="#{escape_once(value)}") }.join(" ") end diff --git a/lib/banzai/filter/reference_gatherer_filter.rb b/lib/banzai/filter/reference_gatherer_filter.rb deleted file mode 100644 index 96fdb06304e5f6..00000000000000 --- a/lib/banzai/filter/reference_gatherer_filter.rb +++ /dev/null @@ -1,65 +0,0 @@ -module Banzai - module Filter - # HTML filter that gathers all referenced records that the current user has - # permission to view. - # - # Expected to be run in its own post-processing pipeline. - # - class ReferenceGathererFilter < HTML::Pipeline::Filter - def initialize(*) - super - - result[:references] ||= Hash.new { |hash, type| hash[type] = [] } - end - - def call - Querying.css(doc, 'a.gfm').each do |node| - gather_references(node) - end - - load_lazy_references unless ReferenceExtractor.lazy? - - doc - end - - private - - def gather_references(node) - return unless node.has_attribute?('data-reference-filter') - - reference_type = node.attr('data-reference-filter') - reference_filter = Banzai::Filter.const_get(reference_type) - - return if context[:reference_filter] && reference_filter != context[:reference_filter] - - return if author && !reference_filter.user_can_reference?(author, node, context) - - return unless reference_filter.user_can_see_reference?(current_user, node, context) - - references = reference_filter.referenced_by(node) - return unless references - - references.each do |type, values| - Array.wrap(values).each do |value| - result[:references][type] << value - end - end - end - - def load_lazy_references - refs = result[:references] - refs.each do |type, values| - refs[type] = ReferenceExtractor.lazily(values) - end - end - - def current_user - context[:current_user] - end - - def author - context[:author] - end - end - end -end diff --git a/lib/banzai/filter/sanitization_filter.rb b/lib/banzai/filter/sanitization_filter.rb index 42dbab9d27e97d..ca80aac5a0894c 100644 --- a/lib/banzai/filter/sanitization_filter.rb +++ b/lib/banzai/filter/sanitization_filter.rb @@ -63,7 +63,7 @@ def remove_unsafe_links begin uri = Addressable::URI.parse(node['href']) - uri.scheme.strip! if uri.scheme + uri.scheme = uri.scheme.strip.downcase if uri.scheme node.remove_attribute('href') if UNSAFE_PROTOCOLS.include?(uri.scheme) rescue Addressable::URI::InvalidURIError diff --git a/lib/banzai/filter/snippet_reference_filter.rb b/lib/banzai/filter/snippet_reference_filter.rb index d507eb5ebe1f60..212a0bbf2a03f7 100644 --- a/lib/banzai/filter/snippet_reference_filter.rb +++ b/lib/banzai/filter/snippet_reference_filter.rb @@ -5,6 +5,8 @@ module Filter # # This filter supports cross-project references. class SnippetReferenceFilter < AbstractReferenceFilter + self.reference_type = :snippet + def self.object_class Snippet end diff --git a/lib/banzai/filter/upload_link_filter.rb b/lib/banzai/filter/upload_link_filter.rb index 7edfe5ade2dae2..c0f503c9af3a85 100644 --- a/lib/banzai/filter/upload_link_filter.rb +++ b/lib/banzai/filter/upload_link_filter.rb @@ -8,6 +8,8 @@ module Filter # class UploadLinkFilter < HTML::Pipeline::Filter def call + return doc unless project + doc.search('a').each do |el| process_link_attr el.attribute('href') end @@ -31,7 +33,11 @@ def process_link_attr(html_attr) end def build_url(uri) - File.join(Gitlab.config.gitlab.url, context[:project].path_with_namespace, uri) + File.join(Gitlab.config.gitlab.url, project.path_with_namespace, uri) + end + + def project + context[:project] end # Ensure that a :project key exists in context diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb index eea3af842b6e10..331d80072578e9 100644 --- a/lib/banzai/filter/user_reference_filter.rb +++ b/lib/banzai/filter/user_reference_filter.rb @@ -4,6 +4,8 @@ module Filter # # A special `@all` reference is also supported. class UserReferenceFilter < ReferenceFilter + self.reference_type = :user + # Public: Find `@user` user references in text # # UserReferenceFilter.references_in(text) do |match, username| @@ -21,43 +23,6 @@ def self.references_in(text) end end - def self.referenced_by(node) - if node.has_attribute?('data-group') - group = Group.find(node.attr('data-group')) rescue nil - return unless group - - { user: group.users } - elsif node.has_attribute?('data-user') - { user: LazyReference.new(User, node.attr('data-user')) } - elsif node.has_attribute?('data-project') - project = Project.find(node.attr('data-project')) rescue nil - return unless project - - { user: project.team.members.flatten } - end - end - - def self.user_can_see_reference?(user, node, context) - if node.has_attribute?('data-group') - group = Group.find(node.attr('data-group')) rescue nil - Ability.abilities.allowed?(user, :read_group, group) - else - super - end - end - - def self.user_can_reference?(user, node, context) - # Only team members can reference `@all` - if node.has_attribute?('data-project') - project = Project.find(node.attr('data-project')) rescue nil - return false unless project - - user && project.team.member?(user) - else - super - end - end - def call return doc if project.nil? @@ -114,9 +79,12 @@ def link_class def link_to_all(link_text: nil) project = context[:project] + author = context[:author] + url = urls.namespace_project_url(project.namespace, project, only_path: context[:only_path]) - data = data_attribute(project: project.id) + + data = data_attribute(project: project.id, author: author.try(:id)) text = link_text || User.reference_prefix + 'all' link_tag(url, data, text) diff --git a/lib/banzai/filter/wiki_link_filter.rb b/lib/banzai/filter/wiki_link_filter.rb index 06d10c98501bcd..7dc771afd71a51 100644 --- a/lib/banzai/filter/wiki_link_filter.rb +++ b/lib/banzai/filter/wiki_link_filter.rb @@ -25,7 +25,7 @@ def project_wiki? end def process_link_attr(html_attr) - return if html_attr.blank? || file_reference?(html_attr) + return if html_attr.blank? || file_reference?(html_attr) || hierarchical_link?(html_attr) uri = URI(html_attr.value) if uri.relative? && uri.path.present? @@ -40,12 +40,17 @@ def rebuild_wiki_uri(uri) uri end + def project_wiki + context[:project_wiki] + end + def file_reference?(html_attr) !File.extname(html_attr.value).blank? end - def project_wiki - context[:project_wiki] + # Of the form `./link`, `../link`, or similar + def hierarchical_link?(html_attr) + html_attr.value[0] == '.' end def project_wiki_base_path diff --git a/lib/banzai/lazy_reference.rb b/lib/banzai/lazy_reference.rb deleted file mode 100644 index 1095b4debc76b9..00000000000000 --- a/lib/banzai/lazy_reference.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Banzai - class LazyReference - def self.load(refs) - lazy_references, values = refs.partition { |ref| ref.is_a?(self) } - - lazy_values = lazy_references.group_by(&:klass).flat_map do |klass, refs| - ids = refs.flat_map(&:ids) - klass.where(id: ids) - end - - values + lazy_values - end - - attr_reader :klass, :ids - - def initialize(klass, ids) - @klass = klass - @ids = Array.wrap(ids).map(&:to_i) - end - - def load - self.klass.where(id: self.ids) - end - end -end diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index ed3cfd6b02323d..b27ecf3c923a95 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -23,7 +23,8 @@ def self.filters Filter::LabelReferenceFilter, Filter::MilestoneReferenceFilter, - Filter::TaskListFilter + Filter::TaskListFilter, + Filter::InlineDiffFilter ] end diff --git a/lib/banzai/pipeline/reference_extraction_pipeline.rb b/lib/banzai/pipeline/reference_extraction_pipeline.rb deleted file mode 100644 index 919998380e4a0e..00000000000000 --- a/lib/banzai/pipeline/reference_extraction_pipeline.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Banzai - module Pipeline - class ReferenceExtractionPipeline < BasePipeline - def self.filters - FilterArray[ - Filter::ReferenceGathererFilter - ] - end - end - end -end diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb index f4079538ec55d9..bf366962aef318 100644 --- a/lib/banzai/reference_extractor.rb +++ b/lib/banzai/reference_extractor.rb @@ -1,28 +1,6 @@ module Banzai # Extract possible GFM references from an arbitrary String for further processing. class ReferenceExtractor - class << self - LAZY_KEY = :banzai_reference_extractor_lazy - - def lazy? - Thread.current[LAZY_KEY] - end - - def lazily(values = nil, &block) - return (values || block.call).uniq if lazy? - - begin - Thread.current[LAZY_KEY] = true - - values ||= block.call - - Banzai::LazyReference.load(values.uniq).uniq - ensure - Thread.current[LAZY_KEY] = false - end - end - end - def initialize @texts = [] end @@ -31,23 +9,21 @@ def analyze(text, context = {}) @texts << Renderer.render(text, context) end - def references(type, context = {}) - filter = Banzai::Filter["#{type}_reference"] + def references(type, project, current_user = nil) + processor = Banzai::ReferenceParser[type]. + new(project, current_user) + + processor.process(html_documents) + end - context.merge!( - pipeline: :reference_extraction, + private - # ReferenceGathererFilter - reference_filter: filter - ) + def html_documents + # This ensures that we don't memoize anything until we have a number of + # text blobs to parse. + return [] if @texts.empty? - self.class.lazily do - @texts.flat_map do |html| - text_context = context.dup - result = Renderer.render_result(html, text_context) - result[:references][type] - end.uniq - end + @html_documents ||= @texts.map { |html| Nokogiri::HTML.fragment(html) } end end end diff --git a/lib/banzai/reference_parser.rb b/lib/banzai/reference_parser.rb new file mode 100644 index 00000000000000..557bec4316e45f --- /dev/null +++ b/lib/banzai/reference_parser.rb @@ -0,0 +1,14 @@ +module Banzai + module ReferenceParser + # Returns the reference parser class for the given type + # + # Example: + # + # Banzai::ReferenceParser['issue'] + # + # This would return the `Banzai::ReferenceParser::IssueParser` class. + def self.[](name) + const_get("#{name.to_s.camelize}Parser") + end + end +end diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb new file mode 100644 index 00000000000000..3d7b9c4a02409c --- /dev/null +++ b/lib/banzai/reference_parser/base_parser.rb @@ -0,0 +1,204 @@ +module Banzai + module ReferenceParser + # Base class for reference parsing classes. + # + # Each parser should also specify its reference type by calling + # `self.reference_type = ...` in the body of the class. The value of this + # method should be a symbol such as `:issue` or `:merge_request`. For + # example: + # + # class IssueParser < BaseParser + # self.reference_type = :issue + # end + # + # The reference type is used to determine what nodes to pass to the + # `referenced_by` method. + # + # Parser classes should either implement the instance method + # `references_relation` or overwrite `referenced_by`. The + # `references_relation` method is supposed to return an + # ActiveRecord::Relation used as a base relation for retrieving the objects + # referenced in a set of HTML nodes. + # + # Each class can implement two additional methods: + # + # * `nodes_user_can_reference`: returns an Array of nodes the given user can + # refer to. + # * `nodes_visible_to_user`: returns an Array of nodes that are visible to + # the given user. + # + # You only need to overwrite these methods if you want to tweak who can see + # which references. For example, the IssueParser class defines its own + # `nodes_visible_to_user` method so it can ensure users can only see issues + # they have access to. + class BaseParser + class << self + attr_accessor :reference_type + end + + # Returns the attribute name containing the value for every object to be + # parsed by the current parser. + # + # For example, for a parser class that returns "Animal" objects this + # attribute would be "data-animal". + def self.data_attribute + @data_attribute ||= "data-#{reference_type.to_s.dasherize}" + end + + def initialize(project = nil, current_user = nil) + @project = project + @current_user = current_user + end + + # Returns all the nodes containing references that the user can refer to. + def nodes_user_can_reference(user, nodes) + nodes + end + + # Returns all the nodes that are visible to the given user. + def nodes_visible_to_user(user, nodes) + projects = lazy { projects_for_nodes(nodes) } + project_attr = 'data-project' + + nodes.select do |node| + if node.has_attribute?(project_attr) + node_id = node.attr(project_attr).to_i + + if project && project.id == node_id + true + else + can?(user, :read_project, projects[node_id]) + end + else + true + end + end + end + + # Returns an Array of objects referenced by any of the given HTML nodes. + def referenced_by(nodes) + ids = unique_attribute_values(nodes, self.class.data_attribute) + + references_relation.where(id: ids) + end + + # Returns the ActiveRecord::Relation to use for querying references in the + # DB. + def references_relation + raise NotImplementedError, + "#{self.class} does not implement #{__method__}" + end + + # Returns a Hash containing attribute values per project ID. + # + # The returned Hash uses the following format: + # + # { project id => [value1, value2, ...] } + # + # nodes - An Array of HTML nodes to process. + # attribute - The name of the attribute (as a String) for which to gather + # values. + # + # Returns a Hash. + def gather_attributes_per_project(nodes, attribute) + per_project = Hash.new { |hash, key| hash[key] = Set.new } + + nodes.each do |node| + project_id = node.attr('data-project').to_i + id = node.attr(attribute) + + per_project[project_id] << id if id + end + + per_project + end + + # Returns a Hash containing objects for an attribute grouped per their + # IDs. + # + # The returned Hash uses the following format: + # + # { id value => row } + # + # nodes - An Array of HTML nodes to process. + # + # collection - The model or ActiveRecord relation to use for retrieving + # rows from the database. + # + # attribute - The name of the attribute containing the primary key values + # for every row. + # + # Returns a Hash. + def grouped_objects_for_nodes(nodes, collection, attribute) + return {} if nodes.empty? + + ids = unique_attribute_values(nodes, attribute) + + collection.where(id: ids).each_with_object({}) do |row, hash| + hash[row.id] = row + end + end + + # Returns an Array containing all unique values of an attribute of the + # given nodes. + def unique_attribute_values(nodes, attribute) + values = Set.new + + nodes.each do |node| + if node.has_attribute?(attribute) + values << node.attr(attribute) + end + end + + values.to_a + end + + # Processes the list of HTML documents and returns an Array containing all + # the references. + def process(documents) + type = self.class.reference_type + + nodes = documents.flat_map do |document| + Querying.css(document, "a[data-reference-type='#{type}'].gfm").to_a + end + + gather_references(nodes) + end + + # Gathers the references for the given HTML nodes. + def gather_references(nodes) + nodes = nodes_user_can_reference(current_user, nodes) + nodes = nodes_visible_to_user(current_user, nodes) + + referenced_by(nodes) + end + + # Returns a Hash containing the projects for a given list of HTML nodes. + # + # The returned Hash uses the following format: + # + # { project ID => project } + # + def projects_for_nodes(nodes) + @projects_for_nodes ||= + grouped_objects_for_nodes(nodes, Project, 'data-project') + end + + def can?(user, permission, subject) + Ability.abilities.allowed?(user, permission, subject) + end + + def find_projects_for_hash_keys(hash) + Project.where(id: hash.keys) + end + + private + + attr_reader :current_user, :project + + def lazy(&block) + Gitlab::Lazy.new(&block) + end + end + end +end diff --git a/lib/banzai/reference_parser/commit_parser.rb b/lib/banzai/reference_parser/commit_parser.rb new file mode 100644 index 00000000000000..0fee9d267dee63 --- /dev/null +++ b/lib/banzai/reference_parser/commit_parser.rb @@ -0,0 +1,34 @@ +module Banzai + module ReferenceParser + class CommitParser < BaseParser + self.reference_type = :commit + + def referenced_by(nodes) + commit_ids = commit_ids_per_project(nodes) + projects = find_projects_for_hash_keys(commit_ids) + + projects.flat_map do |project| + find_commits(project, commit_ids[project.id]) + end + end + + def commit_ids_per_project(nodes) + gather_attributes_per_project(nodes, self.class.data_attribute) + end + + def find_commits(project, ids) + commits = [] + + return commits unless project.valid_repo? + + ids.each do |id| + commit = project.commit(id) + + commits << commit if commit + end + + commits + end + end + end +end diff --git a/lib/banzai/reference_parser/commit_range_parser.rb b/lib/banzai/reference_parser/commit_range_parser.rb new file mode 100644 index 00000000000000..69d01f8db1577c --- /dev/null +++ b/lib/banzai/reference_parser/commit_range_parser.rb @@ -0,0 +1,38 @@ +module Banzai + module ReferenceParser + class CommitRangeParser < BaseParser + self.reference_type = :commit_range + + def referenced_by(nodes) + range_ids = commit_range_ids_per_project(nodes) + projects = find_projects_for_hash_keys(range_ids) + + projects.flat_map do |project| + find_ranges(project, range_ids[project.id]) + end + end + + def commit_range_ids_per_project(nodes) + gather_attributes_per_project(nodes, self.class.data_attribute) + end + + def find_ranges(project, range_ids) + ranges = [] + + range_ids.each do |id| + range = find_object(project, id) + + ranges << range if range + end + + ranges + end + + def find_object(project, id) + range = CommitRange.new(id, project) + + range.valid_commits? ? range : nil + end + end + end +end diff --git a/lib/banzai/reference_parser/external_issue_parser.rb b/lib/banzai/reference_parser/external_issue_parser.rb new file mode 100644 index 00000000000000..a1264db21115f0 --- /dev/null +++ b/lib/banzai/reference_parser/external_issue_parser.rb @@ -0,0 +1,25 @@ +module Banzai + module ReferenceParser + class ExternalIssueParser < BaseParser + self.reference_type = :external_issue + + def referenced_by(nodes) + issue_ids = issue_ids_per_project(nodes) + projects = find_projects_for_hash_keys(issue_ids) + issues = [] + + projects.each do |project| + issue_ids[project.id].each do |id| + issues << ExternalIssue.new(id, project) + end + end + + issues + end + + def issue_ids_per_project(nodes) + gather_attributes_per_project(nodes, self.class.data_attribute) + end + end + end +end diff --git a/lib/banzai/reference_parser/issue_parser.rb b/lib/banzai/reference_parser/issue_parser.rb new file mode 100644 index 00000000000000..24076e3d9ec237 --- /dev/null +++ b/lib/banzai/reference_parser/issue_parser.rb @@ -0,0 +1,40 @@ +module Banzai + module ReferenceParser + class IssueParser < BaseParser + self.reference_type = :issue + + def nodes_visible_to_user(user, nodes) + # It is not possible to check access rights for external issue trackers + return nodes if project && project.external_issue_tracker + + issues = issues_for_nodes(nodes) + + nodes.select do |node| + issue = issue_for_node(issues, node) + + issue ? can?(user, :read_issue, issue) : false + end + end + + def referenced_by(nodes) + issues = issues_for_nodes(nodes) + + nodes.map { |node| issue_for_node(issues, node) }.uniq + end + + def issues_for_nodes(nodes) + @issues_for_nodes ||= grouped_objects_for_nodes( + nodes, + Issue.all.includes(:author, :assignee, :project), + self.class.data_attribute + ) + end + + private + + def issue_for_node(issues, node) + issues[node.attr(self.class.data_attribute).to_i] + end + end + end +end diff --git a/lib/banzai/reference_parser/label_parser.rb b/lib/banzai/reference_parser/label_parser.rb new file mode 100644 index 00000000000000..e5d1eb11d7f5d3 --- /dev/null +++ b/lib/banzai/reference_parser/label_parser.rb @@ -0,0 +1,11 @@ +module Banzai + module ReferenceParser + class LabelParser < BaseParser + self.reference_type = :label + + def references_relation + Label + end + end + end +end diff --git a/lib/banzai/reference_parser/merge_request_parser.rb b/lib/banzai/reference_parser/merge_request_parser.rb new file mode 100644 index 00000000000000..c9a9ca79c09c52 --- /dev/null +++ b/lib/banzai/reference_parser/merge_request_parser.rb @@ -0,0 +1,11 @@ +module Banzai + module ReferenceParser + class MergeRequestParser < BaseParser + self.reference_type = :merge_request + + def references_relation + MergeRequest.includes(:author, :assignee, :target_project) + end + end + end +end diff --git a/lib/banzai/reference_parser/milestone_parser.rb b/lib/banzai/reference_parser/milestone_parser.rb new file mode 100644 index 00000000000000..a000ac61e5c3f8 --- /dev/null +++ b/lib/banzai/reference_parser/milestone_parser.rb @@ -0,0 +1,11 @@ +module Banzai + module ReferenceParser + class MilestoneParser < BaseParser + self.reference_type = :milestone + + def references_relation + Milestone + end + end + end +end diff --git a/lib/banzai/reference_parser/snippet_parser.rb b/lib/banzai/reference_parser/snippet_parser.rb new file mode 100644 index 00000000000000..fa71b3c952aa3f --- /dev/null +++ b/lib/banzai/reference_parser/snippet_parser.rb @@ -0,0 +1,11 @@ +module Banzai + module ReferenceParser + class SnippetParser < BaseParser + self.reference_type = :snippet + + def references_relation + Snippet + end + end + end +end diff --git a/lib/banzai/reference_parser/user_parser.rb b/lib/banzai/reference_parser/user_parser.rb new file mode 100644 index 00000000000000..a12b0d1956010d --- /dev/null +++ b/lib/banzai/reference_parser/user_parser.rb @@ -0,0 +1,92 @@ +module Banzai + module ReferenceParser + class UserParser < BaseParser + self.reference_type = :user + + def referenced_by(nodes) + group_ids = [] + user_ids = [] + project_ids = [] + + nodes.each do |node| + if node.has_attribute?('data-group') + group_ids << node.attr('data-group').to_i + elsif node.has_attribute?(self.class.data_attribute) + user_ids << node.attr(self.class.data_attribute).to_i + elsif node.has_attribute?('data-project') + project_ids << node.attr('data-project').to_i + end + end + + find_users_for_groups(group_ids) | find_users(user_ids) | + find_users_for_projects(project_ids) + end + + def nodes_visible_to_user(user, nodes) + group_attr = 'data-group' + groups = lazy { grouped_objects_for_nodes(nodes, Group, group_attr) } + visible = [] + remaining = [] + + nodes.each do |node| + if node.has_attribute?(group_attr) + node_group = groups[node.attr(group_attr).to_i] + + if node_group && + can?(user, :read_group, node_group) + visible << node + end + # Remaining nodes will be processed by the parent class' + # implementation of this method. + else + remaining << node + end + end + + visible + super(current_user, remaining) + end + + def nodes_user_can_reference(current_user, nodes) + project_attr = 'data-project' + author_attr = 'data-author' + + projects = lazy { projects_for_nodes(nodes) } + users = lazy { grouped_objects_for_nodes(nodes, User, author_attr) } + + nodes.select do |node| + project_id = node.attr(project_attr) + user_id = node.attr(author_attr) + + if project && project_id && project.id == project_id.to_i + true + elsif project_id && user_id + project = projects[project_id.to_i] + user = users[user_id.to_i] + + project && user ? project.team.member?(user) : false + else + true + end + end + end + + def find_users(ids) + return [] if ids.empty? + + User.where(id: ids).to_a + end + + def find_users_for_groups(ids) + return [] if ids.empty? + + User.joins(:group_members).where(members: { source_id: ids }).to_a + end + + def find_users_for_projects(ids) + return [] if ids.empty? + + Project.where(id: ids).flat_map { |p| p.team.members.to_a } + end + end + end +end diff --git a/lib/ci/ansi2html.rb b/lib/ci/ansi2html.rb index ac6d667cf8d571..229050151d379e 100644 --- a/lib/ci/ansi2html.rb +++ b/lib/ci/ansi2html.rb @@ -23,8 +23,8 @@ module Ansi2html cross: 0x10, } - def self.convert(ansi) - Converter.new().convert(ansi) + def self.convert(ansi, state = nil) + Converter.new.convert(ansi, state) end class Converter @@ -84,22 +84,38 @@ 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 - def convert(ansi) - @out = "" - @n_open_tags = 0 - reset() + attr_accessor :offset, :n_open_tags, :fg_color, :bg_color, :style_mask + + STATE_PARAMS = [:offset, :n_open_tags, :fg_color, :bg_color, :style_mask] + + def convert(raw, new_state) + reset_state + restore_state(raw, new_state) if new_state.present? + + start = @offset + ansi = raw[@offset..-1] + + open_new_tag - s = StringScanner.new(ansi.gsub("<", "<")) - while(!s.eos?) + s = StringScanner.new(ansi) + until s.eos? if s.scan(/\e([@-_])(.*?)([@-~])/) handle_sequence(s) + elsif s.scan(/\e(([@-_])(.*?)?)?$/) + break + elsif s.scan(/' else @out << s.scan(/./m) end + @offset += s.matched_size end close_open_tags() - @out + + { state: state, html: @out, text: ansi[0, @offset - start], append: start > 0 } end def handle_sequence(s) @@ -121,6 +137,20 @@ def handle_sequence(s) evaluate_command_stack(commands) + open_new_tag + end + + def evaluate_command_stack(stack) + return unless command = stack.shift() + + if self.respond_to?("on_#{command}", true) + self.send("on_#{command}", stack) + end + + evaluate_command_stack(stack) + end + + def open_new_tag css_classes = [] unless @fg_color.nil? @@ -138,20 +168,8 @@ def handle_sequence(s) css_classes << "term-#{css_class}" if @style_mask & flag != 0 end - open_new_tag(css_classes) if css_classes.length > 0 - end + return if css_classes.empty? - def evaluate_command_stack(stack) - return unless command = stack.shift() - - if self.respond_to?("on_#{command}", true) - self.send("on_#{command}", stack) - end - - evaluate_command_stack(stack) - end - - def open_new_tag(css_classes) @out << %{} @n_open_tags += 1 end @@ -163,6 +181,31 @@ def close_open_tags end end + def reset_state + @offset = 0 + @n_open_tags = 0 + @out = '' + reset + end + + def state + state = STATE_PARAMS.inject({}) do |h, param| + h[param] = send(param) + h + end + Base64.urlsafe_encode64(state.to_json) + end + + def restore_state(raw, new_state) + state = Base64.urlsafe_decode64(new_state) + state = JSON.parse(state, symbolize_names: true) + return if state[:offset].to_i > raw.length + + STATE_PARAMS.each do |param| + send("#{param}=".to_sym, state[param]) + end + end + def reset @fg_color = nil @bg_color = nil diff --git a/lib/ci/api/api.rb b/lib/ci/api/api.rb index 353c4ddebf8edc..17bb99a2ae5024 100644 --- a/lib/ci/api/api.rb +++ b/lib/ci/api/api.rb @@ -1,9 +1,7 @@ -Dir["#{Rails.root}/lib/ci/api/*.rb"].each {|file| require file} - module Ci module API class API < Grape::API - include APIGuard + include ::API::APIGuard version 'v1', using: :path rescue_from ActiveRecord::RecordNotFound do @@ -31,9 +29,9 @@ class API < Grape::API helpers ::API::Helpers helpers Gitlab::CurrentSettings - mount Builds - mount Runners - mount Triggers + mount ::Ci::API::Builds + mount ::Ci::API::Runners + mount ::Ci::API::Triggers end end end diff --git a/lib/ci/api/runners.rb b/lib/ci/api/runners.rb index 192b1d18a51df0..0c41f22c7c56bb 100644 --- a/lib/ci/api/runners.rb +++ b/lib/ci/api/runners.rb @@ -28,20 +28,20 @@ class Runners < Grape::API post "register" do required_attributes! [:token] + attributes = { description: params[:description], + tag_list: params[:tag_list] } + + unless params[:run_untagged].nil? + attributes[:run_untagged] = params[:run_untagged] + end + runner = if runner_registration_token_valid? # Create shared runner. Requires admin access - Ci::Runner.create( - description: params[:description], - tag_list: params[:tag_list], - is_shared: true - ) + Ci::Runner.create(attributes.merge(is_shared: true)) elsif project = Project.find_by(runners_token: params[:token]) # Create a specific runner for project. - project.runners.create( - description: params[:description], - tag_list: params[:tag_list] - ) + project.runners.create(attributes) end return forbidden! unless runner diff --git a/lib/ci/charts.rb b/lib/ci/charts.rb index d53bdcbd0f2215..e163663693479d 100644 --- a/lib/ci/charts.rb +++ b/lib/ci/charts.rb @@ -64,7 +64,8 @@ def collect commits.each do |commit| @labels << commit.short_sha - @build_times << (commit.duration / 60) + duration = commit.duration || 0 + @build_times << (duration / 60) end end end diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 504d3df9d34991..026a5ac97caf38 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -1,6 +1,6 @@ module Ci class GitlabCiYamlProcessor - class ValidationError < StandardError;end + class ValidationError < StandardError; end DEFAULT_STAGES = %w(build test deploy) DEFAULT_STAGE = 'test' @@ -265,7 +265,7 @@ def validate_job_artifacts!(name, job) end def validate_job_dependencies!(name, job) - if !validate_array_of_strings(job[:dependencies]) + unless validate_array_of_strings(job[:dependencies]) raise ValidationError, "#{name} job: dependencies parameter should be an array of strings" end diff --git a/lib/container_registry/blob.rb b/lib/container_registry/blob.rb new file mode 100644 index 00000000000000..4e20dc4f87534e --- /dev/null +++ b/lib/container_registry/blob.rb @@ -0,0 +1,48 @@ +module ContainerRegistry + class Blob + attr_reader :repository, :config + + delegate :registry, :client, to: :repository + + def initialize(repository, config) + @repository = repository + @config = config || {} + end + + def valid? + digest.present? + end + + def path + "#{repository.path}@#{digest}" + end + + def digest + config['digest'] + end + + def type + config['mediaType'] + end + + def size + config['size'] + end + + def revision + digest.split(':')[1] + end + + def short_revision + revision[0..8] + end + + def delete + client.delete_blob(repository.name, digest) + end + + def data + @data ||= client.blob(repository.name, digest, type) + end + end +end diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb new file mode 100644 index 00000000000000..4d726692f45156 --- /dev/null +++ b/lib/container_registry/client.rb @@ -0,0 +1,61 @@ +require 'faraday' +require 'faraday_middleware' + +module ContainerRegistry + class Client + attr_accessor :uri + + MANIFEST_VERSION = 'application/vnd.docker.distribution.manifest.v2+json' + + def initialize(base_uri, options = {}) + @base_uri = base_uri + @faraday = Faraday.new(@base_uri) do |conn| + initialize_connection(conn, options) + end + end + + def repository_tags(name) + @faraday.get("/v2/#{name}/tags/list").body + end + + def repository_manifest(name, reference) + @faraday.get("/v2/#{name}/manifests/#{reference}").body + end + + def repository_tag_digest(name, reference) + response = @faraday.head("/v2/#{name}/manifests/#{reference}") + response.headers['docker-content-digest'] if response.success? + end + + def delete_repository_tag(name, reference) + @faraday.delete("/v2/#{name}/manifests/#{reference}").success? + end + + def blob(name, digest, type = nil) + headers = {} + headers['Accept'] = type if type + @faraday.get("/v2/#{name}/blobs/#{digest}", nil, headers).body + end + + def delete_blob(name, digest) + @faraday.delete("/v2/#{name}/blobs/#{digest}").success? + end + + private + + def initialize_connection(conn, options) + conn.request :json + conn.headers['Accept'] = MANIFEST_VERSION + + conn.response :json, content_type: /\bjson$/ + + if options[:user] && options[:password] + conn.request(:basic_auth, options[:user].to_s, options[:password].to_s) + elsif options[:token] + conn.request(:authorization, :bearer, options[:token].to_s) + end + + conn.adapter :net_http + end + end +end diff --git a/lib/container_registry/config.rb b/lib/container_registry/config.rb new file mode 100644 index 00000000000000..589f9f4380a1ea --- /dev/null +++ b/lib/container_registry/config.rb @@ -0,0 +1,16 @@ +module ContainerRegistry + class Config + attr_reader :tag, :blob, :data + + def initialize(tag, blob) + @tag, @blob = tag, blob + @data = JSON.parse(blob.data) + end + + def [](key) + return unless data + + data[key] + end + end +end diff --git a/lib/container_registry/registry.rb b/lib/container_registry/registry.rb new file mode 100644 index 00000000000000..0e634f6b6eff40 --- /dev/null +++ b/lib/container_registry/registry.rb @@ -0,0 +1,21 @@ +module ContainerRegistry + class Registry + attr_reader :uri, :client, :path + + def initialize(uri, options = {}) + @uri = uri + @path = options[:path] || default_path + @client = ContainerRegistry::Client.new(uri, options) + end + + def repository(name) + ContainerRegistry::Repository.new(self, name) + end + + private + + def default_path + @uri.sub(/^https?:\/\//, '') + end + end +end diff --git a/lib/container_registry/repository.rb b/lib/container_registry/repository.rb new file mode 100644 index 00000000000000..0e4a7cb3cc9afc --- /dev/null +++ b/lib/container_registry/repository.rb @@ -0,0 +1,48 @@ +module ContainerRegistry + class Repository + attr_reader :registry, :name + + delegate :client, to: :registry + + def initialize(registry, name) + @registry, @name = registry, name + end + + def path + [registry.path, name].compact.join('/') + end + + def tag(tag) + ContainerRegistry::Tag.new(self, tag) + end + + def manifest + return @manifest if defined?(@manifest) + + @manifest = client.repository_tags(name) + end + + def valid? + manifest.present? + end + + def tags + return @tags if defined?(@tags) + return [] unless manifest && manifest['tags'] + + @tags = manifest['tags'].map do |tag| + ContainerRegistry::Tag.new(self, tag) + end + end + + def blob(config) + ContainerRegistry::Blob.new(self, config) + end + + def delete_tags + return unless tags + + tags.all?(&:delete) + end + end +end diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb new file mode 100644 index 00000000000000..43f8d6dc8c24bd --- /dev/null +++ b/lib/container_registry/tag.rb @@ -0,0 +1,77 @@ +module ContainerRegistry + class Tag + attr_reader :repository, :name + + delegate :registry, :client, to: :repository + + def initialize(repository, name) + @repository, @name = repository, name + end + + def valid? + manifest.present? + end + + def manifest + return @manifest if defined?(@manifest) + + @manifest = client.repository_manifest(repository.name, name) + end + + def path + "#{repository.path}:#{name}" + end + + def [](key) + return unless manifest + + manifest[key] + end + + def digest + return @digest if defined?(@digest) + + @digest = client.repository_tag_digest(repository.name, name) + end + + def config_blob + return @config_blob if defined?(@config_blob) + return unless manifest && manifest['config'] + + @config_blob = repository.blob(manifest['config']) + end + + def config + return unless config_blob + + @config ||= ContainerRegistry::Config.new(self, config_blob) + end + + def created_at + return unless config + + @created_at ||= DateTime.rfc3339(config['created']) + end + + def layers + return @layers if defined?(@layers) + return unless manifest + + @layers = manifest['layers'].map do |layer| + repository.blob(layer) + end + end + + def total_size + return unless layers + + layers.map(&:size).sum + end + + def delete + return unless digest + + client.delete_repository_tag(repository.name, digest) + end + end +end diff --git a/lib/event_filter.rb b/lib/event_filter.rb index f15b2cfd231090..668d2fa41b3064 100644 --- a/lib/event_filter.rb +++ b/lib/event_filter.rb @@ -27,7 +27,7 @@ def initialize(params) @params = if params params.dup else - []#EventFilter.default_filter + [] # EventFilter.default_filter end end diff --git a/lib/gitlab.rb b/lib/gitlab.rb index 7479e729db1442..37f4c34054feda 100644 --- a/lib/gitlab.rb +++ b/lib/gitlab.rb @@ -1,4 +1,4 @@ -require 'gitlab/git' +require_dependency 'gitlab/git' module Gitlab def self.com? diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb index 132f9cd1966ba9..3e3986d6382781 100644 --- a/lib/gitlab/backend/shell.rb +++ b/lib/gitlab/backend/shell.rb @@ -180,7 +180,7 @@ def version # exists?('gitlab/cookies.git') # def exists?(dir_name) - File.exists?(full_path(dir_name)) + File.exist?(full_path(dir_name)) end protected diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb index 9b83292ef33adc..8d1ad62fae0b08 100644 --- a/lib/gitlab/bitbucket_import/client.rb +++ b/lib/gitlab/bitbucket_import/client.rb @@ -121,7 +121,7 @@ def incompatible_projects def get(url) response = api.get(url) - raise Unauthorized if (400..499).include?(response.code.to_i) + raise Unauthorized if (400..499).cover?(response.code.to_i) response end diff --git a/lib/gitlab/bitbucket_import/project_creator.rb b/lib/gitlab/bitbucket_import/project_creator.rb index 941f818b8478f6..b90ef0b0fba3e9 100644 --- a/lib/gitlab/bitbucket_import/project_creator.rb +++ b/lib/gitlab/bitbucket_import/project_creator.rb @@ -11,7 +11,7 @@ def initialize(repo, namespace, current_user, session_data) end def execute - project = ::Projects::CreateService.new( + ::Projects::CreateService.new( current_user, name: repo["name"], path: repo["slug"], @@ -21,11 +21,8 @@ def execute import_type: "bitbucket", import_source: "#{repo["owner"]}/#{repo["slug"]}", import_url: "ssh://git@bitbucket.org/#{repo["owner"]}/#{repo["slug"]}.git", + import_data: { credentials: { bb_session: session_data } } ).execute - - project.create_or_update_import_data(credentials: { bb_session: session_data }) - - project end end end diff --git a/lib/gitlab/ci/build/artifacts/metadata.rb b/lib/gitlab/ci/build/artifacts/metadata.rb index f2020c82d40543..cd2e83b4c27e96 100644 --- a/lib/gitlab/ci/build/artifacts/metadata.rb +++ b/lib/gitlab/ci/build/artifacts/metadata.rb @@ -56,7 +56,7 @@ def match_entries(gz) child_pattern = '[^/]*/?$' unless @opts[:recursive] match_pattern = /^#{Regexp.escape(@path)}#{child_pattern}/ - until gz.eof? do + until gz.eof? begin path = read_string(gz).force_encoding('UTF-8') meta = read_string(gz).force_encoding('UTF-8') diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb index 85583dce9eeb75..9dc2602867e07d 100644 --- a/lib/gitlab/contributions_calendar.rb +++ b/lib/gitlab/contributions_calendar.rb @@ -19,7 +19,7 @@ def timestamps select('date(created_at) as date, count(id) as total_amount'). map(&:attributes) - dates = (1.year.ago.to_date..(Date.today + 1.day)).to_a + dates = (1.year.ago.to_date..Date.today).to_a dates.each do |date| date_id = date.to_time.to_i.to_s diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index f44d1b3a44ec91..92c7e8b9d88afd 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -1,18 +1,22 @@ module Gitlab module CurrentSettings def current_application_settings - key = :current_application_settings - - RequestStore.store[key] ||= begin - settings = nil + if RequestStore.active? + RequestStore.fetch(:current_application_settings) { ensure_application_settings! } + else + ensure_application_settings! + end + end - if connect_to_db? - settings = ::ApplicationSetting.current - settings ||= ::ApplicationSetting.create_from_defaults unless ActiveRecord::Migrator.needs_migration? - end + def ensure_application_settings! + settings = ::ApplicationSetting.cached - settings || fake_application_settings + if !settings && connect_to_db? + settings = ::ApplicationSetting.current + settings ||= ::ApplicationSetting.create_from_defaults unless ActiveRecord::Migrator.needs_migration? end + + settings || fake_application_settings end def fake_application_settings @@ -36,6 +40,7 @@ def fake_application_settings two_factor_grace_period: 48, akismet_enabled: false, repository_checks_enabled: true, + container_registry_token_expire_delay: 5, ) end diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 6f9da69983a4a2..42bec913a45ce7 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -5,11 +5,11 @@ def self.adapter_name end def self.mysql? - adapter_name.downcase == 'mysql2' + adapter_name.casecmp('mysql2').zero? end def self.postgresql? - adapter_name.downcase == 'postgresql' + adapter_name.casecmp('postgresql').zero? end def self.version diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb new file mode 100644 index 00000000000000..fd14234c5581b2 --- /dev/null +++ b/lib/gitlab/database/migration_helpers.rb @@ -0,0 +1,142 @@ +module Gitlab + module Database + module MigrationHelpers + # Creates a new index, concurrently when supported + # + # On PostgreSQL this method creates an index concurrently, on MySQL this + # creates a regular index. + # + # Example: + # + # add_concurrent_index :users, :some_column + # + # See Rails' `add_index` for more info on the available arguments. + def add_concurrent_index(*args) + if transaction_open? + raise 'add_concurrent_index can not be run inside a transaction, ' \ + 'you can disable transactions by calling disable_ddl_transaction! ' \ + 'in the body of your migration class' + end + + if Database.postgresql? + args << { algorithm: :concurrently } + end + + add_index(*args) + end + + # Updates the value of a column in batches. + # + # This method updates the table in batches of 5% of the total row count. + # Any data inserted while running this method (or after it has finished + # running) is _not_ updated automatically. + # + # This method _only_ updates rows where the column's value is set to NULL. + # + # table - The name of the table. + # column - The name of the column to update. + # value - The value for the column. + def update_column_in_batches(table, column, value) + quoted_table = quote_table_name(table) + quoted_column = quote_column_name(column) + + ## + # Workaround for #17711 + # + # It looks like for MySQL `ActiveRecord::Base.conntection.quote(true)` + # returns correct value (1), but `ActiveRecord::Migration.new.quote` + # returns incorrect value ('true'), which causes migrations to fail. + # + quoted_value = connection.quote(value) + processed = 0 + + total = exec_query("SELECT COUNT(*) AS count FROM #{quoted_table}"). + to_hash. + first['count']. + to_i + + # Update in batches of 5% + batch_size = ((total / 100.0) * 5.0).ceil + + while processed < total + start_row = exec_query(%Q{ + SELECT id + FROM #{quoted_table} + ORDER BY id ASC + LIMIT 1 OFFSET #{processed} + }).to_hash.first + + stop_row = exec_query(%Q{ + SELECT id + FROM #{quoted_table} + ORDER BY id ASC + LIMIT 1 OFFSET #{processed + batch_size} + }).to_hash.first + + query = %Q{ + UPDATE #{quoted_table} + SET #{quoted_column} = #{quoted_value} + WHERE id >= #{start_row['id']} + } + + if stop_row + query += " AND id < #{stop_row['id']}" + end + + execute(query) + + processed += batch_size + end + end + + # Adds a column with a default value without locking an entire table. + # + # This method runs the following steps: + # + # 1. Add the column with a default value of NULL. + # 2. Update all existing rows in batches. + # 3. Change the default value of the column to the specified value. + # 4. Update any remaining rows. + # + # These steps ensure a column can be added to a large and commonly used + # table without locking the entire table for the duration of the table + # modification. + # + # table - The name of the table to update. + # column - The name of the column to add. + # type - The column type (e.g. `:integer`). + # default - The default value for the column. + # allow_null - When set to `true` the column will allow NULL values, the + # default is to not allow NULL values. + def add_column_with_default(table, column, type, default:, allow_null: false) + if transaction_open? + raise 'add_column_with_default can not be run inside a transaction, ' \ + 'you can disable transactions by calling disable_ddl_transaction! ' \ + 'in the body of your migration class' + end + + transaction do + add_column(table, column, type, default: nil) + + # Changing the default before the update ensures any newly inserted + # rows already use the proper default value. + change_column_default(table, column, default) + end + + begin + transaction do + update_column_in_batches(table, column, default) + end + # We want to rescue _all_ exceptions here, even those that don't inherit + # from StandardError. + rescue Exception => error # rubocop: disable all + remove_column(table, column) + + raise error + end + + change_column_null(table, column, false) unless allow_null + end + end + end +end diff --git a/lib/gitlab/diff/inline_diff_marker.rb b/lib/gitlab/diff/inline_diff_marker.rb index dccb717e95dfbf..87a9b1e23acc41 100644 --- a/lib/gitlab/diff/inline_diff_marker.rb +++ b/lib/gitlab/diff/inline_diff_marker.rb @@ -1,6 +1,11 @@ module Gitlab module Diff class InlineDiffMarker + MARKDOWN_SYMBOLS = { + addition: "+", + deletion: "-" + } + attr_accessor :raw_line, :rich_line def initialize(raw_line, rich_line = raw_line) @@ -8,7 +13,7 @@ def initialize(raw_line, rich_line = raw_line) @rich_line = ERB::Util.html_escape(rich_line) end - def mark(line_inline_diffs) + def mark(line_inline_diffs, mode: nil, markdown: false) return rich_line unless line_inline_diffs marker_ranges = [] @@ -20,13 +25,22 @@ def mark(line_inline_diffs) end offset = 0 - # Mark each range - marker_ranges.each_with_index do |range, i| - class_names = ["idiff"] - class_names << "left" if i == 0 - class_names << "right" if i == marker_ranges.length - 1 - offset = insert_around_range(rich_line, range, "", "", offset) + # Mark each range + marker_ranges.each_with_index do |range, index| + before_content = + if markdown + "{#{MARKDOWN_SYMBOLS[mode]}" + else + "" + end + after_content = + if markdown + "#{MARKDOWN_SYMBOLS[mode]}}" + else + "" + end + offset = insert_around_range(rich_line, range, before_content, after_content, offset) end rich_line.html_safe @@ -34,6 +48,14 @@ def mark(line_inline_diffs) private + def html_class_names(marker_ranges, mode, index) + class_names = ["idiff"] + class_names << "left" if index == 0 + class_names << "right" if index == marker_ranges.length - 1 + class_names << mode if mode + class_names.join(" ") + end + # Mapping of character positions in the raw line, to the rich (highlighted) line def position_mapping @position_mapping ||= begin diff --git a/lib/gitlab/diff/parser.rb b/lib/gitlab/diff/parser.rb index d0815fc7eeae1b..522dd2b942897d 100644 --- a/lib/gitlab/diff/parser.rb +++ b/lib/gitlab/diff/parser.rb @@ -17,16 +17,16 @@ def parse(lines) Enumerator.new do |yielder| @lines.each do |line| next if filename?(line) - - full_line = line.gsub(/\n/, '') - + + full_line = line.delete("\n") + if line.match(/^@@ -/) type = "match" - + line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0 line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0 - - next if line_old <= 1 && line_new <= 1 #top of file + + next if line_old <= 1 && line_new <= 1 # top of file yielder << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new) line_obj_index += 1 next @@ -39,8 +39,8 @@ def parse(lines) yielder << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new) line_obj_index += 1 end - - + + case line[0] when "+" line_new += 1 diff --git a/lib/gitlab/email/message/repository_push.rb b/lib/gitlab/email/message/repository_push.rb index 8f9be6cd9a3511..e2fee6b9f3ecb9 100644 --- a/lib/gitlab/email/message/repository_push.rb +++ b/lib/gitlab/email/message/repository_push.rb @@ -2,22 +2,21 @@ module Gitlab module Email module Message class RepositoryPush - attr_accessor :recipient attr_reader :author_id, :ref, :action include Gitlab::Routing.url_helpers + include DiffHelper delegate :namespace, :name_with_namespace, to: :project, prefix: :project delegate :name, to: :author, prefix: :author delegate :username, to: :author, prefix: :author - def initialize(notify, project_id, recipient, opts = {}) + def initialize(notify, project_id, opts = {}) raise ArgumentError, 'Missing options: author_id, ref, action' unless opts[:author_id] && opts[:ref] && opts[:action] @notify = notify @project_id = project_id - @recipient = recipient @opts = opts.dup @author_id = @opts.delete(:author_id) @@ -38,7 +37,7 @@ def commits end def diffs - @diffs ||= (compare.diffs if compare) + @diffs ||= (safe_diff_files(compare.diffs, diff_refs) if compare) end def diffs_count @@ -49,6 +48,10 @@ def compare @opts[:compare] end + def diff_refs + @opts[:diff_refs] + end + def compare_timeout diffs.overflow? if diffs end diff --git a/lib/gitlab/email/reply_parser.rb b/lib/gitlab/email/reply_parser.rb index 6ed36b51f12d9b..3411eb1d9ce415 100644 --- a/lib/gitlab/email/reply_parser.rb +++ b/lib/gitlab/email/reply_parser.rb @@ -65,7 +65,7 @@ def discourse_email_trimmer(body) (l =~ /On \w+ \d+,? \d+,?.*wrote:/) # Headers on subsequent lines - break if (0..2).all? { |off| lines[idx+off] =~ REPLYING_HEADER_REGEX } + break if (0..2).all? { |off| lines[idx + off] =~ REPLYING_HEADER_REGEX } # Headers on the same line break if REPLYING_HEADER_LABELS.count { |label| l.include?(label) } >= 3 diff --git a/lib/gitlab/fogbugz_import/project_creator.rb b/lib/gitlab/fogbugz_import/project_creator.rb index 3840765db87813..1918d5b208d036 100644 --- a/lib/gitlab/fogbugz_import/project_creator.rb +++ b/lib/gitlab/fogbugz_import/project_creator.rb @@ -12,7 +12,7 @@ def initialize(repo, fb_session, namespace, current_user, user_map = nil) end def execute - project = ::Projects::CreateService.new( + ::Projects::CreateService.new( current_user, name: repo.safe_name, path: repo.path, @@ -21,12 +21,9 @@ def execute visibility_level: Gitlab::VisibilityLevel::INTERNAL, import_type: 'fogbugz', import_source: repo.name, - import_url: Project::UNKNOWN_IMPORT_URL + import_url: Project::UNKNOWN_IMPORT_URL, + import_data: { data: { 'repo' => repo.raw_data, 'user_map' => user_map }, credentials: { fb_session: fb_session } } ).execute - - project.create_or_update_import_data(data: { 'repo' => repo.raw_data, 'user_map' => user_map }, credentials: { fb_session: fb_session }) - - project end end end diff --git a/lib/gitlab/github_import/branch_formatter.rb b/lib/gitlab/github_import/branch_formatter.rb new file mode 100644 index 00000000000000..a15fc84b4182b3 --- /dev/null +++ b/lib/gitlab/github_import/branch_formatter.rb @@ -0,0 +1,29 @@ +module Gitlab + module GithubImport + class BranchFormatter < BaseFormatter + delegate :repo, :sha, :ref, to: :raw_data + + def exists? + project.repository.branch_exists?(ref) + end + + def name + @name ||= exists? ? ref : "#{ref}-#{short_id}" + end + + def valid? + repo.present? + end + + def valid? + repo.present? + end + + private + + def short_id + sha.to_s[0..7] + end + end + end +end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index 0f9e3ee14ee742..408d9b796325c3 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -3,12 +3,15 @@ module GithubImport class Importer include Gitlab::ShellAdapter - attr_reader :project, :client + attr_reader :client, :project, :repo, :repo_url def initialize(project) - @project = project - if import_data_credentials - @client = Client.new(import_data_credentials[:user]) + @project = project + @repo = project.import_source + @repo_url = project.import_url + + if credentials + @client = Client.new(credentials[:user]) @formatter = Gitlab::ImportFormatter.new else raise Projects::ImportService::Error, "Unable to find project import data credentials for project ID: #{@project.id}" @@ -22,12 +25,12 @@ def execute private - def import_data_credentials - @import_data_credentials ||= project.import_data.credentials if project.import_data + def credentials + @credentials ||= project.import_data.credentials if project.import_data end def import_labels - client.labels(project.import_source).each do |raw_data| + client.labels(repo).each do |raw_data| Label.create!(LabelFormatter.new(project, raw_data).attributes) end @@ -37,7 +40,7 @@ def import_labels end def import_milestones - client.list_milestones(project.import_source, state: :all).each do |raw_data| + client.list_milestones(repo, state: :all).each do |raw_data| Milestone.create!(MilestoneFormatter.new(project, raw_data).attributes) end @@ -47,9 +50,7 @@ def import_milestones end def import_issues - client.list_issues(project.import_source, state: :all, - sort: :created, - direction: :asc).each do |raw_data| + client.list_issues(repo, state: :all, sort: :created, direction: :asc).each do |raw_data| gh_issue = IssueFormatter.new(project, raw_data) if gh_issue.valid? @@ -68,29 +69,50 @@ def import_issues end def import_pull_requests - client.pull_requests(project.import_source, state: :all, - sort: :created, - direction: :asc).each do |raw_data| - pull_request = PullRequestFormatter.new(project, raw_data) - - if pull_request.valid? - merge_request = MergeRequest.new(pull_request.attributes) - - if merge_request.save - apply_labels(pull_request.number, merge_request) - import_comments(pull_request.number, merge_request) - import_comments_on_diff(pull_request.number, merge_request) - end + pull_requests = client.pull_requests(repo, state: :all, sort: :created, direction: :asc) + .map { |raw| PullRequestFormatter.new(project, raw) } + .select(&:valid?) + + source_branches_removed = pull_requests.reject(&:source_branch_exists?).map { |pr| [pr.source_branch_name, pr.source_branch_sha] } + target_branches_removed = pull_requests.reject(&:target_branch_exists?).map { |pr| [pr.target_branch_name, pr.target_branch_sha] } + branches_removed = source_branches_removed | target_branches_removed + + create_refs(branches_removed) + + pull_requests.each do |pull_request| + merge_request = MergeRequest.new(pull_request.attributes) + + if merge_request.save + apply_labels(pull_request.number, merge_request) + import_comments(pull_request.number, merge_request) + import_comments_on_diff(pull_request.number, merge_request) end end + delete_refs(branches_removed) + true rescue ActiveRecord::RecordInvalid => e raise Projects::ImportService::Error, e.message end + def create_refs(branches) + branches.each do |name, sha| + client.create_ref(repo, "refs/heads/#{name}", sha) + end + + project.repository.fetch_ref(repo_url, '+refs/heads/*', 'refs/heads/*') + end + + def delete_refs(branches) + branches.each do |name, _| + client.delete_ref(repo, "heads/#{name}") + project.repository.rm_branch(project.creator, name) + end + end + def apply_labels(number, issuable) - issue = client.issue(project.import_source, number) + issue = client.issue(repo, number) if issue.labels.count > 0 label_ids = issue.labels.map do |raw| @@ -102,12 +124,12 @@ def apply_labels(number, issuable) end def import_comments(issue_number, noteable) - comments = client.issue_comments(project.import_source, issue_number) + comments = client.issue_comments(repo, issue_number) create_comments(comments, noteable) end def import_comments_on_diff(pull_request_number, merge_request) - comments = client.pull_request_comments(project.import_source, pull_request_number) + comments = client.pull_request_comments(repo, pull_request_number) create_comments(comments, merge_request) end diff --git a/lib/gitlab/github_import/pull_request_formatter.rb b/lib/gitlab/github_import/pull_request_formatter.rb index d21b942ad4bc54..a2947b56ad912e 100644 --- a/lib/gitlab/github_import/pull_request_formatter.rb +++ b/lib/gitlab/github_import/pull_request_formatter.rb @@ -1,15 +1,20 @@ module Gitlab module GithubImport class PullRequestFormatter < BaseFormatter + delegate :exists?, :name, :project, :repo, :sha, to: :source_branch, prefix: true + delegate :exists?, :name, :project, :repo, :sha, to: :target_branch, prefix: true + def attributes { iid: number, title: raw_data.title, description: description, - source_project: source_project, - source_branch: source_branch.name, - target_project: target_project, - target_branch: target_branch.name, + source_project: source_branch_project, + source_branch: source_branch_name, + head_source_sha: source_branch_sha, + target_project: target_branch_project, + target_branch: target_branch_name, + base_target_sha: target_branch_sha, state: state, milestone: milestone, author_id: author_id, @@ -24,7 +29,15 @@ def number end def valid? - !cross_project? && source_branch.present? && target_branch.present? + source_branch.valid? && target_branch.valid? && !cross_project? + end + + def source_branch + @source_branch ||= BranchFormatter.new(project, raw_data.head) + end + + def target_branch + @target_branch ||= BranchFormatter.new(project, raw_data.base) end private @@ -52,7 +65,7 @@ def body end def cross_project? - source_repo.present? && target_repo.present? && source_repo.id != target_repo.id + source_branch_repo.id != target_branch_repo.id end def description @@ -65,35 +78,10 @@ def milestone end end - def source_project - project - end - - def source_repo - raw_data.head.repo - end - - def source_branch - source_project.repository.find_branch(raw_data.head.ref) - end - - def target_project - project - end - - def target_repo - raw_data.base.repo - end - - def target_branch - target_project.repository.find_branch(raw_data.base.ref) - end - def state - @state ||= case true - when raw_data.state == 'closed' && raw_data.merged_at.present? + @state ||= if raw_data.state == 'closed' && raw_data.merged_at.present? 'merged' - when raw_data.state == 'closed' + elsif raw_data.state == 'closed' 'closed' else 'opened' diff --git a/lib/gitlab/gitignore.rb b/lib/gitlab/gitignore.rb new file mode 100644 index 00000000000000..f46b43b61a4e8e --- /dev/null +++ b/lib/gitlab/gitignore.rb @@ -0,0 +1,56 @@ +module Gitlab + class Gitignore + FILTER_REGEX = /\.gitignore\z/.freeze + + def initialize(path) + @path = path + end + + def name + File.basename(@path, '.gitignore') + end + + def content + File.read(@path) + end + + class << self + def all + languages_frameworks + global + end + + def find(key) + file_name = "#{key}.gitignore" + + directory = select_directory(file_name) + directory ? new(File.join(directory, file_name)) : nil + end + + def global + files_for_folder(global_dir).map { |file| new(File.join(global_dir, file)) } + end + + def languages_frameworks + files_for_folder(gitignore_dir).map { |file| new(File.join(gitignore_dir, file)) } + end + + private + + def select_directory(file_name) + [gitignore_dir, global_dir].find { |dir| File.exist?(File.join(dir, file_name)) } + end + + def global_dir + File.join(gitignore_dir, 'Global') + end + + def gitignore_dir + Rails.root.join('vendor/gitignore') + end + + def files_for_folder(dir) + Dir.glob("#{dir.to_s}/*.gitignore").map { |file| file.gsub(FILTER_REGEX, '') } + end + end + end +end diff --git a/lib/gitlab/gitlab_import/importer.rb b/lib/gitlab/gitlab_import/importer.rb index 96717b42bae29a..3f76ec979778e1 100644 --- a/lib/gitlab/gitlab_import/importer.rb +++ b/lib/gitlab/gitlab_import/importer.rb @@ -5,9 +5,9 @@ class Importer def initialize(project) @project = project - credentials = import_data - if credentials && credentials[:password] - @client = Client.new(credentials[:password]) + import_data = project.import_data + if import_data && import_data.credentials && import_data.credentials[:password] + @client = Client.new(import_data.credentials[:password]) @formatter = Gitlab::ImportFormatter.new else raise Projects::ImportService::Error, "Unable to find project import data credentials for project ID: #{@project.id}" @@ -17,7 +17,7 @@ def initialize(project) def execute project_identifier = CGI.escape(project.import_source) - #Issues && Comments + # Issues && Comments issues = client.issues(project_identifier) issues.each do |issue| diff --git a/lib/gitlab/google_code_import/project_creator.rb b/lib/gitlab/google_code_import/project_creator.rb index 0abb7a64c17e39..326cfcaa8af64c 100644 --- a/lib/gitlab/google_code_import/project_creator.rb +++ b/lib/gitlab/google_code_import/project_creator.rb @@ -11,7 +11,7 @@ def initialize(repo, namespace, current_user, user_map = nil) end def execute - project = ::Projects::CreateService.new( + ::Projects::CreateService.new( current_user, name: repo.name, path: repo.name, @@ -21,12 +21,9 @@ def execute visibility_level: Gitlab::VisibilityLevel::PUBLIC, import_type: "google_code", import_source: repo.name, - import_url: repo.import_url + import_url: repo.import_url, + import_data: { data: { 'repo' => repo.raw_data, 'user_map' => user_map } } ).execute - - project.create_or_update_import_data(data: { 'repo' => repo.raw_data, 'user_map' => user_map }) - - project end end end diff --git a/lib/gitlab/lazy.rb b/lib/gitlab/lazy.rb new file mode 100644 index 00000000000000..2a659ae4c74c28 --- /dev/null +++ b/lib/gitlab/lazy.rb @@ -0,0 +1,34 @@ +module Gitlab + # A class that can be wrapped around an expensive method call so it's only + # executed when actually needed. + # + # Usage: + # + # object = Gitlab::Lazy.new { some_expensive_work_here } + # + # object['foo'] + # object.bar + class Lazy < BasicObject + def initialize(&block) + @block = block + end + + def method_missing(name, *args, &block) + __evaluate__ + + @result.__send__(name, *args, &block) + end + + def respond_to_missing?(name, include_private = false) + __evaluate__ + + @result.respond_to?(name, include_private) || super + end + + private + + def __evaluate__ + @result = @block.call unless defined?(@result) + end + end +end diff --git a/lib/gitlab/markup_helper.rb b/lib/gitlab/markup_helper.rb index a5f767b134d2d6..dda371e65548c2 100644 --- a/lib/gitlab/markup_helper.rb +++ b/lib/gitlab/markup_helper.rb @@ -40,7 +40,7 @@ def asciidoc?(filename) # Returns boolean def plain?(filename) filename.downcase.end_with?('.txt') || - filename.downcase == 'readme' + filename.casecmp('readme').zero? end def previewable?(filename) diff --git a/lib/gitlab/metrics/instrumentation.rb b/lib/gitlab/metrics/instrumentation.rb index 708ef79f3040c4..0f115893a15e0e 100644 --- a/lib/gitlab/metrics/instrumentation.rb +++ b/lib/gitlab/metrics/instrumentation.rb @@ -154,8 +154,6 @@ def #{name}(#{args_signature}) duration = (Time.now - start) * 1000.0 if duration >= Gitlab::Metrics.method_call_threshold - trans.increment(:method_duration, duration) - trans.add_metric(Gitlab::Metrics::Instrumentation::SERIES, { duration: duration }, method: #{label.inspect}) diff --git a/lib/gitlab/metrics/subscribers/rails_cache.rb b/lib/gitlab/metrics/subscribers/rails_cache.rb index 49e5f86e6e6e8b..8e345e8ae4ac6f 100644 --- a/lib/gitlab/metrics/subscribers/rails_cache.rb +++ b/lib/gitlab/metrics/subscribers/rails_cache.rb @@ -6,26 +6,28 @@ class RailsCache < ActiveSupport::Subscriber attach_to :active_support def cache_read(event) - increment(:cache_read_duration, event.duration) + increment(:cache_read, event.duration) end def cache_write(event) - increment(:cache_write_duration, event.duration) + increment(:cache_write, event.duration) end def cache_delete(event) - increment(:cache_delete_duration, event.duration) + increment(:cache_delete, event.duration) end def cache_exist?(event) - increment(:cache_exists_duration, event.duration) + increment(:cache_exists, event.duration) end def increment(key, duration) return unless current_transaction current_transaction.increment(:cache_duration, duration) - current_transaction.increment(key, duration) + current_transaction.increment(:cache_count, 1) + current_transaction.increment("#{key}_duration".to_sym, duration) + current_transaction.increment("#{key}_count".to_sym, 1) end private diff --git a/lib/gitlab/middleware/go.rb b/lib/gitlab/middleware/go.rb index 50b0dd32380325..5764ab15652796 100644 --- a/lib/gitlab/middleware/go.rb +++ b/lib/gitlab/middleware/go.rb @@ -39,7 +39,7 @@ def go_body(request) request_url = URI.join(base_url, project_path) domain_path = strip_url(request_url.to_s) - "\n"; + "\n" end def strip_url(url) diff --git a/lib/gitlab/middleware/rails_queue_duration.rb b/lib/gitlab/middleware/rails_queue_duration.rb new file mode 100644 index 00000000000000..56608b1b2765dd --- /dev/null +++ b/lib/gitlab/middleware/rails_queue_duration.rb @@ -0,0 +1,24 @@ +# This Rack middleware is intended to measure the latency between +# gitlab-workhorse forwarding a request to the Rails application and the +# time this middleware is reached. + +module Gitlab + module Middleware + class RailsQueueDuration + def initialize(app) + @app = app + end + + def call(env) + trans = Gitlab::Metrics.current_transaction + proxy_start = env['HTTP_GITLAB_WORHORSE_PROXY_START'].presence + if trans && proxy_start + # Time in milliseconds since gitlab-workhorse started the request + trans.set(:rails_queue_duration, Time.now.to_f * 1_000 - proxy_start.to_f / 1_000_000) + end + + @app.call(env) + end + end + end +end diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb index 71c5b6801fb66e..183bd10d6a339b 100644 --- a/lib/gitlab/project_search_results.rb +++ b/lib/gitlab/project_search_results.rb @@ -74,7 +74,7 @@ def wiki_blobs end def notes - project.notes.user.search(query).order('updated_at DESC') + project.notes.user.search(query, as_user: @current_user).order('updated_at DESC') end def commits diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb index 5c352c96de522a..40766f35f77984 100644 --- a/lib/gitlab/redis.rb +++ b/lib/gitlab/redis.rb @@ -25,7 +25,7 @@ def self.with end @pool.with { |redis| yield redis } end - + def self.redis_store_options url = new.url redis_config_hash = ::Redis::Store::Factory.extract_host_options_from_uri(url) @@ -40,10 +40,10 @@ def self.redis_store_options def initialize(rails_env=nil) rails_env ||= Rails.env config_file = File.expand_path('../../../config/resque.yml', __FILE__) - + @url = "redis://localhost:6379" - if File.exists?(config_file) - @url =YAML.load_file(config_file)[rails_env] + if File.exist?(config_file) + @url = YAML.load_file(config_file)[rails_env] end end end diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 13c4d64c99b0d9..11c0b01f0dc06b 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -4,10 +4,9 @@ class ReferenceExtractor < Banzai::ReferenceExtractor REFERABLES = %i(user issue label milestone merge_request snippet commit commit_range) attr_accessor :project, :current_user, :author - def initialize(project, current_user = nil, author = nil) + def initialize(project, current_user = nil) @project = project @current_user = current_user - @author = author @references = {} @@ -18,17 +17,21 @@ def analyze(text, context = {}) super(text, context.merge(project: project)) end + def references(type) + super(type, project, current_user) + end + REFERABLES.each do |type| define_method("#{type}s") do - @references[type] ||= references(type, reference_context) + @references[type] ||= references(type) end end def issues if project && project.jira_tracker? - @references[:external_issue] ||= references(:external_issue, reference_context) + @references[:external_issue] ||= references(:external_issue) else - @references[:issue] ||= references(:issue, reference_context) + @references[:issue] ||= references(:issue) end end @@ -46,11 +49,5 @@ def self.references_pattern @pattern = Regexp.union(patterns.compact) end - - private - - def reference_context - { project: project, current_user: current_user, author: author } - end end end diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index ace906a6f59dec..1cbd6d945a0668 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -96,5 +96,9 @@ def git_reference_regex (? %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage target text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'altGlyph' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format glyph-orientation-horizontal glyph-orientation-vertical glyphRef id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'altGlyphDef' => %w[id xml:base xml:lang xml:space], - 'altGlyphItem' => %w[id xml:base xml:lang xml:space], - 'animate' => %w[accumulate additive alignment-baseline attributeName attributeType baseline-shift begin by calcMode clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dur enable-background end externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight from glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning keySplines keyTimes letter-spacing lighting-color marker-end marker-mid marker-start mask max min onbegin onend onload onrepeat opacity overflow pointer-events repeatCount repeatDur requiredExtensions requiredFeatures restart shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width systemLanguage text-anchor text-decoration text-rendering to unicode-bidi values visibility word-spacing writing-mode xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'animateColor' => %w[accumulate additive alignment-baseline attributeName attributeType baseline-shift begin by calcMode clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dur enable-background end externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight from glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning keySplines keyTimes letter-spacing lighting-color marker-end marker-mid marker-start mask max min onbegin onend onload onrepeat opacity overflow pointer-events repeatCount repeatDur requiredExtensions requiredFeatures restart shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width systemLanguage text-anchor text-decoration text-rendering to unicode-bidi values visibility word-spacing writing-mode xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'animateMotion' => %w[accumulate additive begin by calcMode dur end externalResourcesRequired fill from id keyPoints keySplines keyTimes max min onbegin onend onload onrepeat origin path repeatCount repeatDur requiredExtensions requiredFeatures restart rotate systemLanguage to values xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'animateTransform' => %w[accumulate additive attributeName attributeType begin by calcMode dur end externalResourcesRequired fill from id keySplines keyTimes max min onbegin onend onload onrepeat repeatCount repeatDur requiredExtensions requiredFeatures restart systemLanguage to type values xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'circle' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor cx cy direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events r requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'clipPath' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule clipPathUnits color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'color-profile' => %w[id local name rendering-intent xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'cursor' => %w[externalResourcesRequired id requiredExtensions requiredFeatures systemLanguage x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'defs' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'desc' => %w[class id style xml:base xml:lang xml:space], - 'ellipse' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor cx cy direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rx ry shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'feBlend' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in in2 kerning letter-spacing lighting-color marker-end marker-mid marker-start mask mode opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feColorMatrix' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering type unicode-bidi values visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feComponentTransfer' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feComposite' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in in2 k1 k2 k3 k4 kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity operator overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feConvolveMatrix' => %w[alignment-baseline baseline-shift bias class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display divisor dominant-baseline edgeMode enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kernelMatrix kernelUnitLength kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity order overflow pointer-events preserveAlpha result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style targetX targetY text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feDiffuseLighting' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor diffuseConstant direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kernelUnitLength kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feDisplacementMap' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in in2 kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result scale shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xChannelSelector xml:base xml:lang xml:space y yChannelSelector], - 'feDistantLight' => %w[azimuth elevation id xml:base xml:lang xml:space], - 'feFlood' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feFuncA' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], - 'feFuncB' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], - 'feFuncG' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], - 'feFuncR' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], - 'feGaussianBlur' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stdDeviation stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feImage' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events preserveAspectRatio result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'feMerge' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feMergeNode' => %w[id xml:base xml:lang xml:space], - 'feMorphology' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity operator overflow pointer-events radius result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feOffset' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'fePointLight' => %w[id x xml:base xml:lang xml:space y z], - 'feSpecularLighting' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kernelUnitLength kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering specularConstant specularExponent stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feSpotLight' => %w[id limitingConeAngle pointsAtX pointsAtY pointsAtZ specularExponent x xml:base xml:lang xml:space y z], - 'feTile' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'feTurbulence' => %w[alignment-baseline baseFrequency baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask numOctaves opacity overflow pointer-events result seed shape-rendering stitchTiles stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering type unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'filter' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events primitiveUnits shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'font' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x horiz-origin-y id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi vert-adv-y vert-origin-x vert-origin-y visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'font-face' => %w[accent-height alphabetic ascent bbox cap-height descent font-family font-size font-stretch font-style font-variant font-weight hanging id ideographic mathematical overline-position overline-thickness panose-1 slope stemh stemv strikethrough-position strikethrough-thickness underline-position underline-thickness unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical widths x-height xml:base xml:lang xml:space], - 'font-face-format' => %w[id string xml:base xml:lang xml:space], - 'font-face-name' => %w[id name xml:base xml:lang xml:space], - 'font-face-src' => %w[id xml:base xml:lang xml:space], - 'font-face-uri' => %w[id xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'foreignObject' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'g' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'glyph' => %w[alignment-baseline arabic-form baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor d direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x id image-rendering kerning lang letter-spacing lighting-color marker-end marker-mid marker-start mask opacity orientation overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode unicode-bidi vert-adv-y vert-origin-x vert-origin-y visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'glyphRef' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format glyph-orientation-horizontal glyph-orientation-vertical glyphRef id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'hkern' => %w[g1 g2 id k u1 u2 xml:base xml:lang xml:space], - 'image' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events preserveAspectRatio requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'line' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode x1 x2 xml:base xml:lang xml:space y1 y2], - 'linearGradient' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical gradientTransform gradientUnits id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering spreadMethod stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode x1 x2 xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space y1 y2], - 'marker' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask opacity orient overflow pointer-events preserveAspectRatio refX refY shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi viewBox visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'mask' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask maskContentUnits maskUnits opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'metadata' => %w[id xml:base xml:lang xml:space], - 'missing-glyph' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor d direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi vert-adv-y vert-origin-x vert-origin-y visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'mpath' => %w[externalResourcesRequired id xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'path' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor d direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pathLength pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'pattern' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow patternContentUnits patternTransform patternUnits pointer-events preserveAspectRatio requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi viewBox visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'polygon' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events points requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'polyline' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events points requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'radialGradient' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor cx cy direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight fx fy glyph-orientation-horizontal glyph-orientation-vertical gradientTransform gradientUnits id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events r shape-rendering spreadMethod stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space], - 'rect' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rx ry shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], - 'script' => %w[externalResourcesRequired id type xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'set' => %w[attributeName attributeType begin dur end externalResourcesRequired fill id max min onbegin onend onload onrepeat repeatCount repeatDur requiredExtensions requiredFeatures restart systemLanguage to xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], - 'stop' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask offset opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'style' => %w[id media title type xml:base xml:lang xml:space], - 'svg' => %w[alignment-baseline baseProfile baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onabort onactivate onclick onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onresize onscroll onunload onzoom opacity overflow pointer-events preserveAspectRatio requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi version viewBox visibility width word-spacing writing-mode x xml:base xml:lang xml:space xmlns y zoomAndPan], - 'switch' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'symbol' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events preserveAspectRatio shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi viewBox visibility word-spacing writing-mode xml:base xml:lang xml:space], - 'text' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength transform unicode-bidi visibility word-spacing writing-mode x xml:base xml:lang xml:space y], - 'textPath' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask method onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering spacing startOffset stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength unicode-bidi visibility word-spacing writing-mode xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space], - 'title' => %w[class id style xml:base xml:lang xml:space], - 'tref' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength unicode-bidi visibility word-spacing writing-mode x xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space y], - 'tspan' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength unicode-bidi visibility word-spacing writing-mode x xml:base xml:lang xml:space y], - 'use' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], - 'view' => %w[externalResourcesRequired id preserveAspectRatio viewBox viewTarget xml:base xml:lang xml:space zoomAndPan], - 'vkern' => %w[g1 g2 id k u1 u2 xml:base xml:lang xml:space] - }.freeze + ALLOWED_ATTRIBUTES = { + 'a' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage target text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'altGlyph' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format glyph-orientation-horizontal glyph-orientation-vertical glyphRef id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'altGlyphDef' => %w[id xml:base xml:lang xml:space], + 'altGlyphItem' => %w[id xml:base xml:lang xml:space], + 'animate' => %w[accumulate additive alignment-baseline attributeName attributeType baseline-shift begin by calcMode clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dur enable-background end externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight from glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning keySplines keyTimes letter-spacing lighting-color marker-end marker-mid marker-start mask max min onbegin onend onload onrepeat opacity overflow pointer-events repeatCount repeatDur requiredExtensions requiredFeatures restart shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width systemLanguage text-anchor text-decoration text-rendering to unicode-bidi values visibility word-spacing writing-mode xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'animateColor' => %w[accumulate additive alignment-baseline attributeName attributeType baseline-shift begin by calcMode clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dur enable-background end externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight from glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning keySplines keyTimes letter-spacing lighting-color marker-end marker-mid marker-start mask max min onbegin onend onload onrepeat opacity overflow pointer-events repeatCount repeatDur requiredExtensions requiredFeatures restart shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width systemLanguage text-anchor text-decoration text-rendering to unicode-bidi values visibility word-spacing writing-mode xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'animateMotion' => %w[accumulate additive begin by calcMode dur end externalResourcesRequired fill from id keyPoints keySplines keyTimes max min onbegin onend onload onrepeat origin path repeatCount repeatDur requiredExtensions requiredFeatures restart rotate systemLanguage to values xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'animateTransform' => %w[accumulate additive attributeName attributeType begin by calcMode dur end externalResourcesRequired fill from id keySplines keyTimes max min onbegin onend onload onrepeat repeatCount repeatDur requiredExtensions requiredFeatures restart systemLanguage to type values xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'circle' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor cx cy direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events r requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'clipPath' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule clipPathUnits color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'color-profile' => %w[id local name rendering-intent xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'cursor' => %w[externalResourcesRequired id requiredExtensions requiredFeatures systemLanguage x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'defs' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'desc' => %w[class id style xml:base xml:lang xml:space], + 'ellipse' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor cx cy direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rx ry shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'feBlend' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in in2 kerning letter-spacing lighting-color marker-end marker-mid marker-start mask mode opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feColorMatrix' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering type unicode-bidi values visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feComponentTransfer' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feComposite' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in in2 k1 k2 k3 k4 kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity operator overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feConvolveMatrix' => %w[alignment-baseline baseline-shift bias class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display divisor dominant-baseline edgeMode enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kernelMatrix kernelUnitLength kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity order overflow pointer-events preserveAlpha result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style targetX targetY text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feDiffuseLighting' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor diffuseConstant direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kernelUnitLength kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feDisplacementMap' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in in2 kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result scale shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xChannelSelector xml:base xml:lang xml:space y yChannelSelector], + 'feDistantLight' => %w[azimuth elevation id xml:base xml:lang xml:space], + 'feFlood' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feFuncA' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], + 'feFuncB' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], + 'feFuncG' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], + 'feFuncR' => %w[amplitude exponent id intercept offset slope tableValues type xml:base xml:lang xml:space], + 'feGaussianBlur' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stdDeviation stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feImage' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events preserveAspectRatio result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'feMerge' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feMergeNode' => %w[id xml:base xml:lang xml:space], + 'feMorphology' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity operator overflow pointer-events radius result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feOffset' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'fePointLight' => %w[id x xml:base xml:lang xml:space y z], + 'feSpecularLighting' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kernelUnitLength kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering specularConstant specularExponent stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feSpotLight' => %w[id limitingConeAngle pointsAtX pointsAtY pointsAtZ specularExponent x xml:base xml:lang xml:space y z], + 'feTile' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering in kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events result shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'feTurbulence' => %w[alignment-baseline baseFrequency baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask numOctaves opacity overflow pointer-events result seed shape-rendering stitchTiles stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering type unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'filter' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events primitiveUnits shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'font' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x horiz-origin-y id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi vert-adv-y vert-origin-x vert-origin-y visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'font-face' => %w[accent-height alphabetic ascent bbox cap-height descent font-family font-size font-stretch font-style font-variant font-weight hanging id ideographic mathematical overline-position overline-thickness panose-1 slope stemh stemv strikethrough-position strikethrough-thickness underline-position underline-thickness unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical widths x-height xml:base xml:lang xml:space], + 'font-face-format' => %w[id string xml:base xml:lang xml:space], + 'font-face-name' => %w[id name xml:base xml:lang xml:space], + 'font-face-src' => %w[id xml:base xml:lang xml:space], + 'font-face-uri' => %w[id xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'foreignObject' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'g' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'glyph' => %w[alignment-baseline arabic-form baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor d direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x id image-rendering kerning lang letter-spacing lighting-color marker-end marker-mid marker-start mask opacity orientation overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode unicode-bidi vert-adv-y vert-origin-x vert-origin-y visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'glyphRef' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format glyph-orientation-horizontal glyph-orientation-vertical glyphRef id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'hkern' => %w[g1 g2 id k u1 u2 xml:base xml:lang xml:space], + 'image' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events preserveAspectRatio requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'line' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode x1 x2 xml:base xml:lang xml:space y1 y2], + 'linearGradient' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical gradientTransform gradientUnits id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering spreadMethod stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode x1 x2 xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space y1 y2], + 'marker' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask opacity orient overflow pointer-events preserveAspectRatio refX refY shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi viewBox visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'mask' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask maskContentUnits maskUnits opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'metadata' => %w[id xml:base xml:lang xml:space], + 'missing-glyph' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor d direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi vert-adv-y vert-origin-x vert-origin-y visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'mpath' => %w[externalResourcesRequired id xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'path' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor d direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pathLength pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'pattern' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow patternContentUnits patternTransform patternUnits pointer-events preserveAspectRatio requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi viewBox visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'polygon' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events points requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'polyline' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events points requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'radialGradient' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor cx cy direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight fx fy glyph-orientation-horizontal glyph-orientation-vertical gradientTransform gradientUnits id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events r shape-rendering spreadMethod stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space], + 'rect' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rx ry shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xml:base xml:lang xml:space y], + 'script' => %w[externalResourcesRequired id type xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'set' => %w[attributeName attributeType begin dur end externalResourcesRequired fill id max min onbegin onend onload onrepeat repeatCount repeatDur requiredExtensions requiredFeatures restart systemLanguage to xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space], + 'stop' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask offset opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'style' => %w[id media title type xml:base xml:lang xml:space], + 'svg' => %w[alignment-baseline baseProfile baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onabort onactivate onclick onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onresize onscroll onunload onzoom opacity overflow pointer-events preserveAspectRatio requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering unicode-bidi version viewBox visibility width word-spacing writing-mode x xml:base xml:lang xml:space xmlns y zoomAndPan], + 'switch' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'symbol' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events preserveAspectRatio shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style text-anchor text-decoration text-rendering unicode-bidi viewBox visibility word-spacing writing-mode xml:base xml:lang xml:space], + 'text' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength transform unicode-bidi visibility word-spacing writing-mode x xml:base xml:lang xml:space y], + 'textPath' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask method onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering spacing startOffset stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength unicode-bidi visibility word-spacing writing-mode xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space], + 'title' => %w[class id style xml:base xml:lang xml:space], + 'tref' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength unicode-bidi visibility word-spacing writing-mode x xlink:arcrole xlink:href xlink:role xlink:title xlink:type xml:base xml:lang xml:space y], + 'tspan' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline dx dy enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical id image-rendering kerning lengthAdjust letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures rotate shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering textLength unicode-bidi visibility word-spacing writing-mode x xml:base xml:lang xml:space y], + 'use' => %w[alignment-baseline baseline-shift class clip clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cursor direction display dominant-baseline enable-background externalResourcesRequired fill fill-opacity fill-rule filter flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical height id image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask onactivate onclick onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup opacity overflow pointer-events requiredExtensions requiredFeatures shape-rendering stop-color stop-opacity stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style systemLanguage text-anchor text-decoration text-rendering transform unicode-bidi visibility width word-spacing writing-mode x xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y], + 'view' => %w[externalResourcesRequired id preserveAspectRatio viewBox viewTarget xml:base xml:lang xml:space zoomAndPan], + 'vkern' => %w[g1 g2 id k u1 u2 xml:base xml:lang xml:space] + }.freeze + end end end end diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index 2bbbd3074e86f7..fe65c246101e99 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -62,7 +62,7 @@ def note_url end def wiki_page_url - "#{Gitlab.config.gitlab.url}#{object.wiki.wiki_base_path}/#{object.slug}" + namespace_project_wiki_url(object.wiki.project.namespace, object.wiki.project, object.slug) end end end diff --git a/lib/gitlab/import_url.rb b/lib/gitlab/url_sanitizer.rb similarity index 66% rename from lib/gitlab/import_url.rb rename to lib/gitlab/url_sanitizer.rb index d23b013c1f56e9..7d02fe3c971e9d 100644 --- a/lib/gitlab/import_url.rb +++ b/lib/gitlab/url_sanitizer.rb @@ -1,7 +1,13 @@ module Gitlab - class ImportUrl + class UrlSanitizer + def self.sanitize(content) + regexp = URI::Parser.new.make_regexp(['http', 'https', 'ssh', 'git']) + + content.gsub(regexp) { |url| new(url).masked_url } + end + def initialize(url, credentials: nil) - @url = URI.parse(URI.encode(url)) + @url = Addressable::URI.parse(url) @credentials = credentials end @@ -9,6 +15,13 @@ def sanitized_url @sanitized_url ||= safe_url.to_s end + def masked_url + url = @url.dup + url.password = "*****" unless url.password.nil? + url.user = "*****" unless url.user.nil? + url.to_s + end + def credentials @credentials ||= { user: @url.user, password: @url.password } end diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb index a1ee1cba216bcd..9462f3368e672a 100644 --- a/lib/gitlab/visibility_level.rb +++ b/lib/gitlab/visibility_level.rb @@ -32,6 +32,13 @@ def options } end + def highest_allowed_level + restricted_levels = current_application_settings.restricted_visibility_levels + + allowed_levels = self.values - restricted_levels + allowed_levels.max || PRIVATE + end + def allowed_for?(user, level) user.is_admin? || allowed_level?(level.to_i) end diff --git a/lib/json_web_token/rsa_token.rb b/lib/json_web_token/rsa_token.rb new file mode 100644 index 00000000000000..d6d6af7089c92f --- /dev/null +++ b/lib/json_web_token/rsa_token.rb @@ -0,0 +1,42 @@ +module JSONWebToken + class RSAToken < Token + attr_reader :key_file + + def initialize(key_file) + super() + @key_file = key_file + end + + def encoded + headers = { + kid: kid + } + JWT.encode(payload, key, 'RS256', headers) + end + + private + + def key_data + @key_data ||= File.read(key_file) + end + + def key + @key ||= OpenSSL::PKey::RSA.new(key_data) + end + + def public_key + key.public_key + end + + def kid + # calculate sha256 from DER encoded ASN1 + kid = Digest::SHA256.digest(public_key.to_der) + + # we encode only 30 bytes with base32 + kid = Base32.encode(kid[0..29]) + + # insert colon every 4 characters + kid.scan(/.{4}/).join(':') + end + end +end diff --git a/lib/json_web_token/token.rb b/lib/json_web_token/token.rb new file mode 100644 index 00000000000000..5b67715b0b2ea4 --- /dev/null +++ b/lib/json_web_token/token.rb @@ -0,0 +1,46 @@ +module JSONWebToken + class Token + attr_accessor :issuer, :subject, :audience, :id + attr_accessor :issued_at, :not_before, :expire_time + + def initialize + @id = SecureRandom.uuid + @issued_at = Time.now + # we give a few seconds for time shift + @not_before = issued_at - 5.seconds + # default 60 seconds should be more than enough for this authentication token + @expire_time = issued_at + 1.minute + @custom_payload = {} + end + + def [](key) + @custom_payload[key] + end + + def []=(key, value) + @custom_payload[key] = value + end + + def encoded + raise NotImplementedError + end + + def payload + @custom_payload.merge(default_payload) + end + + private + + def default_payload + { + jti: id, + aud: audience, + sub: subject, + iss: issuer, + iat: issued_at.to_i, + nbf: not_before.to_i, + exp: expire_time.to_i + }.compact + end + end +end diff --git a/lib/support/nginx/registry-ssl b/lib/support/nginx/registry-ssl new file mode 100644 index 00000000000000..92511e268615f4 --- /dev/null +++ b/lib/support/nginx/registry-ssl @@ -0,0 +1,53 @@ +## Lines starting with two hashes (##) are comments with information. +## Lines starting with one hash (#) are configuration parameters that can be uncommented. +## +################################### +## configuration ## +################################### + +## Redirects all HTTP traffic to the HTTPS host +server { + listen *:80; + server_name registry.gitlab.example.com; + server_tokens off; ## Don't show the nginx version number, a security best practice + return 301 https://$http_host:$request_uri; + access_log /var/log/nginx/gitlab_registry_access.log gitlab_access; + error_log /var/log/nginx/gitlab_registry_error.log; +} + +server { + # If a different port is specified in https://gitlab.com/gitlab-org/gitlab-ce/blob/8-8-stable/config/gitlab.yml.example#L182, + # it should be declared here as well + listen *:443 ssl http2; + server_name registry.gitlab.example.com; + server_tokens off; ## Don't show the nginx version number, a security best practice + + client_max_body_size 0; + chunked_transfer_encoding on; + + ## Strong SSL Security + ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/ + ssl on; + ssl_certificate /etc/gitlab/ssl/registry.gitlab.example.com.crt + ssl_certificate_key /etc/gitlab/ssl/registry.gitlab.example.com.key + + ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_session_timeout 5m; + + access_log /var/log/gitlab/nginx/gitlab_registry_access.log gitlab_access; + error_log /var/log/gitlab/nginx/gitlab_registry_error.log; + + location / { + proxy_set_header Host $http_host; # required for docker client's sake + proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900; + + proxy_pass http://localhost:5000; + } + +} diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake deleted file mode 100644 index 16bad4bd2bdcf8..00000000000000 --- a/lib/tasks/auto_annotate_models.rake +++ /dev/null @@ -1,44 +0,0 @@ -if Rails.env.development? - task :set_annotation_options do - # You can override any of these by setting an environment variable of the - # same name. - Annotate.set_defaults( - 'routes' => 'false', - 'position_in_routes' => 'before', - 'position_in_class' => 'before', - 'position_in_test' => 'before', - 'position_in_fixture' => 'before', - 'position_in_factory' => 'before', - 'position_in_serializer' => 'before', - 'show_foreign_keys' => 'true', - 'show_indexes' => 'false', - 'simple_indexes' => 'false', - 'model_dir' => 'app/models', - 'root_dir' => '', - 'include_version' => 'false', - 'require' => '', - 'exclude_tests' => 'true', - 'exclude_fixtures' => 'true', - 'exclude_factories' => 'true', - 'exclude_serializers' => 'true', - 'exclude_scaffolds' => 'true', - 'exclude_controllers' => 'true', - 'exclude_helpers' => 'true', - 'ignore_model_sub_dir' => 'false', - 'ignore_columns' => nil, - 'ignore_unknown_models' => 'false', - 'hide_limit_column_types' => 'integer,boolean', - 'skip_on_db_migrate' => 'false', - 'format_bare' => 'true', - 'format_rdoc' => 'false', - 'format_markdown' => 'false', - 'sort' => 'false', - 'force' => 'false', - 'trace' => 'false', - 'wrapper_open' => nil, - 'wrapper_close' => nil, - ) - end - - Annotate.load_tasks -end diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake index 402bb338f27a62..596eaca6d0d6cc 100644 --- a/lib/tasks/gitlab/backup.rake +++ b/lib/tasks/gitlab/backup.rake @@ -14,6 +14,7 @@ namespace :gitlab do Rake::Task["gitlab:backup:builds:create"].invoke Rake::Task["gitlab:backup:artifacts:create"].invoke Rake::Task["gitlab:backup:lfs:create"].invoke + Rake::Task["gitlab:backup:registry:create"].invoke backup = Backup::Manager.new backup.pack @@ -54,6 +55,7 @@ namespace :gitlab do Rake::Task['gitlab:backup:builds:restore'].invoke unless backup.skipped?('builds') Rake::Task['gitlab:backup:artifacts:restore'].invoke unless backup.skipped?('artifacts') Rake::Task['gitlab:backup:lfs:restore'].invoke unless backup.skipped?('lfs') + Rake::Task['gitlab:backup:registry:restore'].invoke unless backup.skipped?('registry') Rake::Task['gitlab:shell:setup'].invoke backup.cleanup @@ -173,6 +175,33 @@ namespace :gitlab do end end + namespace :registry do + task create: :environment do + $progress.puts "Dumping container registry images ... ".blue + + if Gitlab.config.registry.enabled + if ENV["SKIP"] && ENV["SKIP"].include?("registry") + $progress.puts "[SKIPPED]".cyan + else + Backup::Registry.new.dump + $progress.puts "done".green + end + else + $progress.puts "[DISABLED]".cyan + end + end + + task restore: :environment do + $progress.puts "Restoring container registry images ... ".blue + if Gitlab.config.registry.enabled + Backup::Registry.new.restore + $progress.puts "done".green + else + $progress.puts "[DISABLED]".cyan + end + end + end + def configure_cron_mode if ENV['CRON'] # We need an object we can say 'puts' and 'print' to; let's use a diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index effb8eb60012b3..fad89c73762720 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -303,7 +303,7 @@ namespace :gitlab do else puts "no".red try_fixing_it( - "sudo find #{upload_path} -type d -not -path #{upload_path} -exec chmod 0700 {} \\;" + "sudo chmod 700 #{upload_path}" ) for_more_information( see_installation_guide_section "GitLab" diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake index 1c706dc11b33ec..86f5d65f12830d 100644 --- a/lib/tasks/gitlab/db.rake +++ b/lib/tasks/gitlab/db.rake @@ -29,10 +29,22 @@ namespace :gitlab do tables.delete 'schema_migrations' # Truncate schema_migrations to ensure migrations re-run connection.execute('TRUNCATE schema_migrations') + # Drop tables with cascade to avoid dependent table errors # PG: http://www.postgresql.org/docs/current/static/ddl-depend.html # MySQL: http://dev.mysql.com/doc/refman/5.7/en/drop-table.html - tables.each { |t| connection.execute("DROP TABLE #{t} CASCADE") } + # Add `IF EXISTS` because cascade could have already deleted a table. + tables.each { |t| connection.execute("DROP TABLE IF EXISTS #{t} CASCADE") } + end + + desc 'Configures the database by running migrate, or by loading the schema and seeding if needed' + task configure: :environment do + if ActiveRecord::Base.connection.tables.any? + Rake::Task['db:migrate'].invoke + else + Rake::Task['db:schema:load'].invoke + Rake::Task['db:seed_fu'].invoke + end end end end diff --git a/lib/tasks/gitlab/update_gitignore.rake b/lib/tasks/gitlab/update_gitignore.rake new file mode 100644 index 00000000000000..84aa312002b15d --- /dev/null +++ b/lib/tasks/gitlab/update_gitignore.rake @@ -0,0 +1,46 @@ +namespace :gitlab do + desc "GitLab | Update gitignore" + task :update_gitignore do + unless clone_gitignores + puts "Cloning the gitignores failed".red + return + end + + remove_unneeded_files(gitignore_directory) + remove_unneeded_files(global_directory) + + puts "Done".green + end + + def clone_gitignores + FileUtils.rm_rf(gitignore_directory) if Dir.exist?(gitignore_directory) + FileUtils.cd vendor_directory + + system('git clone --depth=1 --branch=master https://github.com/github/gitignore.git') + end + + # Retain only certain files: + # - The LICENSE, because we have to + # - The sub dir global + # - The gitignores themself + # - Dir.entires returns also the entries '.' and '..' + def remove_unneeded_files(path) + Dir.foreach(path) do |file| + FileUtils.rm_rf(File.join(path, file)) unless file =~ /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ + end + end + + private + + def vendor_directory + Rails.root.join('vendor') + end + + def gitignore_directory + File.join(vendor_directory, 'gitignore') + end + + def global_directory + File.join(gitignore_directory, 'Global') + end +end diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake index ddfaf5d51f2812..78ffccc9d06586 100644 --- a/lib/tasks/rubocop.rake +++ b/lib/tasks/rubocop.rake @@ -1,4 +1,5 @@ unless Rails.env.production? require 'rubocop/rake_task' + RuboCop::RakeTask.new end diff --git a/public/robots.txt b/public/robots.txt index 4f616c7f4c1cac..334f4c035334f7 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -65,3 +65,4 @@ Disallow: /*/*/deploy_keys Disallow: /*/*/hooks Disallow: /*/*/services Disallow: /*/*/protected_branches +Disallow: /*/*/uploads/ diff --git a/shared/registry/.gitkeep b/shared/registry/.gitkeep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb index 462afb24f082a3..6fad7e2b9e7700 100644 --- a/spec/config/mail_room_spec.rb +++ b/spec/config/mail_room_spec.rb @@ -43,7 +43,7 @@ redis_config_file = Rails.root.join('config', 'resque.yml') redis_url = - if File.exists?(redis_config_file) + if File.exist?(redis_config_file) YAML.load_file(redis_config_file)[Rails.env] else "redis://localhost:6379" diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb index 2ba0d4891978de..4cb8b8da15019a 100644 --- a/spec/controllers/admin/projects_controller_spec.rb +++ b/spec/controllers/admin/projects_controller_spec.rb @@ -17,7 +17,7 @@ it 'does not retrieve the project' do get :index, visibility_levels: [Gitlab::VisibilityLevel::INTERNAL] - expect(response.body).to_not match(project.name) + expect(response.body).not_to match(project.name) end end end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index ce2a62ae1fd331..6caf37ddc2c305 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -114,6 +114,82 @@ def go end end + describe 'POST update' do + context 'when the password has changed' do + def update_password(user, password, password_confirmation = nil) + params = { + id: user.to_param, + user: { + password: password, + password_confirmation: password_confirmation || password + } + } + + post :update, params + end + + context 'when the new password is valid' do + it 'redirects to the user' do + update_password(user, 'AValidPassword1') + + expect(response).to redirect_to(admin_user_path(user)) + end + + it 'updates the password' do + update_password(user, 'AValidPassword1') + + expect { user.reload }.to change { user.encrypted_password } + end + + it 'sets the new password to expire immediately' do + update_password(user, 'AValidPassword1') + + expect { user.reload }.to change { user.password_expires_at }.to(a_value <= Time.now) + end + end + + context 'when the new password is invalid' do + it 'shows the edit page again' do + update_password(user, 'invalid') + + expect(response).to render_template(:edit) + end + + it 'returns the error message' do + update_password(user, 'invalid') + + expect(assigns[:user].errors).to contain_exactly(a_string_matching(/too short/)) + end + + it 'does not update the password' do + update_password(user, 'invalid') + + expect { user.reload }.not_to change { user.encrypted_password } + end + end + + context 'when the new password does not match the password confirmation' do + it 'shows the edit page again' do + update_password(user, 'AValidPassword1', 'AValidPassword2') + + expect(response).to render_template(:edit) + end + + it 'returns the error message' do + update_password(user, 'AValidPassword1', 'AValidPassword2') + + expect(assigns[:user].errors).to contain_exactly(a_string_matching(/doesn't match/)) + end + + it 'does not update the password' do + update_password(user, 'AValidPassword1', 'AValidPassword2') + + expect { user.reload }.not_to change { user.encrypted_password } + end + end + end + end + describe "POST impersonate" do context "when the user is blocked" do before do diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb new file mode 100644 index 00000000000000..0d8a68bb51a7cc --- /dev/null +++ b/spec/controllers/health_check_controller_spec.rb @@ -0,0 +1,105 @@ +require 'spec_helper' + +describe HealthCheckController do + let(:token) { current_application_settings.health_check_access_token } + let(:json_response) { JSON.parse(response.body) } + let(:xml_response) { Hash.from_xml(response.body)['hash'] } + + describe 'GET #index' do + context 'when services are up but NO access token' do + it 'returns a not found page' do + get :index + expect(response).to be_not_found + end + end + + context 'when services are up and an access token is provided' do + it 'supports passing the token in the header' do + request.headers['TOKEN'] = token + get :index + expect(response).to be_success + expect(response.content_type).to eq 'text/plain' + end + + it 'supports successful plaintest response' do + get :index, token: token + expect(response).to be_success + expect(response.content_type).to eq 'text/plain' + end + + it 'supports successful json response' do + get :index, token: token, format: :json + expect(response).to be_success + expect(response.content_type).to eq 'application/json' + expect(json_response['healthy']).to be true + end + + it 'supports successful xml response' do + get :index, token: token, format: :xml + expect(response).to be_success + expect(response.content_type).to eq 'application/xml' + expect(xml_response['healthy']).to be true + end + + it 'supports successful responses for specific checks' do + get :index, token: token, checks: 'email', format: :json + expect(response).to be_success + expect(response.content_type).to eq 'application/json' + expect(json_response['healthy']).to be true + end + end + + context 'when a service is down but NO access token' do + it 'returns a not found page' do + get :index + expect(response).to be_not_found + end + end + + context 'when a service is down and an access token is provided' do + before do + allow(HealthCheck::Utils).to receive(:process_checks).with('standard').and_return('The server is on fire') + allow(HealthCheck::Utils).to receive(:process_checks).with('email').and_return('Email is on fire') + end + + it 'supports passing the token in the header' do + request.headers['TOKEN'] = token + get :index + expect(response.status).to eq(500) + expect(response.content_type).to eq 'text/plain' + expect(response.body).to include('The server is on fire') + end + + it 'supports failure plaintest response' do + get :index, token: token + expect(response.status).to eq(500) + expect(response.content_type).to eq 'text/plain' + expect(response.body).to include('The server is on fire') + end + + it 'supports failure json response' do + get :index, token: token, format: :json + expect(response.status).to eq(500) + expect(response.content_type).to eq 'application/json' + expect(json_response['healthy']).to be false + expect(json_response['message']).to include('The server is on fire') + end + + it 'supports failure xml response' do + get :index, token: token, format: :xml + expect(response.status).to eq(500) + expect(response.content_type).to eq 'application/xml' + expect(xml_response['healthy']).to be false + expect(xml_response['message']).to include('The server is on fire') + end + + it 'supports failure responses for specific checks' do + get :index, token: token, checks: 'email', format: :json + expect(response.status).to eq(500) + expect(response.content_type).to eq 'application/json' + expect(json_response['healthy']).to be false + expect(json_response['message']).to include('Email is on fire') + end + end + end +end diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 8ad734721170d1..c4b4a888b4ed4d 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -122,27 +122,23 @@ let(:branch) { "feature" } it { expect(response.status).to eq(200) } - it { expect(subject).to render_template('destroy') } end context "valid branch name with unencoded slashes" do let(:branch) { "improve/awesome" } it { expect(response.status).to eq(200) } - it { expect(subject).to render_template('destroy') } end context "valid branch name with encoded slashes" do let(:branch) { "improve%2Fawesome" } it { expect(response.status).to eq(200) } - it { expect(subject).to render_template('destroy') } end context "invalid branch name, valid ref" do let(:branch) { "no-branch" } it { expect(response.status).to eq(404) } - it { expect(subject).to render_template('destroy') } end end end diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb index 788a609ee40230..4018dac95a2e93 100644 --- a/spec/controllers/projects/compare_controller_spec.rb +++ b/spec/controllers/projects/compare_controller_spec.rb @@ -19,7 +19,7 @@ to: ref_to) expect(response).to be_success - expect(assigns(:diffs).first).to_not be_nil + expect(assigns(:diffs).first).not_to be_nil expect(assigns(:commits).length).to be >= 1 end @@ -32,7 +32,7 @@ w: 1) expect(response).to be_success - expect(assigns(:diffs).first).to_not be_nil + expect(assigns(:diffs).first).not_to be_nil expect(assigns(:commits).length).to be >= 1 # without whitespace option, there are more than 2 diff_splits diff_splits = assigns(:diffs).first.diff.split("\n") diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb index 40bd83af8613f0..fbe8758dda7333 100644 --- a/spec/controllers/projects/group_links_controller_spec.rb +++ b/spec/controllers/projects/group_links_controller_spec.rb @@ -28,7 +28,7 @@ expect(group.shared_projects).to include project end - it 'redirects to project group links page'do + it 'redirects to project group links page' do expect(response).to redirect_to( namespace_project_group_links_path(project.namespace, project) ) @@ -43,7 +43,7 @@ end it 'does not share project with that group' do - expect(group.shared_projects).to_not include project + expect(group.shared_projects).not_to include project end end end diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 2b2ad3b9412ab3..c469480b086e83 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -56,7 +56,7 @@ move_issue expect(response).to have_http_status :found - expect(another_project.issues).to_not be_empty + expect(another_project.issues).not_to be_empty end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index c0a1f45195f8a9..4f621a43d7e058 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -63,7 +63,7 @@ id: merge_request.iid, format: format) - expect(response.body).to eq((merge_request.send(:"to_#{format}")).to_s) + expect(response.body).to eq(merge_request.send(:"to_#{format}").to_s) end it "should not escape Html" do diff --git a/spec/controllers/projects/notification_settings_controller_spec.rb b/spec/controllers/projects/notification_settings_controller_spec.rb index 4908b5456487c4..c5d17d97ec9f0d 100644 --- a/spec/controllers/projects/notification_settings_controller_spec.rb +++ b/spec/controllers/projects/notification_settings_controller_spec.rb @@ -34,5 +34,19 @@ expect(response.status).to eq 200 end end + + context 'not authorized' do + let(:private_project) { create(:project, :private) } + before { sign_in(user) } + + it 'returns 404' do + put :update, + namespace_id: private_project.namespace.to_param, + project_id: private_project.to_param, + notification_setting: { level: :participating } + + expect(response.status).to eq(404) + end + end end end diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index ed64e7cf9af67b..750fbecdd07105 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -38,7 +38,7 @@ include_context 'import applied' it 'does not import team members' do - expect(project.team_members).to_not include member + expect(project.team_members).not_to include member end it 'responds with not found' do diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb index 1caa476d37d92c..fb29274c687676 100644 --- a/spec/controllers/projects/raw_controller_spec.rb +++ b/spec/controllers/projects/raw_controller_spec.rb @@ -42,7 +42,7 @@ before do public_project.lfs_objects << lfs_object allow_any_instance_of(LfsObjectUploader).to receive(:exists?).and_return(true) - allow(controller).to receive(:send_file) { controller.render nothing: true } + allow(controller).to receive(:send_file) { controller.head :ok } end it 'serves the file' do diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 069cd917e5acd2..fba545560c7a53 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -8,6 +8,40 @@ let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') } describe "GET show" do + context "user not project member" do + before { sign_in(user) } + + context "user does not have access to project" do + let(:private_project) { create(:project, :private) } + + it "does not initialize notification setting" do + get :show, namespace_id: private_project.namespace.path, id: private_project.path + expect(assigns(:notification_setting)).to be_nil + end + end + + context "user has access to project" do + context "and does not have notification setting" do + it "initializes notification as disabled" do + get :show, namespace_id: public_project.namespace.path, id: public_project.path + expect(assigns(:notification_setting).level).to eq("global") + end + end + + context "and has notification setting" do + before do + setting = user.notification_settings_for(public_project) + setting.level = :watch + setting.save + end + + it "shows current notification setting" do + get :show, namespace_id: public_project.namespace.path, id: public_project.path + expect(assigns(:notification_setting).level).to eq("watch") + end + end + end + end context "rendering default project view" do render_views @@ -81,6 +115,17 @@ expect(public_project_with_dot_atom).not_to be_valid end end + + context 'when the project is pending deletions' do + it 'renders a 404 error' do + project = create(:project, pending_delete: true) + sign_in(user) + + get :show, namespace_id: project.namespace.path, id: project.path + + expect(response.status).to eq 404 + end + end end describe "#update" do diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb new file mode 100644 index 00000000000000..209fa37d97d920 --- /dev/null +++ b/spec/controllers/registrations_controller_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe RegistrationsController do + describe '#create' do + around(:each) do |example| + perform_enqueued_jobs do + example.run + end + end + + let(:user_params) { { user: { name: "new_user", username: "new_username", email: "new@user.com", password: "Any_password" } } } + + context 'when sending email confirmation' do + before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false) } + + it 'logs user in directly' do + post(:create, user_params) + expect(ActionMailer::Base.deliveries.last).to be_nil + expect(subject.current_user).not_to be_nil + end + end + + context 'when not sending email confirmation' do + before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true) } + + it 'does not authenticate user and sends confirmation email' do + post(:create, user_params) + expect(ActionMailer::Base.deliveries.last.to.first).to eq(user_params[:user][:email]) + expect(subject.current_user).to be_nil + end + end + end +end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 83cc8ec6d26dc0..5dc8724fb50f28 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -12,7 +12,7 @@ post(:create, user: { login: 'invalid', password: 'invalid' }) expect(response) - .to set_flash.now[:alert].to /Invalid login or password/ + .to set_flash.now[:alert].to /Invalid Login or password/ end end @@ -35,6 +35,27 @@ def authenticate_2fa(user_params) post(:create, { user: user_params }, { otp_user_id: user.id }) end + 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 + + authenticate_2fa(remember_me: '1', otp_attempt: user.current_otp) + + expect(response.cookies['remember_user_token']).to be_present + end + + it 'does nothing when disabled' do + allow(controller).to receive(:find_user).and_return(user) + expect(controller).not_to receive(:remember_me) + + authenticate_2fa(remember_me: '0', otp_attempt: user.current_otp) + + expect(response.cookies['remember_user_token']).to be_nil + end + end + ## # See #14900 issue # @@ -47,7 +68,7 @@ def authenticate_2fa(user_params) authenticate_2fa(login: another_user.username, otp_attempt: another_user.current_otp) - expect(subject.current_user).to_not eq another_user + expect(subject.current_user).not_to eq another_user end end @@ -56,7 +77,7 @@ def authenticate_2fa(user_params) authenticate_2fa(login: another_user.username, otp_attempt: 'invalid') - expect(subject.current_user).to_not eq another_user + expect(subject.current_user).not_to eq another_user end end @@ -73,7 +94,7 @@ def authenticate_2fa(user_params) before { authenticate_2fa(otp_attempt: 'invalid') } it 'does not authenticate' do - expect(subject.current_user).to_not eq user + expect(subject.current_user).not_to eq user end it 'warns about invalid OTP code' do diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 8045c8b940d722..c61ec174665d2a 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -112,4 +112,26 @@ expect(response).to render_template('calendar_activities') end end + + describe 'GET #snippets' do + before do + sign_in(user) + end + + context 'format html' do + it 'renders snippets page' do + get :snippets, username: user.username + expect(response.status).to eq(200) + expect(response).to render_template('show') + end + end + + context 'format json' do + it 'response with snippets json data' do + get :snippets, username: user.username, format: :json + expect(response.status).to eq(200) + expect(JSON.parse(response.body)).to have_key('html') + end + end + end end diff --git a/spec/factories/abuse_reports.rb b/spec/factories/abuse_reports.rb index d0e8c778518334..8f6422a7825e00 100644 --- a/spec/factories/abuse_reports.rb +++ b/spec/factories/abuse_reports.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: abuse_reports -# -# id :integer not null, primary key -# reporter_id :integer -# user_id :integer -# message :text -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :abuse_report do reporter factory: :user diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb index c80e7366551981..efe9803b1a7159 100644 --- a/spec/factories/broadcast_messages.rb +++ b/spec/factories/broadcast_messages.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# created_at :datetime -# updated_at :datetime -# color :string(255) -# font :string(255) -# - FactoryGirl.define do factory :broadcast_message do message "MyText" diff --git a/spec/factories/forked_project_links.rb b/spec/factories/forked_project_links.rb index 19a54946fe0ea9..b16c1272e6833d 100644 --- a/spec/factories/forked_project_links.rb +++ b/spec/factories/forked_project_links.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :forked_project_link do association :forked_to_project, factory: :project diff --git a/spec/factories/label_links.rb b/spec/factories/label_links.rb index 2939d4307c5700..3580174e873f55 100644 --- a/spec/factories/label_links.rb +++ b/spec/factories/label_links.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string(255) -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :label_link do label diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb index ea2be8928d5bf3..eb489099854d71 100644 --- a/spec/factories/labels.rb +++ b/spec/factories/labels.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: labels -# -# id :integer not null, primary key -# title :string(255) -# color :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# template :boolean default(FALSE) -# - FactoryGirl.define do factory :label do sequence(:title) { |n| "label#{n}" } diff --git a/spec/factories/lfs_objects.rb b/spec/factories/lfs_objects.rb index 327858ce435db3..a81645acd2b868 100644 --- a/spec/factories/lfs_objects.rb +++ b/spec/factories/lfs_objects.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: lfs_objects -# -# id :integer not null, primary key -# oid :string(255) not null -# size :integer not null -# created_at :datetime -# updated_at :datetime -# file :string(255) -# - include ActionDispatch::TestProcess FactoryGirl.define do diff --git a/spec/factories/lfs_objects_projects.rb b/spec/factories/lfs_objects_projects.rb index 50b45843c9910d..1ed0355c8e4fcb 100644 --- a/spec/factories/lfs_objects_projects.rb +++ b/spec/factories/lfs_objects_projects.rb @@ -1,14 +1,3 @@ -# == Schema Information -# -# Table name: lfs_objects_projects -# -# id :integer not null, primary key -# lfs_object_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :lfs_objects_project do lfs_object diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb index e281e2f227b6cb..c6a08d78b78f62 100644 --- a/spec/factories/merge_requests.rb +++ b/spec/factories/merge_requests.rb @@ -1,32 +1,3 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string(255) -# merge_status :string(255) -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# updated_by_id :integer -# merge_error :string(255) -# merge_params :text -# merge_when_build_succeeds :boolean default(FALSE), not null -# merge_user_id :integer -# merge_commit_sha :string -# - FactoryGirl.define do factory :merge_request do title diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb index e5dcb15901419e..c32e205ee69bb2 100644 --- a/spec/factories/notes.rb +++ b/spec/factories/notes.rb @@ -1,24 +1,3 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string(255) -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# commit_id :string(255) -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# updated_by_id :integer -# is_award :boolean default(FALSE), not null -# - require_relative '../support/repo_helpers' include ActionDispatch::TestProcess @@ -28,41 +7,39 @@ project note "Note" author + on_issue factory :note_on_commit, traits: [:on_commit] - factory :note_on_commit_diff, traits: [:on_commit, :on_diff] + factory :note_on_commit_diff, traits: [:on_commit, :on_diff], class: LegacyDiffNote factory :note_on_issue, traits: [:on_issue], aliases: [:votable_note] factory :note_on_merge_request, traits: [:on_merge_request] - factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff] + factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff], class: LegacyDiffNote factory :note_on_project_snippet, traits: [:on_project_snippet] factory :system_note, traits: [:system] factory :downvote_note, traits: [:award, :downvote] factory :upvote_note, traits: [:award, :upvote] trait :on_commit do - project + noteable nil + noteable_id nil + noteable_type 'Commit' commit_id RepoHelpers.sample_commit.id - noteable_type "Commit" end trait :on_diff do line_code "0_184_184" end - trait :on_merge_request do - project - noteable_id 1 - noteable_type "MergeRequest" + trait :on_issue do + noteable { create(:issue, project: project) } end - trait :on_issue do - noteable_id 1 - noteable_type "Issue" + trait :on_merge_request do + noteable { create(:merge_request, source_project: project) } end trait :on_project_snippet do - noteable_id 1 - noteable_type "Snippet" + noteable { create(:snippet, project: project) } end trait :system do diff --git a/spec/factories/oauth_access_tokens.rb b/spec/factories/oauth_access_tokens.rb index 7700b15d538199..ccf02d0719b1f4 100644 --- a/spec/factories/oauth_access_tokens.rb +++ b/spec/factories/oauth_access_tokens.rb @@ -1,18 +1,3 @@ -# == Schema Information -# -# Table name: oauth_access_tokens -# -# id :integer not null, primary key -# resource_owner_id :integer -# application_id :integer -# token :string not null -# refresh_token :string -# expires_in :integer -# revoked_at :datetime -# created_at :datetime not null -# scopes :string -# - FactoryGirl.define do factory :oauth_access_token do resource_owner diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index ecd0e44dd62aa5..da8d97c9f82c27 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -1,42 +1,3 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# creator_id :integer -# issues_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# namespace_id :integer -# issues_tracker :string(255) default("gitlab"), not null -# issues_tracker_id :string(255) -# snippets_enabled :boolean default(TRUE), not null -# last_activity_at :datetime -# import_url :string(255) -# visibility_level :integer default(0), not null -# archived :boolean default(FALSE), not null -# avatar :string(255) -# import_status :string(255) -# repository_size :float default(0.0) -# star_count :integer default(0), not null -# import_type :string(255) -# import_source :string(255) -# commit_count :integer default(0) -# import_error :text -# ci_id :integer -# builds_enabled :boolean default(TRUE), not null -# shared_runners_enabled :boolean default(TRUE), not null -# runners_token :string -# build_coverage_regex :string -# build_allow_git_fetch :boolean default(TRUE), not null -# build_timeout :integer default(3600), not null -# - FactoryGirl.define do # Project without repository # @@ -60,6 +21,12 @@ trait :private do visibility_level Gitlab::VisibilityLevel::PRIVATE end + + trait :empty_repo do + after(:create) do |project| + project.create_repository + end + end end # Project with empty repository @@ -67,9 +34,7 @@ # This is a case when you just created a project # but not pushed any code there yet factory :project_empty_repo, parent: :empty_project do - after :create do |project| - project.create_repository - end + empty_repo end # Project with test repository diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb index 7f331c37256aad..74497dc82c030b 100644 --- a/spec/factories/releases.rb +++ b/spec/factories/releases.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: releases -# -# id :integer not null, primary key -# tag :string(255) -# description :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# - FactoryGirl.define do factory :release do tag "v1.1.0" diff --git a/spec/factories/todos.rb b/spec/factories/todos.rb index 7ae06c278408ca..f426e27afedddc 100644 --- a/spec/factories/todos.rb +++ b/spec/factories/todos.rb @@ -1,21 +1,3 @@ -# == Schema Information -# -# Table name: todos -# -# id :integer not null, primary key -# user_id :integer not null -# project_id :integer not null -# target_id :integer -# target_type :string not null -# author_id :integer -# action :integer not null -# state :string not null -# created_at :datetime -# updated_at :datetime -# note_id :integer -# commit_id :string -# - FactoryGirl.define do factory :todo do project @@ -36,5 +18,9 @@ commit_id RepoHelpers.sample_commit.id target_type "Commit" end + + trait :build_failed do + action { Todo::BUILD_FAILED } + end end end diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb index 62de081661d651..675d9bd18b7aa9 100644 --- a/spec/factories_spec.rb +++ b/spec/factories_spec.rb @@ -5,8 +5,8 @@ describe "#{factory.name} factory" do let(:entity) { build(factory.name) } - it 'does not raise error when created 'do - expect { entity }.to_not raise_error + it 'does not raise error when created' do + expect { entity }.not_to raise_error end it 'should be valid', if: factory.build_class < ActiveRecord::Base do diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb index 2e9851fb4425a1..7bbe20fec43c47 100644 --- a/spec/features/admin/admin_builds_spec.rb +++ b/spec/features/admin/admin_builds_spec.rb @@ -19,6 +19,7 @@ visit admin_builds_path expect(page).to have_selector('.nav-links li.active', text: 'All') + expect(page).to have_selector('.row-content-block', text: 'All builds') expect(page.all('.build-link').size).to eq(4) expect(page).to have_link 'Cancel all' end diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb new file mode 100644 index 00000000000000..dec2dedf2b519a --- /dev/null +++ b/spec/features/admin/admin_health_check_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +feature "Admin Health Check", feature: true do + include WaitForAjax + + before do + login_as :admin + end + + describe '#show' do + before do + visit admin_health_check_path + end + + it { page.has_text? 'Health Check' } + it { page.has_text? 'Health information can be retrieved' } + + it 'has a health check access token' do + token = current_application_settings.health_check_access_token + expect(page).to have_content("Access token is #{token}") + expect(page).to have_selector('#health-check-token', text: token) + end + + describe 'reload access token', js: true do + it 'changes the access token' do + orig_token = current_application_settings.health_check_access_token + click_button 'Reset health check access token' + wait_for_ajax + expect(find('#health-check-token').text).not_to eq orig_token + end + end + end + + context 'when services are up' do + before do + visit admin_health_check_path + end + + it 'shows healthy status' do + expect(page).to have_content('Current Status: Healthy') + end + end + + context 'when a service is down' do + before do + allow(HealthCheck::Utils).to receive(:process_checks).and_return('The server is on fire') + visit admin_health_check_path + end + + it 'shows unhealthy status' do + expect(page).to have_content('Current Status: Unhealthy') + expect(page).to have_content('The server is on fire') + end + end +end diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 26d03944b8a24d..8ebd4a6808eef4 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -79,7 +79,7 @@ end it 'changes registration token' do - expect(page_token).to_not eq token + expect(page_token).not_to eq token end end end diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 4570e4091284ce..96621843b30940 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -152,7 +152,7 @@ it 'sees impersonation log out icon' do icon = first('.fa.fa-user-secret') - expect(icon).to_not eql nil + expect(icon).not_to eql nil end it 'can log out of impersonated user back to original user' do @@ -210,6 +210,8 @@ def expect_two_factor_status(status) before do fill_in "user_name", with: "Big Bang" fill_in "user_email", with: "bigbang@mail.com" + fill_in "user_password", with: "AValidPassword1" + fill_in "user_password_confirmation", with: "AValidPassword1" check "user_admin" click_button "Save changes" end @@ -223,6 +225,7 @@ def expect_two_factor_status(status) @simple_user.reload expect(@simple_user.name).to eq('Big Bang') expect(@simple_user.is_admin?).to be_truthy + expect(@simple_user.password_expires_at).to be <= Time.now end end end diff --git a/spec/features/builds_spec.rb b/spec/features/builds_spec.rb index 090a941958f901..7a05d30e8b51cc 100644 --- a/spec/features/builds_spec.rb +++ b/spec/features/builds_spec.rb @@ -46,7 +46,7 @@ it { expect(page).to have_content @build.short_sha } it { expect(page).to have_content @build.ref } it { expect(page).to have_content @build.name } - it { expect(page).to_not have_link 'Cancel running' } + it { expect(page).not_to have_link 'Cancel running' } end end @@ -62,7 +62,7 @@ it { expect(page).to have_content @build.short_sha } it { expect(page).to have_content @build.ref } it { expect(page).to have_content @build.name } - it { expect(page).to_not have_link 'Cancel running' } + it { expect(page).not_to have_link 'Cancel running' } end describe "GET /:project/builds/:id" do diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index dacaa96d76046b..20f0b27bcc136d 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -137,8 +137,8 @@ expect(page).to have_content commit.git_commit_message expect(page).to have_content commit.git_author_name expect(page).to have_link('Download artifacts') - expect(page).to_not have_link('Cancel running') - expect(page).to_not have_link('Retry failed') + expect(page).not_to have_link('Cancel running') + expect(page).not_to have_link('Retry failed') end end @@ -155,9 +155,9 @@ expect(page).to have_content commit.sha[0..7] expect(page).to have_content commit.git_commit_message expect(page).to have_content commit.git_author_name - expect(page).to_not have_link('Download artifacts') - expect(page).to_not have_link('Cancel running') - expect(page).to_not have_link('Retry failed') + expect(page).not_to have_link('Download artifacts') + expect(page).not_to have_link('Cancel running') + expect(page).not_to have_link('Retry failed') end end end diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb new file mode 100644 index 00000000000000..53b4f027117d3f --- /dev/null +++ b/spec/features/container_registry_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe "Container Registry" do + let(:project) { create(:empty_project) } + let(:repository) { project.container_registry_repository } + let(:tag_name) { 'latest' } + let(:tags) { [tag_name] } + + before do + login_as(:user) + project.team << [@user, :developer] + stub_container_registry_tags(*tags) + stub_container_registry_config(enabled: true) + allow(Auth::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token') + end + + describe 'GET /:project/container_registry' do + before do + visit namespace_project_container_registry_index_path(project.namespace, project) + end + + context 'when no tags' do + let(:tags) { [] } + + it { expect(page).to have_content('No images in Container Registry for this project') } + end + + context 'when there are tags' do + it { expect(page).to have_content(tag_name)} + end + end + + describe 'DELETE /:project/container_registry/tag' do + before do + visit namespace_project_container_registry_index_path(project.namespace, project) + end + + it do + expect_any_instance_of(::ContainerRegistry::Tag).to receive(:delete).and_return(true) + + click_on 'Remove' + end + end +end diff --git a/spec/features/issues/filter_issues_spec.rb b/spec/features/issues/filter_issues_spec.rb index 192e3619375c8e..7efbaaa048c5fc 100644 --- a/spec/features/issues/filter_issues_spec.rb +++ b/spec/features/issues/filter_issues_spec.rb @@ -154,4 +154,180 @@ end end end + + describe 'filter issues by text' do + before do + create(:issue, title: "Bug", project: project) + + bug_label = create(:label, project: project, title: 'bug') + milestone = create(:milestone, title: "8", project: project) + + issue = create(:issue, + title: "Bug 2", + project: project, + milestone: milestone, + author: user, + assignee: user) + issue.labels << bug_label + + visit namespace_project_issues_path(project.namespace, project) + end + + context 'only text', js: true do + it 'should filter issues by searched text' do + fill_in 'issue_search', with: 'Bug' + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 2) + end + end + + it 'should not show any issues' do + fill_in 'issue_search', with: 'testing' + + page.within '.issues-list' do + expect(page).not_to have_selector('.issue') + end + end + end + + context 'text and dropdown options', js: true do + it 'should filter by text and label' do + fill_in 'issue_search', with: 'Bug' + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 2) + end + + click_button 'Label' + page.within '.labels-filter' do + click_link 'bug' + end + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 1) + end + end + + it 'should filter by text and milestone' do + fill_in 'issue_search', with: 'Bug' + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 2) + end + + click_button 'Milestone' + page.within '.milestone-filter' do + click_link '8' + end + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 1) + end + end + + it 'should filter by text and assignee' do + fill_in 'issue_search', with: 'Bug' + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 2) + end + + click_button 'Assignee' + page.within '.dropdown-menu-assignee' do + click_link user.name + end + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 1) + end + end + + it 'should filter by text and author' do + fill_in 'issue_search', with: 'Bug' + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 2) + end + + click_button 'Author' + page.within '.dropdown-menu-author' do + click_link user.name + end + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 1) + end + end + end + end + + describe 'filter issues and sort', js: true do + before do + bug_label = create(:label, project: project, title: 'bug') + bug_one = create(:issue, title: "Frontend", project: project) + bug_two = create(:issue, title: "Bug 2", project: project) + + bug_one.labels << bug_label + bug_two.labels << bug_label + + visit namespace_project_issues_path(project.namespace, project) + end + + it 'should be able to filter and sort issues' do + click_button 'Label' + page.within '.labels-filter' do + click_link 'bug' + end + + page.within '.issues-list' do + expect(page).to have_selector('.issue', count: 2) + end + + click_button 'Last created' + page.within '.dropdown-menu-sort' do + click_link 'Oldest created' + end + + page.within '.issues-list' do + expect(first('.issue')).to have_content('Frontend') + end + end + end + + describe 'filter by any author', js: true do + before do + user2 = create(:user, name: "tester") + create(:issue, project: project, author: user) + create(:issue, project: project, author: user2) + + visit namespace_project_issues_path(project.namespace, project) + end + + it 'should show filter by any author link' do + click_button "Author" + fill_in "Search authors", with: "tester" + + page.within ".dropdown-menu-author" do + expect(page).to have_content "tester" + end + end + + it 'should show filter issues by any author' do + page.within '.issues-list' do + expect(page).to have_selector ".issue", count: 2 + end + + click_button "Author" + fill_in "Search authors", with: "tester" + + page.within ".dropdown-menu-author" do + click_link "tester" + end + + page.within '.issues-list' do + expect(page).to have_selector ".issue", count: 1 + end + end + end end diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index 84c8e20ebaa6d0..c7019c5aea1586 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -19,7 +19,7 @@ end scenario 'moving issue to another project not allowed' do - expect(page).to have_no_select('move_to_project_id') + expect(page).to have_no_selector('#move_to_project_id') end end @@ -37,7 +37,7 @@ end scenario 'moving issue to another project' do - select(new_project.name_with_namespace, from: 'move_to_project_id') + first('#move_to_project_id', visible: false).set(new_project.id) click_button('Save changes') expect(current_url).to include project_path(new_project) @@ -47,14 +47,18 @@ expect(page).to have_content(issue.title) end - context 'projects user does not have permission to move issue to exist' do + context 'user does not have permission to move the issue to a project', js: true do let!(:private_project) { create(:project, :private) } let(:another_project) { create(:project) } background { another_project.team << [user, :guest] } scenario 'browsing projects in projects select' do - options = [ '', 'No project', new_project.name_with_namespace ] - expect(page).to have_select('move_to_project_id', options: options) + click_link 'Select project' + + page.within '.select2-results' do + expect(page).to have_content 'No project' + expect(page).to have_content new_project.name_with_namespace + end end end @@ -65,7 +69,7 @@ end scenario 'user wants to move issue that has already been moved' do - expect(page).to have_no_select('move_to_project_id') + expect(page).to have_no_selector('#move_to_project_id') end end end diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb index e4efdbe2421d0d..f5cfe2d666ef93 100644 --- a/spec/features/issues/note_polling_spec.rb +++ b/spec/features/issues/note_polling_spec.rb @@ -9,8 +9,11 @@ end scenario 'Another user adds a comment to an issue', js: true do - note = create(:note_on_issue, noteable: issue, note: 'Looks good!') + note = create(:note, noteable: issue, project: project, + note: 'Looks good!') + page.execute_script('notes.refresh();') + expect(page).to have_selector("#note_#{note.id}", text: 'Looks good!') end end diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb index b03dd0f666df56..466a6f7dfa7075 100644 --- a/spec/features/issues/update_issues_spec.rb +++ b/spec/features/issues/update_issues_spec.rb @@ -95,7 +95,7 @@ find('.dropdown-menu-milestone a', text: "No Milestone").click click_update_issues_button - expect(first('.issue')).to_not have_content milestone.title + expect(first('.issue')).not_to have_content milestone.title end end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index d5755c293c53a7..9271964166a7dd 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -64,10 +64,68 @@ end end + describe 'due date', js: true do + context 'on new form' do + before do + visit new_namespace_project_issue_path(project.namespace, project) + end + + it 'should save with due date' do + date = Date.today.at_beginning_of_month + + fill_in 'issue_title', with: 'bug 345' + fill_in 'issue_description', with: 'bug description' + + page.within '.datepicker' do + click_link date.day + end + + expect(find('#issuable-due-date', visible: false).value).to eq date.to_s + + click_button 'Submit issue' + + page.within '.issuable-sidebar' do + expect(page).to have_content date.to_s(:medium) + end + end + end + + context 'on edit form' do + let(:issue) { create(:issue, author: @user,project: project, due_date: Date.today.at_beginning_of_month.to_s) } + + before do + visit edit_namespace_project_issue_path(project.namespace, project, issue) + end + + it 'should save with due date' do + date = Date.today.at_beginning_of_month + + expect(find('#issuable-due-date', visible: false).value).to eq date.to_s + + date = date.tomorrow + + fill_in 'issue_title', with: 'bug 345' + fill_in 'issue_description', with: 'bug description' + + page.within '.datepicker' do + click_link date.day + end + + expect(find('#issuable-due-date', visible: false).value).to eq date.to_s + + click_button 'Save changes' + + page.within '.issuable-sidebar' do + expect(page).to have_content date.to_s(:medium) + end + end + end + end + describe 'Issue info' do it 'excludes award_emoji from comment count' do issue = create(:issue, author: @user, assignee: @user, project: project, title: 'foobar') - create(:upvote_note, noteable: issue) + create(:upvote_note, noteable: issue, project: project) visit namespace_project_issues_path(project.namespace, project, assignee_id: @user.id) @@ -331,7 +389,7 @@ page.within '.assignee' do click_link 'Edit' end - + page.within '.dropdown-menu-user' do click_link @user.name end @@ -431,6 +489,43 @@ end end + describe 'due date' do + context 'update due on issue#show', js: true do + let(:issue) { create(:issue, project: project, author: @user, assignee: @user) } + + before do + visit namespace_project_issue_path(project.namespace, project, issue) + end + + it 'should add due date to issue' do + page.within '.due_date' do + click_link 'Edit' + + page.within '.ui-datepicker-calendar' do + first('.ui-state-default').click + end + + expect(page).to have_no_content 'None' + end + end + + it 'should remove due date from issue' do + page.within '.due_date' do + click_link 'Edit' + + page.within '.ui-datepicker-calendar' do + first('.ui-state-default').click + end + + expect(page).to have_no_content 'None' + + click_link 'remove due date' + expect(page).to have_content 'None' + end + end + end + end + def first_issue page.all('ul.issues-list > li').first.text end diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb index 8c38dd5b122eec..c1b178c3b6ceff 100644 --- a/spec/features/login_spec.rb +++ b/spec/features/login_spec.rb @@ -32,7 +32,7 @@ let(:user) { create(:user, :two_factor) } before do - login_with(user) + login_with(user, remember: true) expect(page).to have_content('Two-factor Authentication') end @@ -52,6 +52,12 @@ def enter_code(code) expect(current_path).to eq root_path end + it 'persists remember_me value via hidden field' do + field = first('input#user_remember_me', visible: false) + + expect(field.value).to eq '1' + end + it 'blocks login with invalid code' do enter_code('foo') expect(page).to have_content('Invalid two-factor code') @@ -121,7 +127,7 @@ def enter_code(code) user = create(:user, password: 'not-the-default') login_with(user) - expect(page).to have_content('Invalid login or password.') + expect(page).to have_content('Invalid Login or password.') end end diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 0148c87084a6bc..1d892fe1a55b85 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -278,6 +278,10 @@ def doc(html = @html) it 'includes GollumTagsFilter' do expect(doc).to parse_gollum_tags end + + it 'includes InlineDiffFilter' do + expect(doc).to parse_inline_diffs + end end # Fake a `current_user` helper diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb new file mode 100644 index 00000000000000..edc0bdec3db537 --- /dev/null +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +feature 'Merge request created from fork' do + given(:user) { create(:user) } + given(:project) { create(:project, :public) } + given(:fork_project) { create(:project, :public) } + + given!(:merge_request) do + create(:forked_project_link, forked_to_project: fork_project, + forked_from_project: project) + + create(:merge_request_with_diffs, source_project: fork_project, + target_project: project, + description: 'Test merge request') + end + + background do + fork_project.team << [user, :master] + login_as user + end + + scenario 'user can access merge request' do + visit_merge_request(merge_request) + + expect(page).to have_content 'Test merge request' + end + + context 'pipeline present in source project' do + include WaitForAjax + + given(:pipeline) do + create(:ci_commit_with_two_jobs, project: fork_project, + sha: merge_request.last_commit.id, + ref: merge_request.source_branch) + end + + background { pipeline.create_builds(user) } + + scenario 'user visits a pipelines page', js: true do + visit_merge_request(merge_request) + page.within('.merge-request-tabs') { click_link 'Builds' } + wait_for_ajax + + page.within('table.builds') do + expect(page).to have_content 'rspec' + expect(page).to have_content 'spinach' + end + + expect(find_link('Cancel running')[:href]) + .to include fork_project.path_with_namespace + end + end + + def visit_merge_request(mr) + visit namespace_project_merge_request_path(project.namespace, + project, mr) + end +end diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb new file mode 100644 index 00000000000000..1c130057c5693a --- /dev/null +++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb @@ -0,0 +1,161 @@ +require 'spec_helper' + +describe 'Projects > Merge requests > User lists merge requests', feature: true do + include SortingHelper + + let(:project) { create(:project, :public) } + let(:user) { create(:user) } + + before do + @fix = create(:merge_request, + title: 'fix', + source_project: project, + source_branch: 'fix', + assignee: user, + milestone: create(:milestone, due_date: '2013-12-11'), + created_at: 1.minute.ago, + updated_at: 1.minute.ago) + create(:merge_request, + title: 'markdown', + source_project: project, + source_branch: 'markdown', + assignee: user, + milestone: create(:milestone, due_date: '2013-12-12'), + created_at: 2.minutes.ago, + updated_at: 2.minutes.ago) + create(:merge_request, + title: 'lfs', + source_project: project, + source_branch: 'lfs', + created_at: 3.minutes.ago, + updated_at: 10.seconds.ago) + end + + it 'filters on no assignee' do + visit_merge_requests(project, assignee_id: IssuableFinder::NONE) + + expect(current_path).to eq(namespace_project_merge_requests_path(project.namespace, project)) + expect(page).to have_content 'lfs' + expect(page).not_to have_content 'fix' + expect(page).not_to have_content 'markdown' + expect(count_merge_requests).to eq(1) + end + + it 'filters on a specific assignee' do + visit_merge_requests(project, assignee_id: user.id) + + expect(page).not_to have_content 'lfs' + expect(page).to have_content 'fix' + expect(page).to have_content 'markdown' + expect(count_merge_requests).to eq(2) + end + + it 'sorts by newest' do + visit_merge_requests(project, sort: sort_value_recently_created) + + expect(first_merge_request).to include('lfs') + expect(last_merge_request).to include('fix') + expect(count_merge_requests).to eq(3) + end + + it 'sorts by oldest' do + visit_merge_requests(project, sort: sort_value_oldest_created) + + expect(first_merge_request).to include('fix') + expect(last_merge_request).to include('lfs') + expect(count_merge_requests).to eq(3) + end + + it 'sorts by last updated' do + visit_merge_requests(project, sort: sort_value_recently_updated) + + expect(first_merge_request).to include('lfs') + expect(count_merge_requests).to eq(3) + end + + it 'sorts by oldest updated' do + visit_merge_requests(project, sort: sort_value_oldest_updated) + + expect(first_merge_request).to include('markdown') + expect(count_merge_requests).to eq(3) + end + + it 'sorts by milestone due soon' do + visit_merge_requests(project, sort: sort_value_milestone_soon) + + expect(first_merge_request).to include('fix') + expect(count_merge_requests).to eq(3) + end + + it 'sorts by milestone due later' do + visit_merge_requests(project, sort: sort_value_milestone_later) + + expect(first_merge_request).to include('markdown') + expect(count_merge_requests).to eq(3) + end + + it 'filters on one label and sorts by due soon' do + label = create(:label, project: project) + create(:label_link, label: label, target: @fix) + + visit_merge_requests(project, label_name: [label.name], + sort: sort_value_due_date_soon) + + expect(first_merge_request).to include('fix') + expect(count_merge_requests).to eq(1) + end + + context 'while filtering on two labels' do + let(:label) { create(:label, project: project) } + let(:label2) { create(:label, project: project) } + + before do + create(:label_link, label: label, target: @fix) + create(:label_link, label: label2, target: @fix) + end + + it 'sorts by due soon' do + visit_merge_requests(project, label_name: [label.name, label2.name], + sort: sort_value_due_date_soon) + + expect(first_merge_request).to include('fix') + expect(count_merge_requests).to eq(1) + end + + context 'filter on assignee and' do + it 'sorts by due soon' do + visit_merge_requests(project, label_name: [label.name, label2.name], + assignee_id: user.id, + sort: sort_value_due_date_soon) + + expect(first_merge_request).to include('fix') + expect(count_merge_requests).to eq(1) + end + + it 'sorts by recently due milestone' do + visit namespace_project_merge_requests_path(project.namespace, project, + label_name: [label.name, label2.name], + assignee_id: user.id, + sort: sort_value_milestone_soon) + + expect(first_merge_request).to include('fix') + end + end + end + + def visit_merge_requests(project, opts = {}) + visit namespace_project_merge_requests_path(project.namespace, project, opts) + end + + def first_merge_request + page.all('ul.mr-list > li').first.text + end + + def last_merge_request + page.all('ul.mr-list > li').last.text + end + + def count_merge_requests + page.all('ul.mr-list > li').count + end +end diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb index 389812ff7e1c06..2835cf44494920 100644 --- a/spec/features/notes_on_merge_requests_spec.rb +++ b/spec/features/notes_on_merge_requests_spec.rb @@ -19,10 +19,14 @@ end describe 'On a merge request', js: true, feature: true do - let!(:merge_request) { create(:merge_request) } - let!(:project) { merge_request.source_project } + let!(:project) { create(:project) } + let!(:merge_request) do + create(:merge_request, source_project: project, target_project: project) + end + let!(:note) do - create(:note_on_merge_request, :with_attachment, project: project) + create(:note_on_merge_request, :with_attachment, noteable: merge_request, + project: project) end before do @@ -192,7 +196,7 @@ end it 'should be removed when canceled' do - page.within(".diff-file form[id$='#{line_code}']") do + page.within(".diff-file form[id$='#{line_code}-true']") do find('.js-close-discussion-note-form').trigger('click') end diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index 1adab7e9c6c3ef..c7c00a3266a32c 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -32,7 +32,8 @@ context 'adding a new note on a Issue', js: true do before do issue = create(:issue, author: author, project: project) - create(:note, note: 'Ultralight Beam', noteable: issue, author: participant) + create(:note, note: 'Ultralight Beam', noteable: issue, + project: project, author: participant) visit_issue(project, issue) end @@ -47,7 +48,8 @@ context 'adding a new note on a Merge Request ', js: true do before do merge = create(:merge_request, source_project: project, target_project: project, author: author) - create(:note, note: 'Ultralight Beam', noteable: merge, author: participant) + create(:note, note: 'Ultralight Beam', noteable: merge, + project: project, author: participant) visit_merge_request(project, merge) end diff --git a/spec/features/pipelines_spec.rb b/spec/features/pipelines_spec.rb new file mode 100644 index 00000000000000..acd6fb3538c6c8 --- /dev/null +++ b/spec/features/pipelines_spec.rb @@ -0,0 +1,189 @@ +require 'spec_helper' + +describe "Pipelines" do + include GitlabRoutingHelper + + let(:project) { create(:empty_project) } + let(:user) { create(:user) } + + before do + login_as(user) + project.team << [user, :developer] + end + + describe 'GET /:project/pipelines' do + let!(:pipeline) { create(:ci_commit, project: project, ref: 'master', status: 'running') } + + [:all, :running, :branches].each do |scope| + context "displaying #{scope}" do + let(:project) { create(:project) } + + before { visit namespace_project_pipelines_path(project.namespace, project, scope: scope) } + + it { expect(page).to have_content(pipeline.short_sha) } + end + end + + context 'anonymous access' do + before { visit namespace_project_pipelines_path(project.namespace, project) } + + it { expect(page).to have_http_status(:success) } + end + + context 'cancelable pipeline' do + let!(:running) { create(:ci_build, :running, commit: pipeline, stage: 'test', commands: 'test') } + + before { visit namespace_project_pipelines_path(project.namespace, project) } + + it { expect(page).to have_link('Cancel') } + it { expect(page).to have_selector('.ci-running') } + + context 'when canceling' do + before { click_link('Cancel') } + + it { expect(page).not_to have_link('Cancel') } + it { expect(page).to have_selector('.ci-canceled') } + end + end + + context 'retryable pipelines' do + let!(:failed) { create(:ci_build, :failed, commit: pipeline, stage: 'test', commands: 'test') } + + before { visit namespace_project_pipelines_path(project.namespace, project) } + + it { expect(page).to have_link('Retry') } + it { expect(page).to have_selector('.ci-failed') } + + context 'when retrying' do + before { click_link('Retry') } + + it { expect(page).not_to have_link('Retry') } + it { expect(page).to have_selector('.ci-pending') } + end + end + + context 'for generic statuses' do + context 'when running' do + let!(:running) { create(:generic_commit_status, status: 'running', commit: pipeline, stage: 'test') } + + before { visit namespace_project_pipelines_path(project.namespace, project) } + + it 'not be cancelable' do + expect(page).not_to have_link('Cancel') + end + + it 'pipeline is running' do + expect(page).to have_selector('.ci-running') + end + end + + context 'when failed' do + let!(:running) { create(:generic_commit_status, status: 'failed', commit: pipeline, stage: 'test') } + + before { visit namespace_project_pipelines_path(project.namespace, project) } + + it 'not be retryable' do + expect(page).not_to have_link('Retry') + end + + it 'pipeline is failed' do + expect(page).to have_selector('.ci-failed') + end + end + end + + context 'downloadable pipelines' do + context 'with artifacts' do + let!(:with_artifacts) { create(:ci_build, :artifacts, :success, commit: pipeline, name: 'rspec tests', stage: 'test') } + + before { visit namespace_project_pipelines_path(project.namespace, project) } + + it { expect(page).to have_selector('.build-artifacts') } + it { expect(page).to have_link(with_artifacts.name) } + end + + context 'without artifacts' do + let!(:without_artifacts) { create(:ci_build, :success, commit: pipeline, name: 'rspec', stage: 'test') } + + it { expect(page).not_to have_selector('.build-artifacts') } + end + end + end + + describe 'GET /:project/pipelines/:id' do + let(:pipeline) { create(:ci_commit, project: project, ref: 'master') } + + before do + @success = create(:ci_build, :success, commit: pipeline, stage: 'build', name: 'build') + @failed = create(:ci_build, :failed, commit: pipeline, stage: 'test', name: 'test', commands: 'test') + @running = create(:ci_build, :running, commit: pipeline, stage: 'deploy', name: 'deploy') + @external = create(:generic_commit_status, status: 'success', commit: pipeline, name: 'jenkins', stage: 'external') + end + + before { visit namespace_project_pipeline_path(project.namespace, project, pipeline) } + + it 'showing a list of builds' do + expect(page).to have_content('Tests') + expect(page).to have_content(@success.id) + expect(page).to have_content('Deploy') + expect(page).to have_content(@failed.id) + expect(page).to have_content(@running.id) + expect(page).to have_content(@external.id) + expect(page).to have_content('Retry failed') + expect(page).to have_content('Cancel running') + end + + context 'retrying builds' do + it { expect(page).not_to have_content('retried') } + + context 'when retrying' do + before { click_on 'Retry failed' } + + it { expect(page).not_to have_content('Retry failed') } + it { expect(page).to have_content('retried') } + end + end + + context 'canceling builds' do + it { expect(page).not_to have_selector('.ci-canceled') } + + context 'when canceling' do + before { click_on 'Cancel running' } + + it { expect(page).not_to have_content('Cancel running') } + it { expect(page).to have_selector('.ci-canceled') } + end + end + end + + describe 'POST /:project/pipelines' do + let(:project) { create(:project) } + + before { visit new_namespace_project_pipeline_path(project.namespace, project) } + + context 'for valid commit' do + before { fill_in('Create for', with: 'master') } + + context 'with gitlab-ci.yml' do + before { stub_ci_commit_to_return_yaml_file } + + it { expect{ click_on 'Create pipeline' }.to change{ Ci::Commit.count }.by(1) } + end + + context 'without gitlab-ci.yml' do + before { click_on 'Create pipeline' } + + it { expect(page).to have_content('Missing .gitlab-ci.yml file') } + end + end + + context 'for invalid commit' do + before do + fill_in('Create for', with: 'invalid reference') + click_on 'Create pipeline' + end + + it { expect(page).to have_content('Reference not found') } + end + end +end diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb index 13c9b95b3169a3..51be81d634c17e 100644 --- a/spec/features/projects/badges/list_spec.rb +++ b/spec/features/projects/badges/list_spec.rb @@ -8,12 +8,10 @@ project = create(:project) project.team << [user, :master] login_as(user) - visit edit_namespace_project_path(project.namespace, project) + visit namespace_project_badges_path(project.namespace, project) end scenario 'user displays list of badges' do - click_link 'Badges' - expect(page).to have_content 'build status' expect(page).to have_content 'Markdown' expect(page).to have_content 'HTML' @@ -26,7 +24,6 @@ end scenario 'user changes current ref on badges list page', js: true do - click_link 'Badges' select2('improve/awesome', from: '#ref') expect(page).to have_content 'badges/improve/awesome/build.svg' diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb new file mode 100644 index 00000000000000..0c51fe72ca4e4b --- /dev/null +++ b/spec/features/projects/developer_views_empty_project_instructions_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +feature 'Developer views empty project instructions', feature: true do + let(:project) { create(:empty_project, :empty_repo) } + let(:developer) { create(:user) } + + background do + project.team << [developer, :developer] + + login_as(developer) + end + + context 'without an SSH key' do + scenario 'defaults to HTTP' do + visit_project + + expect_instructions_for('http') + end + + scenario 'switches to SSH', js: true do + visit_project + + select_protocol('SSH') + + expect_instructions_for('ssh') + end + end + + context 'with an SSH key' do + background do + create(:personal_key, user: developer) + end + + scenario 'defaults to SSH' do + visit_project + + expect_instructions_for('ssh') + end + + scenario 'switches to HTTP', js: true do + visit_project + + select_protocol('HTTP') + + expect_instructions_for('http') + end + end + + def visit_project + visit namespace_project_path(project.namespace, project) + end + + def select_protocol(protocol) + find('#clone-dropdown').click + find(".#{protocol.downcase}-selector").click + end + + def expect_instructions_for(protocol) + msg = :"#{protocol.downcase}_url_to_repo" + + expect(page).to have_content("git clone #{project.send(msg)}") + end +end diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb new file mode 100644 index 00000000000000..073a83b6896431 --- /dev/null +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +feature 'User wants to add a .gitignore file', feature: true do + include WaitForAjax + + before do + user = create(:user) + project = create(:project) + project.team << [user, :master] + login_as user + visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitignore') + end + + scenario 'user can see .gitignore dropdown' do + expect(page).to have_css('.gitignore-selector') + end + + scenario 'user can pick a .gitignore file from the dropdown', js: true do + find('.js-gitignore-selector').click + wait_for_ajax + within '.gitignore-selector' do + find('.dropdown-input-field').set('rails') + find('.dropdown-content li', text: 'Rails').click + end + wait_for_ajax + + expect(page).to have_content('/.bundle') + expect(page).to have_content('# Gemfile.lock, .ruby-version, .ruby-gemset') + end +end 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 3d6ffbc4c6bc97..ecc818eb1e151c 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 @@ file_content = find('.file-content') expect(file_content).to have_content('The MIT License (MIT)') - expect(file_content).to have_content("Copyright (c) 2016 #{project.namespace.human_name}") + 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 click_button 'Commit Changes' @@ -33,7 +33,7 @@ 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("Copyright (c) 2016 #{project.namespace.human_name}") + expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end scenario 'project master creates a license file from the "Add license" link' do @@ -48,7 +48,7 @@ file_content = find('.file-content') expect(file_content).to have_content('The MIT License (MIT)') - expect(file_content).to have_content("Copyright (c) 2016 #{project.namespace.human_name}") + 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 click_button 'Commit Changes' @@ -56,6 +56,6 @@ 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("Copyright (c) 2016 #{project.namespace.human_name}") + expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end 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 3268e240200e6a..34eda29c2852a0 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 @@ file_content = find('.file-content') expect(file_content).to have_content('The MIT License (MIT)') - expect(file_content).to have_content("Copyright (c) 2016 #{project.namespace.human_name}") + 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 # Remove pre-receive hook so we can push without auth @@ -34,6 +34,6 @@ 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("Copyright (c) 2016 #{project.namespace.human_name}") + expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end end diff --git a/spec/features/project/shortcuts_spec.rb b/spec/features/projects/shortcuts_spec.rb similarity index 79% rename from spec/features/project/shortcuts_spec.rb rename to spec/features/projects/shortcuts_spec.rb index 2595c4181e5ed8..54aa9c66a08cf7 100644 --- a/spec/features/project/shortcuts_spec.rb +++ b/spec/features/projects/shortcuts_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' feature 'Project shortcuts', feature: true do - let(:project) { create(:project) } + let(:project) { create(:project, name: 'Victorialand') } let(:user) { create(:user) } describe 'On a project', js: true do @@ -14,7 +14,7 @@ describe 'pressing "i"' do it 'redirects to new issue page' do find('body').native.send_key('i') - expect(page).to have_content('New Issue') + expect(page).to have_content('Victorialand') end end end diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index 8edeb8d18af91e..a5ed3595b0a441 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -29,8 +29,8 @@ end before do - expect(page).to_not have_content(@specific_runner3.display_name) - expect(page).to_not have_content(@specific_runner3.display_name) + expect(page).not_to have_content(@specific_runner3.display_name) + expect(page).not_to have_content(@specific_runner3.display_name) end it "places runners in right places" do @@ -110,4 +110,37 @@ expect(page).to have_content(@specific_runner.platform) end end + + feature 'configuring runners ability to picking untagged jobs' do + given(:project) { create(:empty_project) } + given(:runner) { create(:ci_runner) } + + background do + project.team << [user, :master] + project.runners << runner + end + + scenario 'user checks default configuration' do + visit namespace_project_runner_path(project.namespace, project, runner) + + expect(page).to have_content 'Can run untagged jobs Yes' + end + + context 'when runner has tags' do + before { runner.update_attribute(:tag_list, ['tag']) } + + scenario 'user wants to prevent runner from running untagged job' do + visit runners_path(project) + page.within('.activated-specific-runners') do + first('small > a').click + end + + uncheck 'runner_run_untagged' + click_button 'Save changes' + + expect(page).to have_content 'Can run untagged jobs No' + expect(runner.reload.run_untagged?).to eq false + end + end + end end diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb index 58aabd913ebcb1..4229e82b4438c5 100644 --- a/spec/features/signup_spec.rb +++ b/spec/features/signup_spec.rb @@ -2,20 +2,45 @@ feature 'Signup', feature: true do describe 'signup with no errors' do - it 'creates the user account and sends a confirmation email' do - user = build(:user) - visit root_path + context "when sending confirmation email" do + before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true) } - fill_in 'new_user_name', with: user.name - fill_in 'new_user_username', with: user.username - fill_in 'new_user_email', with: user.email - fill_in 'new_user_password', with: user.password - click_button "Sign up" + it 'creates the user account and sends a confirmation email' do + user = build(:user) + + visit root_path + + fill_in 'new_user_name', with: user.name + fill_in 'new_user_username', with: user.username + fill_in 'new_user_email', with: user.email + fill_in 'new_user_password', with: user.password + click_button "Sign up" - expect(current_path).to eq users_almost_there_path - expect(page).to have_content("Please check your email to confirm your account") + expect(current_path).to eq users_almost_there_path + expect(page).to have_content("Please check your email to confirm your account") + end end + + context "when not sending confirmation email" do + before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false) } + + it 'creates the user account and goes to dashboard' do + user = build(:user) + + visit root_path + + fill_in 'new_user_name', with: user.name + fill_in 'new_user_username', with: user.username + fill_in 'new_user_email', with: user.email + fill_in 'new_user_password', with: user.password + click_button "Sign up" + + expect(current_path).to eq dashboard_projects_path + expect(page).to have_content("Welcome! You have signed up successfully.") + end + end + end describe 'signup with errors' do diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb new file mode 100644 index 00000000000000..08a97085a9c9e5 --- /dev/null +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +feature 'Master creates tag', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, namespace: user.namespace) } + + before do + project.team << [user, :master] + login_with(user) + visit namespace_project_tags_path(project.namespace, project) + end + + scenario 'with an invalid name displays an error' do + create_tag_in_form(tag: 'v 1.0', ref: 'master') + + expect(page).to have_content 'Tag name invalid' + end + + scenario 'with an invalid reference displays an error' do + create_tag_in_form(tag: 'v2.0', ref: 'foo') + + expect(page).to have_content 'Target foo is invalid' + end + + scenario 'that already exists displays an error' do + create_tag_in_form(tag: 'v1.1.0', ref: 'master') + + expect(page).to have_content 'Tag v1.1.0 already exists' + end + + scenario 'with multiline message displays the message in a

    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%0AyTt_yOm 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

    1qR!S6^`Zw3 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%0A!eQwyL26g)jh2{j4v+V-J86+ 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

    NmpERPAlQoRSIb{#0>KR3q6OZbg{;~X*Z1#55 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 Z{=bj$@9Ig1XU_j;J|gv*iNS+|0RTUZZOs4x -- GitLab From 28ba2176dc02563761df00dd48434158685d1daf Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 13:19:41 +0200 Subject: [PATCH 122/714] fix issue restoring repo --- lib/gitlab/import_export/repo_restorer.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index dc45238bf2a6ae..9417393ecd1b67 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,18 +3,20 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project:, path_to_bundle: ) + def initialize(project:, path_to_bundle:) @project = project @path_to_bundle = path_to_bundle end def restore - return true unless File.exists?(@path) + return true unless File.exists?(@path_to_bundle) FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path: path_to_repo, bundle_path: @path_to_bundle) + rescue + false end private -- GitLab From f11920e21d35d8b34b9206a7ddf37422ca1914fa Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 14:21:27 +0200 Subject: [PATCH 123/714] more fixes - restoring repo --- lib/gitlab/import_export/import_service.rb | 4 ++-- lib/gitlab/import_export/repo_restorer.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index a4555699ff2bf6..ae5a878d637d12 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -45,11 +45,11 @@ def path_with_namespace end def repo_path - File.join('storage_path', 'project.bundle') + File.join(storage_path, 'project.bundle') end def wiki_repo_path - File.join('storage_path', 'project.wiki.bundle') + File.join(storage_path, 'project.wiki.bundle') end end end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 9417393ecd1b67..7a4cda828b4705 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -14,7 +14,7 @@ def restore FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(path_to_repo) - git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path: path_to_repo, bundle_path: @path_to_bundle) + git_unbundle(repo_path: path_to_repo, bundle_path: @path_to_bundle) rescue false end -- GitLab From 9c60eca87fe30d34e29d26d667a9235912dcbe7e Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 15:23:59 +0200 Subject: [PATCH 124/714] fix wiki import --- lib/gitlab/import_export/import_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index ae5a878d637d12..31b77981badc02 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -33,7 +33,7 @@ def restore_repo end def restore_wiki_repo - Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, project: project_tree.project).restore + Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, project: ProjectWiki.new(project_tree.project)).restore end def storage_path -- GitLab From 2a135866a24170e1db106885d4134e33141c07dd Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 16:24:09 +0200 Subject: [PATCH 125/714] added more tests to integration spec --- .../projects/import_export/import_file_spec.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index b9173e44554518..a7da7a21ea8765 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -7,6 +7,7 @@ let!(:namespace) { create(:namespace, name: "asd", owner: user) } 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 } background do allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) login_as(user) @@ -32,8 +33,15 @@ click_on 'Continue to the next step' # import starts - expect(Project.last).not_to be_nil - expect(Project.last.issues).not_to be_empty - expect(Project.last.repo_exists?).to be true + expect(project).not_to be_nil + expect(project.issues).not_to be_empty + expect(project.merge_requests).not_to be_empty + expect(project.repo_exists?).to be true + expect(wiki_exists?).to be true + end + + def wiki_exists? + wiki = ProjectWiki.new(project) + File.exists?(wiki.repository.path_to_repo) && !wiki.repository.empty? end end -- GitLab From 9f5dd2de4e85eba70cd469b36db1c19988c3603f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 5 May 2016 18:12:24 +0200 Subject: [PATCH 126/714] handling errors a bit better on import failure --- app/workers/project_import_worker.rb | 18 +++++++++--------- lib/gitlab/import_export/import_service.rb | 14 ++++++++++---- .../import_export/project_tree_restorer.rb | 4 +++- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/workers/project_import_worker.rb b/app/workers/project_import_worker.rb index aaa59f79d7f901..cc75da704f6498 100644 --- a/app/workers/project_import_worker.rb +++ b/app/workers/project_import_worker.rb @@ -11,15 +11,15 @@ def perform(current_user_id, tmp_file, namespace_id, path) owner: current_user, namespace_id: namespace_id, project_path: path) + if project + project.repository.after_import + project.import_finish + else + logger.error("There was an error during the import: #{tmpfile}") + end + end - # TODO: Move this to import service - # if result[:status] == :error - # project.update(import_error: result[:message]) - # project.import_fail - # return - # end - - project.repository.after_import - project.import_finish + def logger + Sidekiq.logger end end diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 31b77981badc02..99fb9bad78d870 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -14,7 +14,8 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) end def execute - Gitlab::ImportExport::Importer.import(archive_file: @archive_file, storage_path: storage_path) + Gitlab::ImportExport::Importer.import(archive_file: @archive_file, + storage_path: storage_path) project_tree.project if [restore_project_tree, restore_repo, restore_wiki_repo].all? end @@ -25,15 +26,20 @@ def restore_project_tree end def project_tree - @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, user: @current_user, project_path: @project_path, namespace_id: @namespace.id) + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, + user: @current_user, + project_path: @project_path, + namespace_id: @namespace.id) end def restore_repo - Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path, project: project_tree.project).restore + Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path, + project: project_tree.project).restore end def restore_wiki_repo - Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, project: ProjectWiki.new(project_tree.project)).restore + Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, + project: ProjectWiki.new(project_tree.project)).restore end def storage_path diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 0bc23dfaa24501..7aa0ff46cde088 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -14,6 +14,8 @@ def restore @tree_hash = ActiveSupport::JSON.decode(json) @project_members = @tree_hash.delete('project_members') create_relations + rescue + false end def project @@ -50,7 +52,7 @@ def create_project project_params: project_params, user: @user, namespace_id: @namespace_id) project.path = @project_path project.name = @project_path - project.save + project.save! project end -- GitLab From ce598b05414d52b31437dbe19412eb6a9a16f1b5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 6 May 2016 13:40:02 +0200 Subject: [PATCH 127/714] fixed and refactored a few things based on MR feedback --- .../projects/import_export/export_service.rb | 5 +- lib/gitlab/import_export.rb | 2 +- lib/gitlab/import_export/command_line_util.rb | 27 ++++----- lib/gitlab/import_export/import_export.yml | 24 ++++---- .../import_export/import_export_reader.rb | 26 ++++---- .../import_export/project_tree_saver.rb | 12 ++-- .../import_export_reader_spec.rb | 4 +- .../import_export/project_tree_saver_spec.rb | 60 ++++++++++--------- .../gitlab/import_export/repo_bundler_spec.rb | 8 +-- .../import_export/wiki_repo_bundler_spec.rb | 8 +-- spec/support/import_export/import_export.yml | 16 ++--- 11 files changed, 92 insertions(+), 100 deletions(-) diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 47ceff18af6248..fd569e1c9ae23e 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -5,10 +5,7 @@ class ExportService < BaseService def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) # TODO handle errors - save_project_tree - bundle_repo - bundle_wiki_repo - save_all + save_all if [save_project_tree, bundle_repo, bundle_wiki_repo].all? end private diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 539eae13f33d05..aa69f7c44a59de 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -6,7 +6,7 @@ def export_path(relative_path:) File.join(storage_path, relative_path) end - def project_atts + def project_attributes %i(name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) end diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 5ff72f5ff8d3a1..4a1018072c667c 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -1,36 +1,31 @@ module Gitlab module ImportExport module CommandLineUtil - def tar_cf(archive:, dir:) - tar_with_options(archive: archive, dir: dir, options: 'cf') + def tar_czf(archive:, dir:) + tar_with_options(archive: archive, dir: dir, options: 'czf') end def untar_zxf(archive:, dir:) untar_with_options(archive: archive, dir: dir, options: 'zxf') end - def untar_xf(archive:, dir:) - untar_with_options(archive: archive, dir: dir, options: 'xf') - end - - def tar_czf(archive:, dir:) - tar_with_options(archive: archive, dir: dir, options: 'czf') + def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) + execute(%W(#{git_bin_path} --git-dir=#{repo_path} bundle create #{bundle_path} --all)) end - def git_bundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) - cmd = %W(#{git_bin_path} --git-dir=#{repo_path} bundle create #{bundle_path} --all) - _output, status = Gitlab::Popen.popen(cmd) - status.zero? + def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_path:) + execute(%W(#{git_bin_path} clone --bare #{bundle_path} #{repo_path})) end def tar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive} -C #{dir} .) - _output, status = Gitlab::Popen.popen(cmd) - status.zero? + execute(%W(tar -#{options} #{archive} -C #{dir} .)) end def untar_with_options(archive:, dir:, options:) - cmd = %W(tar -#{options} #{archive} -C #{dir}) + execute(%W(tar -#{options} #{archive} -C #{dir})) + end + + def execute(cmd) _output, status = Gitlab::Popen.popen(cmd) status.zero? end diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 92f492e9013af9..ca433e72d5f000 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -1,22 +1,23 @@ -# Class relationships to be included in the project import/export -:project_tree: - - :issues: +# Model relationships to be included in the project import/export +project_tree: + - issues: - :notes - :labels - :milestones - :snippets - :releases - :events - - :project_members: + - project_members: - :user - - :merge_requests: + - merge_requests: - :merge_request_diff - :notes - - :ci_commits: + - ci_commits: - :statuses -:attributes_only: - :project: +# Only include the following attributes for the models specified. +included_attributes: + project: - :name - :path - :description @@ -27,11 +28,12 @@ - :snippets_enabled - :visibility_level - :archived - :user: + user: - :id - :email - :username -:attributes_except: - :snippets: +# Do not include the following attributes for the models specified. +excluded_attributes: + snippets: - :expired_at \ No newline at end of file diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 14049cb1bd2fb7..77db6cabe3853c 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -4,7 +4,7 @@ module ImportExportReader extend self def project_tree - { only: atts_only[:project], include: build_hash(tree) } + { only: included_attributes[:project], include: build_hash(tree) } end def tree @@ -14,24 +14,24 @@ def tree private def config - @config ||= YAML.load_file('lib/gitlab/import_export/import_export.yml') + @config ||= YAML.load_file('lib/gitlab/import_export/import_export.yml').with_indifferent_access end - def atts_only - config[:attributes_only] + def included_attributes + config[:included_attributes] || {} end - def atts_except - config[:attributes_except] + def excluded_attributes + config[:excluded_attributes] || {} end def build_hash(array) - array.map do |el| - if el.is_a?(Hash) - process_include(el) + array.map do |model_object| + if model_object.is_a?(Hash) + process_include(model_object) else - only_except_hash = check_only_and_except(el) - only_except_hash.empty? ? el : { el => only_except_hash } + only_except_hash = check_only_and_except(model_object) + only_except_hash.empty? ? model_object : { model_object => only_except_hash } end end end @@ -82,12 +82,12 @@ def check_only_and_except(value) def check_only(value) key = key_from_hash(value) - atts_only[key].nil? ? {} : { only: atts_only[key] } + included_attributes[key].nil? ? {} : { only: included_attributes[key] } end def check_except(value) key = key_from_hash(value) - atts_except[key].nil? ? {} : { except: atts_except[key] } + excluded_attributes[key].nil? ? {} : { except: excluded_attributes[key] } end def key_from_hash(value) diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index 394411a56c2301..29d715c16d374c 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -3,19 +3,13 @@ module ImportExport class ProjectTreeSaver attr_reader :full_path - def initialize(project: , shared: ) + def initialize(project:, shared:) @project = project @export_path = shared.export_path - end - - def save @full_path = File.join(@export_path, project_filename) - save_to_disk end - private - - def save_to_disk + def save FileUtils.mkdir_p(@export_path) File.write(full_path, project_json_tree) true @@ -24,6 +18,8 @@ def save_to_disk false end + private + # TODO remove magic keyword and move it to a shared config def project_filename "project.json" diff --git a/spec/lib/gitlab/import_export/import_export_reader_spec.rb b/spec/lib/gitlab/import_export/import_export_reader_spec.rb index e71c7b60b80d98..0b2da73a2259b4 100644 --- a/spec/lib/gitlab/import_export/import_export_reader_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_reader_spec.rb @@ -1,4 +1,4 @@ -require 'rspec' +require 'spec_helper' describe Gitlab::ImportExport::ImportExportReader do @@ -17,7 +17,7 @@ end it 'should generate hash from project tree config' do - allow(described_class).to receive(:config).and_return(YAML.load_file(test_config)) + allow(described_class).to receive(:config).and_return(YAML.load_file(test_config).deep_symbolize_keys) expect(described_class.project_tree).to eq(project_tree_hash) end 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 5c1b9af2c13e98..67e6267b741193 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -1,42 +1,20 @@ require 'spec_helper' describe Gitlab::ImportExport::ProjectTreeSaver, services: true do - describe :save do + describe 'saves the project tree into a json object' do - # TODO refactor this into a setup method - - let(:user) { create(:user) } - let(:issue) { create(:issue, assignee: user) } - let(:merge_request) { create(:merge_request) } - let(:label) { create(:label) } - let(:snippet) { create(:project_snippet) } - let(:commit_status) { create(:commit_status) } - let(:release) { create(:release) } - let!(:project) do - create(:project, - :public, - name: 'searchable_project', - issues: [issue], - merge_requests: [merge_request], - labels: [label], - snippets: [snippet], - releases: [release] - ) - end - let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) } - let!(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } - let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } - let(:project_tree_saver) { Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: shared) } - let!(:issue_note) { create(:note, note: ":+1: issue", noteable: issue) } - let!(:merge_request_note) { create(:note, note: ":+1: merge_request", noteable: merge_request) } + let(:project_tree_saver) { described_class.new(project: project, shared: shared) } + let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } + let(:user) { create(:user) } + let(:project) { setup_project } - before(:each) do + before do project.team << [user, :master] allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) end - after(:each) do + after do FileUtils.rm_rf(export_path) end @@ -109,6 +87,30 @@ end end + def setup_project + issue = create(:issue, assignee: user) + merge_request = create(:merge_request) + label = create(:label) + snippet = create(:project_snippet) + commit_status = create(:commit_status) + release = create(:release) + + project = create(:project, + :public, + issues: [issue], + merge_requests: [merge_request], + labels: [label], + snippets: [snippet], + releases: [release] + ) + + create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch, statuses: [commit_status]) + create(:milestone, project: project) + create(:note, noteable: issue) + create(:note, noteable: merge_request) + project + end + def project_json(filename) JSON.parse(IO.read(filename)) end diff --git a/spec/lib/gitlab/import_export/repo_bundler_spec.rb b/spec/lib/gitlab/import_export/repo_bundler_spec.rb index 23447d878a8bb9..fa926bab823dc9 100644 --- a/spec/lib/gitlab/import_export/repo_bundler_spec.rb +++ b/spec/lib/gitlab/import_export/repo_bundler_spec.rb @@ -1,20 +1,20 @@ require 'spec_helper' describe Gitlab::ImportExport::RepoBundler, services: true do - describe :bundle do + describe 'bundle a project Git repo' do let(:user) { create(:user) } let!(:project) { create(:project, :public, name: 'searchable_project') } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } - let(:bundler) { Gitlab::ImportExport::RepoBundler.new(project: project, shared: shared) } + let(:bundler) { described_class.new(project: project, shared: shared) } - before(:each) do + before do project.team << [user, :master] allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) end - after(:each) do + after do FileUtils.rm_rf(export_path) end 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 6cc95edc2178c2..60a0145c1a093d 100644 --- a/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb +++ b/spec/lib/gitlab/import_export/wiki_repo_bundler_spec.rb @@ -1,23 +1,23 @@ require 'spec_helper' describe Gitlab::ImportExport::WikiRepoBundler, services: true do - describe :bundle do + describe 'bundle a wiki Git repo' do let(:user) { create(:user) } let!(:project) { create(:project, :public, name: 'searchable_project') } let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" } let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) } - let(:wiki_bundler) { Gitlab::ImportExport::WikiRepoBundler.new(project: project, shared: shared) } + let(:wiki_bundler) { described_class.new(project: project, shared: shared) } let!(:project_wiki) { ProjectWiki.new(project, user) } - before(:each) do + before do project.team << [user, :master] allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) project_wiki.wiki project_wiki.create_page("index", "test content") end - after(:each) do + after do FileUtils.rm_rf(export_path) end diff --git a/spec/support/import_export/import_export.yml b/spec/support/import_export/import_export.yml index e6985d6413cd98..3ceec506401216 100644 --- a/spec/support/import_export/import_export.yml +++ b/spec/support/import_export/import_export.yml @@ -1,20 +1,20 @@ # Class relationships to be included in the project import/export -:project_tree: +project_tree: - :issues - :labels - - :merge_requests: + - merge_requests: - :merge_request_diff - :merge_request_test - - :commit_statuses: + - commit_statuses: - :commit -:attributes_only: - :project: +included_attributes: + project: - :name - :path - :merge_requests: + merge_requests: - :id -:attributes_except: - :merge_requests: +excluded_attributes: + merge_requests: - :iid \ No newline at end of file -- GitLab From b6ab4a311396d12cdb686df885fe48c58ea31218 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 6 May 2016 14:39:57 +0200 Subject: [PATCH 128/714] missing private keyword --- lib/gitlab/import_export/command_line_util.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index 4a1018072c667c..c99b0d83b41c7b 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -17,6 +17,8 @@ def git_unbundle(git_bin_path: Gitlab.config.git.bin_path, repo_path:, bundle_pa execute(%W(#{git_bin_path} clone --bare #{bundle_path} #{repo_path})) end + private + def tar_with_options(archive:, dir:, options:) execute(%W(tar -#{options} #{archive} -C #{dir} .)) end -- GitLab From 49cdb778a17b25014c9439eb1a719e1fac9d04d0 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 6 May 2016 15:18:25 +0200 Subject: [PATCH 129/714] few fixes to import specs and code --- lib/gitlab/import_export/project_tree_restorer.rb | 5 +++-- spec/lib/gitlab/import_export/members_mapper_spec.rb | 4 ++-- {lib => spec/lib}/gitlab/import_export/project.json | 0 spec/lib/gitlab/import_export/project_tree_restorer_spec.rb | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) rename {lib => spec/lib}/gitlab/import_export/project.json (100%) diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 7aa0ff46cde088..ad77f7f69b19ea 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -14,7 +14,8 @@ def restore @tree_hash = ActiveSupport::JSON.decode(json) @project_members = @tree_hash.delete('project_members') create_relations - rescue + rescue => e + # TODO: handle errors better, move them to a shared thing false end @@ -83,7 +84,7 @@ def create_relation(relation, relation_hash_list) def relation_from_factory(relation, relation_hash) Gitlab::ImportExport::RelationFactory.create( - relation_sym: relation, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) + relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) end end end diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb index 9175356c641a1a..a4d3d6d122f69f 100644 --- a/spec/lib/gitlab/import_export/members_mapper_spec.rb +++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::ImportExport::MembersMapper, services: true do - describe :map do + describe 'map members' do let(:user) { create(:user) } let(:project) { create(:project, :public, name: 'searchable_project') } @@ -31,7 +31,7 @@ end let(:members_mapper) do - Gitlab::ImportExport::MembersMapper.new( + described_class.new( exported_members: exported_members, user: user, project_id: project.id) end diff --git a/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json similarity index 100% rename from lib/gitlab/import_export/project.json rename to spec/lib/gitlab/import_export/project.json diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index aa8a12c4caaf31..0958365ff9e1f1 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -1,11 +1,11 @@ require 'spec_helper' describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do - describe :restore do + describe 'restore project tree' do let(:user) { create(:user) } let(:namespace) { create(:namespace, owner: user) } - let(:project_tree_restorer) { Gitlab::ImportExport::ProjectTreeRestorer.new(path: "lib/gitlab/import_export/", user: user, project_path: 'project', namespace_id: namespace.id) } + let(:project_tree_restorer) { described_class.new(path: Rails.root.join("spec/lib/gitlab/import_export/"), user: user, project_path: 'project', namespace_id: namespace.id) } context 'JSON' do let(:restored_project_json) do -- GitLab From 8ac53eb5d0dcc6d0248a8b178a3c1b5f2d2284e1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 6 May 2016 17:55:06 +0200 Subject: [PATCH 130/714] started refactoring import export reader - WIP --- lib/gitlab/import_export.rb | 2 +- lib/gitlab/import_export/attributes_finder.rb | 35 ++++++++++ .../import_export/import_export_reader.rb | 68 ++++++------------- .../import_export_reader_spec.rb | 4 +- 4 files changed, 57 insertions(+), 52 deletions(-) create mode 100644 lib/gitlab/import_export/attributes_finder.rb diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index aa69f7c44a59de..84860b43cbe72f 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -11,7 +11,7 @@ def project_attributes end def project_tree - Gitlab::ImportExport::ImportExportReader.project_tree + Gitlab::ImportExport::ImportExportReader.new.project_tree end def storage_path diff --git a/lib/gitlab/import_export/attributes_finder.rb b/lib/gitlab/import_export/attributes_finder.rb new file mode 100644 index 00000000000000..12ae79a877330b --- /dev/null +++ b/lib/gitlab/import_export/attributes_finder.rb @@ -0,0 +1,35 @@ +module Gitlab + module ImportExport + class AttributesFinder + def initialize(included_attributes:, excluded_attributes:) + @included_attributes = included_attributes || {} + @excluded_attributes = excluded_attributes || {} + end + + def find(model_object) + parsed_hash = find_attributes_only(model_object) + parsed_hash.empty? ? model_object : { model_object => parsed_hash } + end + + def find_attributes_only(value) + find_included(value).merge(find_excluded(value)) + end + + def find_included(value) + key = key_from_hash(value) + @included_attributes[key].nil? ? {} : { only: @included_attributes[key] } + end + + def find_excluded(value) + key = key_from_hash(value) + @excluded_attributes[key].nil? ? {} : { except: @excluded_attributes[key] } + end + + private + + def key_from_hash(value) + value.is_a?(Hash) ? value.keys.first : value + end + end + end +end \ No newline at end of file diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 77db6cabe3853c..a6cf191010561b 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -1,37 +1,27 @@ module Gitlab module ImportExport - module ImportExportReader - extend self + class ImportExportReader + #FIXME - def project_tree - { only: included_attributes[:project], include: build_hash(tree) } + def initialize(config: 'lib/gitlab/import_export/import_export.yml') + config = YAML.load_file('lib/gitlab/import_export/import_export.yml').with_indifferent_access + @tree = config[:project_tree] + @attributes_parser = Gitlab::ImportExport::AttributesFinder.new(included_attributes: config[:included_attributes], + excluded_attributes: config[:excluded_attributes]) end - def tree - config[:project_tree] + def project_tree + { only: @attributes_parser.find_included(:project), include: build_hash(@tree) } end private - def config - @config ||= YAML.load_file('lib/gitlab/import_export/import_export.yml').with_indifferent_access - end - - def included_attributes - config[:included_attributes] || {} - end - - def excluded_attributes - config[:excluded_attributes] || {} - end - - def build_hash(array) - array.map do |model_object| + def build_hash(model_list) + model_list.map do |model_object| if model_object.is_a?(Hash) process_include(model_object) else - only_except_hash = check_only_and_except(model_object) - only_except_hash.empty? ? model_object : { model_object => only_except_hash } + @attributes_parser.find(model_object) end end end @@ -51,48 +41,30 @@ def process_include(hash, included_classes_hash = {}) def process_current_class(hash, included_classes_hash, value) value = value.is_a?(Hash) ? process_include(hash, included_classes_hash) : value - only_except_hash = check_only_and_except(hash.keys.first) - included_classes_hash[hash.keys.first] ||= only_except_hash unless only_except_hash.empty? + attributes_hash = @attributes_parser.find_attributes_only(hash.keys.first) + included_classes_hash[hash.keys.first] ||= attributes_hash unless attributes_hash.empty? value end def add_new_class(current_key, included_classes_hash, value) - only_except_hash = check_only_and_except(value) + attributes_hash = @attributes_parser.find_attributes_only(value) parsed_hash = { include: value } - unless only_except_hash.empty? + unless attributes_hash.empty? if value.is_a?(Hash) - parsed_hash = { include: value.merge(only_except_hash) } + parsed_hash = { include: value.merge(attributes_hash) } else - parsed_hash = { include: { value => only_except_hash } } + parsed_hash = { include: { value => attributes_hash } } end end included_classes_hash[current_key] = parsed_hash end def add_to_class(current_key, included_classes_hash, value) - only_except_hash = check_only_and_except(value) - value = { value => only_except_hash } unless only_except_hash.empty? + attributes_hash = @attributes_parser.find_attributes_only(value) + value = { value => attributes_hash } unless attributes_hash.empty? old_values = included_classes_hash[current_key][:include] included_classes_hash[current_key][:include] = ([old_values] + [value]).compact.flatten end - - def check_only_and_except(value) - check_only(value).merge(check_except(value)) - end - - def check_only(value) - key = key_from_hash(value) - included_attributes[key].nil? ? {} : { only: included_attributes[key] } - end - - def check_except(value) - key = key_from_hash(value) - excluded_attributes[key].nil? ? {} : { except: excluded_attributes[key] } - end - - def key_from_hash(value) - value.is_a?(Hash) ? value.keys.first : value - end end end end diff --git a/spec/lib/gitlab/import_export/import_export_reader_spec.rb b/spec/lib/gitlab/import_export/import_export_reader_spec.rb index 0b2da73a2259b4..6be2289b5a02cf 100644 --- a/spec/lib/gitlab/import_export/import_export_reader_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_reader_spec.rb @@ -17,8 +17,6 @@ end it 'should generate hash from project tree config' do - allow(described_class).to receive(:config).and_return(YAML.load_file(test_config).deep_symbolize_keys) - - expect(described_class.project_tree).to eq(project_tree_hash) + expect(described_class.new(config: test_config).project_tree).to eq(project_tree_hash) end end -- GitLab From fb6586151acc290bed8d4337f019d86aed84a33d Mon Sep 17 00:00:00 2001 From: fliespl Date: Mon, 9 May 2016 08:11:07 +0000 Subject: [PATCH 131/714] Broken instructions. git fetch --all --tags doesn't refresh tags --- doc/update/8.6-to-8.7.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/update/8.6-to-8.7.md b/doc/update/8.6-to-8.7.md index 4a2c6ea91d2557..8aceb29224352a 100644 --- a/doc/update/8.6-to-8.7.md +++ b/doc/update/8.6-to-8.7.md @@ -45,7 +45,7 @@ sudo -u git -H git checkout 8-7-stable-ee ```bash cd /home/git/gitlab-shell -sudo -u git -H git fetch --all --tags +sudo -u git -H git fetch --tags sudo -u git -H git checkout v2.7.2 ``` -- GitLab From 3aee167dcc26e6b9b92d6f67b316280675f5cde8 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 11:10:12 +0200 Subject: [PATCH 132/714] fixed issues after refactor, spec passing --- lib/gitlab/import_export/import_export_reader.rb | 10 +++++----- .../gitlab/import_export/import_export_reader_spec.rb | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index a6cf191010561b..3f45de209cc3f5 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -4,14 +4,14 @@ class ImportExportReader #FIXME def initialize(config: 'lib/gitlab/import_export/import_export.yml') - config = YAML.load_file('lib/gitlab/import_export/import_export.yml').with_indifferent_access - @tree = config[:project_tree] - @attributes_parser = Gitlab::ImportExport::AttributesFinder.new(included_attributes: config[:included_attributes], - excluded_attributes: config[:excluded_attributes]) + config_hash = YAML.load_file(config).with_indifferent_access + @tree = config_hash[:project_tree] + @attributes_parser = Gitlab::ImportExport::AttributesFinder.new(included_attributes: config_hash[:included_attributes], + excluded_attributes: config_hash[:excluded_attributes]) end def project_tree - { only: @attributes_parser.find_included(:project), include: build_hash(@tree) } + @attributes_parser.find_included(:project).merge(include: build_hash(@tree)) end private diff --git a/spec/lib/gitlab/import_export/import_export_reader_spec.rb b/spec/lib/gitlab/import_export/import_export_reader_spec.rb index 6be2289b5a02cf..f826c5ec8e6e5f 100644 --- a/spec/lib/gitlab/import_export/import_export_reader_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_reader_spec.rb @@ -17,6 +17,6 @@ end it 'should generate hash from project tree config' do - expect(described_class.new(config: test_config).project_tree).to eq(project_tree_hash) + expect(described_class.new(config: test_config).project_tree) =~ (project_tree_hash) end end -- GitLab From 9c639041fe312f8edf1613809ac665cb8755ffb7 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 12:15:50 +0200 Subject: [PATCH 133/714] bit more refactoring of import export reader, fixed rubocop warning --- lib/gitlab/import_export/attributes_finder.rb | 2 +- .../import_export/import_export_reader.rb | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/gitlab/import_export/attributes_finder.rb b/lib/gitlab/import_export/attributes_finder.rb index 12ae79a877330b..8a599ad5261c6a 100644 --- a/lib/gitlab/import_export/attributes_finder.rb +++ b/lib/gitlab/import_export/attributes_finder.rb @@ -32,4 +32,4 @@ def key_from_hash(value) end end end -end \ No newline at end of file +end diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 3f45de209cc3f5..35ff05350d808d 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -17,30 +17,30 @@ def project_tree private def build_hash(model_list) - model_list.map do |model_object| - if model_object.is_a?(Hash) - process_include(model_object) + model_list.map do |model_object_hash| + if model_object_hash.is_a?(Hash) + process_model_object(model_object_hash) else - @attributes_parser.find(model_object) + @attributes_parser.find(model_object_hash) end end end - def process_include(hash, included_classes_hash = {}) - hash.values.flatten.each do |value| - current_key = hash.keys.first - value = process_current_class(hash, included_classes_hash, value) + def process_model_object(model_object_hash, included_classes_hash = {}) + model_object_hash.values.flatten.each do |model_object| + current_key = model_object_hash.keys.first + model_object = process_current_class(model_object_hash, included_classes_hash, model_object) if included_classes_hash[current_key] - add_to_class(current_key, included_classes_hash, value) + add_to_class(current_key, included_classes_hash, model_object) else - add_new_class(current_key, included_classes_hash, value) + add_new_class(current_key, included_classes_hash, model_object) end end included_classes_hash end def process_current_class(hash, included_classes_hash, value) - value = value.is_a?(Hash) ? process_include(hash, included_classes_hash) : value + value = value.is_a?(Hash) ? process_model_object(hash, included_classes_hash) : value attributes_hash = @attributes_parser.find_attributes_only(hash.keys.first) included_classes_hash[hash.keys.first] ||= attributes_hash unless attributes_hash.empty? value -- GitLab From 7ff2a51eb24032895e6199c62de44e17de65af7b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 17:58:43 +0200 Subject: [PATCH 134/714] more refactoring to import export reader --- lib/gitlab/import_export/attributes_finder.rb | 9 ++- .../import_export/import_export_reader.rb | 56 +++++++++---------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/lib/gitlab/import_export/attributes_finder.rb b/lib/gitlab/import_export/attributes_finder.rb index 8a599ad5261c6a..cfb9f0eef1867b 100644 --- a/lib/gitlab/import_export/attributes_finder.rb +++ b/lib/gitlab/import_export/attributes_finder.rb @@ -11,8 +11,9 @@ def find(model_object) parsed_hash.empty? ? model_object : { model_object => parsed_hash } end - def find_attributes_only(value) - find_included(value).merge(find_excluded(value)) + def parse(model_object) + parsed_hash = find_attributes_only(model_object) + yield parsed_hash unless parsed_hash.empty? end def find_included(value) @@ -27,6 +28,10 @@ def find_excluded(value) private + def find_attributes_only(value) + find_included(value).merge(find_excluded(value)) + end + def key_from_hash(value) value.is_a?(Hash) ? value.keys.first : value end diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 35ff05350d808d..84c3f3e97296fb 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -1,13 +1,13 @@ module Gitlab module ImportExport class ImportExportReader - #FIXME def initialize(config: 'lib/gitlab/import_export/import_export.yml') config_hash = YAML.load_file(config).with_indifferent_access @tree = config_hash[:project_tree] @attributes_parser = Gitlab::ImportExport::AttributesFinder.new(included_attributes: config_hash[:included_attributes], excluded_attributes: config_hash[:excluded_attributes]) + @json_config_hash = {} end def project_tree @@ -19,51 +19,49 @@ def project_tree def build_hash(model_list) model_list.map do |model_object_hash| if model_object_hash.is_a?(Hash) - process_model_object(model_object_hash) + build_json_config_hash(model_object_hash) else @attributes_parser.find(model_object_hash) end end end - def process_model_object(model_object_hash, included_classes_hash = {}) + def build_json_config_hash(model_object_hash) model_object_hash.values.flatten.each do |model_object| current_key = model_object_hash.keys.first - model_object = process_current_class(model_object_hash, included_classes_hash, model_object) - if included_classes_hash[current_key] - add_to_class(current_key, included_classes_hash, model_object) - else - add_new_class(current_key, included_classes_hash, model_object) - end + + @attributes_parser.parse(current_key) { |hash| @json_config_hash[current_key] ||= hash } + + handle_model_object(current_key, model_object) end - included_classes_hash + @json_config_hash end - def process_current_class(hash, included_classes_hash, value) - value = value.is_a?(Hash) ? process_model_object(hash, included_classes_hash) : value - attributes_hash = @attributes_parser.find_attributes_only(hash.keys.first) - included_classes_hash[hash.keys.first] ||= attributes_hash unless attributes_hash.empty? - value + def handle_model_object(current_key, model_object) + if @json_config_hash[current_key] + add_model_value(current_key, model_object) + else + create_model_value(current_key, model_object) + end end - def add_new_class(current_key, included_classes_hash, value) - attributes_hash = @attributes_parser.find_attributes_only(value) + def create_model_value(current_key, value) parsed_hash = { include: value } - unless attributes_hash.empty? - if value.is_a?(Hash) - parsed_hash = { include: value.merge(attributes_hash) } - else - parsed_hash = { include: { value => attributes_hash } } - end + + @attributes_parser.parse(value) do |hash| + parsed_hash = { include: hash_or_merge(value, hash) } end - included_classes_hash[current_key] = parsed_hash + @json_config_hash[current_key] = parsed_hash + end + + def add_model_value(current_key, value) + @attributes_parser.parse(value) { |hash| value = { value => hash } } + old_values = @json_config_hash[current_key][:include] + @json_config_hash[current_key][:include] = ([old_values] + [value]).compact.flatten end - def add_to_class(current_key, included_classes_hash, value) - attributes_hash = @attributes_parser.find_attributes_only(value) - value = { value => attributes_hash } unless attributes_hash.empty? - old_values = included_classes_hash[current_key][:include] - included_classes_hash[current_key][:include] = ([old_values] + [value]).compact.flatten + def hash_or_merge(value, hash) + value.is_a?(Hash) ? value.merge(hash) : hash end end end -- GitLab From bd0c8ce40542dd3c05526c4c80df4ad4c151b4b6 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 18:07:29 +0200 Subject: [PATCH 135/714] fixed space --- spec/features/projects/import_export/import_file_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index a7da7a21ea8765..03298149b604a2 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -8,6 +8,7 @@ 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 } + background do allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) login_as(user) -- GitLab From 5dad9f1fcbd432f1c2cc2e861983e4c49cfce140 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 16:19:07 +0000 Subject: [PATCH 136/714] new line missing --- lib/gitlab/import_export/attributes_finder.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/gitlab/import_export/attributes_finder.rb b/lib/gitlab/import_export/attributes_finder.rb index cfb9f0eef1867b..3439ef1006edba 100644 --- a/lib/gitlab/import_export/attributes_finder.rb +++ b/lib/gitlab/import_export/attributes_finder.rb @@ -1,6 +1,7 @@ module Gitlab module ImportExport class AttributesFinder + def initialize(included_attributes:, excluded_attributes:) @included_attributes = included_attributes || {} @excluded_attributes = excluded_attributes || {} -- GitLab From 21be0cae62af3ba5e0e71758d260287b164fe504 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 18:33:48 +0200 Subject: [PATCH 137/714] fixing merge issues --- lib/gitlab/import_export.rb | 4 ---- lib/gitlab/import_export/import_export.yml | 1 - 2 files changed, 5 deletions(-) diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 84860b43cbe72f..655373c03af975 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -6,10 +6,6 @@ def export_path(relative_path:) File.join(storage_path, relative_path) end - def project_attributes - %i(name path description issues_enabled wall_enabled merge_requests_enabled wiki_enabled snippets_enabled visibility_level archived) - end - def project_tree Gitlab::ImportExport::ImportExportReader.new.project_tree end diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index ca433e72d5f000..36128909df4dc8 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -22,7 +22,6 @@ included_attributes: - :path - :description - :issues_enabled - - :wall_enabled - :merge_requests_enabled - :wiki_enabled - :snippets_enabled -- GitLab From 6a12ff6345e517af9cf07cb61f3a0ea85562f399 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Mon, 9 May 2016 18:40:31 +0200 Subject: [PATCH 138/714] renaming variable --- lib/gitlab/import_export/import_export_reader.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 84c3f3e97296fb..37093ff58ed8ff 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -17,11 +17,11 @@ def project_tree private def build_hash(model_list) - model_list.map do |model_object_hash| - if model_object_hash.is_a?(Hash) - build_json_config_hash(model_object_hash) + model_list.map do |model_objects| + if model_objects.is_a?(Hash) + build_json_config_hash(model_objects) else - @attributes_parser.find(model_object_hash) + @attributes_parser.find(model_objects) end end end -- GitLab From 5b51d13c5e432cb76dc911047cc8c5932ecfe421 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 10 May 2016 12:01:10 +0200 Subject: [PATCH 139/714] removed method no longer needed --- lib/gitlab/import_export.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 22973ff3b6a48d..655373c03af975 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -6,10 +6,6 @@ def export_path(relative_path:) File.join(storage_path, relative_path) end - def project_tree_list - project_tree.map {|r| r.is_a?(Hash) ? r.keys.first : r } - end - def project_tree Gitlab::ImportExport::ImportExportReader.new.project_tree end -- GitLab From e6fcd6d5bd8580f992f557c05aef3cc335b7ee8b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 10 May 2016 12:30:45 +0200 Subject: [PATCH 140/714] fixed more import merging issues --- spec/lib/gitlab/import_export/project.json | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index 4a12c951dcbc49..8b6a16c049fd69 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -3,7 +3,6 @@ "path": "gitlabhq", "description": null, "issues_enabled": true, - "wall_enabled": false, "merge_requests_enabled": true, "wiki_enabled": true, "snippets_enabled": true, -- GitLab From 17ce63a5e19f03fb1fec04724ca6d41e463a32b6 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 10 May 2016 13:11:21 +0200 Subject: [PATCH 141/714] updated spec export file --- .../import_export/test_project_export.tar.gz | Bin 338759 -> 322702 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 87f118b6e230a19317e7070bf04c7ad072f0eb9c..8147c289b8e763d509d35f0293814d92489772f3 100644 GIT binary patch delta 60492 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 KGKXOSD+2%%?;8LB delta 76674 zcmeCXDSZ5zNWFYF2g3_>?QjO>C%el-CcocgFXb@dUiEaXOG1+zlsGOqF8S`q!MXRl zQj^Kcy~-Zb?{$l4USgTTcZp>Qr^j?9*Ze#8H`o83v-kYY*Y9?}d;k4>?e(Omt)|B3 zZH(tXH#UAR-O|GN|F*uuGofau|Gz~3z82PC`uY0vdTs_GLFUem`mTnf3mg~(SXdlg z7~Wj?|92fD!@PHL9Oh+Z2ZURcPyPMx#;4ro_J4lCi~ny_Ro*;$mecN3#SvL$6=}KP zU-_Dk>IWAIoT#5&FTkPIb@IFYQ~4f2mJQ7R%Pl^izyAOH=kq7usUFJ9eSPp>_%F`D zfIyCzGna(A*qQ_j6qvY#8k_4cdIV}~c!cn<2{SW43^3r~OD}g`c(*k-fJ3`HF^+%A zZg%~J5?r~QO^$2VxVT&h3s4bhabi{!FtoVh6>=nqr)?)Q)5HXh7xt?c$;8^!u zPSfaED$3Ep61i}K#uN>y#-^?X4>_i2JnPReH1rNskopwgbK}>a{ajMF7#}`tEE3wX zskB(V<>4Oni9>lwAv;fzLW5X)vYt~kgLJHj>ts|IaEAYINT34{J+_zeCX`G zQ#WsSUJzns?>=I))Dz zx)cxAEA=xiTEHP7@pt_$1t%63)~!y9buJ1B){C&k6a=p5&|vEPD8sVJr7Q6fhl^vt zwEuJ0aV*sMS5t+t@#)Agl7wQ*ttG0A2HiTvD z&`7(i#Bt`6#EeGAX$cA*BD@FRNH=|yY!hp2`0pCta^ch|uBMyX9wLnF%?k{8W;_g- zqRPU%wO)jAaiRbROS5R;4vshRAqQJBEM(do4jC{scRMI#2#Bz{H!V<5kZFt*Q|)5p zV3{2CW51iEmj+jBQc$~#lR$w0k4{sgJ&PvW=0g&jTMi{kXa}gUE#)|}e?^y2l#`2& zp`h!ce{<5cRk(QD8w}k!A6uuHo^d;}CSitcwrNH zgY)8r{}*xnH}7vyK6O?~^+j9J*CQFbxtsr`y}oaA{C|q`6MgCba-4rB^L~go`)8~6 zS6zC-{+vJ6OX|P*n=PpS{`mgMC-yf5{+>Rzzx`nSCdF_69c>coZ~pkMb;kZ?!~fLB z=PR2NXE66XoNgb}(A25$Kq7vPOM^$CU|^5`qJ$QXU-pk4Hf|^r|Hj10*xJxy(8A#) zlB&tn9u?Jeq+wbD2V0h@kwW6kO5clXUXPo|CFU@?v)y|4L*PjTV{OYr-J~5~78d#Uh^~Q^|u*pCzCR7rPr_7v#)x4-^$k?#eMIuePHGx#>KfxeoKXv#67P0d#t+u}5_{Glh-`(ks>x`0acK)0=bE0tV#ONtcGWBOQe{SCR;!E#^ zPi3Y0uRd>l!4O_>$o%z<1^Z8LHl1>{_C@y)1CF^+)cKg0j_;G(}>*Cj^g!+Fg zUDmnT`%n7gN{%Mgo*ifHj|hK0Z1&&%<4e7!yQVo0_j`M*swe%K_cTC5G3EgG@x#W3 z8_zD$e623Scifoqij44t`~-HvfBKhse;%~0WvQ>4*5A&%M4ZuU-MXV1dzGU8{r2h6 zi)dI_*tA9WjlzxlOHVFp?iT+2o8!{HP5Kgl%;(iqdYstN$@{1Me&W%C+5b1+f5{R( z`#;Byf|9gbijDUB~5&Luw~> zXDR#7|B!PpqF!|klU=yXId-9~Ji^)?9|A&E8{3>WOL0s(6qzoRX(Y_WwRCdy@AkWe ze>%l$*4(|Q$h`03nJKrtW>%O^y)|jhzaz2Nr)*ze>N!2RSy4u1q5P&7!FzV9y*T~B zY{$N`eL_ZEKK(Q zx_9UAcJpjIJu@lenpx&%)u?zWv-k?h*Ps7fd|b0AXwS5hLBjcUn_m~2{aAaj`FVUz zZhzSQMAv&;75x+rzcF=d-7*^ToX?$^9~|Lek&(ie9foxbx2*Ok?#Y^ZyBg2ik8oGTWE%fCAmS^keXT_#(9 z>33tVrbs#8BnzLbS(abC8BSfv?`oc|!pR(0(QvZHNT|J2HEX-3jjlz-j)-$|;%2PE z+b=#&{rsiwT)c+$L(hs=%gR5_EOzXSdZx+pQTc-F+6hmSy^b&3am^&$>R}g8aKnoJ zAIn>g{w<#@E6e=#eaiNk@V%3(swNe8jDNO57tZv&h57?BM#3E!X2qP8|6lX5D;yhRs~Q%~M%Qr`jo0 z{!hH2`?Bh0>~;SAif>q#rmy!dBY6|4RiK>RVwDLR=jw$B)Z8_ch0?OLC?Ba_fMZNHTuoV zuZ|*jc8(l3(>|+AD#3$8OL3IPvbpnDnp>jJ#Xs+vfPx-&j?zvoFo%n#@L1 zy^HX+W8YlDcWhFvB0&f2V?0-Jqnx3U##XIl$$?_*QB`^6n_$%!FE?a$Yw%&d21AoNH zds|&ukJdI%42}$*q*qZKtY5z?dYL=7mdexhzp^c7FI*Kq*?7go!$xjiQnFu81RL?o zRbBR)C;x#xzARh&_}8NAv#QIa*s^_#S3b&~pzFW(xcx)78zOBFHBOkWy%F~6-=%w| zN-YZ3cMqRezsK>uX=y>cVN#6uo1oXsLi{l{I~82tGoA8h3!TaFt}`m4M)kzZ`gb7) zkq<(?=43ytbqNUHeQSQ%Z=X{)d~;1!Tu)yU<+JWmMW0UEjF*2KuGfCtnbN)GYyQ)O zcQG3-d4x>WS^Z-d+x;0~n}ZTJhi<&r^uO!+>}1#C-aBXZT@~r|-&Wlza*VzI)V@D6 zwyx-~Et_I~&Ug3WX`SC9<4Q%}b1#Y%ga*Iq!p$>IoKC6P<0!Kg#*J^IOXO zKKRR?eN*6An#0_`0C@`Hp3kVn6--n7-_mW>R0?JGn%@aN^^g&wey3tL<)? z@V3W3#L%cdshe4eKPp@Q{D=2_nP0jSm*;Cr?D4P8n?CPXNavB2&)=r$-CMG(Gp6U% zg^%w;&D1vdD$myz7v5&oFSbi-<;jJ`SwZs(JRDRnO=?-m>g~C2jY6A$riG{NVH0zO zvpVrnDweJbm7Ld^rtRJL{M(;5zpm}o-cWx2$c|+tl^ga2POCq&clE}jS2A8t47&Qs z?NI>##QAqV{^o8|*Z6t)!HYqg9M(QIIb|<<%>AmJPkUj+ z->I%qnu3~oQ{CbwWYxa4>)yNKr|9*GO9U0l7%JDia8TUfz}4LlN}9)Xte4j#;WY`{G+uzl%4Mk23d75PL8A zrRwmPEZ0{*cb6xh%aNFo;1k6*v%`x^hN zlJ@=dEjHlLqIgHQcSnrYl+9kc(c|E>^Pj7Z?5jP!N1V|C%cX!ctYQD`)3U zw)^X(_jYs5#u8DHH^(3886T7|zE4n`U zHSk1iD6LUT54?l0wRWoS#_-UA_FSp!$MD)%m?oX8iX#!TXKFdi~GbU$Z)+r*ZEoytsLKFMs#!NzCDUZq9j7 zQxN{NWoA~GOmd>fU;V#R$`HR4#XL?JWCV6Qu`*Ndx{XOr0GfV=X=&7FA z^5tFS+0XZNO>^u*kN%$hTCXkh`PrqpmEG6Bx19fQx$RN)y6UP9ktcq~d;eUjygk*u zzeaw>Jmtp^cy1Po^sX_f3jn6^f6%PDL-Co4y zBbVFw`|a$+fHwk`0_pZQ--On?Z4|$@`a$8^y#i+ynm)1%YAQ@@*%jk;`;cADD(={M zdt4r0X%MzOs$m?xW$M;tU%N#f`9_^Pvf$Ajj@0GdZ{Kd#_e;rd^@{d1C+{%5Mc zd$?}$^-Gy|l=ZjV+PDApn{AH9?%!Xk^4$Bl`@(NS3u`JB=zm`K!iM+Wf^Vor#>vB`&9@>4Iwa0M6LGiN-zE>Z7 zTKU}d^X#ximx8jn|F2$jDdUgz*ZV1MvlgYFcywxK?|XffFP*QFS7lc^wQZj{Rm}4C z;T?}o7bqG;*`BT6!c^#z`!nUyy!xuPRX1lY`LLt*T~_V;DChs1-RHhLzldpj?eu3g zsvB%0|15IL-1|b)ZrYmDul^bRc;UT&*M>(&pLb7}(tmvaVmb2zg$bWe9=_sur9*4k zf2IGApK5K>D76q%y|g5E+AEGb604_vJ#yvv`n#+sAry`rsv%UtL3 zc+WBq6Z^`t*B@m~8$O;D{$3g-rRsOHn8|x@mDOyfzTGU}b6RJ&?cJqRA9l1VZ(B|z z`?+|z{jxc=q93=0Ogtx7cV<>o=v1zKiT#S@FPv^3{Wt69u76nzYrnaO{W9G<&;D!I zWA4tfvLCl!*`1Uviu|)?zs=w3qki=&yXOCy9rdn%vHxTxR@czntuKrAbIkm+HpzUl z{Qj`N6BlSHubKPrRBBm7Z{ypzx^ge|&T9_lw~ib;*YcN7OQlO8Qq$A(=Eas-cc*Sw z-_f@)c>0diGQFHu&$r9oR;=>fczTMc`J);4+wyF?mia zy;aX$=F9$ek9TC9v2VGK;N=K^v$L9Sr=M%}tX{P07uy7jKOfY4nT+FBw05jb;rzGv zbK?e0@ta+VPgQSsx{00Yez#7Pzd>RDYbN94k3RmIBi`dAWpVn+wU`a|)_up*TOOtG zT)v!KJM~#7)7|p7lOOYFKJK5OXK`0!UC+w6EfE!u>kmwMU{qoYK6uHp^|t z|8(iR>X5*vwgW_|Ml!l?)n_v2_)@UV;+4k! zSH~yBpJtu@PvPvG`lN4xyC3iPJiBv-$Aa^ zHJ^88N${!Ieo;B|jJ0>=yJww0pM7* zcoDg{sp*#9b2j@;yJ{bJPvx2O(rU%Jb%kjhoDX)iYt^3=oGCGD%15C^S*ad+^PN0u z_3MT1`?gKL;Fh^$&R5T$*`HQSpThg)`x4Fcpm{gG^?k@a)n3>bAk%4A;q04Sy(RKC z>$!^&YrJmhrq8){{#{w&^PP8M9@%W)bj{0A>S^iT{uI{ zliW9H{dCpyH@O|~Xie>+hX+0C7l%1N)~lHCan1BSnf1$ks%NKeGh8ZbWbLG5kmk^| zMtkv!$$4(_0=wT@nyDWQId1gY^1k!*!jCztF6W+%{a*f|A>B-D-_cnc&&i}zawOGk zTodTB%s$mTeE%Nd6`@jo`S?n;vT(%5A;ydqsekio35H%L9{~f?xk4lVtp} z9>2A|_@n*LR>ybsU81r#tevmV>_|DbD}UCjWj-#pPX#$@)*r5IuW&seeqDZTRpDDF z{=?c=y}(_4?4H9?icH2wFlpyemr_w+KsPsl^d8Z*{%xS z6?cC^aOcDi*ZWV{sm@&`&wlEo%2#E!rN=hi*_3hreUw8~&cll`pLW)-%nmd8*wYYH z=l8Mr-mKK^;#2J2t9EI?bUNH-4&0S8WxZwy3zE^C1b|>U;Jh^ zW$cP#jo=TS{>M98Uu3oI)X+VDkKVbQu6JX1S97U$R9LWD)0`JCZbhy4Y;pPeUf1%Q z+=P98W2|hX9y9Ox?@v}JJmiyZJN9Nto3PEfrOQtF?Yhvd z{8+o`Aooh;*ZQl!uG!PK+@eJ(YThZ69U_IC3!m6M?$V!B@7%)Yf3J6)ucp+ow|`l7 zJ=ijD<{F*1v-d|OzB}eoACvX1^v4wHFZ*81@e74Px2jL$Y9&lWndrLJ!MJroODJ_dXuCqq;*OrG8GN z&giJ$7{6L2{N3%z-Hukj*Y4RNwqI=aO~q@Ij^^yS9+Gfn`VuDA^$n*Y-_IJS2iEM*~pe-pKLm<@uJf*W21Z){Z%Vk_Fp@kZmY0E@0{uSdaWn^-`({4 z;w0Ne`&>G0ZzOy6C$7)cPTDm|V(;$iEa%Ir|E7FX+qlRiM{Ua#*6q`dRa$4%ZQrkR z`c-f9{JNJ9H@)1+kgaZb`KIuf6I0u6rstj58j*P@rN3t_)AFqb>kgTEe}9;GYIbPu zoP*Qu+eFOY`*Yj7jy*HD-v6sRuYAOyeygOq&U5$UvD}Z>PEjg7zQz5o?(OrMEAltY zz$~}#xRPJtmsc>`g>*`qE5YM|}iu%G6nq&9N?dzQ< zzjgEH-z#UA2iTfs9By|#d2#;k??DQRCm&gV`uuxe@??Hqrr9!gEf2i!*A{TwT(SD@ zZ-t=wAa|3u!AY@QhYn3DX$nJ3r%I`?kx3qEnKxx5pXg#B2$ukO%enX@_{eWuU)ZrjW# z9;mDA-|U_KZ)1e__Ir7ok4Z*kmbWCk_d3p<#xVOWZ=Xed-G(WV$E)>=wPeD)z?dFJ@@)N%skt!>$oFu#YLxtGgI^1?wnvzE}7#XCNQ}InHXa05O^5@dFwe|H%0uTFpE~u|qB5(ZA z@JrL}*%ANtyxni3R)5zeVZFHcy`#%#`i4(?IIaD;ZvBD2-*UF`E8fT^Wvp5kV{*Da z=Kj4htL?>NtL9|e*Ob4g{3W|NO6>DOJHz-?PNkiiAH~wI9-c9G5tH!I()ZoJJ95^x zJ8ZdrWLftL*N1OPPS-V59f?^pLG94$+Ko|aOO}eyeq~d5{>m0FtuJNI>-)M^*Uxxc z9Ff`G&(AcS&HKYty(6p5SC|z22)(tPVpKb+(-wRtda`|Og-H`d0L9}|8hDrb?g2O->3e%vNkqP4{wMT zK3@I(nTjm0&XvvAWklmIe7QSoje1meu;BkdZ`=I!Jk#s93!c_`8KUJL$|O1E^i-j% z7W0>Ehz>j#aDLnN(5&!#@u3oIVNb-5oH|l;!XW1OiM!XEY#s+)jCAySB(W^~hV_9^Og2_R74M zxphFo@?D8-=)av->-it-{km)G-bu5q?I&tPt4^9>UBCL%Vou&GJ9+uOrye+%9)I%1 zPaYYMe=*i4OlJIDnkn|e?8b?r({)Lc_X;n(G|4kzP3;Hkie*_!rn9ftKRGS7Q7i0>4S1XzpE{MXPNFg`^Pcj@pG60N2zl&CyNa+7Et*zFB2IbDG4LdFPy`-Fjm8Va|JJuZJa~VV-7kN37pI zTy<;uQLE*zl-nB){E%NB!Fc$t+N%AP8+02gL?5aa{8lMq4av(tCgW&#TV>nP2fG@k zZqP4%{^RG&pC*n9)7GlCzp1})tKLnz{@d@BTJ7xLbCXped7?XS@D9m7}qg$EL68rK{btnR%rr zrfVBX2y|{PTinm(dXjy=Uq{~>nW>yhj_UdxJI@pMH|UZ?-jo|pEVZ@29&(j`yY!+>*;+JzY!g`g^2wpVH}gOLJo5A-vwB>N>atnMGmq#T zn`RWix$k_t#d;yz*qm*~$qvTnS@u0!y@)BH_t;OzFX?slMH$Eb&H0eg<9*%tY?iZ4 zg0KG-z0aBF)-U_78oT*#+-@5tom(ECk8XHy`Pp8DnA7K+r0*SDSaRCz+HSsf!^b6} zx5VPVbFcXFXjh1gfcg4$`n_3lgV zKK3zHZ~x+{mVZ(vi3i+H_h-`oU=$)a+wAz`>!N~U;tJiGdB0vJ7X_wls+{DpU{g~5 zb(6|>KLzR^?n*puy}wx{=Tfwe!>WbK4~&oeW_De;?LbIt)3SAw4H6bgxG~oAvt+v2 ztax~`cHd<|>o~nEy~tFZ>N?kRlW(kZt?|0s_O45HXP(JQ2k&}m^Z!g77y4xQ!_t2| z+yDLyV@KPa1SMA{mcJcakJ!n(e54TC*>YLN8pFT^k);_)JQ_batMe8+EG*Vv4Wl!Uu zs(C@eZ{2qp+o{LyU-mqhAKUAtTsdpPXSa2?O<$&pTt8QvIxAqsGvTbu;Xm12uVk}5 zj_|u_`AaWttLn6Vm1`YYdY0ayp1XGJzGl|<{-2bR%wLzQ(zPDzc*4%@U9S25(AQ6_ z4DT1#i#}-&dDSuDp}XJ>{RO{g9oQTe9yqXP@0d6hse$BH+v4(!QJ_$u{x+N$cvxRW9K-ens2A2)d5$D}t= zHF<}wmP}{)gDO|F_S#Q&Bl=ky-?@x$FG_vd1I&9tq9ZYE9d-K6YTYH_t}Gu79q)dzo~TIxDa>mnTr0Tv{sRT zd&Ug2H{7ZzFRIXD!=S+QXf~rcl zO@!oA$Fg;9s*S~&lX9HvUR4XIeXX9zC9vM#_H{;4$d`;RLyv+do?$)tVRwG5m;D?s zVt(V0fLq18`vuE-4ocSkc&Ph7)QxM)yw93m+y}2b?^0O)QYY&)|25&W%Wuw+{&V2Z z@*24~zwKuvCf^ih+5Pp?<=`310)4rY!JpTvFNr-{nzN#)LS)L-Fwu#@-cl=+ zc0T)@F7#CIMSEz!OqNQ8#`#~f^49NN@;PJHI1e z{|qv$Zx#Nw?MAHl)Yct0B{#Ucepx6jSo+)g-#xAy*A&>&=ih&Gd)`Hxd)9H!&IIY$ z@O(G(%<Ds*~Cg{4Oupt{ee1Fmk&J)n`Sg^vdPJr8&$sk zFx@@(n2+vRbxp=E>c-BKl;0)GpVm$L=9=v!cTwh~L7lG6@i^H)xn+mWEaa{4opF*O z{^W%@4>F_Wyju;oZ3|?|6!`MES*26*_Ua3VH{PFiXZjAAy>9~lFEGh!?T)V7f9B;B zVd@ys%+;Don@wkb1O{YzzQ`H_z>HNb2{;lT@p8T?z;k+&Xq@><6iib=BF8wvR z8^U_Z=CoJMzPhS&MO$A6wEmJ=cYTSETU`ACr9&Ein>_*yl}>p*@T@D(3=v>gnK;S& zpi$>se({Zmf*OzSh|P@G*AskYxmfu8&ioS1AI2rM6W$vAy!zYg*TI?d%U2#hm=az3 zW^YNF^gegjL1-NmF+!#X5oT+Yju3yo|!nODy8n#gN17rYWpv#_;T~|=c*f}KGi?<7Ta<1 zResly$h7*}od4?S!5V{(A1|*oyRLg?w(3{r!jnEeG9wz88MHaADR&Qd1B?X&tK1`-9GYh)uP*eiPdwKP5SZv-TcF;m+o(yDN$+i zHrDs%toKn@ljTL9dj8P8Jmbxt)x61@BH!%)_v2xc(!X76zAQeM==tmz6Yr7Z<_ptf z_66+toGToA;|yP}UReBzsY~khjehkszs`NU>v~^dnD76kQ9956R8{YF4N?m~_2TVy zf4^=27PIeLFE>$*y~fW&t#WUDIB$jp@5J5G$7|l*D!sO^&UanSn(ZGVZ{5DOcgv-K z4Kw2JmYaC*)?9jI^&dV9-*?N+7jSpp;0sfi)U^{+=6EHqcV6DSg8$)m#aDG5PwK-$ zFP!bt-f{2st|RZF%%=f>}Y2NOoa?rH#e1J5SQ)a&$Ac z-zyA^-Z8W8yzBE<=@-|3era+gC`xg`cE9w;^&El!8Gn4(dZ3!~4!`fAn_J47pPmza zWO(vj@S=}O?T@B6U0=v6u|o7vMTz{%l=ap8iV}X4t>m~P{=U4-HHrIJo%-xuTwABI zuiPy9E^1+la>Cg?A*VpFv?wQ_1i1Qgo;*q8fQ-mPAIS1U{{wm!LrLQ+odW_ zaNVw0OV@?y|Tx3Ob)7U{ib_1iMJ&C+1>1E3R(3}4`=9vs~-M*_IBE) zd-Gl{+i<~h-yy$ymv1nL%Ad^BToE$)P{e~9dm3D?%scV(=hnO44b9KR-rfoL8JB32 zK6hh`MrBqx;&wN(uxfd zZZ9j;D|-`jo*!juT(Iox&efKc=l*HjiSs+69relKaKkS36wa436-pdLRAOv?CT?Y1 zzxLI(SAO3w?$uI1uyoz)0_V&hDKCHDp8u>&qQ=o|h5VAgUw>TF{B8L4ad+@6w)T1h z@9uYumhQ0&{6&O1)b)O~rc9~$`l6Bb=~>C|$D7`~D%vc&d zevA0U=B|Fl&gjpjq1>9QZC_=#@c-@0(Wiv$QWcwxMvx;h$3uy*YpRw)=_n^4-Ty)+fB(-yFVdlG!iTQ*Luizt}wSE%!g% zQOG$((|Dh+zsa9A4og3-mFxF@KQHk0P)Ojmf=i!gd|wcC=EBVM9XnoDw!ME<8TDQF zZiT`{R9FY33&x=!wnPuH%vvHS8f-?Ba1AILE&hs~Kb z=R8YiPH5e^w=-*AbsosxwlDPPI#=;hQ^8=n!~?1FbGv4BoUrQsz`0{# z@+(2R=#&@de?3o{8KiUY#qTM*bvQV7`=9!_KyG<&X5i&VTmP^vGZbF&|AWHT*h7=+ z&({1*Jiga@N=%2&)?GD6+TSf)_)=o+qKP6~ZZj|06cZVwSa`zOeJTIXt2L27XMayO z@mj=l$tFoRs9oVzLZj`TN33%__1<{aY1&S5dnmE-{gRWtS0l>|PU-JGH$5clVUYW^ zb*Db>^ZfNPN6M%oN^VnTk%8BgXR@1C_gv*&sr9e^E|ZAf=g(8lh9%bh3R|OW%ZmHH9sMNae1FH@xx4J7o9|kEow8jo z%53?fey6XqwFB$z*QuO1GcEKuqkb#D-P`*=&+U1cd~Ww%OUAbjy|WHi#u?f>2B?3n zeLrKv!|KI{Z1eTRR+g$Mudv!Ix02(5L;U%_T$8JpOXsQeRk_TZmAm@~bFZ|*veLI- zbMD`3HeI$hInZ(M{q$@0doq;QobT2@5&Bv-{rb<`|2_Vu8+Y4JUR!_1P5Wxj)a@VV z@-O$&xxdek%XGPPe;rSsXouLVn$xq>e#{Z_UjFn{#qP^H4yrDi-s*Y6JpbYA_L%2y zU${?`3*k|FCg&@5@8mfZWdHo|P* zRM~$e%UkAk?XaHHwmaQ6>(bTNKSgEJ`#&sD`J8z!-XZ${&nzzS<$p4GF8Hm84({I2 z9=W9O{fi17rH>~2Cp=`cdtD*@HsJpfi@jgY?`~}G+o+)J%;&9~RUtEx=Y@9ohg;Q^ z^<_o3IJ`{0**-F;tSai&exd$&AaeklGdONi_Lktm_Gb) zE?vXJ%kHw}-0fR`qpVq8+*)L##%7wg*4A%#zPZ$1STbVKpPv_Q&%18o`|->4{tw>|m0w!PyW-cf`Uy*oOJ1*t zIFn>Jmy2UTa9?o#thw<&-z|K5VEg58n?5F$S5XrmZMZ3WJ$AX-(=&D-za9N9X}o7X zlgsR#S>Inrq%zL6Kc&Zg^w)&*Hq)4Er0S=v+%V(0SgD%JlBKdWw!7bj&aDpN+U!zm(^Pp3C`lYqnmA{W-}fQ&j$d^viQ=yi|fO z6_@C(`F1Ggx#aBJU;k&Bu4LzDUZhePP$OU2u=3QWOo!#u`IO=%ZddL3q-k>O>dgyz z&Ucnt#rNsYnqMAgar-pO(`m`CTW@hiPHlhmj7M0jp!e(2J(??~iSe91RW%`S;X*5) z)k{?CU7QXaJ?~KaDj=`Zf1%j2#Z1p`6)N}Ccm)5}yno|9QjP_7o)UL zGW+QX$!EW{Bec3!Bt%y_WT?)lRbN@;?z~yrzUvNe`_qLNJ?}B}zB^)3))SKdcJ+1_ zp=JwP?{(KYdXMgrkqMBz{K4RER@aRix9-%Ia~`$6x32!i9@Zc4dG5*F_~Uc*X4PAk z-zz@y*75J`6~8?BeZ)r5ZL$k@*PE~2mMdED{q~#XGkyjpl&D>5)Vn|VO^Th{g@ab} zrGGzOJI$-D|NgJHhg-i&S8Z4`srTpKzU$n}@Oqwm zuKCG5GH(lb+COf7FBUyB`_@Y_%_`OXGG^>k*R&Odeeig4eKSwkii%=?o&B2A&Phn# z;EU>buh(C{!>IOQ?zLwkR+ZZ>-q+B+R}iIic3XwC&LZEZ3}0`wkx0vcJ4PW#WT3OK(a2kKH^`CrS6D=<#ni zr!K!6%A;D4_p5Lb`;X=wz27+_q*ZQs)jz&G|9WAZz}6Up_GN$e=44H1kBxbuzi>;? z9kch0h9zynhxC3%+&g7GW5t6fcQ0i5)@)iBy6Ii>xx1@By_QeCy6Kpa*y5${EcNuA zb|#$=&i)<3F?mPPoq09|Cp+%#kaz7gy?g4cteK4P{vulDosCg!1%J-KU3{{=bpNKez;B9mg&{ps3p&R%TnWJn;!iZDDz6XnJce2 z)5+dGQ~cSdWAoce(}W8JcE{QWba21<@O5d=pHDvxT>7nl%x-pMSnRC4@mKfC^DI2m zUY)(~ZfD3iZNZ7{-|M-*>AX5W&u`;ARgU=j#6OA8zVAD@<^ki$OH<}1wIv{x z<9tf$Gmh~l$mjB*Bna!ux|TO39H4{xw~hxGo6cDdxAl0*Q`vAjGc<^^=0Q`Q&0McaEjPP2uR`WcJ$7Nblk)se7DqC!=r=n#v?ea{ zSGP4>_{cciv1j?pEo+|${4@%PE`H@V;X>}d;C&yD>`r>$b6wT1x;a8z$9(7cYIOqz z<13Xj>%$@H-wZJDTYjR?!f z?Ek+CW@m2QDey}E+%36NzpTAney~sXU*)tu=#rLf?Bp9Ctl#7x(N+;Ya`C6`)9SB^ zuiPJtuM%IpTyfX_W>K47#vgAsGSBR5J9~?5r_PQ);yrEknY+p-9&*s<%M<-lK7ZL_ zt$3|J6WyEZgumObvs)ZGXU{Zgb`OycYwG5nd!vXvZQF&;?rP;mpTCC$6@a^x6zh54nFpDeaJj}i8-woNz_kOag|IKKhc+{u3 z)$ZcOTF2zX_s!?{HqOuLj%i*vd#>=Eli!brF`c=$_s}IvnG=&%RXmzGJNIvW*az*c z<_{mqF4bY2{eE5i^m}1Hq}oaY zaJcZb>4;G-Ti>Cn!W}anioMq>XJT|{`ZE91o0KB;_5Qo1R_1MBWC&ZnKkXdwYOOEYIP#Xh+GHuI}%#1HFFiJoz% zkA!&lncmKS7jfvYCDX!%VwZjt*}j}s)c-v?X6omcv98Ciz5BR-$s0+jC$Ek!~4%*-p9@65|np0XkS$Gi;2jfH{j`Ai!(#{a$b+|YK`lF6GFzO#OL z=slle+x4FuYK?ttS{#Qy1pP}24Ad70Z_b>xq^%-Ph zJp2sShc8;~|5I0a>+c7%6))fJey6e4=fm%Pj?t|8d7fe0q;>1#@2$No9=Y%9@95~7 z3B~MvTLs_bX)SS#{LmZv_(S-;t%huC-y6rPul^=ysqR#%UXf(I?$puM`tQ^4nt6!E zPJTB#m*vlj!y6m8gt{!wds%CoVf?w_aA0V>b#TC()0W-pxx&*!S$EC9S8?Ii)tVJL zr^`MS)U9%h@N)Y-WBUmWkNS^Wc4>T%R+)=chN!46?Ilw4 zAHI8=6s~=gciRyYW|NQd?=Lm~`?V~f@cqT<4=0J=n4{mU;$!yFEk5ev1pb`s6H@Je zeLm;;`(|imb>?rmNlPsbzH+pi(`3DEj*+HUz1w@gotL8J>SXO+B^=#;_qY|q@td7G znI}ulU-~ENuW_o3&q{Pv%ak?b_untEFwlF~i5iC^_u{mzRrjt74u5-{cjNhW-%|JP z->z2Xbii7zbjb_rn0;|6i?YuQ`=0HgI znj?A)eromg`{!KH_5QWxn#2x4AGWEHfmUGo^2lux<3Idck#UDG5Bx%=^L#efwSGCeFG((J|+?hCH*@EFO2;d7WI?(gBs}H6S9&dc{`t*)JooKbO#Jn?|M_(Ga(!x7_QVb0r6o%OZg`h; zr)fuMd!)scE;L**;r9%wi?6Jw-Zkm?+c7oy5re`KomJUVeOj|(Lzdq8GlggUwvBT? zOK$o4XTyRCs`^)+)m?bKYZ6Pam8m03#2o4JH`YuxThA^w%Mo7W&YxPB&3A`Y_Q~A( z&eekQo!jy_^G`aw`Y35!Z{;T~zxcN+N1pWr&7$Re^HWb8a=NxybmIC=FQ;j1>*r=h zl~g^FQw^Q_Ci=sltbEg?fRaT5V%k?DpPT0ehuX{yo&S`37t6Do#byU4Nq-U7yt;SF zUu~b;6W8rt8n~R-aOc~z_cqnFuV6UKS%0B9+<#kepU`^yPwZFkWc_=gc~rZ8s<(q)@%8od-!;&zWh0_qTGm1ds&&6Rh|MJrBz2+&Z-<-kSpTSRoicq zqZ?i=QqI|+JjJKqWzFRp^8;Sn7jZbQdpb*%vy3G-PCa&qd$7h^^-nu)W?a`Ucx`i} zw#06K4$t$vH=TyNM5MD{Rc1f^BJBRZzC1N_>u)yM;`|@KSAP$lJ6-mOu3O=H;bVzQ zoo%!De?EC$w>ECtvn^g75#^=lFU`>R(pb|c^yA5i{<42R>(77K>i%n8-1nlo4|42* z_t(ChC$J@Sv-ZB@zDkelmmQe%S?}&Iqm%z{JotFGR%luA>N&PDr>AaUwA*&kM|kR? zRZfv*^=Cha90|UlUYYe#F8S${)BO`4EM>pFPf&2#t*qvg$`vL1Q)~14Py$2228F|T`F;1neCZs zko~tt^-U8`UAIrOjaldKIZuA|DeNB$!y59A`b&N@kLu*VoHo@3^&$mp$&|TKgkc*CcMZ zUo=_j^^^LzPmMPJ8|!C;7`ANJOnzJTOeQDC-1@{9?c(dVfBe{cJ8GNp${ejb@?~GQ z{e87bwr08No=VRZOW$pKt7DyTNZDU>&ey}gZNHv>y}^1P|KUTm>+ZeFoyIUzJGUcD z;=zf|gTi^5<^{Jl+KSYNnQdKLvYKUU=$6&pi&+2N2=8rKvU<&p3%A1kp497e=EuJ) zneZy**mSdy8P`9ZE}Ne6(#1|V=nF@Lj;pPe=Lc3t`#ZYtXV0D?^lrA~Y>C;+H{P0e zF3o##%+DR#Wrd%T{|KLU-Lw43^}P#k9?#*~D7B_J@3Z%nhici*_zUp1H8 z?c<_wAGeEq=F8tQ|9f=%qM=Pif4q9i(&tZ9QNx8=9u_q;$=L@{J<2h4!$Gp~58}~;))f57P%3eg39=X!|Jv9CKzVh6* z8<{8Tmz;Tse&wMF@pyVIAq^vyml6?0{KE$7bMF88?CH)~{<{Y*LKaNTW9_N!G1 z%iXkg&s=T4?Ww|!m8*6I9m(M+|NmFz^Wutsc_K6B&#Tm){Z_s5(N(wZo?p>RZSTqb zY@d`Xb?Bw*mX{8lZ?b29p7dhpoO5L_VpcsedgCs*o}WFT-u{Eq-WlKYw{$p`P7MiR z{lPN-jKlJur{5{>i~Xw=b9$ouzK1q*lWOZ4_FpQk5ZNgIugzfF><#f}w!E@uFu)`Birdi=cy$e|Fic9Ki~A$?ctkuauZ*?VQar}yQ*4pO{4klH_`k0 zkE}noGdG5HQSO$yZMhew*8ecNc|PfEN?O{T?ThZ3nVm4Gnz-x#-%s1a-}^oNBRS*R zEw8OR?@l~*gEb+2QReGcUE9u>US2Y#)%N`FdrJ+(oZP24&ghE%`}6uDRoljOd6On` zZp*kinL+vY%IcXDZO>U1hRTM2mYd8yak12eA8%a4HvVl`s;aa1^qGF;ve}oG=GCWM z_xEOqo69qg-(Kkj=g+%~B(#=$?)|6lw$IRQ#dvQq&fRpk{+CyHxZkSP=T>?>&w3`;E~|1jtMt0n>dTES0W)|RJ{+jnrnIB}(Gd;? z5vj>rT7|{D-YqBSGwvcvQDKa3VPbQ%|xEdF%(iSn`j8xkka@LzwKE4zHno0CT0PR^{Bn(Dyi zr8QHlUfA_M^D4i`t8Y3?cgzT!Sv32uzxdC(*Ygh?ICH{7(cjS6Q`_B9SzRmfc3r~d zg4jZZx@$J?BCkD2xqt3@L_9;0X7hri1^<(H*}~d(dUk!xbndH-``wsw|3@o(vf1af zo8P`JKKr{oreU%NOM}yj`m-}7r6MF|CEt*osTroWQlx%HD^luTFr8kO&*fZ}uzkfP#ah%cClP|XZJ3+FBy_#QWk??iFft=Py6<-u{)9r!Y^v#T_Id_|gN@f$ z{Qj=UrFHX^YSgYS&6BB-zcM9HKJ|<|Tot>1@$6earcFM*g}YyI`)!WRcD7Ci4O8}e z%-!1XU;AZOd&i+w8W-cQl?8kXmN>6lWMOXjd%KR51%p@Z0@nZi<=^ckksaG5?{=r9zMPL`u|QP|Jm7bcQ!mZbG~5X z(K{ycDwCD2i}NMu@IL$SUpBDcKCdKiUffSnr%9K@y>=TckAHfsHIZZGVi+;r)an(&NF^^umEH~ra)A-6? zC%m=duZ+3wcgEc<-4l8CLCmmi}X5p>NZn| zOq#udyY>C#E;;*)bvBouzF8?YU5~+G|eulqyv3cJj2^+%08Vu10VER?qvq^+R}dyFk0f@A}n~7z+!hu6sCl zW|EWZ-iCw;SAXulo1ww9GF2`8r~!|5=BiCAuCw0~oZr)B)&)LO56sh=(R)UEo%^|bsYYPs{Tr!6)%e|}xwoR^`Q%b@FO!vE=&YwCY1*G#eI zX*qcN;2iT`{v z(@$8`|MGj2#~?(+Ou`H1(OQwm@G+Sl{zYBx^{?J2M3eN=N^ zqtQ)8R8Pda^<>*5d#QsTvShm#yte+a?YH<;#czg88CDurf4{pvGrasN`PZCvb^Cv3 zx38J@=~v#5Ute7HWdbF?h;BJDc|xh$H(C3pZ;bEbzn^~-Te!nUch(y#?F~IaK~c-Z zHY_PVdVfK^)migBZ*%MC=)L}GV^OR&k@wgC@YLB6hs0eU{J->4V(*bJkLm?%E9>W< zaj|+^_hUhR_^Y6QH~h{o$Zk{I&=oc(e1Xu0MfIoR*H)RGwBGk_%}lk|wbzY{b!RZH z(psLm@=40G#n021EkCH8y0`0!oqz1vO^msda_4?p@#u<8smep<3_YW(A`bO`_CM7- zsBpjL-SwY^iBsGpSzKQo>R9&n1gmq#%O@+|e3|rS{;_j^gubq5x#=ucC3@{o$HV!2 z6V7XGx$r$j)kvy$M^{=|kDJhztko|}uWd})adh(kkeu(zqKbdDf7VDy9{Aq7Z_|(X zU$WBE=f_T+J7LPq$c1u~&Gw&mT77h$q_I!^Ypc(ZO+tU?ta5Z)o+=!8>5TUkpQfPK z0{f5Jg>-GJ`!c)pZS69(CDrQjJ!)n`fQ8WjE7^5k38jq(gDUk}y~ z{xeS;D5<}d9P<9?)Z*t1Ti@(R7Py^vWFlW9@21{~Y*lypcB_Y82$zs(%Q%z z%C&0l`}hc*mbmr?f6jBiPw7-k7>Z_GG!|WC>w|a?dbH*c90vzgHx~K8JC^)yAn+f;L4l$;%fyNhCPcr^Rb5zO%gay-It_YB8l} zYybT3+Z61Oo%glHXQsi+#pW;T(j)X{JUe5yivPA^>f3)}L_14cd`rg3c(8#ELhAH6R=4-E>8?dl4%x5in<=gh{#LR0uw;UEM z|NU}u_!Wk$ElS+_Vjs7uP7;{pGx1_x-tn0;6q-9uSldrH`K2^0ef^B}uf;Aep6dpv(uqft62ZaOYVq(gk+CIJaHsI#h)c;?KcXL0#|Lb|v&-SZ1X6j3y+^etH`tV-;JZi&z*TUdH33zZ$f_jP;=k1`fIG`)6`Fey0gT#UsjxI zdP^`lnPpkq=C{>O`N`pbgkp9YOW!^>ePZ9L-leO=r{BJJw!h2$b-AzZ)u^}Z{gJ`D z*7ZfrW<7k%tm>G`{nuFbltqkx7ypY zxVIR2b1s|y^^2>f^s$ep9tBQ`Y`<%>Hllo0`f+>TlRjbfYsHr>+$me7vF}_>+a7n{ zu#^UX*K&p?%uXgcCmLJk?YmXwr#IHmmTOiKlJM#@7}i}def(CdHLVoV(j-} z_ubRqMC)I?zTKsNTThP9&D10I;(`@_9;?-bta|3H?N<6f*Z-{A_OHEtit%w8GBW>i z9b_)3^4>b}EskZ^>ashNzpOIj`F}h1c|`rm4cA21-MKGe^M3aG-nG0p*0?)|T%A^W zmd`nEmqg9Bka+vqQx96+xgA~m_rAHaefa$w_s#kK&0GI?asB$`{Q4VjcV6nfCurIH zV?CSya@?kb&Z?Cr@BqMbnfGMN!?qfSK_}( z-dBI(`Zc_@&!g(<-NS;bV(a}TPwKYL;V9<0n6T5A!}3?eCr77K2G11RKHbed-x?A; zH+}LFZ7+5srOT16nVElN_cGpnGRb82aiJ^Kwf@d!flD?$)mgOq`n}IwrJJRS?AqrV z7bw@6Tm7`Q`S#-I(jS`*PcA6emfZPf&r$sqYR-oYDj$hPXVw>OTUTE)7?yur*y@h8}jB1{R z-0T~k%Q8PbOgd8GZ+;<%@$9T6Yr<8po=yKYS%2^66Hb#EmrQrK*tdkq_1(Mt`%AxF zJ9E`^`g;xuAE}$4b>qW@AJ06tIg~+3><~-6TN&dD$s3bbt>VmAFuY?Ulb;fPFg*Od z)P}9i@>f|UrYtZux!$(Wn!#t?b%n?ox3;fVI8yN7@IU#y@Kx$xwp>{{=g7iI&zP^w zsf~^~dP0a{TTNPFof!AUjiSw(Q{CEnmPBaY>wkXuQf2s#%=!gCHy14bvfxt9CRXA9 z%kFRI%eYjZbH>QB%dAQ?tJHpTGf$3-uujVNxc#w$PsAqnTW1AJbGKc&o)qXG=4>ZX zanm5+YG7)k-o=!#8CmbQ%Q&yNlDoM0Q}x2@-Z@^3E-Nn8Z3$Ykn_+_<>nsD!_fsEv zb@2YabNAl4bi-%IU6=RG-~Aoxi>`&3w z+N$fh>|f!w&vzX(`|d9k*0;~yvh}zxGry|fy~$rR4nCC-d628KM|ag>w(S<3rnA*N zUM%Kj{v#{QBB%VpMsn?{`Yyfm$6rK#=?=Pk{FG!>e7*f~t$ZDb78ySo+GLShSO#&ek7Er%r?z&spQt3_HyfL?O$B^ zyJLx%U}&rOi)%MG{GMHC!?;{rI^ko<&pu`zGdA&rcjhNDUoZ!{tX}r;3|C2g&+&?F zOSt@f5}vJ=)tk9k_Td@_ZLZn7V%hKRZ#{OpDQZW}fvA7p3_)MQKDPxIZE+4?zenh? zcGU@vq8G^rk1UPsaO=yH(|F8UlW^&{?FB(W&pTX3d#9O7o?E|~)o$-Jm8+^+TTlM~ zclC{{hi=xZW#4o5%$S;Ubcez><>f*ZWxe$$1Tv#ie;ZFpF=R^Ha+YuNl#j03Zl~U) z_-uE|*}*r<=&0LSk7yyO&GUm|TIW@6{_WMBkdkqtKY0JG90seMkF9=ezP5f^ADi-; z^R`Qu%Lcm&?DPx0u`#>#QIpG-uWftTn9PDyHuY&W1nEAR6ZhYdlVP(@k;lkpDk))%7{Qj&RP~y*T&tA>(}4W%-|gUZoIA^Q3z~8o6hJt-c z;)3;$)MvMy)t#FpW_5+T5L|i)6UdCjK4eS+T=71HG!bMb8<1U_0@9UUL~yEwBG2o=A0;<@N;W< z<2vg4iM3(bJp*_Ztq`IA3Y-BwyJkq+KE6#p$qrt&AldTe0F}0ZqxJ~ z$N#-GnrpQ3S@F>Vi;vwUdw2BAV4EiT>-1mt>)pMjIWJF?USG{Gw3f6sDZr5NRx@79}i z{GVnPE*PsK`ZQEYF7xP~_x~m}MC*20`{_>c@U~Wre*Wm0X56JGZo#(I9J1V>trytL zIOMSI%Z$ke-zLYO$g5U6rug%ev`m{-{Vos9|I5xMWvmUbGqrf-mvDvQB*(uU(n>p$ zuDkQi>BuQPuysk1(0%js3@^-1anEg&V%D7LmG-UJD`nHB{p%$!gp>rdd<>~9Q)piN zw6^!k3VtqGxybc8CR4Y}yTf~^ocrCctx^|xWMeS(v#&x+f5?=d*pF6_QZ_++h*t@nd8-nerwH$UIY{diUI{$zz||KEr_ zyMOFk;*m*w2mLmmE1YCi*;all_*+YWV{67;tKI6ag_i%!p1PIcCCB-~88u4TlQ%!! zYs=GE-LK^TXHn_D{CO<3E3Bq}`nQUy??CU*Eu3c@O4;iBw`}q8sXBJJAeYEje>V2cWiQ>pM7`feHV-L>P^Si zGRWSVY~CU!v(w*r`mayxt1K+`M&FUwpMP-qtlAYEF2QRPx^2yAshjz99e9Wi+S^;_HNHl`cjV;(!-j|ZA<^$G4voPt$_rzy-?5w*#w%jceM7xN=yot%G5Z{#`$g0yXrZR1#TMfU{ zyJ!9!jx5_I&b;lS|B9nmw7U23Bn7RIPzP^;nbC2R12*k>X0v_zk5!Wn%`{DvnR4!{ z;X3{L{FaZR!C!WL|85d1S6sYl&TsFI7g8rTl>Pm>`cN5b*aN$tHy=*V-PV)D72woi z_%fsH?3%2QHkSB1)6EXGo5gH;ajtX6;Wanb+^oLY#}Hh*W5eBRSM`_eZfkKSk=7XQ~vQcmC>a?Dgu(PZJJr zC#RTWVLlhUZwFkC?VV|(_kz{a_gcZ_*B;F!7cI=@u6$RaUGZ*?`-6{s<@-W2#b0&` zKU=dR?uTQR?ERmvJbjxTs(x=P(Y+o#^KDCd>;968RKCB}0mvVS{$ zVb}K88_z6Q7+~~n<>47ht!u5V$LfBRz%f3Jr5(;JfilvdyEmNh??-yu-y=k?&A z$M$vnj?HWHefU#DBR`%$#JAzctvlSYG@U zR{UXobnE__wK`rdDh1Z2SFSwT9B|LZZiVB4f~Z5c8um$b{M>f^H8&sohvV8QYoDcc zaC0uaaQFEO`Jj(2htIKost(*N=G;`d)MV|PU9FKG%0)Xp3?vV~P@a6kSA_Mb^NQ}? zlMO!q-sJgSe8Re&#dF*5lN!ozkI9{>PvkIkRNSCr(8M+M=+{TK?KAo|nJMdp-t~~G zJ!da}YW>9{#zranXaD|biVf$_^ioJS2s}~2SMSfv>Q+>insil$?YXbc^;X*u5&ynl zEjt~)T7GHY^tqdP=c7%R1U5Ca1;#hASx%_>y>a91qq(~taBBxF+o4dl;ik{}4Cb9@ zH`XUIM_o0#p0-FLySAf__ng_>60<|LGmksiT`Jn;|Kd8gbWZnYhvFn*#{-Sd85W~ail0xk{T3@}sCdh5MCX|#NepJ)=?m4|p9oL#2S7xlMTYhk# z#MV>p?LGN?9~2GT-o5Ktad-AVi`g-jOZJGeJU=aG?BM))O|^RMp4<+VN}X?;qszv`-(6m(TVsAp(0F@duPCQ(y&j|Dh8tdIrpj)YSN+uRNo%nBW_YbZFd}ES zpTeO7T7e^Z8iV*TYOj7o9DiMzF@hfc}zd|MbR6%Wr3oMoNY+| z=?k~-6xTP-4nJddoilP1-{e|@?}FA`u3JRIj!%?%?l|dqgNg3R1!jRWeeQaPNYpEQ zZ`-g)cJITVEzb*{H(j|O#jV4m!I)^!_Hn6SX!gRpPabqAr#!cJi{xLIXA`>U(V&mCko zW;g2<_GmI*_o{W4@s79t)vhwyaUyWG4^y1TgTLNEb1Y=m zT#gU^J41~@XNie(O2DH}Nw-8FKd|`EIOEyh$^T|GdH5=7sWV8;T9BnPvtWJbMR%pV zo>g{X4*N4hdu@&18%UVw>N9USwb*K7xrNC0Usihh(vsrOT~zmWc@_O$Zo+dybb(>u zq;u1X6r`eZ;xANga&mOa2`Kl%=urkH|CJ1Lsr>w_I(d?uGBx6v3VZPh3gY8$SZ9Q zyllLjacxaC*Nhoq7ZSUj^yXb!@Va3AYEad&4zf9=gCexX#b5QM1JqJ6mFzU# zFZ1fli;KTsec)7RjOq0)^${5&t9~1=O1k$vY>!r}hKs1a(V@bNwHzN)AAv4TDAYHoku1jj#R?P*Q)_uW$Yn0aH(_Y3kezXMA4>3-|l zzdd29+MK9&H_k{;uDhx$;IYNc{nJ+wcayD4L*-t!C;A=W_TLt1pBT0&pI4dnEgP4} z*;J{7uC5YKFK#jN{Sm%dxHX6mwyZuMItD$i-2f7`n{Lg`}oygT=7uZk!oyj{DB zJ#V{IaN);kn+(g8R89qnsb(n74wC1*%K2fYwaxk8sd@L!`EoA*dA6`!&HHVQrD(@F z7fGIJlTVlSDtXnOPH%hm^2zc5bD zH-)~vdsp$FaLN8W(Ws_Xp;hN${bdfj7rC#W^{?A0(c<}sg;VsZ*{aJ4MN===@XTi6 z_)yP1oqOiRZ+q_QdrPxTkGggL8L#Tv4d1ncdc0QGo_JJm`qpE!h4?%OmXd9jem=n-@kc=KecPys_&On{77BHtx)Yzt7!f-fMCALS;Zo z7XJ)uqjfSbzVW^}lKX$k60g6jt`zEZG0!RUVqcYi!f|e^xNEyu#>SIDhRX6wqEy)z zw<<_Ji&>MSCho9Xz25iuUbQJ^Z{jvh@G_TQKWl|>q>19*kLsVq9Z#C>e9G(I_I7RQ z+Mv!XAGQ2T(e8J8nIqq9{PX(XtplLcTbDWGEmpAElGcWLO?%TA2C2)Fi?aVploXoZRGtFg~ zOwTQd+slz$@=*Q#kE&<47ye{i!s)uGfYn**a}`n zOG-@HnJ-%_wSX}#V+E3r0CF{z6z2eGfwu_p|S7$K&Ta#)G&%slr zT-@z#{=aXE_1AX^pIGIov*5ysyYb7|R@90ICp4+>o!Iel!*U1dcJY-eGYSQS)!t}r zdA@{0W}~h7pRGO#eUYbHcC)?s+4flUu}+CfM|MYW*&E zx_&U}#uV!*wW;Z@V$s=Z>whb{P1>!+)O%chS&;CydVdRsqUb69^}=h4`nVq73@Bkb zU-uzJ>*A|-@*7tcv^7|SPg1xy=|O?vtl(O&@CCf3OMLF1`91H)uFfB?YZnx&{fZV+ z5m0<5+VoOSIp1r7x70)9JLy~Q7#xuIi=S!fzhvv?55Ic~Qka{$z6A+o>fgyRy7Pl; zqS4k?hKbf(8q>Bs;^Y67~O1-QjYm zH=dkWv2~ZyTV5UIZ2vE3z06tqoTTrdee7Ij_(bUsx zObm|&T~=1gK2oM7f1*C#GGv-)*UuGQvBH|J-R<>vj%gphvZrW~%eCIK*=yL}bE<0} z@fNT(cRe~!B-QfZtQRGTi`N{SQ0KmK)ojm?KRD~mZ6lbH4JM~Qepz7rH!H zRv+rWwYqAhrJC2F8~-1-{7K+?nxf$%D(?F-@Iixbz_-6&TzcNAJawCtxZITMminu_ zxIq5XACGPMxS`!BM)vu4tA>1D0hjc|M|HRCVhhVw-boZsHEY^kAH^E+;B%&mk4#kG z&s#H&$g*pi3BGz2bYOy;ZE(-S`BOWLqPIq#ESNF3_j2M(Uhi^#2BG%KS>>A^Gw+)> z(44#mup|LPAh%{yC$j@ZFB=ZyjZ_K`5La9u_uMM@6)eIU!C># zUX3u=RBWCm*_l&lv^2hO;>X0zEZlM-Ge5JkCi1+m5VubHu6y`#blc`H7B?pD>)mI$ zM1G&n4V%eVuQewAkiRK+QvHI)hp<~@t-UFVrxS%+K} zzW7rd{zl#ZN2K)Z`A->UYPG#Y z*yCI0*E*eg(V{iWD{S{NdTjL1+W$cOq~47BIbrRunx$IoU%pyrswFw=r$|YYg&XUd z5)HkVL1B~JS2{h~v5z(6S#NEQK<}Feubf&}%nFwgvSOU`+_1>{ljF;%n37o9%2DC$Htj)6*`r*FU>Em-X1|gFiAOJPJSBhCTAFn(fRb%Ps%JHe(vMh9-MO z3_*m$!+u{?G`;(^GEVShFGmEmy z`pdA)s#Zwr?c|fo9wlF!6gS&)%6>7f*sK4Iw4bE5-mnhs=YMO<=3A8ZqNrd?sK@EN zZR_3cYV(>rc>J;K!LkwAURK;#qb^>|uj#Z; zQT6+s8=KZxb-s*eU*a(-JgGz2^_W8P?ZB#8d0W=V%6*%JlXSYhn{^NVOq!jyK*jfOQ+=sJr+@zq zhV6UWO~t1B?~eccO(-(Bpu%9;ucgNS7qv{k>ymyxwZr{gwYy8(tyhV6y~17_on=|x zQkUEOU3IIM>4)Rr_C3k8XP!Heb0xpKr0MP4%!?mwy!ZT_&Y>+D)u`7Z)Na0$;=fNs@vi#cE@MiQk@yoK8F3M=im3^OtEYmOON@_RcSBt)*dySwZ%=OlI=}= z(3j(hDp{ofbtoq6Q% z));#srTzBDIF05RPB-Tg_q?#`n!UtJC9CYUM?VED`;xv(=?9~opV$GdgS8u19CpdC zlV+*668fF2_H^UsbvMts&XeA_GQCk0u} zU2-Z-q3_|Tp5N!JEGDE%t1s_RCSZP9iQ^h3S^d&5_j;maGedYVs#c& zGY(%kUFN50Vbt6CBArY6tChB>F@7(Oh`}rbDf>G%l)g&DG_%&0Bx3sI|7j=YJEA!nTzTA1BC0dKFHUyD1Rl z()OsQ;{7IpHEBkCv+k_&W!kiT&BbX9Ia6Fawi>Jd>023hVaB0lzx3sn)_oLp*Gqf! z!8YZ#LHoHG_v$A;?yonS-s-%}(qgxUq;YZ9-xs$AK2M?byE7?8sI!$2)URR5<;8Ir)Gcqm@}!bImTx@2m^9zm3z_X3wB)2^4^IB#eV-+E_6F^S6Y*;Ig;dwc z6-6^n_APfhr(?h%x$wpQgeU1%^8Us5*g5hmU6OC}Kb^Swrr66Lo@!yIM5Ja1&*E^H z#(Js#?lqoA6DP0U`m*J2{0o|uh+WIF+P2$vu z%wDgV^8mzz@^ z_XRmmcbYiq-pizvH*Qbz3(WIBCAj?x>N>Ud<=dyr^L*+Ve|PnA@kORPox0|s{?%Xn zM$E;4{jRPWS(a00FIdi;{f(#QW>TQ-yjOd6{gB{|Pn$PSZ`~=23MRgPy^_sQMvJRr z_iuMx8nsc;|5&|r)?JmSYu%5XoA^j+i_#XUUB!Vjymncxu3<~Kw0}?fugjle!o{rS z#Vs;@xy9~wqvch>m-RW=1PO zmK^h#`)6s$sn$y`9w}w>!dxUT;?>- z5$`44j}^CVx#u9cV48?}&?`5QHQDl8cbf>GInyxp!7>|*bvy~HJI|>7{LsJauFmWi zixO|XNK@|mx`1cFZ{3r-Id|$NEEGz7;cd)VwT44W73`eTV*QMOV6@*sl9OSs5QCjxnhH$ zkI=<%>*nZn_pcZUZ_UXzJ=vIQwac>duAklt`S972FX|6`ICMWZRL`O7WU^`5%()ep zV%sg33)%&oe;ReGboM4~6MlYieVJ9>@;}ua6PCYlf4(A0YWe+Bmk(SNWmr@TqoSkx8?DUKaMgjy z5p4ClI^KWONHtATO;>bWug1+9B^ou==zxXuq^k$3Ud}IGX~cZAE9SKQuc=-AnpSOZ zy5v$>E#kLL>b#n(7qO!AIK;?W;dfW7+ zS{-bjKNhVCKd#0x_FkBrZi}F7?{@I(Vw-y2XtXx2Uo{_uj~`ae=Dt zhmF<^O&Xt*9+dWO&QMTrsq3~l;_ff?a{|lOiuT{;oAtiG?aH_!YOK)H^>wGMXj`G? zx(4no;y3eja+X_#Cf&K~Cim^h_xkwnP0LRkT>l$${&?-jX!R_{O=&%kKWw@mbm9AK zp|_X6vZc9}9{4*g>|W=4;l%#!4!v_dJEIyECRw$<&g^D-Y-mMc@ml~K~Ne+xPsQ-3LSK`lmujOI!ihG1BCLgc;6QkX={AT6J z`fc^89CEh86Hcr9yy_G<`0mVF7wd@QbAE2RHvRB#>(d?rg0q?zFm^M~3|3E(x^P<2 zaUZ8Z(W~PoET6h0gXj2%lQRMoyDw{WPdX}jxs$bBX64jQ zKOc_g57pvA4sGjWozZy4ee&_y9g?5FMu&Q?uQxbU|L})?-DyE@At63zxsV@ivA2FT zuW60-5ea|b_){}tg0Sc(Q)>YOkwqbuoA*22eXlJ$KVZSMOAZCN z|3a(6vQ?`DjU6Ytub#zoHuLtUsDB=FQ%=|3`r~P~_nq_KBMYZ;{&u||ufN`3>Ck?m zu!Z`vi!vi7|{R<5+9Hda?6HhT!P%;)1{&PXouUKOU0Y)4OMQ$S?geaksY*!@a%g zUnccDD_kurSP++Nd){}ksD-#`PA&W0OB?}qg0o)fiB4+x-%(OfV6xY8=G`y1t}`DF zypxpv&Oh&<%Z&ho?{nH7Dpfa3saKN!;G!&hvZppKPE_$9r*>24s^iUHrIs;mpDAj( zYgU{4t2s{VX3YN3Ip4wWaA)qVP|YoNjm?v$I_oQ){S@I-=pe?vq}XtDk%F{pt<% ze;(~p%sJJqqA6*ca>7z#@xhOaIXU$1Sxn&QU0v~Pj^EWc%LEoN9to9m`}?QTW#=LR z-aSl(tsDREXe>DYHeokA&&o@Ce7c-#e_zvCoW!fTZq>FrE#2GIrR7WIjASk-&DrGi zQ;=74!YNx%>vM$>;+mQtIjlF$mt$S$yF|)W_*nhd-wvfb|Kpx6IlQV?$?TfHm+P^Q zMk$kRL%bXBz5AQ>L(slIe!tY#r!Qu_Ty^vLzPD5UzkVyA_Q7&O@saZl!5*?@b}>OW zkH*F>>~Y?HOt<{~iH9|O3s)pqe|#umBb?P}weEQ&QNMV~xc{OC(#%&iqy zzw1~XoOrAwXnsA@o+aA5RNt~*>VEUgn0fE(#m_d~X4}9RV70U6vQaDluk&)3YCb9~ z&fL49#dGV2)8Ch_>5}*unsdtL(9JC@=KQVk8?Mdv$v(sIXll;GS+8waecV&$TX6eN zw~P>p-4%ZI*UKrYe5|YzpILRM3!dRA5jIp8_iJo!qQQ*yl zEdIve?%>l+t^a+F)%~?pI%4-yq4^m9&&;J;#Db@N)MijL@N?N+9J>2;>MOJI^Jil} z$S|qSVmrN{R&w3Sn@c&ipP8Rf&mp_DWzN2R{PwGTbAQy?R_6UN7E3Zbv;NzPT>%VA zyl!vzZZ`E{-*i>0#X{<&-;>OhW*_|Cdk5vV`LhWvp1~TpaPk%P0Iy@0R($?8shvt3q=8mbS%B|~n zu{^DKaB;oSqN`e4W36X}cD(0Od~mW^ZttN)?@ASAs8%^im zcyH|YRyL*bdce7Nyey`wU$1Mi&C@~4 zBjc9j{fTmBt`9HPNH5x!7G^r@XUc-)C+6+?S8MOeH7;Ku-T%8@SmFN}mWO=XSkre{ zI;32$MUDhZVJQNB*6*N!z;e;+eAg0NeJ}$tx#q<$D{R zwcH`w=aeV&L=VS%nz=V#-!;3JU@4)}aCLF4>1p$K4~}g4>*9G~t&eG2<*86H`BLj+ z9gl9lo*^QXz)_KEUp+ZVR809_mEe@Ab6YYGiubLto>M25-oA#>wtAKR#Vht&eJAUV zc9p)_aQd$U7mMERTbZtJKh^J1^4a*zlQAJs@uJPQ||)Kdt#QYf3ERLCZsX zdL<$h%{RYp`0AwN)7LM_^?Jnt*I5;c^2tZOFBja9>>ToF=h`lVr!_5JQZFYg6ttM( zx#}8Yy-j8K^yd{GXSdF+U_7rc!_W|#q`W?RexLk;d$Yr5EPGmWIV!{P>*;pM`uD$g zS3SF!x6pdNQ^``-&b^l(%eq7y4UV+fcHP}`!dw0$uj<~YB)*C*V~(4DAt$t|{?7Sy zy^yMd7T>tr7C3Ahn)aSaNmT$fYn+>Ps77H6jIc&SiWuinD2f7|8>p?33g+&4~tcK5Kc@>Vv_ zU+m|qSq`f%eOqCj7d( zJbtcH0P_^hrzN}I@07lO^RG;S7qbD|nj@C{Zx3WO$Sn~3BKz}U-y$8!*z4~NjVvC- zDBL>cUl&p@>$0Oh>wv(Sr6PRV%x{ek%-B5+%zQ?466}|2vT*epfvAfXxP<`1<9p|FbtJ8{Up8R>)c0 zGre+kNr}Bl-1oTpVA~VxGcK)-+c2a4xWrP=9YIxJWAoc*ZDe8%Em}}1wcO^+p}R{o zZTGEuv2K>fC;bawYS#spODu5bTfpn`X?2r{0S6bu5qovd+0!@<{4Z=^R$%CueQQ?a ztr@Gb4lvxfdq7io^&w6Bdget8OIE$Um0zm#Yu`1&1#bcyL+!5biZ5=cbnGwlxYwbV zu+vral(V;}nZKqem*(4;pYv|sPg1L0Gx0~%gFmr_4-U*c`7kB#T?)Uc#Qc{tZeF~6 z^1Pux`H_Aj^J)C7x_p>Wg;_Lg``r4cJckD{*|9}0F z<+tJQ=Y?NNbGx2~)l^MgxBps=#^s!-_`FRo|G(t_%y{}fTi&|NE9(w@OzCx1-3t~4eFe?Y**lY)qO?v%Ul}wx=Pw?O3MArelXnMCVv0EHQzT` z7JPVRwR>+<@#1$(nyXXqU9Y{gu03J7UjCfhVb{%Crrh3}E_`i{|EygKxs67*Tl03! z-7dPNO>D01tu4Ec_+{^DlrLMxwl-@3iotIZlz4DE)JPdg3FMkLyaG9=zdcH-G;6{gpNf*$=EU zgCwiheLZ=a@7&LXOD{E57d=zhd&J;d{ke$ab#AxsJe>Ny%V~YRZB3~Bql~PY4QEbF znh^M~aqhb>b6@!1ZCw_mzbP>+)q8oyq={#b27MQJtN&5rj2G7o7NsYNT&wlJY`N3S zX4TW(bZ9zTzU=L9#majwFVb&cX>@$%^PT4&^T}^wDp>f?XR2^L^_cvB0Im|lMIkDVUOjA((`Hq@^k|YJBr<|Ip)5WgV|C#+m{Qs!+ z=P#JfIrQz=BLVYLu|7^azP#y2xo7n!EpIZiedO7Ft*B8wQfbXR&u@ocZD{y^p}r(p z@zAI28J1F$3W8UZJ(4x+=TJJ$wL{9`z^&PrGxuIrQ{niaFyS%pe&5h{7kS)#DW$^0TLJ|NZV5Q`MF=Pg&MRy>7a|*6>E{z|)|x z%Z|CP8}{7&(xuz{?bEcNsjshB2CUm~-F11^g8Hz~wNdpi->+J6eW`5x49o9t(obj2 zFpfnTbr-0neqPbC0(V=Ijq%r z6RfWsipu3l`)ro;Ca`l;L_#{(O|~fultO&t}F|CD(KVR!eWEn z=f6t{b{P7X#p)I>p3&GPkuW*hj<=|7k{a)!z?>_OE?(w)Ja0?=U*6?K*B@V>u|`@V zO7YM=huh2lFdis=y1zB#q73WSk}ETIf3ma}3X@E5pFefk-gD>fAMi-F>QB{ZZnNQH zt3C6z=<}On<>41rY6RMB&+zVcP@2vjzX2Y24>5(f{K0jr_CH zizG_to9;X`wT*YN%`$-s*46brhPqZuzO6ja5V@m4!Q%CleHn*>{=QnGl9|}xIMG09gT+Dp-L0P&$=6p-JMFt&Mbh-ya^?E> zG0n4ED^Ig5mHhN%>c({rp~gSeR&3Nw=5&90!g)@S-}^01li1GGzMM9B*0beer6O)C zJT|VanAzEpyk7VAnL|${SKofv5UkzimGyCRrQ-EDK_<__8+M+*5LZ&NcB0S486C%^ z4cxP&u3emLGO6Lz)@VaNi)n6-oB+ZUCeO}Vmr{;S5(b?IP7c6|#+R`LEapei_h1Vr)j%8G{-n-gk z_Rm%-A?14iVUgUmsUKTzBpOFbNcV`?%1{>uPBw&c~Vt@X@AaqUGi4Pt8l-jtaFm? zugYIPe%^g}u0dw|=QgW*GhQDq*E#>-o3H+orZe90ri#kRZ>CPK|9fM>Hj_H9IrGd* zXE@hft{2VYV%3odyvCH1dR;gF%iJ5Qr)9D;G;N-9G_znEugTZK*bNg!Y~C5(IP-5) z@{wY$8(Ba8sLYGu^}Zyh&;5Pc42~Rw@ZLoZ**%8&ol(9!Qbyp`I7p3 zE7pEj40C;Zb^5xuFZ1KA{G6YzyP1A`jl6+sq((-8{)&c54S@+vA_4-ckpTugAO4GT z|4ZlNV)^%9k>%l}1^;FL@vAuem-h&m)Y|Z8zue;gD;7JyE$6hk@80u~(az#mdaaq3)w;KQ>(5Gl;nkZWp1bGUHf1`j|5Bnf|Etn`x!2M-^g6ktq{-jMMas*@sZ9Rr;Ey0?E9bHayMSMy|lY> z{exKM5I>_nMW*7_L)<=7elM&KQ(3j$QiAh3pQX`M zz4b*FIk^dsYTI~c&3>w0WYKxAg-@=)Z0Qf(epR_wkA6Sd(k3uFqAcWAe!KbGLh6Z^wh>KR93AU|9C3^5Q<>)*H(n*{5+V zHj~-1^5CJ3x_@g0*(aV}Q@`D@!0+J=DW@e(jlz)=+8(uSIC&>h-TAV^(slX#(KGk= zf11Tra=}WbTk{Ho`%PV)l?@wHC%l&S5}Orr^AE3Pc5C9DkW-ccB^-0UgqE_!Gp;I4 z^pX^~t`Z%s`fn9ywv$x9n8UowLho!%9tZAqU-2mG-Q~+ql(jD$xbk8Vdx22B;{`d@ zDQsy6Pt6ZVi8*xm+gz<_XV|EQSU)l2Rdkf8?tn01zver5lh^&&| zvby@&t(Cqv^9_~1$6QLBC%#qHH*RvugTwW9x|6t+8Fa)yEIxQjE6RO~ha$^M{rsOP zTSbNXebu*pE=WuN-&AjSe|mW2wByHaE?av-@#@CP%WnRv2dB&t@0#}J+0k2`xheZ) z%WF4P?d$un%)WQ}l0CO(6==rC_j+Faw5ey=;j_F!S3Ya(T%>PQth{k{ply!%p`!EW zU*&IHySko1*Go}stNq3+;R#>fcp5I5Ss2@sDn9SamwLgMYfCpde6FqSedq42Be<8R z=LdFSsbcJ-DkzbZPZnC98FyEs=( zcz+>}Hz81y3jAc^68$xIhtAQJNBKg7jBi(qoD07`Q=#;Pms*lq$-Bo!eOcAJmf!fd zwEE(mol{o^3pN*hl=nVX|3q?zgs9=vNox+-CCoOR`1<~)#8jrMmQ!{2J$Sou3Wwg2 zU~@U;b9}9jUgjTKvU&Q=JKp*gwYxTaT>fr<)Z&PWUd718+aj*jn-|7cJV-R*x_`w* zv1Fp=O6~`ew|>;dMzy`%?03v_L)45~DW@H5#V5WMt(dEP)%LO|?=kZt_h(z{H}M-! z2x`u$n`tCGTfBGwYe}AKZb{3|y?H0oy2f-0>#O$e==`<*yH2oo)g0M-Rf;QbZ|NqJ z61HE{ReZLsmW^sle4S7qx0APi={)Jn{O;@DT)Z=}`>ti(hd;qHH~*T>_n>gj|BC6g zJC)Cyzt2k*FueW$j*Zp?O9`bzb0>1SmG{@@F$b|KTfAoO?hduc@8p}dPAx8M#?s1^ z&yS*9+5N5l2ZsI@&T@E>v1z~DgPGN9b00Td@B3()EwJS1vBE-wH(zFFw|Z~qt9R4x zDm!)VkA>JnwHbS!ZBP8{u%)u$evJN!?v71ggJ#;ye|5)VmHP$v`!g4)|6KR9pY3sm zi2MClBJ~%RNeZtnRlB;hB2jVW;ZN^X^p8$G^Kpsfc8ROYT|#^vR`x8bdphCo3b&V+ z?%#d3aIK)d@$BZZ-c-rB*|~e?J>&DT@822Pn)}ASh|_OX-PEk*i$imlURgS)#c6}! zfg@MBH!D5NEPb>o_sb`-u=Q>xPBr&W-C(*g`B{0e+uxkMef1xsjvCh%e^5z~k2XR2eF@c>DSTmz`p+Yi zio%aS&$t_#r@rbNYyRoY8^2bnRYhm+nNr5k8-8VvaEG#lZRxhGm4QpX&5`}x%OPEh{6l^`6zlOb*dM{s zyFa1nX@Barb^o%pTJrB5d#1l3g>TLF9nXL8@<*=DOEW%x^TX-?XKn{4{19^gzm@O( zq!xA_RS(v$%$7wDXIFZNZP=h$!z=B$+s^yBivjOv@%7f{^Nxz`k+>^0S?+HAzi=1d zS1D}S<~%2Z+J1TY2%K9m&;L=x%fFuwytKXXSE#k*Vtn$+byr;Ht3@y+?_u9$F65hc z^WR~w%;u&EDXFKgYAr1bIr37pEk!4Kfo-Oh7PoFu!|TH9HA+^Sf~Ic%a!kQ%b&VLq?D51;z>O7+N#`1;4LDtWmj)3|)(1NvOrBT7terJPJzEAZ-u zn@`bn-(X42;GpaAzqzMw^_QNqB+JIeJW)?_N%?)HoQCUShsD0`PnGo8ys2^WuiQSZ z+KzYbPkx_PUb<-l>rN%}`yc9soAVO>ag?9qn`rp|vchT~7MH~CeKNjR^$v$$k(-!x zQGIv4@XKGW9=Eo?b2Xi1YxZn;$JIS8LK7Gh9d8`$$@{D1@z98!HYEJ&=b)7`@AXIS(4XrW?(iL+4b?3>*CIOZMk82{qO=ex8tk) zdABSp*WJo{dw+GG`0V2Us#e7lciXOHtKXr}e%r&Zjr+OAw{70LIRXv#h#$x+-XptD zV|VmJ-N*X`mj<1mY9Dd-kn=y6CJ|TW#OI6}jHS=51G*C2xkH80GIHErEW0MY`it|c z(9J@-u2`*qz-ydXe@$qk#77;oUTc;g>U~Q}HE-7bj5@Kd|CNG%@{7`G4O=~0x~3HR zaa5n3o6?W1Z2C!TzMlU2{Xw!Z%IyGL6( zZBH-0`$$3h`>ahLUW7Vpoin|4;j&bf_w+3@xr85UO71D(dp&0!pSGT@0-w`?{tZ*6 z%@JBFtvxAhd7Rn4r-cVLu*cox6k6oWq{X$4%du?kOK(;A=Hn+arFM$CM=x!0)}8rv z#q#zue!LfiPkM_5GiNgV&uQeiU%%wvYf%r6{m;^VAMWB*+m)wd$13he!3hTw`ae4Ael!=X ze=bzmyX~EQh2X=zIk6vCg_-HaiM>?3Hl^#uR+XM=$#a=2nzjmSDdrn4nt$Mf9n)&T z+lI;+`NB7wGHyzo_uDmj#gxSG^f@cM_>|OD-tJ*okuV`gv$J=W=9SPnmuD^Z`M6QZ zZ`I^0Ld}IaA)hN9-&w3)+;p?pSIq9g-8E~r-nv-t_BmnF94C&9sC~!HB>MJjoF=F( zIm2uJd%MZ;r(c)W+3j0?Yr&>4t}h#_KQ0Xq z_04PG#@vq>H#2>G(5JS0rQU<~mlf81 zhva^DkPuYvuOP!R)P`+OFNMp3;+b?3Z8p?5E@1?q+woBg*Dg{j<`Kwc#1&Oz*=_ zYc(#5(3{hDKV@=t_@Sp0qh1QnOn$ZIq@s?0m`6^v2;OLQ4r=3#fqWp%|)2yw0C*&NCUvuW(C+4{2D!=`8q?D``d~_o>e&#kPS^<!OKr|lFt|n zBW;5}vY(ka!BbaQ*#6Rv`AaTN*17vERb|HGdCWWXkDZeE|6$s0_ti~D`{a8Yj;pQ+-`18=*v7rNL;$WCRQoNp|2)~WUI8{>N6 z-owGci+E$YmFKow^G=w{o85Te>t)5nZn6;XQZ!rFrk>76K`r?Ugt?^`y*xE}ek~@!^E`RX;A@A$=j@+v+ zh;LD7-?e|sh7h?AWnRV;?KD$mk9fxyuLl}px-&L}-u@$+f#oqfU+BNJDj`#URTb7;_c zfi1gKy7c_&@4x);o-O_3w|9$5UqpzN+1I~2wAe%WgVvpZCugVjT)33-$-pA9dj;RA z!g&uKztebRZ8)>&)jOSO<$upE;wjGRDAc_E^WkY{e>LX+m6I&VCYRr4 zO59x9%5mtP!Hx|ACCeREe>KZR>|Cpq&)j)1q4oGl4YQEnb#|Qf_ugDmdN3_fRZ==? zRou0uUdIZVK4{z&vk$U(cJ$Wdot>|)_|AxWv)a}0&HEKg7k%IMs)W}$F5^k?f@s-3 z$yTYp{Vo1?4$E$w$j!^T`@>adZMi6}=b;M=ru=^P^3Q*`^%)xtm&ImmX#MU6tSLfI4u9I?yTH&g@4SucbGoN;;@y! z#P>b2WOZ%oKJ|y?F8g0u%O6b^t?-+Zz20oqr262rhfgoQS~|%uQzvSDtq>&E;>My}kC$wY-9337-?zSoS0s9M96oJ*%f&5) zYk5ge*Ipe9ZpDR$NADSK75;x`Q=NYVmu!By{FS}mOry5UxZZ!ae)AQv*}r78e#+k3 zlJPE_|Igz65ARE{9rR#a-Jp@AXR|Rm`iM4Pc;&o*ItisBpKkG~o~^u_pKB!bw%|eJ z|DudHU96ex-_IwJiEb~VC+9yw`wx}0b>+Y+*%GFz& zFh^%qa;{G9(wwtRte=d#ejTfSJ@fRoBioLd`Mc{DGqEwnvp-XPGV`~_=>php9 z+f&2B=9JALA@Jw_&-Mfbk$(*$^ZvgnRC~EnO7&T?fk2ArhMWH%{t0hh!)A8;+04`5 z1sK_x0@&tev41`DHm^eJRkx$Sy)q*y?$gajFQsmIn^7UNiCwbP@!E_3`Lj3PjH$0* zwQED^#xlY3k8x2NyZeGKOjg%xnw8lbJ;QRs^|PJjdpF*@lh?RR&gP`gzsV~mPnjJ% zXU4p#L8fJs=FD9*S;m*2L2&XTHAt{?n4lPvuF4aM4xPoc#SI5p!kdDqTyg z-SaJTV@r&c?YEw@KLmgt~>7k{i$vfH!gCl6zp(vQyqrO(fQ`uL@2a+E}k%C8Go zcJTQuy;s|Q^?Kk(=S+ zvikP@&Dp8d(e+uvhkt3MpPlID-4Gf363j9+phn)ZSyW}3d^i54{w}TzkOwmtuyzB^M4lq zSrd6b`C!+-j}(Qgi#wLf9TZ)d^TKi)GJA3t{Iqg`VuyW_HBZ~X40{dpPG()C1M z>u{ikS|+b%^yiRe70-kp=N9-#-!wGk|MGt6GQl-Vcg7cn7xRXvhx0vM8K-f`I6h=@ z^tNcG=NEZzKap3`-y|F%`#7%t-?C>VALc)~p0A#*8g|$F^Zp>SHH8a{&$VrA<8{() zyH$F2y+Nd7b|Rwu?^MazW*w`PtovR)1Wp6nAU^*PH}KuO~j!O%Lh4 zj%3}OV8yepft@Qtadjx{3DH`rfJGR-(Wv+L6YwR`o) zg}HBiY*k1(H1k))onu{g|0-^L{#@8oofflNZn{aav5xWID`|JOw7>9Rbng3Q$H?1l zI63`7_CeSFux(qmm}otASDGg+A<`}SYBJZKDM(@PrlL5k$$Oww=?{b zX9MHIwS1mT$1P;|zy6SH$^Vt^cq6^z&D_~<>hJ2cE|>4RaPrZeX_vi8_EP9JV zCM{lTP^I`UsbI>ji64($ywxA*#Mg8yo&Rv)k+iB}x!o)H19~0Z)3&Ak+mb%}?%#je z+SS(F!TTQ6_ZNo$buOBHs(*%b&B}|KE7v>~)~MGD?0><^_IG23w%g}(r{`=-VoCOV zd@^2$+e1@bb>gA94|H7ZIRdSCxHi^WE{zNbXl|eI++)>59f>CM>0vQE*I8_JZb{#k zz43YbMUg@=o#<22JEnOx&GWQnIqqxmWHz@jU-QHb^E^+yEU$lN<8!p>z|Y$}fVbohmjDo1Yj^|^vxWwt*Aj;wY`*|O&O&g%)`OjoBKwYvAp z#JTDJhSd6#UdxqyZ>Ff^nE4Q#S0#CQ5 zlke5tNM+dA!5<^XZ1I!Z&*? z&u!iQ>E_RRr*-Ea%)KwU{c7F2dogo4j(42Ax^UlB1=AF{7prG837A>iuP|MEpP~La zf57vG+N+PFHFWPzyd^jJywTsx&5p;8-&PbT4caXH|3bQ(mCo+Y_+6*k-)`CPn&SrJ z`QxtN>)g9M?SDviS~Ge5moNRm8}}>gqU1i~ca8Ts1ugBLXEE0wI4f0lfBBt1@v9=O z!(T_s@vbnMv*U2xhPV?hN_K&FcdD#-%I9uqRxhIX!?W~q^ob+4;wPQW?mzx%)}%$7 zUI_g7WoWsj{p63Q(JSXL#NYmyQX<3lK44;>zL>Pd^)4Q!=gkH`jvnQdZxP}7v3$;@ zDT!_uId7}Z+!M;mc)9WXcJFgn?FFR&+e{HWu>J5(VKz1M>2VYO-L0~DTUi?#zbmHu z$KNg6?k4B**7N#(`DcFQu@I}s!N>=PYWLlNmBOssr%(E3-mzVt^Q(IS!yJ*=K86eHYk4PF6uvAz_`Bu_UrOcCpZ6bm zYltZCdsyx#mgQg@uz0 zEG6U~Wn9p?W!7nZaM-k z#O;fUnaUJJm1xV2y{9)?7pJc;-u}Pt{nzhT=a)W>FFRLtcHfJ=Rd;JR<~>!?p4ar` z^33J4n;n=Bybzu7t$*Y5YG2(owbRW+7u?BzJxNyRI?EQTO|vuBf7zlX!p>skZxB;| z&G17=>=vtAtExO+?p)64C)XKxdcrR4w7aecB^-GV*Spo{eVfiS({L0luYwc@)+Mj;@qka{m|KF2s7lOl-THZ;$ z`)NP@j*5cqmk%thN@s$0wEY%vj8h7+Ze$Rc@UmWh&wl%e4{aAxGIAy+o_`a)GoVdD z=ggWz%ta@JE?oFqwz3`?y?w`B$53KUUh$Wcr^Y{9ShB z;_RaD2PHp6sXuHApDA$i-C>c&Qxif(*4gjuce1QdEu1NEF0J!!{fVm$63lV`76?Ym zheX+)k(}t2cG{uhO;1qA#qOBGo3)Zx%kOC_KRqKMna_K?a@tM%r@Pp11-o&J9(2jC z{t%y-ae7Ln^RkYH<&LKrJ|9pGUcKNJ>s^Mg#+pr4^$CgZC)60u?~Fdap0QOUs>L+t zr$Y7;hiOYsIX{Ywb31o@Q$@Y&yAN}PZOgJEp6HovT)*|S`7VLZXk%%gkk|Gp7i9JI zuP87tc~;YeLRYiuPOatf24WJU&a)`kA|xRkK7&2~S zS?#M3_#Do~V6wOMXnDutz{Gc3KjweY(m75!u{5)Iq_{@z7 zyCFtE#7n(N&Gl~lJrXKG1+`9b73YY#Z#*4-0PWn5s>z{EA z_o^ReMQW=g0#`tfP;p4~LH?MlYp&*8u8s_cKK>Ub_$@~Goe$jboz zOFt!4YgPI8Pxv;Q*Oq^KX;S5C{@CEkZr@*Fb0;t9H#u^@e9K)gbAA`&PM0Oe+GWqU zA1XN4Rls|#x~yNLEuv=cQQt}PD);deat18=uYIa$s;f|l9|PZ4)6(4*BEj{qbdOE? zabLPqZN2>DbQTYvM-Efx-)=LgW8~Or&|ltk#ph`3zsKjp1d=XKO})t7G0!qO*E~TY z;^7U}c7eCmRwe)~_@)-%m)t zc$>M|!@#$!Lhyk`;)HwqgtQhsSY-5DzdrMRQk3bh?Y-7+Dp&IM`?XEiV_*sTTr_?4 z!hiyS~4Lf{l?nJ z6?KWX>X&?F@_)=|Wpiis6YT!NH9fDDv!Xsy zPju1}o74YPgoE`D{rgeTVe{;W)Pqf-@lzAFtrhf>&MTN~G*2&hajsC(l6vlW?|`oU@A9Tw;#(bjWo!p{Vc-l!N>o`{*RS-<`*uV23T`=br7SCuR}Kj*8*#JPt% z=Oomc6&+pvF=<}=yjjwXuWM3@__fzQNOtfM>rxTvcv-8tIqHhN@9{mpW`}kN>{9RC z81h>?aJ9wpV8i#Ta!!>#;+=kOiLk`GdMC4uY{}b-Hw3I=$)B2dFfZ=d>jKF&-x9Cg z)6<>wY}+>Dx0Syg4~0ID;w$zjPvf?!<5?Uq>+9o?+u?^I%x(J@PIO#;nZxw|=`%@< zF29VHwzDkXQ`)QbT-<5Xp{pUcBSfQ1Q>6oYN-|x_?phlk?EhJuFR@{*n(_~chMkvp ze0Hv%yzHAF_Wu z@mOA0#kVov zr`Xl*HePyu?&qb`KZ;dX?3~>A%*pxYbE}knWqI4;a+K$WR#-bJ-8vK4uKRn9Z_NG5 zIcY1;EllN)ymhGW%8UAEvz{N$EWJEIUA{qU(%(2Ow;S`GGT)UksO~sD`|C5c?IP>x=`$ZDC8itN=*LgjMaJFKsm=39TC9?FfZ7t*g_Yd{2GGBsu56qPzDt^eE+Q zf3oA?iwhxP>Z|YDoM7?Rt-9-W$6#Jg{mtu>56ZJK&fdf;;qh?;+n@QlCl;Gd%M1#6 zzBO0BT=LGJ%%4X#zulm^b^Y9H|E@3Cy7O3`)z0T8 ztLM+GSTpPW-Iys?jLn19JtUsWPMN)zyC{W?^~t%%-wh_!?2Tw z9&x{y*T<~2ytTPv`|J5C>jNuS7kNJOJ@dk3&+~hEw^TMQ%dL6SdycyzZqJ0*w$tA4 z%_*MyHRDe7`9(eaDmUiNIM=db^W94MZM9}^J{|k(mv-9rOO>*!l%`-$%Wihh_$jI} zZn6=t)4E))l^ob)ajWF=%%3dsj~+N~EZ$eAV(=sVi9zrF`r8*jS9NU+beH}2a{5(` z70%1EC5$K{;=YogV(EFZ3NT;DP=IJ3A+s&|LZNv*6Y*Dd$9TTeSwFTX11 zy`OE_+{VM%;Q{7T`~D}tBFrq0cA4fm=K7ytX|!IADYJJsYEv-uvnaa2G1{pi%3DTnOm-ne{8cf+xi zbH6`L3#si9-Mj7gbwiHk{-8>r`1 zmesruN?Xo%DQmt`o8uOE+rg_kWFr5jjOFw1e$UPLCdhs2?ec{@hc{=qToJFoxW8^A zXRNyEnMr44=8E6ld*txEX^Z*~M}FS(&hz6d2VtkXU7f;w>rZ{_y1LFWVwHydIphBy z7u@)|?&x#ht#vzgRb^y$E|o5xC0KX%01xk9`KvNz!7uZs*&oxm$zc4z<;~`4IoA$- zYZjlCdN9*r%eK;Gt8Yqu|MYS}P8`b-rJ2U{mrm(0O_;T3EzkZ7bvZtqd)H5qZhzJ5 zp>3kM&!_sgfq3+@g{dbeIIZ(@ydx-=Eh;d3oy#%pY5JC{Y{oHZ^)gwTk&_N zV5^eGZvQOVr1O`H)K?^2_egwV3uc;~I&J=pqw>5qA5A;W zqo!mzFxLy6JS?D=`QyUg+ilUaL}$Kn|EMxK%2~MF_FwD0OY_b}&e`_(KKnslErs18 zuk<$9EXpuE;iSIdaUfwX4c)nGizFN$#&n>v(??d?(Jiny@35G?}vuo zN$Ok{p9Bgc{+?u;8=+Tn}6P1=e{-m`S}*=yE#?}?(xL}@9*hnJ@0{!2QzyWcb=XIcO3Ybw5% zPNW6%{A5Zj{<8ed%%ghQ5i34(tpAtXH{)*T%FhvZ@*if*+xh<90ojE5Rkb^`8|MV; z&+PQRe@|1PIi#FzQt0+;+v`QYy?x;8D)ud={~Zf^T!TO!=l11i98PNSbEh~wFEZXN zY;pF=?Y8Ns>$aKe>^f5N$#9>R=S#L{svDA&vPxzwKKE;v9QTgz4l8rMZ{}L#aX5R0 zSK@YwT>0SDD|cT?UT>>C%Wr%1DfJ06?}a}tEpC~ng{z%bwM`Lt$m}!CzFs0` z=57xu|6LZn8me>H^S9MicW}CG5WIQ1`@N-lVL9WyO+Qafm~eWx(}je__0yM_oK`j8 zc6`&4jQ)~qD-WJ4{BUxA&E2_<+P9>>WqUt;I`z(8cjxu3yK7Sa@c+DO_+h2!qVFPK zVh%)FtSDT5$81O2$zxGVHr{66bez4u`PEc?hx+d&r@lNkGPCG-e!g#WY3zo{n-BJB zly*IymnzO&e{NEY<(G%AZicY@dAVzSuQt!S>w6|@{FoY~!F~7i%NaZOD;9m2)5|H< z-0JYvV9veU35GiF^8ysS#9QWD)QG=4deA_=db9Jg%J}`;wzT|y-Em~5YT~-08^RUa zWqJh#HGa-ftKav*o@aVZBl(AUEQl$ zdhBzna*;XDzV1IYoT~qJpKoA3`W$wOJ7edPhx#^F z8(I=-|9Y=mxzxTxQ+W0{wv2x|?Ti`HnioG!`}DAEwxiMv=h)|SFYU|znYVF=>jyE> z$EL!}OKL*yD`Z5STDb0_q6TMu;KWO!{o7YfYHq5DsAJh#_~Ao%$o<`2r-Y^@9eXvK zdF@?~6|-MYQH@yCa*_G1*}i~FP1BW*7H4VmNdBMUy8D^&`DO90&LyI(PC}CFg~M~Z zwmti*>U-1ku;9V{`JD?wwKwv2EOB$W$nKK3sI$8N=J%x4tkJCQJd1X{T_;f&JGEZD zYOOUF_lX0hbDw|F;c%N}BvV^7kCFdYevEp=myiFLj_a^pElDw9$A`Y9PyO~t^2GUhac;RPn;WFFxHve^RTsJ#*4{bTttNI#_hRG~ zvqQ&SX77G>OhbQ;sG0WDW)*9LZv7`_-=2zBIi;Up&G$EM>#XzTAv6EkR9s$rdY|s$ z^XrNtBZ>@V>jf%j8b~{z$T#$?6^nko;HB@9#^hONjtjA!HGL9vzWn$!&lxTiEUdvh z_w(E=2`|3+AR&5M!==d^W2UJT^8dYd`0VlC+Y^*;2iXh#un1I4P5KZ*T1=c`LH=Tk~}vn*4JZp2)6 zv5*pae02ZT-+O-F_SIclJHx4kduj1`r4sLrL7#l)vFG|l>$WgmVd2jZH-50Tb2CHh zjb-^OdA`-`%I8s<@Vk{My?$BQbk*%gm}5V9<-fdt<9#oiobgq++Lm`KSO0$R!1|0| z^$W*rq0nax|F21TYPx>+aQzJjm?R4Nqo8g9fGKe{+Ub-hmR7Xhz^IEl0iXnz4&0dcIrECS`Mz$sCvx|TbbGlBKU7aMsSjP&ac6(l ztJI4@v3 zZmN7=z+kH*m2*Z@b?0ZUMqTehr>m@T2{LX?%`AUTHN1PPl`u86K5(UyzT51Svo%*w z%e-5DZM{#;oLlq7+xZnU;wQ(Od=9aw4%qhi|AG|(ckel@ zPf)g8vd*Et@8RYpH(Ttw%8aFpYFT#XgqSVT-KANnd@T8k9NW@_o)qtnjh=2|OD5je zx?p*?slG+{{qm%eU$^h4EECH;+o!Jo z?98q^GZLq65I(cl`@FkmFz55TqVuk=U|&`)b5KKY|B}NucnBdSS^xFh#zmg+Vy8WfDYx}PRTFMm zrc}>L(|o^o%_g0dg51Abb!Coqy*=6{AQi&XZZcUwHu{1nx8DB44tglGdojEB#Svzmy z7X9_J9vIH4S6IonY(|+_L73W|udf*&&g@r^@bI`&aCbvv;rq|mr)#G)Yt<~r9K^cJ66IlIWq#pk-;8NK^YRD$Om3Z8VsdEs6g=9>BsF7F;)Fx%)^^pvaxbx52?w3ed<(c&bJ*ZeVEU~D8P#uAbAGULE#Dd9uCX!o z>E}B8F3azI=kChYOjk0WW%Xe7eg5aX`Yg+z&2@OSw~|C_x2vfnesfFC*M_?6+J_EYSu;# zwu%)uH}Ie7OYuI%|HH!R#<$mV)&;HDI^#~PUbVcn+N)+?(Qh&P^A@XkDL z-hV7|b&8ErZLwr|u-<}+Q*0m4614p~qvP|B;JNE&Ye*gYT=VpE*5xHUXCAFzS}*y^ zr^BamN#@z~zirQ+96YqHXNjHcPFGpG;2+)hzg4|^>-Su+`D=J~(Pg&nJt6yk^>awG zs?TzbY}!>X`DF#0k*)hag%{Hla&K1bID1$@EGK-*gV;|G_o+-=pPD21u_Ru0TA1R} z^Ao;`IR@<85o+yrXlkuq@RH}AKMlX==Nn!4u*Kn*)78HC1;=w9+}oFQE%wBme@p9l z5?cOmoOSKXogN zKCdZPx?P_CvFLoL)Iov7cc+3*-CS(6e4^@;uiMpq%d&aZE;bi$GvF48k$EO8)bQYy z-IxDYoDFZ^@_w_SocXonw2iL6l4Heu?;FH-rk%KW!rXAt-^Ed)Rh6OJ6(4M{KkQvR z-7;?P+ckSzp1RDoKe+Ckhe-Xgr2#8<%KCKN^K@C|(I@GWfRkJY55(@Bczw+~ z^ZN;wnKREWIsVz~wQAWK+ozqb*XqwcdG%$R@YGv|fu8PpQI59dHb085_nuNdx>e-B zH|I*{=;Xf>uHTC1HLqVdyVQ&I+pH4Z1x{^|UstW@U2BnS-RYb(|N5!-yA*5d4%M%a z3)6OX$=S9k&G6N)pYLMII%ePX)mq}r{kHyf$~K!TY0G9gg)$Ylz12++x-ue>rZbuoLwJ$y~f&g`>C_*o_*dB6%}rG;ZEd* zSkcl$L45mEroVq#@vL&6#VUK*M#JQSpGKdB-IgjQt<%|Z`Sq$#Qgby08^dSGT%LAc zHPAui!Ig;MV<-RQJ`D}|)l%*)@Vv0m?WK58f@VAKyu%_nor&-C1$J*d8Ln?8_CUFQ z+lR0J8rHXctDng$zrKU}Tt@x0u)`8xe{K)jnY$%ywZqBI&NER<)@5cKc9ySbvvk{- z&YqQMx~t>JC4rcqtDi8&X=f!Sw5&Y3YTf_Mm&CsQj?5BppOO5dqUqO}*=ctfT9^Dz z*3%QVp0O<}c;fH&Uw^+}|I>Xm%1$drMp)cLtEJL<-)p5y*N)5A-}!boaP7PGf`7j- zXdOS!bk(=TyUTCQ^}6rBFS+%6-zK^H^X>OZSGs?_+IIV?_`>zGpX(pkw>|HcY`kOU z;pH>$Yv}D<@HY3CsL!H4i-@()%v%z8s+o?r2LDU^vTmwnWX2@MSF9fa@BGz zdux2#J>t??Mju6!RRY364_wsi`A#0ZkSKN}z((=%zHi~|_9xq~9*&=ExyQNqn7Ll3 z+5g{qCs!TmxOt-F&*$s}$`|X_x6<$l8X7d!Dn&oiMZ)xVkCvzgWm+PKZnC;VQ zeEO+Ru{6)=OWnJ-r)=O{A+#b%MU{nN_u5Za=F~5Xv)dmwRbjT?Ptp6p$xB2>9(c1Pk`}__kuBzM3@iXKN zo8|WkMYg*i_SRRv|I6)WB~UUk?AeEV8&@A@Xy4sZ%X--V6hli)U!6!pN{a1-cbmW1 z-f;fCwO!FOWVSGS{w?F(CAF39THP}l)(F<=y4^m$SNff%^VPmG>m5q3|Ep(r+(@ph zEquU{rrprV!L`)P{YDhO(4{hd!Han>X2zBj)E!ok{LpilL;qBL$A!zBm**s0;xznP zeywB6zLsBk_nq$j*4SCDcR0UgY0Sd<&znv~zm=<4#r*1#$Fo%iE2Yhj`*vx6-uq%yXIlCz4OPGGM`BMxCye`h|kWZQ8!v zu-J6a=}^_tf2ymj^A9KJId86azw6~S`}Ehxg@3o?=QJ0w9B*Zu6C&LAo2#;MxBOB2 zsI~px;yd$6_nXoQh#@e%W90S2 z=gr2d-)rsu`71PIZ*uTdBKt=Z5uu4~zEp@qgf( zsr!lfqNMz$1i5=XKkFaWczNlpx-VqYJhj&IfBlKqo^`zwKIBG;-G23*BhqfB0zb_|MC*3OFu(v`Zm#fAc|! z%xQjC)Z1QU{Lfq7pvBm>{QXfQ(S0WmFMjfb{XuJkPgkkJht9i;J^H+*?+e`B7ZYH+ zrn0_3;it5H-oHPZ6+7Pk+3|c%%DEMOlaCt&6dVuRU9Yv%DUGLIxS%r1W_I?HT1AnL zg!e2fzKh+RtX}zb`h~xyLVvBCnKPf1Y?c7rj7ocGPId$I z{`(dz_vM=Dg!(7bCdKA`Uz~Z3sp@3=%jY{w46-a9MzJ`-p4uNU<)N%=~5rd-gQ z(ziJ;SCb;83vv&v?yU^n_JsM#@pHdcKf9x$ z&@tuHi|C@vm&-F&F84oPVWEAv(mUK!E!5w={@B6Grvg)7<##nWhzM~lHsx&JI?J8S z=>W&Nla=?^uV8r=$`k)Jg@b@!~Oko&2v6yd7fL^w6kQB!V68g{KK(sim_8z=fw1? z{(P>XS6hFsLjD-zrghc&RV^#o|2_=AzPm%y)pOJ78p~PRGoSjLoccT`VqQ|;{ur5f zuEpEenQv%T_H=xqe=5Zx|KqWOS!cdHzt%GU!JT`|(YtRuoIWr5_{6dA?NuRv!=Kj7 zyQuj7aN;y6!M*E$pXCxrn?Fr!_JgWvzfblT-Fq4_v47FVXP@h%4Nv86IP!~qo2<;W zn7RtSe&L%YImxGI|DX8o=Y;5Dy(*QdMvwWI*_-~%OwVyzeKt2x@q(0}-b_!o`Y-;8 zVLVTdgg$TFl6?LC0)ex_d&6t%)-UvuSef)D9~SWJb_%Mu`2I63b;&V1>FVsQ8J|t>XYv(1l5`Pn z*`ThJZFuYv`}8+;KMT3%E)bGuSIEeG(yP2%&^Kq&rq8Y+2TuPJu*tr@e{0#QNdBdT zQ_9m7j?Rp~Ql|g3yz6g{k86aN_M$Gn+P*l;Cu?pzFT0soF+F&X=ymgTCv$iu@6QdN zGOs*olcMh3*RcDDA+_ zAnx#DfBdn9>kFi|-#^SK=)ldu@9<&2`-F~Tt-9NPGc$2Ia5LCD9N2$Y*7(b!o!j|c zm@FN*8F(E&?H9QJVP&)b_TUyKc8BQ+N0`jnul}n$;xkWi`-~$@iye6X*E4cDeB0l3 zG5E*qP1`+KnVB898B`o@@3)tI_3`Ah?P0FWat_=K?hZTlFNsKWl}p@S-^%Rhzzy~p z$EULjK@+#1KFSR88px3!4Q;+KeBAzvl?CKTVTU*S53pwHC9`f9b7SF!n!Npz@9dI@ z?Rsr2at`%xYT4&VAN{(YQ$WFiL)Iz!oQU-Om)oW@CrRIyXqLV)BklP9tM6XrZJf1r z((c9p;VK0c0ge_qg+_s{mo4|0TJAaPH!_$ly#Bx1I66)BZYKZho~ic#8fwj@-k#et zv+{H8{mRexZk}47W>fc+^RZfd!S@@c`EzFf`nbe&o!#;u+w1kdU;AR|p1xL98O^JDel+bq)mR+{&mUbFcwcl)}n z_afzGUfI?>IQ}~K-?uxg_V$&(SNqjIn8LiQbWhdGhuJUZ?Xb9K$n&*uMsyu0^!-;Iok1*h!i z-%MNVpKo^br?_AB`;V^r70+Y7KAV3nqUz`s_40~G_BTKE%;)=k#_IRxZ1p!eOU$g_ zK8#KO|8Diw^gowtUe&)^zihAZ$7}cZ{ry%et#>Pb{_cG12fL=Xv|s-G?)RfblVfJY zem1vyero3S|GWQ8tGTLu*!=J5v)9x6-v21tFgq^$gZl2A%14#r@*g*TTX}i&H^%pW zvR^!Wc{}gdhc?y!vOgEEeD-m6{?po$pNFgMmh#+9z4EGDuX0uLwKtzOc|YZ@*Sq)i zmihKG@;|OTX7{cBw9Iq!`RZ?P-M{b8zBWre|6Aj>gUhC`-}(AqH~ZZGZo)+8$GV@y_XMf0O>YTA#gJ@Iznx?f(}~cgNNr zHvKMtj{n!e?$vx&um3-*+joEK{AJ?uA0CFr$JXyZXD@&6!xs5-yW=0R$>y&4_2Xl_ z&+Ljjs>bO{rtR7E>P=$#pBMM~KJVK8|Djf^wEXYKXX4i%xn_Kk#{@jfI|L^-g_S!vvmp}ge`rf~D=iC3p*cM&RT;G4A z^xMlvA0GD0{(cx&pRE&}{&F+>|8F_(8ouA#d^z$t|77#1^zVW*9oNTxy41gaPWAVT z^)=saWyeKU9P*z(tL)U>!{6j{#8te|h+S=FTtA%+2B^Y&71yPH+FQ-9B2RPS>)_v9S^ z<$k-%kGR_JD11}#`VcF>eCgS*)88A#{QQ;l_3!?-H8Vec`zxKh_s8blMxV>>{lBJO zCK>t9<@WPehi-k3+xatUv3+&c=Cxl;&366!`uus1?cdpsypEtgoGYxHN=cJF(|=b4zI(|=sr+*f}y|EAP&S%bgo!T(Dy=*!)z^nE;U@A+RI zmD+#r&%giY#nX7duyywDyJO?x{F#?mbG`a~ zi|427^D659Xw6@{{rL)gvmcxO{=2Vp``Hf7XMgvvNGZ3j{+8?g?&hC$tlwpd&+fYS z*MEw=l+Djy$K&Gv`~7}$#k~34kE6_o_S;*0-Pg|l@3iY?F&XRpH~0MieEE8Po%M?; z_O>SGzYoQy&#yh6v##dfP2+c)o|oVGJpZ7#_@3`);)CS(?l{?8Fa58ed;b3KU%Z$9 zd)Vi{?arsG#h+APzBx1{pH22&@rlE+<}wAhA9+8&yZ8Db$HkRTS4)?RAAh^4_4|+i zx^i1S{(hCbd6(Lr!a2+1u73Q}q@AvFJNeG6*|8g6mEGrw3K4qu_rs@fy+4n33g6M5 zZu|S}g4=C(XU%->!M^9O@zYt~itEj#OHVr17sc(kcz42nT>KCpv z%eeRc-j33nAB5%aKEK2KUH{L|Eym{ib3fGUy|7Dv6#2BfIxfcQ-;%?8cRn!bN<9@}5dySLkyPTlCd?(fk$>;5~HM{2F@D$n)B=Y9BheDl?%oAyVr#2!t$bfrTl7a-J>vCy zqr}2*o95OP-Vi%ix?3ma|Ibfl!AG6*FY`y{u4ncBS9EmG@wS+Mt9|EJf4?<1&*H4j z%T?F!-FesCX)nenU2=4(t+>su4=dXJtEbxZS^qlOYAwF)U(u6|$Ap{BcR%&YKRwU% zd;Onh#rE2IHO154+1KCu`!DeD<-_$qR(^PPy}YjK=4yG_->2l(&);&~9&6@KW*lnypVZ>fa4-_kFwLtGa%lMbf(Z@7?n2 z%|Cs#47Ye5yC`n+$=S>Ie|;1>U#9Zwn!S3`e^Z`rTD@nk+P}B0y1Sm|n*W?IFE!h5 zUWC@)9}oEB|2({UegCiO+{kCw^yBPaFWIka_43%wscXyQQ;#ogX5-zJbfj{*&A0mN z_iJxoGR_x&cdIC`@RH)oxBV3l^S{5_`ju6^{!Yb|gqF}V2P5n#D#q)PuzV*Db|C`k#_2`^`Uk{u6+dO%k z&&E6Z^F3pJ*wOQUe@9N=crF?&%oVpuy?eBbT_T}5}-!(R~`*n!f z-!yo({g%tp^}p9t{w*t>dw)*pC$;@^jm);L+kQ1~>F;;<^Y&D(EdD)rW_TC(wjHHE zZvNK&`)U7UyW6>$io1WR*3aK}{_OJ{tBl_J^Y*>Haldo+zM8KS9^X2*W&RwCj}5Z( z{$A{TruhE-$JO_zUH|jo=1P0>Z8zVRWq(UPc3~TT+^+x2`pYGD<=m@3%wMc5_w(}mnnzp1z2)y%yuO+H|L5)NW_7PS&-T@9D}J{+ zI%dzowCQgPKF;r(^WhIW|GfvX#qX}ve?RxL@$SE~hO^fM@2k4Em499Je}R{mQm^l? z`uBYKl=#}WZ}|CQKAkq*w(Izw)ZgO!?6mg&D$RYaFS+sQ+u3(5zMj*6rdyeM?pX5w zqTkQn|NXmp`u{Pen@BFjZU#;F-zCW(! zQfaiWMg6|)OV7T`e(ou{7$=?cz30RH%&iJ>V+bzvwEb=~TI;m!QI)%l{u$L;sjUf%Wn-}jBF=Kj%_ zKEC=Xy=3~IV2Qf>&$hpxZufOp|Mj15w}sEEe0MYd&9r|+q^uAkey#8`aqf6M>v zs_wZz&tAK}#`?*b?0I%MU!VW8d%yLMls`}P_ZKs_=YIRD`#-Yeg8H{d&(-WVygolK z=IdAYu=zg@_=Wq-F?+V3TP%ND)pxP*^1gpDGq*pu7hV79*{|)q`=9^vuFI1tzLoDU zJJ&u==WhAw)8%J(eSYu#&hBk}r+nO(FYAn-@7Z(mUcL3h_Tc%yU$xBjVo%*Zv*y~C z?6BDLHV@Ood4GO6cRlat$+O%0f1I`bAG__spRX&^?q>la1Gt(}o zS6sVve|~v}|G%!<<^MjOIchCeaqY1D^X;d6Eq?Aet{3y``u@Ee)>WQc*RBPUc%lEH; zK3mtn>fgd)ttHm)m|=*5CgxvFfG#d71Ll#mZBTMxWXJW2NKm`$f;25;wp5e|`Ru zzu*5o+r@kTR_goulDe%QTc_vme_FXcXTz`0x95LeUwwVfpA%OZ@evpf4DU%hp1 z@uPFUYyPl*KB<{stB|?*eO2oGv+@ydH^}GL-*Y>+TYT;Qo3Y#LN?VIQY)X`l+w#!r za(Vp!1-W_kuOF?R_UF-F*SX908h?Ms+ZX@#sIq>!`MZk40`(u7|L1)>EPsE|T(gHa z?*D!DY^8hbj|XqA>e>Ez5*l9p@vyM{nRy%c7uIKgyRiCxMcH!B^1o?|oAo4$-^u3R z|MzY|<5WbgwOcxo+0{-{<>`#rW-?-o1MN@0Ww&+kSs){xoy?y&v;F zJY3xEAM@o=e^C1!gTHUx)8an$ji3@nBov> zSRZHgeMYF2*#3$ysw=zw{{H@$9kwm%yY2U#pZ2eRAbw}#-=+Qa25xh{zg#aCU-2#L zH?RGxefQrOoUr;kw>Hl*Y58uo9y|T-*E+Ue+x_C5b^XTAVd=6qwa?n>uj|YF{G5HJ zc)iTDpYKgxo__u9_lFJ7|NT9-nmsf4*uL-QPQRX0ePlv){ElxgA3vKh`Q5&kz4G(F zecaT0Ja<;?wySS;mq+}cIkEV>{O1pn&)@uhG;{i%A0PAN^(<>{m><>mE}jgy!OWvyX9x&KCcd)ceDO~_kX?Wx~Y$n%X{lyy-1HcBUkz;RQhkm zk7Mnz|5kiI%ei~6`SULe)!&uB{;}7-HshwZ^ojX%cRUl#e^Y$N{gCo&`I;wlxBvV1 zM{>Te{wg|z&37y9 zx^|k4Nqu`_cb#G7?nmwWe;=OuoA>79hrhSgEiCzW>vmkZU*XpJ*7g7H*Dg<$t9rCT z{Z_fofkk!Y3WA z(sw^RdOmrl;qLqm51IGhd2+nJUgo;l$FFbi7H{95w7PrSDI5D=>38nWi56d9be6GS z_S3B;J6F$}|G3X~N5Q`Zv#;GxoPFQ^>y0Y!{AbVKf4!Hre7|1(4EvH}_r&jieph(= z3E%zamrl;VQ+@lGzU$wThm@B8bHNYwmU(pvrR@zlH4`TrLb+-*ExSM!mxdCp|L-8EZf%YOZi zyC3s$d-}G2X?wNHf4}&*-_IiBpJa7h(NEs6pMOG+{i&ZV{pHKgdYLbO=l|FLzr?D0 z>7j#tp?8=Unl3Z^YPoeZXMh8bj{3X%dFyduHCyf zV_Nls4YNhcrerRBTTvf&Qg_;2CpkOmNX_DTFGXa}oh|k|`1p;}wt%9dIWtSs!_UZE ze;lRxW7_LV(c`mUJ~>-*ZR71-r1H(xV}6U4 zPm7Ly_VjMj#l+XY`e!|^%DZ)T*VCWIo6pIp-@c~$>1}S>$ybHX4X$Q9zO}2KFY3lK zr;DEl6i}>Wjd23APvu zr1FLDH*4qZdUP|5Pc@-x-tD>Nb7ubFVys&~rJ76i(`=qa%U<{YS+!+*q$>Np%=0Fv zFR)D%zrq*yO5o_qrc0_Gv5V$SVtwdPk+HNsBmDYgYnB!2r5~%NuUJ-b@j%tlrstOg zoA)jCPP_MNrf0iN{K>S}yjkbY?zWtKTKtntjp*(}iJ_OLGx&5c{pprHy)#l`h10$F zl6wv~Hy$kJa#iO~Vq;{V&+^vyy!zCar`I~!J-+3)@6D{61wJ|IuUTvtUoB#l*gW$o z(`Vn^kIvL@Il24A`=3rTCEY!RG6YRhgVY{Jt$SU#F1*Zwy(*w+O_zK7>D3j}qFdse zylrNbr|k?%sy`O@sJNi$tj>A;N6g0`&dKcNUA*F(ZGqeLq$L%OFH;}9y0&_jc-qdK zC|k=3q0!e5ZS&IfuHLs}ukPzZ3=yoiJD1Ely))GAdSXiH7&9%`Gi7p)Pjb;f9rV!<-$)q zeOTVGE5g7_=z!b#&JKsJKuymixD_td3r<`6(+~S|al-$MSiCH!Fe@9vzfRxs|}o zaIfhshk*E=l`q!k8OW?;ePX)dalz#J_v;nav#J)|)X2WH-QdZkEyk7g^ErAxt%=-N zn={#X_h-Fq9!LA%+g`27IoQ3%D!Em<)XgV-M#*dKsa&cXE^IujS8{0869I+u>qKnM z=~$^=_u2Jc)##Cns-)Am*Su4>90N@Pr5{UuR<+ifee`7zAB$vyY5N-H%`@HRtdKsL z;#vQCYnP7lt3)Xu`v@z>gb#xHLRtp4Z_}jmCQa~}QnxouaOsH-BX1G06$Sy08qT*D zKI)lP*Kp3^`b^)g=Tt0bF8lU+YgdW#w!|g9(Xx#jCtAF;n^AI9-RQK6?n9HSQCYLx z{v7hy^|)X|WOW{&0Lvs39$6lP?VVvWbW}DM{jFMCuXL`%l*6Ke>DU~HQl;tH!lo0- zb=X;CuN?5*-#Kl%jw(w=khgAin+wC@Yo9Y~MRE@qv+WK|=rFy=GWlwX)PeQeC!IDi z()w~@#SQ6iWplb(rYde0EzO>HVwT*J2bqy43w5uby#3XOdt=qAZ`Zd7EJ^vYL#^Yl zx$cU+e$PC5w0Y~#2PMdtdHK26e0{#cBmSaWtBmCN$DfKHux?dr6&Tk*4#kF2Rya&|GC z#AvraZncN`rWwblNUpJIcdb8I$hLLC!{A4!1KZw-zL=A@Z0@42lW7~{*M~mQG5XcG ziuI77(eecxkq!~QTLME=Z%(QI`g&`ZhVt#o{41+=vQ1U41*u{JFReoM;!Q;<` zWx~Fqq5c}FdzUVek-YZ!O@a2}UE+qN8yXAyB<1!;GHCoNW|@8@{@Gu!p@B-yy%U!z=)P5fyqRR7gyp2CX@%ne`J6r|?wdZ1>1*}G{~sol+) z^WxWssz}eg^Wti^o+Ha$!=B!HjXOTvuG1&2%-bKg`h?M@HR?aCu9`2Goj&PLhZUFS z&c7~Z9qZICudLfEHgSnmhp^HNx6%pPi6$|k6Ybg zVYFPmJ|LsHNJUuGv+mk_U0x=m$yRY{8=ZL!6^n$UGk>m5x^s)Wf1y$XtHq`WBiZwc zv$l3_Yo8dvE1|oPP3g9CD!-4zGRFPFLenC*OY`!EFjT6CKRDG|H21a1rBAWTF9z+p zka4W5M*RG872g;8*BUC$k^i?>;TcEcgys{XLe<;yrR$aJ+!n3NkakXeuX-RLVEYam z%Nu$(>h8}<_76z>T&285dbN4N8AR5I(%yIA=*;h|Ine@IZ%jf~aZ zSF=Ss-HyFKQLnlVqU@7GX^ep|OUY@%}U%mc?xyH=XJ&*|;VcPJ`a(75qIw_9#Wy++vj zP#1}r8YEJIT-1FIIM(Labz8fWLQdCuE?*_%qW--ZK6OS_&Z*BPZqQ1bkB~nHF)ZIN# zZ&et)Z+4YwToxg;@6Q!Clkhe7y!4)*m=vJooh1M0lvoCb)-4am3(3g=2YZ&bwfddZ zVYlGf;?vu!7~Z{WzggQVGpo6aCxzFZ{C@h_g4tVw`{buvf9~RYV|69$XtvP8)l5yk zUAmKRNuTQ4X1=B4pv1`wQ?H2EpYGYlP$iVHTkOkbr`T;C4qUGquK6^(h)wQY5TAeG zTHmD@S<#PDi)%L@HtyEjBHVxYQMi4=-pY&#P(P3@Vja6%vqE~utdt&CR z;iSGN;c;7B`;^|rX+5E3zXa=)I8ROc+LClF+Uv|jU)yCebK@^(?>xw|?7%UV-8uEf zyyC7NX(6Btv1DSPt)7F*756z_S6796j+irBdAF~zu9T~1n#ixOQLfu27TV6riT)^{ z8RB^+k>4#w>#N!=Q?J9>GIKMv8mrxm#bL2etEsMt3~p7 zO-Rr~wpU?Z8K+Gy+g$w8QXG=M(o!n&#$ye)Z-$(O@(F=kWMA${o25~8cs36xT&|ti zac^#%nM%g_@_i~B?Jq1{G4or;ya`J$u+LbUv8i4`@^fWesl}cXN2jtxW-j7fq;BH) zh0)A$mX6Oc(b?~;Rl-(99}r;ZVK#6XvvjVVNSi0b zc7Ug>(q1c{b%DZOHL2Z;9d>j!#Ah!GP0~1NroI23m)?sLS`%+97U?>AR$*Rt%0idz z>L+HJ9S&!!*V=J$sldkj4>xU@vP7*h!pZB4ZN#tCULU?t*}AMv%NI?t{jf7qpw;v7 z=?ydX+6Qi4BAVO(qDQ{zeDkJfZcE?Hey=ho$41Ms_zl0}QS*`w{a2+oJXJCc*FP%z zrk2m-)5fpUS#0NZ`PI!%FKamPMCFCvn(JCky*e2@nzEaxV_Twb}Q`1vbLWbAHnb2aN~l1$q4AaK+Bx$})rEL^TY3$IQ78s%Cw zG16AmViMnt&Ka}$c=?}OUuQjj^~$zRJsXpw8G=H)ZgMfdOS>%-=2j!vCIMOEqhhaP9k6l-pC3a?k$Sn~Ib zj@{uG!FT@_eh~`alA9Ew&hbG|me;rE)w1~~#e`-mFPe2E-+qmG0=Hw%x^tZwlMD+T zWU7unkbN-ey^`l%|Gh_^Kj?fTxbb1@sffK{6LV4=C$G-xdp_|(KC8+1nAsV#b{r0@ z@0&j9L6WD>q3La3qg>ZbWVD^tYvcLYw*F_L7Doi%;a3ZuJZA}#ygX`I% zobJ<1N`>8unmV5gRdN1~d*P#?VQv^a@dO8>vc}As-bPcWSz7Tk)AKefHz|iNW$IG8 zuyKXljOGTfnLdxzq7*jG@Yx0`*L913_*}jn@cjJ)4ttx+{7-$J8T96Ruq`^d%*)6= zwLbB{-zl?oo}K7hwuS%P`2#mK41PrT>9)*kyz|&`#_Ws@Cp!H&4_9gLJfPg{ns6x3 zb=M3*!)kj~k#dPRBdcku<<^fP*5|Dgayc3ru&$o1ch-j^VH}TleL1}#v45WJ{_ttR zE$4QHvM=>KT)?S)W75Q*5e^RjD|&v^7?$tzkZGP#|JQ%iYxfaHT2r_cA_ z>atN6H7XQ#a5xztop@w!orS5IVR(t5Wb2db(I-`Hl0WiPY^|SJwyC2i-Qa??(_W_J zlV=2jYjW2=vZ(he*lBU*is;Tr#ujZ$+k{f3-Qsag2bVTFhxG1~zM;LL+SKMt-__Om zt{sVezVlwLxUgffN5q6@$pUfWzY^HgrA21VGEsQG{dMHy8((tv#=TLNiPe8E*6nvw z{=QIzXOCV#{o{kheHwpXbX+;o*TK72BKfP7pUzJCzXG$b@kbmen#9QY`s(|3 z4R_gzzb*`RvMGMe~gb-YXd zS``??v*^j>FAn)h{4RDk1%7;$dQ)Ao<<5@3r`y>dzkMXV{9f8?(_8N^{9aJVeq~vy zgSVv9VIIDmy=>VBRvh&Idh5Q)1D3a!gl>i;?q&PEC9rw+tF8Mp8#o_Jn(T2DS$%!Q zU(arM7vw@qFUTjZ?2AY!lE?wNtjlV6oC$YkK$t0aBzW8c;67VRFXnvnI(zRYfm zW*JGT^CY}Bz19BuKxadWq(+ImM!(8wg*DeRM5fH@U9;WKgx{Zo)9KxjSEfwyMW~HdM zf33=_-@$R@)l{1YZ}aCAcCWpD`VZ&z4_!HX8x+%o-=qZYy;t@~^5X1bKfSk8ZtThU zVOrudYi8*)i^!~V6|G(;i<;7Y?f)5-ZB#2{cDi`c=PNY}-=xKK|G3W5pEZHA)vv~q z^9J{8*7M!PpMF~A-JDtf@`;ambZD5~nW9gjsWU`yXiTnWBwoatxwN*ohio{4Bq&ycP@!eci+`(Y_#cX zSVM`c+pdUn{RPiv?o7J2QdI5d48dhrcoJ9LkDHOD6eDvjTJTWF<3m$^i!G}^!x6kj zY}pUpYk!MQ7(Lt+9)4$2zspSh3Rh!urMYV@?y_1>Ek9KlIgP8;s6&YV_k?S+A{Xrm zTN3&;WAOsN+7C;6n&UbDBU4C1ow>HIBy>DZM!a~B;t^r)-dSg7iK z#O4$3`!=ll_4?PJgf|y1-1m$;elmwq{%~LR-pSFws)}aG>TAtXHD=e1+F_wF^Y-H> z>C3e9uFZQHnsCcvo4B0NWvPc!3Gz?mEvjuFw#6S$oix|*UtzIH=AqydPGajz1#UW+ z{(6v6SHE@X<*pN}C65cTo-`{tX;yl7($=2D)Rfafy25oqp|_QSzT0e`ZSm(q<*|vC zX%Am+%(edZ<-+!ZIk^f>?ik=x5S7i4gJZZNic}z@>T$4Gwk(c*MP}_4+OXX#(){9@d zMH%S`{|hvhTzt^sv)lAVrJje%EiaVbHn_k%H=^#1gTKP|pysE0mD+BK)u%+Ws{|vG4$q0Gdt>na@dHurbKe-u z9(Jr>VVcXiEOl1bJiq8n@1iq3i#>Ktz2@rcH+#~$kDI22_4+g&oaT7#Pr1#Ft+^5} z4*KcXmu)y+`n<5m-9Iw%aE{fil%*n8RYFMl>99^O&1CgljnI_C?w zRP!YM=oWv_cJn{6{M6@Dmp{i`+?tj;mrv3c6V-`obrzJ zyR3dEUw@G?2t0kI&wuKr57z<&Oq;l)gH$cI?cu-Js#<^Ft*$OniLtG^ROR4?j*bZ) z8}2eNHihtY9r*pl?EGBwy}4{t{PdIG?})Y3IT)|KROb&{|EpJTTJ~3KvD`18mT>Cq z>lUvcVin16GOzHx_)s+`XPQk}#E%;{+#~$v-w)Ok-}^&4xh3st zz4YG|?{3#rt5$d}tiN*iWL@XJ^<{QHiq_5*xX6D0ZqJG!;V1X&w7OTlKk_^B_rvm~ z7Kid!iszZF4e>nx{!66(rX7XfKEJg&S2y#_zr^O9D{a@gryMzJYI{zpt+%)F!5{si zDfY^x--~xBwQW(~ROIoe>h{Ab86nxO(=#{Ac-0m%9%Z|~Y16Xjg^L$4)vM=U7cUMi ze$BaiTh~dh9qVVhvfgwFJ-lT_#~ta=`BxwH+c`a4{kG`@Z}a}rEBF3gn%ff^aPo;| z-{!eI?)!|7oVxi|=3CwMJ+o!K?4IoKlAFhKc*^GB3g@IB6DBU5WGQd=Rzbd4_43yM zNgqXXJ&yvW8PDaWudZlW{-*4?MI|3w{jHY$A6LgH9%eXXUOmz-zY+|TujRhbtT#qPYArx`jY`}f=V$o}Pwr9t#Uw7@cQ-@UJZ!r;K=bjf z+oHRKPEDzC=#2Z(pf0N@@6+_&Thpk2iK0eNS)RJl{6BJhPv0c-IzQkN+b-556CGxEym*MEaFZushubh;8t5fUn=fCx*_G&dG9Q?BD&rGiSrneHJ zLW_3It^6A5@MWU?gC-uS8xElYygws0-M$vBy+ZKB(IuAW&iE{xVto3Z&!-aw7y0A1 z9MIL%n!VKZhxDJ>ui_f)bssg^M@)-TXxp#Pwg0xI$`8Fi_O(_u#etIlj@O@f|6#4` z(=SYab_j(>X{xHY)6WdZ%;hIhLk5qzdeWdTjWY=(Lsq8+PdSQWR=H>4BjB3xr zH#Db}En`2XUvoAiI!4yQb?T$Uc}W)on{?7mHZo6+UhwN!-c{Y6f2=-+L6c^wY;lRm zUy%3imG9a6%e?|qmS_5zbyamew0!jPnU-Udzy0JtZ* zqGP-N^)gTTs&|h?F~lKPc_%VOy-Am^k5!^)$gbCrc%dtu->Ne<tSm-DDP zp8c>UMy`IlSEN6ig^90J!gjB}|E0HkS?-Khoj>jJw8T?xQGu@R;W_S`50qV2jT9_7 z9#R^3-9=fp{3z!gt?()4sh|1Yx=u|K{;kLVHv9I5CjPhkpIT0Jnkih>^~9g?keyQG z3{8<5wM`L?7w;M7PAgMkZ3)Y{IeFPHAFuldG%r;1u2-B?U)8nDbgHM|D??46M;{fc zmhgICJ360x;@p;>MxPm8e4a5ckKu-h>cXAtc{c34e?@1>sx#N4+#NMOX(Y%?H}-7^ zV|G}+qI1*E_ODT{`vmztCgn67bvD`&?D6u8u)SK6XTnhx;U!msghNwUJ%8*~PudTt;m{G@Dmh&QZKzjPD#)55rVw!6 z(JFeq&*fb|XTF(reojWG(2cgQVMPzy&U6MmFUvZob9NJV@#oSVle2=BmcMdYwa9OV z$xC7F83hMshM(CbwxW7gmdUA`g6Cb|vqZ9Ue)ibp7|_>K!MRjQKv#ur(JYo2?;5XV z7jIXe_u4ndq&rOZQ(4KBo!u8@>T`l}7-RxpO{%yxNyNPOTXt|NNx)A5BVjvE&uK;E9LRLY8rY$)>79)X??b21i2j8SUbT*IKk@a zPTRA8)*O<_pBC*c@N~nWjuX>&i~FrOAAYUCX={D{+NaG~aWZk|J#}Qu4!rJ7nw!1e z^Z1I!2dqV|Yu9J5=VY;jPev zZ0ftoXHR&3{cOpzK_br6Dt*1WC8HbNX6@x)a6!={n02f7m0xj|!Kc#Z-Ci7IU9e#L zC)=qihp+u!ozK=n#TW5qw?Op9AP}Od}e7E@Bj_X(c9-M2Gs}sy6mL$2^ zsd9&`RdGzZ-p6}pA6;r0YdE$h-fj`Es(lf#w5(RDFXP3oiDmU62LomA13Or;DJACjDz%e4$c#JiQmCL{3|DQm8I4 zRF+|?TK;m^IG@K;D{oFrJ$g|$_{u>6hTE}0q28G$?OXH$UrhSFYt5Z4mLc!!Lw#pC zcP>46PEp3vDCWhfBYko+CAXdyyS7gw&BgWPhg}@}TPvbBs~#5PnHXLXJF#HHkrMe2 zlTI=6|2LSF`CjS&`AG3S#YcVrTfXBj{m?u6`<=*@KU_&XbxC3{qNkEogUM}vOMZ<8R}jxK5@2b)>QK?-;c)d&x~57la}E5 zGE-Uk6~iHyqt|3E2Q2APKGCO^y(v#S$m-yXgK~@4y)ax|nZEh>8hNSoom2E<(;ZKS z$UmO)aaXcne$6j0L(?T6mq!0!+-G0)Up*(JJGo5c-X$Gh zF`nBOD(VjwCfG9_wn&~mP4%XvYVM6Ax0iYfd%YA|s^=IdShfA$>RC(5g}oO?y*GL- zUZNj)uQW{G$0?Gn`)Yv5hA4pj_7g)7a}O61kq{RnLPe_Bw|wY zBK;~I7fyH`{Hb=&``Z~aS8Z<#^4FPuuY6U}$-=a67B`jlT-CM;`&u`3`LxQ4a*6f6 z;X03=Pt%-Y@$9uso$TxS$=tuc?t75rmd?&w^=Fl5+nuxJho`mw7VMC=J26Y4;g3(v zJApsh8XxyIas@w}Zu_G9MQ_NXM0V?&jvv?NY*?Xb+@{hclV~~j&e*@t3Zm4f z`ETX&xAWfr_k*c~@CJ=9dJFY;nWaxVFzwpZT`ZPARTz6-KF&2=d~nYOJ@dG~=l02{ zoIMv<-809c?930(WM*;CWesfW51xMfR;#|S`^}8QD>XN4Sny89bm{U87KT4FMT%su zAH4Wu%9K4v4@$j$@@ZMS9+$+1#?Oa&i-YG}k`Z5Uae`-Lc^@~k<+cg&32Ad#oo7Cu zu-RBhTP0R=I(KCX-_6DGLXt<;+wYuoZkO2gSgnvQIr9|%%gw*47wCKKyFHtG?aI9} zvSnL!pVdz|DYiaEeBsbP3L}__bY*a{`Av}cDFqj`?T9HUpS#|TcM-)!i4)PcbC5i zXo=pGo5o$q&h@$VW$s~S_T2xDAEffuWlyjEpeb}-{Q1G{RrNC4cQ5BrUFF9;;rP9^ z2K-(Xea|<@vCBVX_Yr3KAve7#NK`$oTenll%a?%tuf z#7KSVktrv54S8avxVUvs)^qRZ>$B=t_ha5tqxZFWyVcB15wSM0%a1Nz;m^>S|G-@H zX}#sDkgs=p#I^hElp3RBq@T3dmpYw+LOx z5$0pIs$qZW6oyPkL90&D9O?aTEVo+gOf}jyfBadsGf>r5Nq^46w+4rIetc;EL0psf zpX$+v{uiomHI|fL*>q4S=j^2!R%d5iN*0^Dam8tA&$Vt&B28z`i0$Gom9x1w=lzsF z?93AkKFhH^Xy`w2o*{g$qU<6s1G_(&$Lkp?4(dCveFf;&RwaX#3kq&DtOy6 z@|cP2rgaZDA6|IbU2>73)y)f6w=KCh=hcCPd5c);6YidHI`yEkH~ghn(|nP|+eEf0 zI$yo@vwq3~4XX|}!JQv36iEJivFB3u&IL!0v-QgjD?6V^g_3nf0i{S?&=D6{8{tDal@UCTU&D99a*Nf=C*8ay~sDEZ^!PrFEszyB=OyWQJ1E}E0F_=lKQaQK3S zO?naw^jHG@B-w7> zcK}1{EFo6UHva-i>8^T4E$=4|rJij09*d4l>l2zfg|D8)Ij!3@;^ro$Mzf4|E++oj z({(m3oit}srSCKrSvf(`(=)b8s*_`bXJ|gbi-iuU{uMiD`w~ zgrHq38ecV^d$HiS$b`5x5e?U+XE`ZOm^aB}>UGzK=2`2cXRXS3+ct4hML^R90mfY# zTutjvy|u~+lwfym)H`IR#3@vACd1t2#Ud^bkEaWKcP%+-v*#ScZ9&`5F1^gDTG@;G zl8;X53p%hZ#6kCP*bxz9+bdtEsCm`5F|siPa~b$P`Y2oEBco-)ajelsQYBYo!B59a zJ7yl>daT;a{BhMRu5Q0WL6M;qk;VlargOtXC7hO(h@6p&ycWXy>$u3{0&N3*UfE@h z(=M4fGZ-H0Qq@%L+{Cp0q1(o%OdO6^FV=Fc;m9yOQ`6PAmMu-{oCKR*CEIzbt)e9x-y|2z6{rI&z z`S0e-63o}FpCa^zd+&;v+J+E44P6tRkov%7TH)a)3-iBBcX{e1^&)J}pD62@ zw;1l0HcG2DZn|99)|F#8!^~jU27`r0>xu=RNoDXdH;VOeu1J5>vG$-3GpnFz_JRYd zawd&}+SfvV1Wx6>uye%%(GoQlRz_~8iwSRwgrb6^&V(+#+i-L(gO9jFc7xraQthss zml_QpnikYQWX<0uv1|v2RJg#EvKcF0$eeks)#;UZuwmBWsZ9MHU8;&pIVLSytaKsZ zKjSi!h`=k;Z?i-;&g1IRy40D!LV>GuMf8OvuJxOi_NW}lV$o&&-FeYlQ`?O3a^}OT zwxGEgJe=QD8jt8VuXR=2CHYOWm)-S{nDa_Cjy)_@D^|&Tt#4nr=*!h9T$79)3JVq| zWHVn~>9yx#-v$?l2i&vOZfRIWc&_LdxiDvel1u005FT;06JC2Nrl>veF;xjL%CUS= z;C%3`V}5(2>Z`T|U0l&zk2%jzs$?$p3CZ!;pnQ6g;_EqTjJL#11FuD{ye7*SHr=D< z^a~+R8HLzI4@y&JeA`stwu?n2?L^z9)q7`$Og|8|+G~eeLf4^dhgJ*q$?D`dvgafi zEZwl)dsBn7rpTd=S2i{M%_}+W55=^+-t;-dZ4(U$SJi3(Cx?Zp-{(?zF zeM5Uv>yE9RTn;9Z-#@OHv%>D404wVR>lcCz*<5~=FHGKUUbSq22h-Xk)A}w6#wo^i zgqjIFIxvsRo4?Hc%Y~~6$CNdiWyRzdF79%^(!kV|^h2yEI+X3SWZjdg5gXZbSvgnC z64SosxM9yC#aVLeS1ho1v~QaAdg+Y%+HHMOvezW_u2dNQVR6>p(#;gNT*xIv#mdPz z@L~a<#E%>S-Zk+7Ym|CcI~eTblVuS(vogwyaqW7ooQE2m$=e%UG}iEUIX>%J=Vhc+ zDp7vGyh%vA_28vc#=6BnY&FC z#_SSh1BTAE7xcZi&SMk&z$eEs?@c;aRMDQUU@-^XB;HN)Hy%}bcTk8=_RV#xSuq=f z0%WY3vMs|-9iDQnqGhFzW`>Gj@?x%yyA0kQ5E4A_W2F}B6W-lYSqoq6)M^uNnalUB zAY%iYbwA50%~m$1Lj`>DYMut)O}CYZJdl)JQ_taSej`b8^P$7Pj^*-{*$9|2sBWpO zl#ACr+{aVk70Q#cYetd-%Pd8vDM1~b45x+O*t8xn%@JJxkWJJ1b83{9zzd~fBOdj2 zRynRAR$eUHPOguq=(Ywj<#2Q`GRU6@5=`(Hzj^f>FcuHHw{p!>Xj$pPe`xH-qT=zYQCxBrY+kxI4E>)Uo@E}p3=l%d@C zb?Jh&$_+se4G*kX*pN1Pf}QZfKE9(;w;UpL5*w5@v~5`x#Q4%PuG==r#^K%+l}6FU z$Ko^&+~A_ew*>{ zGf`)@66tLA%}-sE>ZPtKD&#Ib9K*`G(yJks;Y)*N=d`&_+07XYH=4ISH)+UQq$P3U z(19tT6`pSE1QfEoj{NMNHjBk=w$2NSkEsri7`R1GCams1#K?Sm?i-$qn-g6)ZZ7uB zv3|vum(#hy<=nf)S1z{Pj9mF8Z^tsWt`mX`t512DX*0|XVwiaFSH!*g(50VU-mzKE z?)%F$TkTB)!!^{gix)^vl z8~#iy7MXcjbLlUcjr;HZ`&J~S;mkPGi+RD)2i=~cOP+2QnlM}aM<4$S#tSz#*-vIn zJnfN{Ig2eKe(KhU%B$0F-hWgalP_8CyY!QGR$u+=gUQc!-1;wkBkg47g8-rRnH{_r zG@Ylo)a_huap@sPB&XH{&O#Lr7M&~FZD*sd37%KBZt{wLeo#l|D&q`ZS%r{L!4rCG zIoh|NEmwdf80#FEQ?3 zY%XYN&{oP_EMHr5Ws26zJqsr>C)==GEBO0BbB|spm!*_gg^G8|wvcNT>bkr2^r3EK7MMj52P$3o_j@i_wZ#V0~Qu=8vBiA>Ex}FtTa-4aAUvfiAj!rU-b1<77 zcxS<)(!&!vjOzPBws1Lk2D@->wF&0R6$|ausB|kleqZXhuHCy=UaL+Chx>(WOk8TG z{pDBUUH&Ytzf5~{9*X_@w@Wjm2o)dkAt%synm>S+p7WcgM$|Ys}x($j^bxB5Nd)#hAV_pUG(Da~G+@>nqT`}(~TT=krbzp4tlp&A0sbKaQzqcWPcU(d5gDiyFtd*Dn8D^*4t7?~b4|&#VHni)A?$ zX&gU%^fAj~OP<3mQGs(_q^Vm@5U5t=SSWo}dWFC)r{K+&jS-78E?i#J)9N>6#^fWt z=fywR8Tq;$Tk06J>~M<7>+&`K+750H?BjfVuZwwh$fB2@`k0*h4L#S?sqM1tnp@9X z;C*?)qzhZ>9PXy6yD~6(IT<vKZZhaS=V$TP#hcDnWrmB+Ok zlXh2F-&53_Y%F>G5NC|0@k*uHbAB?Us-HfY;`4fIPtW2%b|$e#ot5X8OzTKGEZ+Pk zR7Gk}=*#@FSt?G~g#1$0imDY&VO;3<&ST47tCnrI{;+>x-lyxx#BycpMjj5QDU6A$ z=1W?f2(It0)IMOLdD*qa;^?8CWYP689m})K4t~(v>G*3x+p~5Zb!j8tAU2cFjZt%d zCcNi5yNu=k#W#HOUWx>!F40-nIaNg|CrTSZkg`mbIrL$8xCCO zoIS-N+3D{FPc6=rlm{tOe(LR8pV3l%$X?D|PVI5itrMQ?kK2_`+>cx{vFOH`37z*N zgsn9HUApzc^Xt9a>;Ftz5xnZ;1f#1Lco-i|uerX&y_uzd-?hvw(!al!Y_)rNv0p}p zSIFj&oYc~?*&YHMQ5}5sojR;qO8&hrA$u*&<3DD&eKZJFyfJaZBsPVoi(9_;2`xF+ z^@{gK*{v%%z6$R(Zc2ORJAd0KwD5W-6Te~kzDdeuDmS09HT(^D!m{)5VoiV)ifA>=$k19^G$sFxW(DJCLk5=iQ}ybzSJ&;GCYX8T z%Gg z2v|Gi&hb6F8ZWUrT=$_zwOKc3$@KVewMVUsfw(>!u6>41xA|@vfKkQ=dSyqmuC*&&I@ zgr~lx25FnVJH$>unb(k{YR$AY_skcD2{Kmmdmem$y|t%6`BEOgaJhB+lJ8~RaTRRm4F>RMN3&W z3zs_^{C+=WipyuIB%@R3)?YVrN}KbVYu@{UhAputoz^F<=GmWmH_s;gYw@w*<9*LA z%ePJH3HkJTYfppnuDm40_tk2@YGOhAyr#~uf9wz-?^f@0JRrG2)_Jz_t&U#;)r;+> z+*{G_a)w=L;|}$9i9q?s4nHdxyc1k!$nYtxs5#T>xYsw4b78*wu`PFWq+V8n!X(SM|Xc7Mk?)DhpN}q)e*Jq|%x*F)mocgrGV9vh$xy{ckAMl*IU$|Ie z{hbTZngwcSt;KHCKgfIVOh{<$l!I=%kDqnTxT$`$xA3HK@s}0TK7QeKZ~Vp3zUIw; zC4MEf=Z-vQpSN+U_9yOTyxnwEZSm|E1?h_>YX_XSR`OL>+Pm_& zd{3*tgXvsx#*LYtJ*Pnv%Hf?J`!o+WO18dOcGk-ARzqmaog{9#*GC-w&iTXI;CItE zJ)mXE0rkV$b$h2xta16?TXre0ex_W8;kp|S4ShQ^WGCC6+!D(@LFlMap8a|Wl?Oo% zGdLX=85~&0dseK$n$cQuJX$cg`PXB zo1?qRc+wa5I`f-eoRDd@k!h0gq#e^+zec$o64bZol6f-eGSe%MM`E^<=ZFSNDb&w+ z@K=>xdb5^9rqxN#s)+TeOQehMeGWA`wc*s=9vKCf1AH%YtG4qMcy6u~+j4U9LIKcf z`Zpcvf>jSAm)y$`YpZ|RoEG?dL8RJ&O9dx0rX}6Uw`dSK@%!A}&KaUNJ+_IIyjo_L zaHcEdu}_fNzde@4^JW+SX_kC+d*UOtNBj5HbNg2OK3Xo5_(n9(B=u0B)RWg|BKd3Y zz43ZjKUG?AQn9k+;S0Xr*L_Y4q*^L#^d)k39gto&YoctZiKyfozvQF$TPN;LS?N6` zOv60r_p$doC)(|txNm!d!%3Bof)foruO28??mAVV9HQGI!eMK@cpX<+g_}&2X`^vk zJ^$Uw1@(%HCiZZDe9e2qOw&Yi@|8CK1@m|;eGK?HW}jYsq99nBfz8FM#7^>Bw&cQB zIu}0ki!1pr`!M6~_dSYC%jzaRTq4JC$=U14bg66El8Np)_hx*UaeSeB^t{NDg-2PO z*pJ8+=ALDqR`{@;ae?KMwo@iy>qC#Maa(hbrR(PbjW5hv^$$3c>=qbF+5_={_P8TR$_q0v?h-0dNu}mf3b^Q~{t-Wgltf z((k0w8e@r7J`Rfgs`a)Gf7HG@In=j2yDV3=h`}jw@6?z#f^QFgcdA~o_o7^s(km^XxYtp6TDH@X&sah&i9OOJMP#%~G%0o*JC1&-vedhGYI5 zNzc1G;L6nCw7-r`4>s?! zPR%&I`{xPyEQSn0XJ3njSFg>wAh^+7v1Hl7&0e2-DVgGX8N z)3?`Kdk!dH$``UU;9txta8+>Umzxu_`(EDupz*qnE#2e5BnBtHC2I~>=_bTHQ9}8ood9D{5J(m zHlMA0kmrG?#iR{!r#UQ>et%mha=~s{xMXbq9rFd>J)QlH{%pT#!y$Fiv-fS-g=32R zNnf0rU+lf8;HD(C)!_@+k`F)N~9j)N@AGs+TG&^ zYkG>B;{L}QQ%_EJ3hB@bc6oF$l3BDyWXsd~DT;=ZgjM=9Br}7z^XRVqoEdmM#nt%0 zw-DE(hPnaY`+xrsPDvn&nHH_NryDd>-qQYJ?Qr8)354x z^BQy+7ryjldfM_e%5}$@^s?Czk7LvmKmzN&bfb%$0a&x z-F!CjTeJNqb$CsBZIrk-Ot5}yoOagaTOV{b%d!aO+vzH)g&a%D)=XCWmX)H^R%Nj# z@WTDWGgNXqrUd-;TDzbwU18n!J5rkkl;gs;?s>A{rJE-yW=3ek>&Jtx#zMhvw9GHcy4pJbiVJ?K4t1 zD(C03{TAPJt)DeLTQ+bN&k=gami0`}Pxa5$Gs^ZCw#mAm5ICpbbX-2hWAo%Wvu>(n z>#XhkSeLtehVB{u_8&^FE}N%6Iu`utoKNumOC9gm zmlY-1d}pfPu7BwDS+$+l4&AVNaz${mdt#JEkHXU_dz9Mv)sCA5Zqmq;S5unxRJ}7n zS#TD(1|bHE;gB`?K4Qeqh!QdS$>-9HMz#*ss8+gOT0J=lwFny9*cI^7y`R z`N64XYF><`hk4)U1i4M$lDx#fF{w93=Wy^79`V;4dt)9M)jX`&#$h$ILokA;NxIo4Y$>_Rsw9$ETW2_0gQfexN?ZLOob!Z=_`Lse+hU zoX688FFfq)xZlUou3%Un&T=$kM!!IaOYm*=H5+$tR0vpj_4yC==OF=C_UdymxF)~3 zta*Hiq%OPQ){U`=sa4OLFOZCYVo`ik$?v`638?fB|0CCt3>;`IfZ!ptQu>9R@z z##{+cTNbXZY5c92a!5E!%_#AOy@+_(POaBPO}QGJlek{j9=|=|hy4!Tt@WkvxcNU@ zajv{;d5dxOt^k*UTbx=P&tlqTMN7{VH9zuWC{#WEj%WU@&ckMtr&~?+^L?YE^{>(W zM`c!Hbk6Jdb=wz7iSM(#x_5!@LpEtSrKD?wVDEBSrcv3z@$IEOEC zHI`nJo<6CGXg-^mDU~B?dqH9LB4_?7h9$`l3g>Yz6mxsEz&b3$Y_rV9%=Vv)66zQ5 z{drO^bA93TU4K@*(aaOtWpK2N<=LjXicpgece+b2^ot+rvN`Je_3&Qne^U+B=BmB? zYVs}Aq(X%4!qHdX^%Os@hm#tvb#qA;Yz3U znoZi(|5n;InHfpfRCvx3{iW=B{~+H*Zy`gazMO+BN9$Q4O=<#vMmkuk%?U7=r&itJ zCm_ox^iYJ4@Ak&IBEM#Z9#lWESb zr+Tu_YjHwAz2CH?CHwNPY-P2U_bIw{gX8gxBPkt6&n@|W|C2%J#=njY_bqmM?nugu zzdyIZ$%sw+XJt%meSL`9PdApcjslO|+~gjXPRm$3nIW~~|FU0vQ&uQ6?J3)GI>bV! zBH4}Mx2wR-dlt;hoflT<|69XxM?h!mb9*xg-@jqnPxvR@2YKv@e zhuF?nmkih$jQ*YotryGPDgRh^&9ldDM>G{JovVzdCW>kP6>@0ca5wa1*Q}c9@KDK> zkFVE4?%w=w%=MQpyj!TDb>-uwmb4vqR!T=S&gLC=tqjjFKP2${O1G)lku`7Hza%}- zJs6|&*i(1PgRBCL0Q0mpM>)4Eycg~+b(*Ke5$Lb~CR`)Yy)*FC^ojL}i^O6i&dvL9 zk&oG*d1s|vi&|~6hx7esk|%F*sqAMt{9kDQCYzVPU9J}&R&?6V>Qr(|L`3;Y%7)}S zTwDqI3sVj=``!Apz*aNQ$T;|hb_nC7_G6W26bv3ts5VRe!V!nWxq( zb};pIW_TA}d+gr45^gs)i6*=W{}eJiHS zRC>@L#2#XK)PwVW*>ZM+e+QGgZcjf_voMns^>RNdB`DK!f%)p0 zp9@PihOW?mxwSQ7PUWGkGeVCz_xw!wVO?*%Ag5kMtNwqEamd=V9fE@UPJOwtTRrVa zs6lYUm*o3Je_YJ1^ou@vnb_s}Oxdc^#x~)|;f%R5&yu;$Szavee-^K3Jn3EFzi;Q% z!VO>YX4ijKuvSw|31~X_*Jx9@p~=Ge+tlQDJN2ZpPHJdn4EZ-@p^xNIQ^iUVnZ2#c zXEXl!kiWmEK9Qx`$}&OeM>j{P@ym-pUVUh3k^eL~|94J`1^-#EHxDXPINq%~{9njz zcE{W{PWBk#H6OW78%>gP@7(v1XRd44!|upy<_o4L?>Nn`nab`kyDf!Rqfm%_!>#^wQeptc`NtfN{=ajC%$VuV|zR^ z<^M7_DZ9;1^&33iWEh%UtvxEQ_M^9G<7Ur$CvS=<>SpBlOsa3%R={&NWW`3moF5m& zc-KBMQ1njOx~MjMwkU78p#98SCpgX?(T_H4O7CBMp5!jrQxV~ljfR)jA=hEa=GT)nJoU%aU!k!*IR~sAve`MOT6ko3Y;|-^x^)sK#nW* zxJ%(#%~U7z@2O(L@=R?2l~f9O5D@dKkK z>#8>s)eME27(_(G1ZVWmXc02;VX0njl_mdn*Wo*1>T-oW4Usd1eOc7XHXmj>%CK+J zck7aet-{lIUrSlHY&&tQ{u8Hx{L#KMKMkc1PusYx&wesT1Fx*y@*NLf+AqBLqOo|# zftP2i^L!YjH0L|9dZ?8#e3m-4eX-R|fyqDfe|()LEGBusSW25k?4`D`&Z_G>o<20m zl3o1kXyzMX0k$KnFKypYaBAbag9~0SdfmG(GMClIyzt493WkXfyY;rD+%{QRAM2A5 zdVluJPXdW+CTYy!Og+0;Vz&=l;{7|k!GRSQw|Q_xr&aUH)O&WQp8r_Nd9#QqHfHVB zgOgN_6yLdSZg93U*k?ihq3dkY{BdttIvl1XXFOy*wcjmt^G%kOnm#ouZbI|@Z(VZO z!&5GEd2@?(nz1O`ysdnP*;#m4kBXSenbzBdJD(_2(k%L5xbQ&P1s`KQg@fBXdB5N2 zlVID@Rk3QqHT7x53Z+v0R$t=zon4P41scruw=iT5SLWKoq4#0?o`evlnLqVh3>(CM zUHH-WQY5r8&!pv_M+>|0MXQeLS4R8H_Z{zjUnOEO=iris(HeQljO_vfwFcfFKXh3* zyEfFfzngxLG5G4fKHYn|uee!TpR7=wG5gCy#z3K}pPPT%&W-vf5fG-rwyp5`vBE>D z@7CW7;QgUzpy((vQL;kB@xgD4ssho9=7~$?9isY+iWn9!KXISRWNf$aSb|J*fX~5% zD>9c@E;2Eln_4KxbHK!U_JozCH}_dGo_1cwcv0X8YrUpm#DmFqyFR_HJ)ZEenosp+ z-I}#$5*Efip4RO=@n?!m*NYiWZkuGig;j1(sGNA+IP+*xO7JDq(84ualDs8-v!vQ5 zseB2I$Y1&_AS-fJe(A#r%d}Ja=dIZEZSG{|=vgyP?%1BRY3`Q#69=9Z^r~**zT=bJ zsK)%bYfi4q6BFCT^_<)KICcsw_cRuhxUzqGOL)`a!z@oOOWx&+b!6C@AyzPK>&?%$f_g7@9rJe?zXIlq1m8(-&{*eGpukw4e12EajE$e? z{Rjy96Rs$5cuiXUxJQpedXZ#y&&dO}S-I^KFE+pb zd2)91hZlT*qfXp#tyAA&EPTWBUD(8Y!9|UJ8B75)SG?7@!tv~fm~%(X;R1!750YXl zR74C}1*^IrX39GmiX=Q)BGRU>T(A7Nc}|0vq4vfDl0K<1ZNjyDT0Ygn%96_EV#j&* zCMmUl^lY4xblsS<(y*HR_7(p=#><;n{(am9q#q~fA>wEeWyy-=GA@16FUw_ z@CdCH-miT}DM0q@(!jr)R`;Wc%ZOD?}WS+jsudGVz! zhj$+mKDq74k5wC{hbEVMOBOX<=^PA!S z?lV1HeE7m8#*61$@{+Y0_3kz6csES*oS@pzHBWOw5vLJHOqW#w>(0yKAq-A#D-R?x z^$AvFI6mW<6!81zg0F1*CRm3|C{J_d{_1kYu=@(vizVUF{^!vP^>QW^d>oJTPE26CWx=*4u0^NTCGVZ1c!E>7q@wjEiKijzJ-J~^C&*?! zc&J+N%F9(ML9=bE>V#!^K^I>O793*fJ$>M{&5vh!H{xaq-MHmakUE9Q&Wbls*J)MV z4Ivc|0jKi0&8t7v9MR%?amP{V(lN~&ZBA2olYV|s6Fg?awWr>eQ)+(8dXv^QIgOzw zS9Aw2&@OYF*eRjbtSi)7C0ME?Z1%U!LR(ZMdBf8U50+V0td_`85ioOWEm>#0z$c6s88UzdA! zto08lWsa%uJGWWD)GDz)(V(N%(F95`Ets5v+>tSUY~=Cf;5eV zm?b0{&M#uU{48x*!mR@whu9f|la<*nXg+sKb368I85<8<+p%YA%XqlhLdw{~0=Q0{ z=i=gd@Z#uVz7;yUy>fhu^aH{)jDr|-ueKhsnVuOGwJ9|!DyeJb#+e&e);liR*t&8j zt3j8~nczvmKEAzY&+6*v3inQGP%VzySm&0Nh{%(xy8d97H>Ac!06*} z#%BKRq;q#JU#n^7sgTfn6Z>!B`lplkEzY?7NVaz7DdFA*FARTyHU)R zGd=oI{x9}bSfAYf=HAT3ul~-N+wEsufByEMK|-w;Ab&2x7$Bmc;+1QEuPr Date: Tue, 10 May 2016 17:15:20 +0200 Subject: [PATCH 142/714] added better error handling. Also refactored some of the code and fixed a few issues in project_tree_saver --- .../projects/import_export/export_service.rb | 8 ++++++-- lib/gitlab/import_export.rb | 4 ---- lib/gitlab/import_export/error.rb | 5 +++++ .../import_export/import_export_reader.rb | 12 ++++++++---- lib/gitlab/import_export/project_tree_saver.rb | 12 ++++++------ lib/gitlab/import_export/repo_bundler.rb | 9 +++++---- lib/gitlab/import_export/saver.rb | 17 ++++++++++------- lib/gitlab/import_export/shared.rb | 15 +++++++++++++++ lib/gitlab/import_export/wiki_repo_bundler.rb | 7 ++++--- .../import_export/import_export_reader_spec.rb | 4 ++-- 10 files changed, 61 insertions(+), 32 deletions(-) create mode 100644 lib/gitlab/import_export/error.rb diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index fd569e1c9ae23e..87a259ed15a4be 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -4,8 +4,8 @@ class ExportService < BaseService def execute(options = {}) @shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work')) - # TODO handle errors save_all if [save_project_tree, bundle_repo, bundle_wiki_repo].all? + notify_worker if @shared.errors.any? end private @@ -23,7 +23,11 @@ def bundle_wiki_repo end def save_all - Gitlab::ImportExport::Saver.save(storage_path: @shared.export_path) + Gitlab::ImportExport::Saver.save(shared: @shared) + end + + def notify_worker + raise Gitlab::ImportExport::Error @shared.errors.join(', ') end end end diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb index 655373c03af975..6835411ba70639 100644 --- a/lib/gitlab/import_export.rb +++ b/lib/gitlab/import_export.rb @@ -6,10 +6,6 @@ def export_path(relative_path:) File.join(storage_path, relative_path) end - def project_tree - Gitlab::ImportExport::ImportExportReader.new.project_tree - end - def storage_path File.join(Settings.shared['path'], 'tmp/project_exports') end diff --git a/lib/gitlab/import_export/error.rb b/lib/gitlab/import_export/error.rb new file mode 100644 index 00000000000000..b47a646c0b9720 --- /dev/null +++ b/lib/gitlab/import_export/error.rb @@ -0,0 +1,5 @@ +module Gitlab + module ImportExport + class Error < StandardError; end + end +end \ No newline at end of file diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 37093ff58ed8ff..b7204d5a87c43e 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -2,16 +2,18 @@ module Gitlab module ImportExport class ImportExportReader - def initialize(config: 'lib/gitlab/import_export/import_export.yml') - config_hash = YAML.load_file(config).with_indifferent_access + def initialize(config: 'lib/gitlab/import_export/import_export.yml', shared:) + @shared = shared + config_hash = YAML.load_file(config).deep_symbolize_keys @tree = config_hash[:project_tree] @attributes_parser = Gitlab::ImportExport::AttributesFinder.new(included_attributes: config_hash[:included_attributes], excluded_attributes: config_hash[:excluded_attributes]) - @json_config_hash = {} end def project_tree @attributes_parser.find_included(:project).merge(include: build_hash(@tree)) + rescue => e + @shared.error(e.message) end private @@ -27,6 +29,8 @@ def build_hash(model_list) end def build_json_config_hash(model_object_hash) + @json_config_hash = {} + model_object_hash.values.flatten.each do |model_object| current_key = model_object_hash.keys.first @@ -61,7 +65,7 @@ def add_model_value(current_key, value) end def hash_or_merge(value, hash) - value.is_a?(Hash) ? value.merge(hash) : hash + value.is_a?(Hash) ? value.merge(hash) : { value => hash } end end end diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index 29d715c16d374c..2287524c8a56d2 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -5,16 +5,16 @@ class ProjectTreeSaver def initialize(project:, shared:) @project = project - @export_path = shared.export_path - @full_path = File.join(@export_path, project_filename) + @shared = shared + @full_path = File.join(@shared.export_path, project_filename) end def save - FileUtils.mkdir_p(@export_path) + FileUtils.mkdir_p(@shared.export_path) File.write(full_path, project_json_tree) true - rescue - # TODO: handle error + rescue => e + @shared.error(e.message) false end @@ -26,7 +26,7 @@ def project_filename end def project_json_tree - @project.to_json(Gitlab::ImportExport.project_tree) + @project.to_json(Gitlab::ImportExport::ImportExportReader.new(shared: @shared).project_tree) end end end diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index cd871687d76381..bcf976fb624761 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -7,21 +7,22 @@ class RepoBundler def initialize(project: , shared: ) @project = project - @export_path = shared.export_path + @shared = shared end def bundle return false if @project.empty_repo? - @full_path = File.join(@export_path, project_filename) + @full_path = File.join(@shared.export_path, project_filename) bundle_to_disk end private def bundle_to_disk - FileUtils.mkdir_p(@export_path) + FileUtils.mkdir_p(@shared.export_path) git_bundle(repo_path: path_to_repo, bundle_path: @full_path) - rescue + rescue => e + @shared.error(e.message) false end diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index 634e58e6039935..024a0e1e7850e5 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -7,32 +7,35 @@ def self.save(*args) new(*args).save end - def initialize(storage_path:) - @storage_path = storage_path + def initialize(shared:) + @shared = shared end def save if compress_and_save - remove_storage_path + remove_@shared.storage_path Rails.logger.info("Saved project export #{archive_file}") archive_file else false end + rescue => e + @shared.error(e.message) + false end private def compress_and_save - tar_czf(archive: archive_file, dir: @storage_path) + tar_czf(archive: archive_file, dir: @shared.storage_path) end - def remove_storage_path - FileUtils.rm_rf(@storage_path) + def remove_shared.storage_path + FileUtils.rm_rf(@shared.storage_path) end def archive_file - @archive_file ||= File.join(@storage_path, '..', "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_project_export.tar.gz") + @archive_file ||= File.join(@shared.storage_path, '..', "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_project_export.tar.gz") end end end diff --git a/lib/gitlab/import_export/shared.rb b/lib/gitlab/import_export/shared.rb index a4ec33a6cf7fc9..4246f73af90e7e 100644 --- a/lib/gitlab/import_export/shared.rb +++ b/lib/gitlab/import_export/shared.rb @@ -1,13 +1,28 @@ module Gitlab module ImportExport class Shared + + attr_reader :errors + def initialize(opts) @opts = opts + @errors = [] end def export_path @export_path ||= Gitlab::ImportExport.export_path(relative_path: @opts[:relative_path]) end + + def error(message) + error_out(message, caller[0].dup) + @errors << message + end + + private + + def error_out(message, caller) + Rails.logger.error("Import/Export error raised on #{caller}: #{message}") + end end end end diff --git a/lib/gitlab/import_export/wiki_repo_bundler.rb b/lib/gitlab/import_export/wiki_repo_bundler.rb index 17f1530d5a08a7..a0000176bb59da 100644 --- a/lib/gitlab/import_export/wiki_repo_bundler.rb +++ b/lib/gitlab/import_export/wiki_repo_bundler.rb @@ -4,14 +4,15 @@ class WikiRepoBundler < RepoBundler def bundle @wiki = ProjectWiki.new(@project) return true if !wiki? # it's okay to have no Wiki - @full_path = File.join(@export_path, project_filename) + @full_path = File.join(@shared.export_path, project_filename) bundle_to_disk end def bundle_to_disk - FileUtils.mkdir_p(@export_path) + FileUtils.mkdir_p(@shared.export_path) git_bundle(repo_path: path_to_repo, bundle_path: @full_path) - rescue + rescue => e + @shared.error(e.message) false end diff --git a/spec/lib/gitlab/import_export/import_export_reader_spec.rb b/spec/lib/gitlab/import_export/import_export_reader_spec.rb index f826c5ec8e6e5f..2fc9a39c68bf89 100644 --- a/spec/lib/gitlab/import_export/import_export_reader_spec.rb +++ b/spec/lib/gitlab/import_export/import_export_reader_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::ImportExport::ImportExportReader do - + let(:shared) { Gitlab::ImportExport::Shared.new(relative_path:'') } let(:test_config) { 'spec/support/import_export/import_export.yml' } let(:project_tree_hash) do { @@ -17,6 +17,6 @@ end it 'should generate hash from project tree config' do - expect(described_class.new(config: test_config).project_tree) =~ (project_tree_hash) + expect(described_class.new(config: test_config, shared: shared).project_tree) =~ (project_tree_hash) end end -- GitLab From d915e7d5cad99b8971e65d30accc8bc7a05fecbc Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 11 May 2016 10:16:23 +0530 Subject: [PATCH 143/714] Reuse the private token param and header for personal access tokens. - https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3749#note_11626427 - Personal access tokens are still a separate entity as far as the codebase is concerned - they just happen to use the same entry point as private tokens. - Update tests and documentation to reflect this change --- app/controllers/application_controller.rb | 2 +- doc/api/README.md | 4 ++-- lib/api/helpers.rb | 4 ++-- spec/controllers/application_controller_spec.rb | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 72ba1a85cff0da..b26afb42e74e52 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -80,7 +80,7 @@ def authenticate_user_from_private_token! end def authenticate_user_from_personal_access_token! - token_string = params[:personal_access_token].presence || request.headers['PERSONAL_ACCESS_TOKEN'].presence + token_string = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence personal_access_token = PersonalAccessToken.active.find_by_token(token_string) user = personal_access_token && personal_access_token.user diff --git a/doc/api/README.md b/doc/api/README.md index 0e9dc7acfed2d6..276816b280740e 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -77,8 +77,8 @@ You can create as many personal access tokens as you like from your GitLab profile (`/profile/personal_access_tokens`); perhaps one for each application that needs access to the GitLab API. -Once you have your token, pass it to the API using either the `personal_access_token` -parameter or the `PERSONAL-ACCESS-TOKEN` header. +Once you have your token, pass it to the API using either the `private_token` +parameter or the `PRIVATE-TOKEN` header. ## Basic Usage diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index de9a1b0eb94908..68642e2d8a7b82 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -4,8 +4,8 @@ module Helpers PRIVATE_TOKEN_PARAM = :private_token SUDO_HEADER ="HTTP_SUDO" SUDO_PARAM = :sudo - PERSONAL_ACCESS_TOKEN_PARAM = :personal_access_token - PERSONAL_ACCESS_TOKEN_HEADER = "HTTP_PERSONAL_ACCESS_TOKEN" + PERSONAL_ACCESS_TOKEN_PARAM = PRIVATE_TOKEN_PARAM + PERSONAL_ACCESS_TOKEN_HEADER = PRIVATE_TOKEN_HEADER def parse_boolean(value) [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(value) diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index e8bdbf1afb72e8..d7835dc6e2bccb 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -72,20 +72,20 @@ def index let(:personal_access_token) { create(:personal_access_token, user: user) } it "logs the user in when the 'personal_access_token' param is populated with the personal access token" do - get :index, personal_access_token: personal_access_token.token + get :index, private_token: personal_access_token.token expect(response.status).to eq(200) expect(response.body).to eq('authenticated') end it "logs the user in when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do - @request.headers["PERSONAL_ACCESS_TOKEN"] = personal_access_token.token + @request.headers["PRIVATE-TOKEN"] = personal_access_token.token get :index expect(response.status).to eq(200) expect(response.body).to eq('authenticated') end it "doesn't log the user in otherwise" do - get :index, personal_access_token: "token" + get :index, private_token: "token" expect(response.status).to_not eq(200) expect(response.body).to_not eq('authenticated') end -- GitLab From 70add1388f514b353d92d2e6a1db0dc173290946 Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Wed, 11 May 2016 10:25:21 +0530 Subject: [PATCH 144/714] Minor fixes after a final look at the diff. - Spaces around `{` and `}` in HAML. - Typo in CHANGELOG. - Remove i18n. --- CHANGELOG | 2 +- .../profiles/personal_access_tokens/index.html.haml | 10 +++++----- config/locales/en.yml | 4 ---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5b52977a9b42d5..d8d8a36e4b1135 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,7 +12,7 @@ v 8.8.0 (unreleased) - GitAccess#protected_tag? no longer loads all tags just to check if a single one exists - Reduce delay in destroying a project from 1-minute to immediately - Make build status canceled if any of the jobs was canceled and none failed - - Allow authentication using personal acces tokens + - Allow authentication using personal access tokens - Upgrade Sidekiq to 4.1.2 - Sanitize repo paths in new project error message - Bump mail_room to 0.7.0 to fix stuck IDLE connections diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index f7482d2c87d901..0f51e8cd8bef6a 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -46,9 +46,9 @@ %tr %td= token.name %td.input-group.personal-access-tokens-token-column - %input.form-control{type: "text", value: token.token, readonly: true} + %input.form-control{ type: "text", value: token.token, readonly: true } %div.input-group-btn - %button.btn.btn-default{type: "button", data: {clipboard_text: token.token}} + %button.btn.btn-default{ type: "button", data: { clipboard_text: token.token } } %i.fa.fa-clipboard %td= token.created_at.to_date - if token.expires_at.present? @@ -56,7 +56,7 @@ - else %td %span.personal-access-tokens-never-expires-label Never - %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: {confirm: t('profile.personal_access_tokens.revoke.confirmation')} + %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: { confirm: "Are you sure? This cannot be undone." } - else %span You don't have any active tokens yet. @@ -78,9 +78,9 @@ %tr %td= token.name %td.input-group.personal-access-tokens-token-column - %input.form-control{type: "text", value: token.token, readonly: true} + %input.form-control{ type: "text", value: token.token, readonly: true } %div.input-group-btn - %button.btn.btn-default{type: "button", data: {clipboard_text: token.token}} + %button.btn.btn-default{ type: "button", data: { clipboard_text: token.token } } %i.fa.fa-clipboard %td= token.created_at.to_date diff --git a/config/locales/en.yml b/config/locales/en.yml index b5b8c4467b04dc..cedb5e207bd379 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -12,7 +12,3 @@ en: pagination: previous: "Prev" next: "Next" - profile: - personal_access_tokens: - revoke: - confirmation: "Are you sure? This cannot be undone." -- GitLab From 49e6fc40b9d23b4081139a3ad141722a6b1f7cfc Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 11 May 2016 13:17:49 +0200 Subject: [PATCH 145/714] fix bad refactor --- lib/gitlab/import_export/saver.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index 024a0e1e7850e5..7532c977fcc0f2 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -13,7 +13,7 @@ def initialize(shared:) def save if compress_and_save - remove_@shared.storage_path + remove_storage_path Rails.logger.info("Saved project export #{archive_file}") archive_file else @@ -30,7 +30,7 @@ def compress_and_save tar_czf(archive: archive_file, dir: @shared.storage_path) end - def remove_shared.storage_path + def remove_storage_path FileUtils.rm_rf(@shared.storage_path) end -- GitLab From 5086e899fe26447e6e24064c9a05d3989c1e8448 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 11 May 2016 13:21:00 +0200 Subject: [PATCH 146/714] fix log statement --- app/workers/project_import_worker.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/project_import_worker.rb b/app/workers/project_import_worker.rb index cc75da704f6498..c6a6d24b4e5d5e 100644 --- a/app/workers/project_import_worker.rb +++ b/app/workers/project_import_worker.rb @@ -15,7 +15,7 @@ def perform(current_user_id, tmp_file, namespace_id, path) project.repository.after_import project.import_finish else - logger.error("There was an error during the import: #{tmpfile}") + logger.error("There was an error during the import: #{tmp_file}") end end -- GitLab From cffae0d22ee159b78f66eb68cae9df4bcb9e83e5 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 11 May 2016 14:51:25 +0200 Subject: [PATCH 147/714] fixing more export problems --- app/services/projects/import_export/export_service.rb | 2 +- app/workers/project_export_worker.rb | 3 +-- lib/gitlab/import_export/saver.rb | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb index 87a259ed15a4be..e6eb6f915b064e 100644 --- a/app/services/projects/import_export/export_service.rb +++ b/app/services/projects/import_export/export_service.rb @@ -27,7 +27,7 @@ def save_all end def notify_worker - raise Gitlab::ImportExport::Error @shared.errors.join(', ') + raise Gitlab::ImportExport::Error.new(@shared.errors.join(', ')) end end end diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb index a1add5395b7ab0..3616b37d2ad415 100644 --- a/app/workers/project_export_worker.rb +++ b/app/workers/project_export_worker.rb @@ -1,13 +1,12 @@ class ProjectExportWorker include Sidekiq::Worker - # TODO: enabled retry - disabled for QA purposes + # TODO: enable retry - disabled for QA purposes sidekiq_options queue: :gitlab_shell, retry: false def perform(current_user_id, project_id) current_user = User.find(current_user_id) project = Project.find(project_id) ::Projects::ImportExport::ExportService.new(project, current_user).execute - # TODO : Handle errors end end diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index 7532c977fcc0f2..a2ff43a3ce3dee 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -13,7 +13,7 @@ def initialize(shared:) def save if compress_and_save - remove_storage_path + remove_export_path Rails.logger.info("Saved project export #{archive_file}") archive_file else @@ -27,15 +27,15 @@ def save private def compress_and_save - tar_czf(archive: archive_file, dir: @shared.storage_path) + tar_czf(archive: archive_file, dir: @shared.export_path) end - def remove_storage_path - FileUtils.rm_rf(@shared.storage_path) + def remove_export_path + FileUtils.rm_rf(@shared.export_path) end def archive_file - @archive_file ||= File.join(@shared.storage_path, '..', "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_project_export.tar.gz") + @archive_file ||= File.join(@shared.export_path, '..', "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_project_export.tar.gz") end end end -- GitLab From ae53840723208d34b78dd67f7aedf9c627af4ed1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 11 May 2016 15:02:55 +0200 Subject: [PATCH 148/714] updated export file for spec --- .../import_export/test_project_export.tar.gz | Bin 322702 -> 338822 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index 8147c289b8e763d509d35f0293814d92489772f3..f2c3c3cd2dc67ba456501a8ba754edf74cdaba9a 100644 GIT binary patch delta 27434 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 Date: Wed, 11 May 2016 17:22:45 +0200 Subject: [PATCH 149/714] refactored import to use shared error stuff and fixed a few issues with recent refactorings --- app/workers/project_import_worker.rb | 1 - .../import_export/import_export_reader.rb | 2 ++ lib/gitlab/import_export/import_service.rb | 19 ++++++++----------- lib/gitlab/import_export/importer.rb | 11 +++++++---- .../import_export/project_tree_restorer.rb | 13 ++++++++----- lib/gitlab/import_export/repo_restorer.rb | 6 ++++-- lib/gitlab/import_export/shared.rb | 2 +- .../project_tree_restorer_spec.rb | 3 ++- 8 files changed, 32 insertions(+), 25 deletions(-) diff --git a/app/workers/project_import_worker.rb b/app/workers/project_import_worker.rb index c6a6d24b4e5d5e..b2902c3278e6d1 100644 --- a/app/workers/project_import_worker.rb +++ b/app/workers/project_import_worker.rb @@ -13,7 +13,6 @@ def perform(current_user_id, tmp_file, namespace_id, path) project_path: path) if project project.repository.after_import - project.import_finish else logger.error("There was an error during the import: #{tmp_file}") end diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index b7204d5a87c43e..f637756b35f8e2 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -2,6 +2,8 @@ module Gitlab module ImportExport class ImportExportReader + attr_reader :tree + def initialize(config: 'lib/gitlab/import_export/import_export.yml', shared:) @shared = shared config_hash = YAML.load_file(config).deep_symbolize_keys diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index 99fb9bad78d870..f7b66448abc966 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -10,12 +10,12 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) @archive_file = archive_file @current_user = owner @namespace = Namespace.find(namespace_id) - @project_path = project_path + @shared = Gitlab::ImportExport::Shared.new(relative_path: path_with_namespace, project_path: project_path) end def execute Gitlab::ImportExport::Importer.import(archive_file: @archive_file, - storage_path: storage_path) + shared: @shared) project_tree.project if [restore_project_tree, restore_repo, restore_wiki_repo].all? end @@ -26,36 +26,33 @@ def restore_project_tree end def project_tree - @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(path: storage_path, - user: @current_user, - project_path: @project_path, + @project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(user: @current_user, + shared: @shared, namespace_id: @namespace.id) end def restore_repo Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path, + shared: @shared, project: project_tree.project).restore end def restore_wiki_repo Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path, + shared: @shared, project: ProjectWiki.new(project_tree.project)).restore end - def storage_path - @storage_path ||= Gitlab::ImportExport.export_path(relative_path: path_with_namespace) - end - def path_with_namespace File.join(@namespace.path, @project_path) end def repo_path - File.join(storage_path, 'project.bundle') + File.join(@shared.export_path, 'project.bundle') end def wiki_repo_path - File.join(storage_path, 'project.wiki.bundle') + File.join(@shared.export_path, 'project.wiki.bundle') end end end diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 8f838287f97696..19c5aafad20d17 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -7,20 +7,23 @@ def self.import(*args) new(*args).import end - def initialize(archive_file: , storage_path:) + def initialize(archive_file: , shared:) @archive_file = archive_file - @storage_path = storage_path + @shared = shared end def import - FileUtils.mkdir_p(@storage_path) + FileUtils.mkdir_p(@shared.storage_path) decompress_archive + rescue => e + @shared.error(e.message) + false end private def decompress_archive - untar_zxf(archive: @archive_file, dir: @storage_path) + untar_zxf(archive: @archive_file, dir: @shared.storage_path) end end end diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index ad77f7f69b19ea..06bf86a1787d16 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -2,11 +2,12 @@ module Gitlab module ImportExport class ProjectTreeRestorer - def initialize(path:, user:, project_path:, namespace_id:) - @path = File.join(path, 'project.json') + def initialize(user:, shared:, namespace_id:) + @path = File.join(shared.export_path, 'project.json') @user = user - @project_path = project_path + @project_path = shared.opts[:project_path] @namespace_id = namespace_id + @shared = shared end def restore @@ -15,7 +16,7 @@ def restore @project_members = @tree_hash.delete('project_members') create_relations rescue => e - # TODO: handle errors better, move them to a shared thing + @shared.error(e.message) false end @@ -44,7 +45,9 @@ def create_relations(relation_list = default_relation_list, tree_hash = @tree_ha end def default_relation_list - Gitlab::ImportExport::ImportExportReader.tree.reject { |model| model.is_a?(Hash) && model[:project_members] } + Gitlab::ImportExport::ImportExportReader.new(shared: @shared).tree.reject do |model| + model.is_a?(Hash) && model[:project_members] + end end def create_project diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 7a4cda828b4705..3909d447448da4 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -3,9 +3,10 @@ module ImportExport class RepoRestorer include Gitlab::ImportExport::CommandLineUtil - def initialize(project:, path_to_bundle:) + def initialize(project:, shared:, path_to_bundle:) @project = project @path_to_bundle = path_to_bundle + @shared = shared end def restore @@ -15,7 +16,8 @@ def restore FileUtils.mkdir_p(path_to_repo) git_unbundle(repo_path: path_to_repo, bundle_path: @path_to_bundle) - rescue + rescue => e + @shared.error(e.message) false end diff --git a/lib/gitlab/import_export/shared.rb b/lib/gitlab/import_export/shared.rb index 4246f73af90e7e..050b0428f45173 100644 --- a/lib/gitlab/import_export/shared.rb +++ b/lib/gitlab/import_export/shared.rb @@ -2,7 +2,7 @@ module Gitlab module ImportExport class Shared - attr_reader :errors + attr_reader :errors, :opts def initialize(opts) @opts = opts diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index 0958365ff9e1f1..7c6a14fc8a8f66 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -5,7 +5,8 @@ let(:user) { create(:user) } let(:namespace) { create(:namespace, owner: user) } - let(:project_tree_restorer) { described_class.new(path: Rails.root.join("spec/lib/gitlab/import_export/"), user: user, project_path: 'project', namespace_id: namespace.id) } + let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "../../../spec/lib/gitlab/import_export/", project_path: 'path') } + let(:project_tree_restorer) { described_class.new(user: user, shared: shared, namespace_id: namespace.id) } context 'JSON' do let(:restored_project_json) do -- GitLab From 385d6df20c7f3a40b40016d5413b50690ce9a48b Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 12 May 2016 10:39:59 +0200 Subject: [PATCH 150/714] typo --- lib/gitlab/import_export/import_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index f7b66448abc966..ea9ba9e7b4b9c6 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -44,7 +44,7 @@ def restore_wiki_repo end def path_with_namespace - File.join(@namespace.path, @project_path) + File.join(@namespace.path, @shared.opts[:project_path]) end def repo_path -- GitLab From f06c5516db2c4b1df480545d11f177838abeb00d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 12 May 2016 10:57:28 +0200 Subject: [PATCH 151/714] fix issue in import_service --- lib/gitlab/import_export/import_service.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/import_export/import_service.rb b/lib/gitlab/import_export/import_service.rb index ea9ba9e7b4b9c6..670f1ebece8100 100644 --- a/lib/gitlab/import_export/import_service.rb +++ b/lib/gitlab/import_export/import_service.rb @@ -10,7 +10,7 @@ def initialize(archive_file:, owner:, namespace_id:, project_path:) @archive_file = archive_file @current_user = owner @namespace = Namespace.find(namespace_id) - @shared = Gitlab::ImportExport::Shared.new(relative_path: path_with_namespace, project_path: project_path) + @shared = Gitlab::ImportExport::Shared.new(relative_path: path_with_namespace(project_path), project_path: project_path) end def execute @@ -43,8 +43,8 @@ def restore_wiki_repo project: ProjectWiki.new(project_tree.project)).restore end - def path_with_namespace - File.join(@namespace.path, @shared.opts[:project_path]) + def path_with_namespace(project_path) + File.join(@namespace.path, project_path) end def repo_path -- GitLab From ff56f7be62a94f336e4cb3382ca983cf5e2c5e54 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 12 May 2016 11:03:55 +0200 Subject: [PATCH 152/714] fix importer issue --- lib/gitlab/import_export/importer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 19c5aafad20d17..20a93f7f6deb2f 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -13,7 +13,7 @@ def initialize(archive_file: , shared:) end def import - FileUtils.mkdir_p(@shared.storage_path) + FileUtils.mkdir_p(@shared.export_path) decompress_archive rescue => e @shared.error(e.message) @@ -23,7 +23,7 @@ def import private def decompress_archive - untar_zxf(archive: @archive_file, dir: @shared.storage_path) + untar_zxf(archive: @archive_file, dir: @shared.export_path) end end end -- GitLab From b2b7b38c944436af5257b1b38d612aeb3d2f237e Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 12 May 2016 11:29:06 +0200 Subject: [PATCH 153/714] fix rubocop warnings --- lib/gitlab/import_export/error.rb | 2 +- lib/gitlab/import_export/import_export_reader.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/error.rb b/lib/gitlab/import_export/error.rb index b47a646c0b9720..e341c4d9cf8989 100644 --- a/lib/gitlab/import_export/error.rb +++ b/lib/gitlab/import_export/error.rb @@ -2,4 +2,4 @@ module Gitlab module ImportExport class Error < StandardError; end end -end \ No newline at end of file +end diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index b7204d5a87c43e..a8b6294662a09f 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -53,7 +53,7 @@ def create_model_value(current_key, value) parsed_hash = { include: value } @attributes_parser.parse(value) do |hash| - parsed_hash = { include: hash_or_merge(value, hash) } + parsed_hash = { include: hash_or_merge(value, hash) } end @json_config_hash[current_key] = parsed_hash end -- GitLab From 8165e52045711958abbb94ee9ea2c00056ccadda Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 12 May 2016 14:27:41 +0200 Subject: [PATCH 154/714] add author on notes to export - so we can add to a note if project member is not found --- lib/gitlab/import_export/import_export.yml | 8 ++++++-- lib/gitlab/import_export/import_export_reader.rb | 12 ++++++++++++ .../gitlab/import_export/project_tree_saver_spec.rb | 7 +++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index 36128909df4dc8..66e6ae86cfe0e1 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -1,7 +1,8 @@ # Model relationships to be included in the project import/export project_tree: - issues: - - :notes + - notes: + :author - :labels - :milestones - :snippets @@ -10,8 +11,9 @@ project_tree: - project_members: - :user - merge_requests: + - notes: + :author - :merge_request_diff - - :notes - ci_commits: - :statuses @@ -31,6 +33,8 @@ included_attributes: - :id - :email - :username + author: + - :name # Do not include the following attributes for the models specified. excluded_attributes: diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index a8b6294662a09f..9aac0eae79ab7f 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -37,10 +37,22 @@ def build_json_config_hash(model_object_hash) @attributes_parser.parse(current_key) { |hash| @json_config_hash[current_key] ||= hash } handle_model_object(current_key, model_object) + process_sub_model(current_key, model_object) if model_object.is_a?(Hash) end @json_config_hash end + def process_sub_model(current_key, model_object) + sub_model_json = build_json_config_hash(model_object).dup + @json_config_hash.slice!(current_key) + + if @json_config_hash[current_key] && @json_config_hash[current_key][:include] + @json_config_hash[current_key][:include] << sub_model_json + else + @json_config_hash[current_key] = { include: sub_model_json } + end + end + def handle_model_object(current_key, model_object) if @json_config_hash[current_key] add_model_value(current_key, model_object) 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 67e6267b741193..b9cf88d3f777c8 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -65,6 +65,10 @@ expect(saved_project_json['issues'].first['notes']).not_to be_empty end + it 'has author on issue comments' do + expect(saved_project_json['issues'].first['notes'].first['author']).not_to be_empty + end + it 'has project members' do expect(saved_project_json['project_members']).not_to be_empty end @@ -77,6 +81,9 @@ expect(saved_project_json['merge_requests'].first['notes']).not_to be_empty end + it 'has author on merge requests comments' do + expect(saved_project_json['merge_requests'].first['notes'].first['author']).not_to be_empty + end it 'has commit statuses' do expect(saved_project_json['ci_commits'].first['statuses']).not_to be_empty end -- GitLab From 25a1c6541aa3dfb41ef006d42ba280d5a1d4103d Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 12:33:13 +0200 Subject: [PATCH 155/714] add message to notes about missing author on import --- .../import_export/import_export_reader.rb | 2 +- lib/gitlab/import_export/importer.rb | 2 +- lib/gitlab/import_export/members_mapper.rb | 19 +++++++++----- .../import_export/project_tree_restorer.rb | 26 ++++++++++++------- .../import_export/project_tree_saver.rb | 2 +- lib/gitlab/import_export/relation_factory.rb | 20 ++++++++++++-- lib/gitlab/import_export/repo_bundler.rb | 2 +- lib/gitlab/import_export/repo_restorer.rb | 2 +- lib/gitlab/import_export/saver.rb | 2 +- lib/gitlab/import_export/shared.rb | 8 +++--- lib/gitlab/import_export/wiki_repo_bundler.rb | 2 +- .../import_export/members_mapper_spec.rb | 8 +++--- .../project_tree_restorer_spec.rb | 5 +--- 13 files changed, 65 insertions(+), 35 deletions(-) diff --git a/lib/gitlab/import_export/import_export_reader.rb b/lib/gitlab/import_export/import_export_reader.rb index 5d218320e23f3d..11a736ecab6657 100644 --- a/lib/gitlab/import_export/import_export_reader.rb +++ b/lib/gitlab/import_export/import_export_reader.rb @@ -15,7 +15,7 @@ def initialize(config: 'lib/gitlab/import_export/import_export.yml', shared:) def project_tree @attributes_parser.find_included(:project).merge(include: build_hash(@tree)) rescue => e - @shared.error(e.message) + @shared.error(e) end private diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb index 20a93f7f6deb2f..d73ce43b491830 100644 --- a/lib/gitlab/import_export/importer.rb +++ b/lib/gitlab/import_export/importer.rb @@ -16,7 +16,7 @@ def import FileUtils.mkdir_p(@shared.export_path) decompress_archive rescue => e - @shared.error(e.message) + @shared.error(e) false end diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index d6124106f575fc..da8aa4756539e6 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -2,18 +2,25 @@ module Gitlab module ImportExport class MembersMapper - def self.map(*args) - new(*args).map - end + attr_reader :map, :note_member_list def initialize(exported_members:, user:, project_id:) @exported_members = exported_members @user = user @project_id = project_id + @note_member_list = [] + + @project_member_map = Hash.new do |_, key| + @note_member_list << key + default_project_member + end + + @map = generate_map end - def map - @project_member_map = Hash.new(default_project_member) + private + + def generate_map @exported_members.each do |member| existing_user = User.where(find_project_user_query(member)).first assign_member(existing_user, member) if existing_user @@ -21,8 +28,6 @@ def map @project_member_map end - private - def assign_member(existing_user, member) old_user_id = member['user']['id'] member['user'] = existing_user diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb index 06bf86a1787d16..a840c9f94786dc 100644 --- a/lib/gitlab/import_export/project_tree_restorer.rb +++ b/lib/gitlab/import_export/project_tree_restorer.rb @@ -16,7 +16,7 @@ def restore @project_members = @tree_hash.delete('project_members') create_relations rescue => e - @shared.error(e.message) + @shared.error(e) false end @@ -26,9 +26,10 @@ def project private - def members_map - @members ||= Gitlab::ImportExport::MembersMapper.map( - exported_members: @project_members, user: @user, project_id: project.id) + def members_mapper + @members_mapper ||= Gitlab::ImportExport::MembersMapper.new(exported_members: @project_members, + user: @user, + project_id: project.id) end def create_relations(relation_list = default_relation_list, tree_hash = @tree_hash) @@ -61,11 +62,18 @@ def create_project end def create_sub_relations(relation, tree_hash) - tree_hash[relation.keys.first.to_s].each do |relation_item| + relation_key = relation.keys.first.to_s + tree_hash[relation_key].each do |relation_item| relation.values.flatten.each do |sub_relation| - relation_hash = relation_item[sub_relation.to_s] - next if relation_hash.blank? - process_sub_relation(relation_hash, relation_item, sub_relation) + + if sub_relation.is_a?(Hash) + relation_hash = relation_item[sub_relation.keys.first.to_s] + sub_relation = sub_relation.keys.first + else + relation_hash = relation_item[sub_relation.to_s] + end + + process_sub_relation(relation_hash, relation_item, sub_relation) unless relation_hash.blank? end end end @@ -87,7 +95,7 @@ def create_relation(relation, relation_hash_list) def relation_from_factory(relation, relation_hash) Gitlab::ImportExport::RelationFactory.create( - relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_map: members_map) + relation_sym: relation.to_sym, relation_hash: relation_hash.merge('project_id' => project.id), members_mapper: members_mapper) end end end diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb index 2287524c8a56d2..ed8ca31d9367d4 100644 --- a/lib/gitlab/import_export/project_tree_saver.rb +++ b/lib/gitlab/import_export/project_tree_saver.rb @@ -14,7 +14,7 @@ def save File.write(full_path, project_json_tree) true rescue => e - @shared.error(e.message) + @shared.error(e) false end diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index dd992ef443eed3..65e2a935fa93ac 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -6,11 +6,12 @@ module RelationFactory OVERRIDES = { snippets: :project_snippets, ci_commits: 'Ci::Commit', statuses: 'commit_status' }.freeze USER_REFERENCES = %w(author_id assignee_id updated_by_id).freeze - def create(relation_sym:, relation_hash:, members_map:) + def create(relation_sym:, relation_hash:, members_mapper:) relation_sym = parse_relation_sym(relation_sym) klass = parse_relation(relation_hash, relation_sym) - update_user_references(relation_hash, members_map) + update_missing_author(relation_hash, members_mapper) if relation_sym == :notes + update_user_references(relation_hash, members_mapper.map) update_project_references(relation_hash, klass) imported_object(klass, relation_hash) @@ -26,6 +27,21 @@ def update_user_references(relation_hash, members_map) end end + def update_missing_author(relation_hash, members_map) + old_author_id = relation_hash['author_id'].dup + relation_hash['author_id'] = members_map.map[old_author_id] + return unless members_map.note_member_list.include?(old_author_id) + + relation_hash['note'] = ('*Blank note*') if relation_hash['note'].blank? + relation_hash['note'].join(missing_author_note(relation_hash['updated_at'], + relation_hash['author']['name'])) + relation_hash.delete('author') + end + + def missing_author_note(updated_at, author_name) + "\n\n *By #{author_name} on #{updated_at} (imported from GitLab project)*" + end + def update_project_references(relation_hash, klass) project_id = relation_hash.delete('project_id') diff --git a/lib/gitlab/import_export/repo_bundler.rb b/lib/gitlab/import_export/repo_bundler.rb index bcf976fb624761..af809f4c38cde7 100644 --- a/lib/gitlab/import_export/repo_bundler.rb +++ b/lib/gitlab/import_export/repo_bundler.rb @@ -22,7 +22,7 @@ def bundle_to_disk FileUtils.mkdir_p(@shared.export_path) git_bundle(repo_path: path_to_repo, bundle_path: @full_path) rescue => e - @shared.error(e.message) + @shared.error(e) false end diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb index 3909d447448da4..36094b95aa4445 100644 --- a/lib/gitlab/import_export/repo_restorer.rb +++ b/lib/gitlab/import_export/repo_restorer.rb @@ -17,7 +17,7 @@ def restore git_unbundle(repo_path: path_to_repo, bundle_path: @path_to_bundle) rescue => e - @shared.error(e.message) + @shared.error(e) false end diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb index a2ff43a3ce3dee..f38229c6c59ede 100644 --- a/lib/gitlab/import_export/saver.rb +++ b/lib/gitlab/import_export/saver.rb @@ -20,7 +20,7 @@ def save false end rescue => e - @shared.error(e.message) + @shared.error(e) false end diff --git a/lib/gitlab/import_export/shared.rb b/lib/gitlab/import_export/shared.rb index 050b0428f45173..01ac332981b472 100644 --- a/lib/gitlab/import_export/shared.rb +++ b/lib/gitlab/import_export/shared.rb @@ -13,9 +13,11 @@ def export_path @export_path ||= Gitlab::ImportExport.export_path(relative_path: @opts[:relative_path]) end - def error(message) - error_out(message, caller[0].dup) - @errors << message + def error(error) + error_out(error.message, caller[0].dup) + @errors << error.message + # Debug: + Rails.logger.error(error.backtrace) end private diff --git a/lib/gitlab/import_export/wiki_repo_bundler.rb b/lib/gitlab/import_export/wiki_repo_bundler.rb index a0000176bb59da..e1e7f753720195 100644 --- a/lib/gitlab/import_export/wiki_repo_bundler.rb +++ b/lib/gitlab/import_export/wiki_repo_bundler.rb @@ -12,7 +12,7 @@ def bundle_to_disk FileUtils.mkdir_p(@shared.export_path) git_bundle(repo_path: path_to_repo, bundle_path: @full_path) rescue => e - @shared.error(e.message) + @shared.error(e) false end diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb index a4d3d6d122f69f..78706f64fb7428 100644 --- a/spec/lib/gitlab/import_export/members_mapper_spec.rb +++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb @@ -42,9 +42,11 @@ it 'defaults to importer project member if it does not exist' do expect(members_mapper.map[-1]).to eq(user.id) end - end - def project_member_user_id(id) - members_mapper.map[id] + it 'updates missing author IDs on missing project member' do + members_mapper.map[-1] + + expect(members_mapper.note_member_list.first).to eq(-1) + end end end diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index 7c6a14fc8a8f66..6464b0141f3e5a 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -7,12 +7,9 @@ let(:namespace) { create(:namespace, owner: user) } let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "../../../spec/lib/gitlab/import_export/", project_path: 'path') } let(:project_tree_restorer) { described_class.new(user: user, shared: shared, namespace_id: namespace.id) } + let!(:restored_project_json) { project_tree_restorer.restore } context 'JSON' do - let(:restored_project_json) do - project_tree_restorer.restore - end - it 'restores models based on JSON' do expect(restored_project_json).to be true end -- GitLab From a86825826915f78a0728becd91f6a31df90543ea Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 14:17:10 +0200 Subject: [PATCH 156/714] update json and fix notes issue --- lib/gitlab/import_export/relation_factory.rb | 4 +- spec/lib/gitlab/import_export/project.json | 5747 ++++++++++++++++-- 2 files changed, 5406 insertions(+), 345 deletions(-) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index 65e2a935fa93ac..0adcd0d5e6cd04 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -28,12 +28,12 @@ def update_user_references(relation_hash, members_map) end def update_missing_author(relation_hash, members_map) - old_author_id = relation_hash['author_id'].dup + old_author_id = relation_hash['author_id'] relation_hash['author_id'] = members_map.map[old_author_id] return unless members_map.note_member_list.include?(old_author_id) relation_hash['note'] = ('*Blank note*') if relation_hash['note'].blank? - relation_hash['note'].join(missing_author_note(relation_hash['updated_at'], + relation_hash['note'] += (missing_author_note(relation_hash['updated_at'], relation_hash['author']['name'])) relation_hash.delete('author') end diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index 8b6a16c049fd69..31851c4c64be16 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -1,429 +1,5490 @@ { - "name": "searchable_project", - "path": "gitlabhq", - "description": null, + "name": "Gitlab Test", + "path": "gitlab-test", + "description": "Aut saepe in eos dolorem aliquam hic.", "issues_enabled": true, "merge_requests_enabled": true, "wiki_enabled": true, - "snippets_enabled": true, + "snippets_enabled": false, "visibility_level": 20, "archived": false, "issues": [ { - "id": 1, - "title": "Debitis vero omnis cum accusamus nihil rerum cupiditate.", + "id": 40, + "title": "Voluptatem modi rerum ipsum vero voluptas repudiandae veniam quibusdam.", "assignee_id": 1, - "author_id": 2, - "project_id": 6, - "created_at": "2016-04-13T14:40:32.471Z", - "updated_at": "2016-04-13T14:40:38.956Z", + "author_id": 4, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.411Z", + "updated_at": "2016-04-12T13:08:26.029Z", "position": 0, "branch_name": null, - "description": null, - "milestone_id": null, + "description": "Aut minima non sit qui nulla rerum laborum.", + "milestone_id": 10, "state": "opened", - "iid": 1, + "iid": 10, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 1357, + "note": "test", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-04-12T13:08:26.006Z", + "updated_at": "2016-04-12T13:08:26.006Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": "", + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 338, + "note": "Fugit in aliquid voluptas dolor.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:19:59.213Z", + "updated_at": "2016-03-22T15:19:59.213Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 337, + "note": "Occaecati consequatur facilis doloribus omnis hic placeat nihil.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:19:59.186Z", + "updated_at": "2016-03-22T15:19:59.186Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 336, + "note": "Nostrum et et est repudiandae non dolores voluptatem.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:19:59.156Z", + "updated_at": "2016-03-22T15:19:59.156Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 335, + "note": "Nihil et aut dolorum aut sit maxime.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:19:59.130Z", + "updated_at": "2016-03-22T15:19:59.130Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 334, + "note": "Non blanditiis voluptatem sit earum accusantium distinctio voluptas officiis.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:19:59.101Z", + "updated_at": "2016-03-22T15:19:59.101Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 333, + "note": "Nesciunt non dolorem similique nam ipsa et.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:19:59.075Z", + "updated_at": "2016-03-22T15:19:59.075Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 332, + "note": "Sed aut fugit et officiis dolor.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:19:59.047Z", + "updated_at": "2016-03-22T15:19:59.047Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 331, + "note": "Officiis iste eum recusandae suscipit consequatur consequatur.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:19:59.015Z", + "updated_at": "2016-03-22T15:19:59.015Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 40, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 39, + "title": "Sit ut adipisci sint temporibus velit quis.", + "assignee_id": 1, + "author_id": 12, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.278Z", + "updated_at": "2016-03-22T15:19:59.473Z", + "position": 0, + "branch_name": null, + "description": "Ab sint nostrum aliquam laudantium magni recusandae qui.", + "milestone_id": 10, + "state": "closed", + "iid": 9, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 346, + "note": "Natus rerum qui dolorem dolorum voluptas.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:19:59.469Z", + "updated_at": "2016-03-22T15:19:59.469Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 345, + "note": "Voluptatibus et qui quis id sed necessitatibus quos.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:19:59.438Z", + "updated_at": "2016-03-22T15:19:59.438Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 344, + "note": "Aperiam possimus ipsam quibusdam in.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:19:59.410Z", + "updated_at": "2016-03-22T15:19:59.410Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 343, + "note": "Ad vel hic molestiae tempora.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:19:59.379Z", + "updated_at": "2016-03-22T15:19:59.379Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 342, + "note": "Vel magnam sed quidem aut molestiae facilis alias.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:19:59.348Z", + "updated_at": "2016-03-22T15:19:59.348Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 341, + "note": "Veritatis dolorum aut qui quod.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:19:59.319Z", + "updated_at": "2016-03-22T15:19:59.319Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 340, + "note": "Illum at cumque dolorum et quia.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:19:59.289Z", + "updated_at": "2016-03-22T15:19:59.289Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 339, + "note": "Fugiat et error molestiae cumque quos aperiam.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:19:59.255Z", + "updated_at": "2016-03-22T15:19:59.255Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 39, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 38, + "title": "Quod quo est quis vel natus nulla eos reiciendis.", + "assignee_id": 12, + "author_id": 3, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.137Z", + "updated_at": "2016-03-22T15:19:59.712Z", + "position": 0, + "branch_name": null, + "description": "Fugit dolor accusantium suscipit facere voluptate.", + "milestone_id": 10, + "state": "opened", + "iid": 8, "updated_by_id": null, "confidential": false, "deleted_at": null, "moved_to_id": null, + "due_date": null, "notes": [ { - "id": 1, - "note": ":+1: issue", - "noteable_type": "Issue", - "author_id": 21, - "created_at": "2016-04-13T14:40:38.944Z", - "updated_at": "2016-04-13T14:40:38.944Z", - "project_id": 8, + "id": 354, + "note": "Id commodi natus vel corrupti ea placeat cum nihil.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:19:59.708Z", + "updated_at": "2016-03-22T15:19:59.708Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 353, + "note": "Quia hic sed ratione eos voluptate dolor occaecati dolorem.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:19:59.680Z", + "updated_at": "2016-03-22T15:19:59.680Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 352, + "note": "Commodi sint voluptatem est aut.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:19:59.650Z", + "updated_at": "2016-03-22T15:19:59.650Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 351, + "note": "Et quibusdam voluptatibus dolores aut quam architecto optio.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:19:59.622Z", + "updated_at": "2016-03-22T15:19:59.622Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 350, + "note": "Fugit natus explicabo sed pariatur et quasi autem.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:19:59.590Z", + "updated_at": "2016-03-22T15:19:59.590Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 349, + "note": "Corporis commodi eos quia optio sunt corrupti.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:19:59.562Z", + "updated_at": "2016-03-22T15:19:59.562Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 348, + "note": "Occaecati nostrum hic dolor tenetur aliquid maxime animi.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:19:59.536Z", + "updated_at": "2016-03-22T15:19:59.536Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 347, + "note": "Inventore ullam sed repellendus laudantium itaque et quia.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:19:59.506Z", + "updated_at": "2016-03-22T15:19:59.506Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 38, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 37, + "title": "Animi suscipit quia ut hic asperiores perferendis nisi ut.", + "assignee_id": 22, + "author_id": 10, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.994Z", + "updated_at": "2016-03-22T15:19:59.972Z", + "position": 0, + "branch_name": null, + "description": "Non quibusdam in maxime earum eveniet itaque culpa.", + "milestone_id": 11, + "state": "closed", + "iid": 7, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 362, + "note": "Quia qui quis molestiae in praesentium.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:19:59.966Z", + "updated_at": "2016-03-22T15:19:59.966Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 361, + "note": "Maxime sed eius qui consequatur beatae.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:19:59.924Z", + "updated_at": "2016-03-22T15:19:59.924Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 360, + "note": "Voluptatum quasi corrupti eveniet sed ut quis quibusdam.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:19:59.897Z", + "updated_at": "2016-03-22T15:19:59.897Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 359, + "note": "Molestias quia eius ipsum non.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:19:59.866Z", + "updated_at": "2016-03-22T15:19:59.866Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 358, + "note": "Aut non est accusantium aliquam.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:19:59.834Z", + "updated_at": "2016-03-22T15:19:59.834Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 357, + "note": "Aspernatur voluptas id voluptas vel cum ipsam.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:19:59.805Z", + "updated_at": "2016-03-22T15:19:59.805Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 356, + "note": "Harum dignissimos provident tempora sit numquam est qui.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:19:59.773Z", + "updated_at": "2016-03-22T15:19:59.773Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 355, + "note": "Sint dignissimos molestiae recusandae delectus.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:19:59.746Z", + "updated_at": "2016-03-22T15:19:59.746Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 37, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 36, + "title": "Quia dolores commodi eligendi ut nemo totam.", + "assignee_id": 3, + "author_id": 4, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.814Z", + "updated_at": "2016-03-22T15:20:00.371Z", + "position": 0, + "branch_name": null, + "description": "Molestiae veniam laudantium autem et natus.", + "milestone_id": 11, + "state": "opened", + "iid": 6, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 370, + "note": "Occaecati temporibus tempore harum vero incidunt veniam iste.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:20:00.365Z", + "updated_at": "2016-03-22T15:20:00.365Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 369, + "note": "Modi architecto officiis quia iste voluptas libero nihil quo.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:20:00.331Z", + "updated_at": "2016-03-22T15:20:00.331Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 368, + "note": "Eaque est tenetur ex est molestiae nobis.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:20:00.296Z", + "updated_at": "2016-03-22T15:20:00.296Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 367, + "note": "Odit enim ut a quo qui.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:20:00.261Z", + "updated_at": "2016-03-22T15:20:00.261Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 366, + "note": "Omnis unde cum officiis est.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:20:00.223Z", + "updated_at": "2016-03-22T15:20:00.223Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 365, + "note": "Ab consequuntur aliquam illo voluptatum.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:20:00.178Z", + "updated_at": "2016-03-22T15:20:00.178Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 364, + "note": "Molestiae dolorem est eos dolores aut.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:20:00.127Z", + "updated_at": "2016-03-22T15:20:00.127Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 363, + "note": "Nemo velit nam quod veniam.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:20:00.083Z", + "updated_at": "2016-03-22T15:20:00.083Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 36, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 35, + "title": "Rerum tenetur harum molestiae quam aut praesentium quaerat doloremque.", + "assignee_id": 4, + "author_id": 1, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.660Z", + "updated_at": "2016-03-22T15:20:00.665Z", + "position": 0, + "branch_name": null, + "description": "Omnis et voluptatibus expedita qui et explicabo rem ut.", + "milestone_id": 11, + "state": "opened", + "iid": 5, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 378, + "note": "Molestiae atque exercitationem culpa harum nemo.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:20:00.660Z", + "updated_at": "2016-03-22T15:20:00.660Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 377, + "note": "Porro sed nobis neque amet velit velit.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:20:00.625Z", + "updated_at": "2016-03-22T15:20:00.625Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 376, + "note": "Dicta officiis doloremque voluptatum qui omnis.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:20:00.589Z", + "updated_at": "2016-03-22T15:20:00.589Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 375, + "note": "Incidunt rerum omnis cum laudantium aut impedit.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:20:00.553Z", + "updated_at": "2016-03-22T15:20:00.553Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 374, + "note": "Et suscipit omnis dolorum officia vero.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:20:00.517Z", + "updated_at": "2016-03-22T15:20:00.517Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 373, + "note": "Doloremque adipisci et cumque inventore beatae consectetur.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:20:00.485Z", + "updated_at": "2016-03-22T15:20:00.485Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 372, + "note": "Dolores sapiente ea dolorum et quae adipisci id.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:20:00.455Z", + "updated_at": "2016-03-22T15:20:00.455Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 371, + "note": "Accusantium repellat tenetur natus dicta ullam saepe facere.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:20:00.420Z", + "updated_at": "2016-03-22T15:20:00.420Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 35, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 34, + "title": "Enim occaecati aut sed quia mollitia eligendi atque dolores voluptatem.", + "assignee_id": 24, + "author_id": 1, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.506Z", + "updated_at": "2016-03-22T15:20:00.961Z", + "position": 0, + "branch_name": null, + "description": "Voluptatem totam magnam fugit assumenda consequatur illo qui.", + "milestone_id": 10, + "state": "opened", + "iid": 4, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 379, + "note": "Praesentium odio quia fugit consequuntur repudiandae ducimus.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:20:00.717Z", + "updated_at": "2016-03-22T15:20:00.717Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + }, + { + "id": 380, + "note": "Dolores aut dolorem quia soluta incidunt commodi quia.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:20:00.754Z", + "updated_at": "2016-03-22T15:20:00.754Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 381, + "note": "Enim et velit iure ad.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:20:00.787Z", + "updated_at": "2016-03-22T15:20:00.787Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 382, + "note": "Impedit nobis quis laudantium ad assumenda.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:20:00.822Z", + "updated_at": "2016-03-22T15:20:00.822Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 383, + "note": "Facere sed numquam quos quas.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:20:00.855Z", + "updated_at": "2016-03-22T15:20:00.855Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 384, + "note": "Ex voluptatem sit provident error.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:20:00.889Z", + "updated_at": "2016-03-22T15:20:00.889Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 385, + "note": "Soluta laboriosam recusandae est cupiditate.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:20:00.925Z", + "updated_at": "2016-03-22T15:20:00.925Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 386, + "note": "Similique dolorem rerum iusto animi perferendis aut inventore.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:20:00.957Z", + "updated_at": "2016-03-22T15:20:00.957Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 34, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + } + ] + }, + { + "id": 33, + "title": "Rem fugiat fugit occaecati quibusdam enim consectetur numquam.", + "assignee_id": 22, + "author_id": 22, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.364Z", + "updated_at": "2016-03-22T15:20:01.227Z", + "position": 0, + "branch_name": null, + "description": "Provident nulla architecto neque beatae fuga alias repudiandae.", + "milestone_id": 10, + "state": "closed", + "iid": 3, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 394, + "note": "Suscipit numquam voluptatibus ipsam libero dolorum dolore totam.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:20:01.223Z", + "updated_at": "2016-03-22T15:20:01.223Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 393, + "note": "Et et sed sit sint.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:20:01.194Z", + "updated_at": "2016-03-22T15:20:01.194Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 392, + "note": "Corrupti perferendis voluptas et iure omnis officia.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:20:01.160Z", + "updated_at": "2016-03-22T15:20:01.160Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 391, + "note": "Autem quo fugit in iste nesciunt tempora.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:20:01.131Z", + "updated_at": "2016-03-22T15:20:01.131Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 390, + "note": "Magni porro ut soluta quis et eveniet maiores.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:20:01.101Z", + "updated_at": "2016-03-22T15:20:01.101Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 389, + "note": "Sed consequuntur debitis nisi veniam exercitationem recusandae a quisquam.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:20:01.070Z", + "updated_at": "2016-03-22T15:20:01.070Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 388, + "note": "Aut impedit qui consectetur dicta temporibus.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:20:01.042Z", + "updated_at": "2016-03-22T15:20:01.042Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 387, + "note": "Officia repudiandae ut culpa ipsa reiciendis.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:20:01.005Z", + "updated_at": "2016-03-22T15:20:01.005Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 33, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 32, + "title": "Velit nihil est alias blanditiis eius earum autem hic.", + "assignee_id": 22, + "author_id": 26, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.225Z", + "updated_at": "2016-03-22T15:20:01.495Z", + "position": 0, + "branch_name": null, + "description": "Id voluptas ut sint aut laborum nobis commodi.", + "milestone_id": 11, + "state": "opened", + "iid": 2, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 402, + "note": "Magni ut eligendi sit sint recusandae voluptas tempore necessitatibus.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:20:01.489Z", + "updated_at": "2016-03-22T15:20:01.489Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 401, + "note": "Est repellat commodi incidunt tempore earum optio unde sint.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:20:01.455Z", + "updated_at": "2016-03-22T15:20:01.455Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 400, + "note": "Vero unde debitis tempore est laboriosam ut esse.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:20:01.421Z", + "updated_at": "2016-03-22T15:20:01.421Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 399, + "note": "Omnis qui asperiores expedita harum voluptatem eius.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:20:01.391Z", + "updated_at": "2016-03-22T15:20:01.391Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 398, + "note": "Dolorem doloribus delectus quo ratione esse veritatis.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:20:01.358Z", + "updated_at": "2016-03-22T15:20:01.358Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 397, + "note": "Quia esse et odit id est omnis dolorum quia.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:20:01.329Z", + "updated_at": "2016-03-22T15:20:01.329Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 396, + "note": "Exercitationem suscipit non rerum tempore sit.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:20:01.297Z", + "updated_at": "2016-03-22T15:20:01.297Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 395, + "note": "Nihil veniam magni sit officiis.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:20:01.268Z", + "updated_at": "2016-03-22T15:20:01.268Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 32, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + }, + { + "id": 31, + "title": "Asperiores recusandae praesentium voluptas pariatur provident qui exercitationem quis.", + "assignee_id": 26, + "author_id": 24, + "project_id": 5, + "created_at": "2016-03-22T15:13:26.889Z", + "updated_at": "2016-03-22T15:20:01.834Z", + "position": 0, + "branch_name": null, + "description": "Ex voluptates qui excepturi cupiditate.", + "milestone_id": 11, + "state": "closed", + "iid": 1, + "updated_by_id": null, + "confidential": false, + "deleted_at": null, + "moved_to_id": null, + "due_date": null, + "notes": [ + { + "id": 410, + "note": "Sit itaque non nihil nisi qui voluptatem dolorem error.", + "noteable_type": "Issue", + "author_id": 1, + "created_at": "2016-03-22T15:20:01.828Z", + "updated_at": "2016-03-22T15:20:01.828Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 409, + "note": "Omnis rem nihil molestiae enim laudantium doloremque.", + "noteable_type": "Issue", + "author_id": 3, + "created_at": "2016-03-22T15:20:01.783Z", + "updated_at": "2016-03-22T15:20:01.783Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 408, + "note": "Ullam harum sit et optio incidunt.", + "noteable_type": "Issue", + "author_id": 4, + "created_at": "2016-03-22T15:20:01.746Z", + "updated_at": "2016-03-22T15:20:01.746Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 407, + "note": "Fugit distinctio ab quo ipsam.", + "noteable_type": "Issue", + "author_id": 10, + "created_at": "2016-03-22T15:20:01.716Z", + "updated_at": "2016-03-22T15:20:01.716Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 406, + "note": "Impedit iste possimus ad ea.", + "noteable_type": "Issue", + "author_id": 12, + "created_at": "2016-03-22T15:20:01.676Z", + "updated_at": "2016-03-22T15:20:01.676Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 405, + "note": "Nemo recusandae dolore distinctio quam consequuntur ut et aut.", + "noteable_type": "Issue", + "author_id": 22, + "created_at": "2016-03-22T15:20:01.641Z", + "updated_at": "2016-03-22T15:20:01.641Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 404, + "note": "Nisi repudiandae repellat nulla culpa quasi expedita quod velit.", + "noteable_type": "Issue", + "author_id": 24, + "created_at": "2016-03-22T15:20:01.601Z", + "updated_at": "2016-03-22T15:20:01.601Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 403, + "note": "Quibusdam odio temporibus nemo voluptatibus accusamus.", + "noteable_type": "Issue", + "author_id": 26, + "created_at": "2016-03-22T15:20:01.552Z", + "updated_at": "2016-03-22T15:20:01.552Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 31, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ] + } + ], + "labels": [ + { + "id": 12, + "title": "test", + "color": "#428bca", + "project_id": 5, + "created_at": "2016-05-10T10:53:14.214Z", + "updated_at": "2016-05-10T10:53:14.214Z", + "template": false, + "description": "test label" + } + ], + "milestones": [ + { + "id": 11, + "title": "v2.0", + "project_id": 5, + "description": "Sapiente facilis architecto reprehenderit aut sed enim.", + "due_date": null, + "created_at": "2016-03-22T15:13:21.631Z", + "updated_at": "2016-03-22T15:13:21.631Z", + "state": "closed", + "iid": 2 + }, + { + "id": 10, + "title": "v1.0", + "project_id": 5, + "description": "Est sed eos minima veniam culpa aut non.", + "due_date": null, + "created_at": "2016-03-22T15:13:21.622Z", + "updated_at": "2016-03-22T15:13:21.622Z", + "state": "closed", + "iid": 1 + } + ], + "snippets": [ + + ], + "releases": [ + + ], + "events": [ + { + "id": 301, + "target_type": "Note", + "target_id": 1357, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-04-12T13:08:30.886Z", + "updated_at": "2016-04-12T13:08:30.886Z", + "action": 6, + "author_id": 1 + }, + { + "id": 227, + "target_type": "MergeRequest", + "target_id": 85, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:19:44.957Z", + "updated_at": "2016-03-22T15:19:44.957Z", + "action": 1, + "author_id": 1 + }, + { + "id": 226, + "target_type": "MergeRequest", + "target_id": 84, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:19:44.600Z", + "updated_at": "2016-03-22T15:19:44.600Z", + "action": 1, + "author_id": 1 + }, + { + "id": 157, + "target_type": "MergeRequest", + "target_id": 15, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:45.936Z", + "updated_at": "2016-03-22T15:13:45.936Z", + "action": 1, + "author_id": 3 + }, + { + "id": 156, + "target_type": "MergeRequest", + "target_id": 14, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:45.500Z", + "updated_at": "2016-03-22T15:13:45.500Z", + "action": 1, + "author_id": 10 + }, + { + "id": 155, + "target_type": "MergeRequest", + "target_id": 13, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:45.242Z", + "updated_at": "2016-03-22T15:13:45.242Z", + "action": 1, + "author_id": 1 + }, + { + "id": 154, + "target_type": "MergeRequest", + "target_id": 12, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:44.940Z", + "updated_at": "2016-03-22T15:13:44.940Z", + "action": 1, + "author_id": 24 + }, + { + "id": 153, + "target_type": "MergeRequest", + "target_id": 11, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:44.568Z", + "updated_at": "2016-03-22T15:13:44.568Z", + "action": 1, + "author_id": 26 + }, + { + "id": 152, + "target_type": "MergeRequest", + "target_id": 10, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:44.225Z", + "updated_at": "2016-03-22T15:13:44.225Z", + "action": 1, + "author_id": 22 + }, + { + "id": 151, + "target_type": "MergeRequest", + "target_id": 9, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:43.868Z", + "updated_at": "2016-03-22T15:13:43.868Z", + "action": 1, + "author_id": 24 + }, + { + "id": 102, + "target_type": "Issue", + "target_id": 40, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.474Z", + "updated_at": "2016-03-22T15:13:28.474Z", + "action": 1, + "author_id": 4 + }, + { + "id": 101, + "target_type": "Issue", + "target_id": 39, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.328Z", + "updated_at": "2016-03-22T15:13:28.328Z", + "action": 1, + "author_id": 12 + }, + { + "id": 100, + "target_type": "Issue", + "target_id": 38, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.204Z", + "updated_at": "2016-03-22T15:13:28.204Z", + "action": 1, + "author_id": 3 + }, + { + "id": 99, + "target_type": "Issue", + "target_id": 37, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:28.055Z", + "updated_at": "2016-03-22T15:13:28.055Z", + "action": 1, + "author_id": 10 + }, + { + "id": 98, + "target_type": "Issue", + "target_id": 36, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.913Z", + "updated_at": "2016-03-22T15:13:27.913Z", + "action": 1, + "author_id": 4 + }, + { + "id": 97, + "target_type": "Issue", + "target_id": 35, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.731Z", + "updated_at": "2016-03-22T15:13:27.731Z", + "action": 1, + "author_id": 1 + }, + { + "id": 96, + "target_type": "Issue", + "target_id": 34, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.564Z", + "updated_at": "2016-03-22T15:13:27.564Z", + "action": 1, + "author_id": 1 + }, + { + "id": 95, + "target_type": "Issue", + "target_id": 33, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.429Z", + "updated_at": "2016-03-22T15:13:27.429Z", + "action": 1, + "author_id": 22 + }, + { + "id": 94, + "target_type": "Issue", + "target_id": 32, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:27.287Z", + "updated_at": "2016-03-22T15:13:27.287Z", + "action": 1, + "author_id": 26 + }, + { + "id": 93, + "target_type": "Issue", + "target_id": 31, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:26.997Z", + "updated_at": "2016-03-22T15:13:26.997Z", + "action": 1, + "author_id": 24 + }, + { + "id": 51, + "target_type": "Milestone", + "target_id": 11, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:21.634Z", + "updated_at": "2016-03-22T15:13:21.634Z", + "action": 1, + "author_id": 26 + }, + { + "id": 50, + "target_type": "Milestone", + "target_id": 10, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:21.625Z", + "updated_at": "2016-03-22T15:13:21.625Z", + "action": 1, + "author_id": 22 + }, + { + "id": 24, + "target_type": null, + "target_id": null, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:20.750Z", + "updated_at": "2016-03-22T15:13:20.750Z", + "action": 8, + "author_id": 12 + }, + { + "id": 23, + "target_type": null, + "target_id": null, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:20.711Z", + "updated_at": "2016-03-22T15:13:20.711Z", + "action": 8, + "author_id": 22 + }, + { + "id": 22, + "target_type": null, + "target_id": null, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:20.667Z", + "updated_at": "2016-03-22T15:13:20.667Z", + "action": 8, + "author_id": 26 + }, + { + "id": 21, + "target_type": null, + "target_id": null, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:20.646Z", + "updated_at": "2016-03-22T15:13:20.646Z", + "action": 8, + "author_id": 1 + }, + { + "id": 5, + "target_type": null, + "target_id": null, + "title": null, + "data": null, + "project_id": 5, + "created_at": "2016-03-22T15:13:10.369Z", + "updated_at": "2016-03-22T15:13:10.369Z", + "action": 1, + "author_id": 1 + } + ], + "project_members": [ + { + "id": 35, + "access_level": 40, + "source_id": 5, + "source_type": "Project", + "user_id": 12, + "notification_level": 3, + "created_at": "2016-03-22T15:13:20.743Z", + "updated_at": "2016-03-22T15:13:20.743Z", + "created_by_id": null, + "invite_email": null, + "invite_token": null, + "invite_accepted_at": null, + "user": { + "id": 12, + "email": "maureen.bogisich@russelkessler.com", + "username": "evans" + } + }, + { + "id": 34, + "access_level": 40, + "source_id": 5, + "source_type": "Project", + "user_id": 22, + "notification_level": 3, + "created_at": "2016-03-22T15:13:20.708Z", + "updated_at": "2016-03-22T15:13:20.708Z", + "created_by_id": null, + "invite_email": null, + "invite_token": null, + "invite_accepted_at": null, + "user": { + "id": 22, + "email": "user0@example.com", + "username": "user0" + } + }, + { + "id": 33, + "access_level": 40, + "source_id": 5, + "source_type": "Project", + "user_id": 26, + "notification_level": 3, + "created_at": "2016-03-22T15:13:20.664Z", + "updated_at": "2016-03-22T15:13:20.664Z", + "created_by_id": null, + "invite_email": null, + "invite_token": null, + "invite_accepted_at": null, + "user": { + "id": 26, + "email": "user4@example.com", + "username": "user4" + } + }, + { + "id": 32, + "access_level": 20, + "source_id": 5, + "source_type": "Project", + "user_id": 1, + "notification_level": 3, + "created_at": "2016-03-22T15:13:20.643Z", + "updated_at": "2016-03-22T15:13:20.643Z", + "created_by_id": null, + "invite_email": null, + "invite_token": null, + "invite_accepted_at": null, + "user": { + "id": 1, + "email": "nospam@bluegod.net", + "username": "root" + } + } + ], + "merge_requests": [ + { + "id": 85, + "target_branch": "feature", + "source_branch": "feature_conflict", + "source_project_id": 5, + "author_id": 1, + "assignee_id": null, + "title": "Cannot be automatically merged", + "created_at": "2016-03-22T15:19:44.807Z", + "updated_at": "2016-03-22T15:20:09.557Z", + "milestone_id": null, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 9, + "description": null, + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 638, + "note": "Ab velit ducimus totam sunt ut.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:09.553Z", + "updated_at": "2016-03-22T15:20:09.553Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 637, + "note": "Ipsum aliquam est in unde similique nihil illo ea.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:09.528Z", + "updated_at": "2016-03-22T15:20:09.528Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 636, + "note": "Soluta inventore adipisci et consequatur expedita aliquid earum modi.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:09.496Z", + "updated_at": "2016-03-22T15:20:09.496Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 635, + "note": "Corporis incidunt tempore est deleniti.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:09.469Z", + "updated_at": "2016-03-22T15:20:09.469Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 634, + "note": "Hic dolores voluptatibus qui necessitatibus.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:09.440Z", + "updated_at": "2016-03-22T15:20:09.440Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 633, + "note": "Rerum architecto placeat doloribus voluptates consequuntur quo.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:09.412Z", + "updated_at": "2016-03-22T15:20:09.412Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 632, + "note": "Vel earum aut ut occaecati aut ut rerum qui.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:09.389Z", + "updated_at": "2016-03-22T15:20:09.389Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 631, + "note": "Est voluptatibus dolores animi numquam.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:09.361Z", + "updated_at": "2016-03-22T15:20:09.361Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 85, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 85, + "state": "collected", + "st_commits": [ + { + "id": "bb5206fee213d983da88c47f9cf4cc6caf9c66dc", + "message": "Feature conflcit added\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "5937ac0a7beb003549fc5fd26fc247adbce4a52e" + ], + "authored_date": "2014-08-06T08:35:52.000+02:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-08-06T08:35:52.000+02:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "message": "Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "570e7b2abdd848b95f2f578043fc23bd6f6fd24d" + ], + "authored_date": "2014-02-27T10:01:38.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T10:01:38.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d", + "message": "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" + ], + "authored_date": "2014-02-27T09:57:31.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:57:31.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9", + "message": "More submodules\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "d14d6c0abdd253381df51a723d58691b2ee1ab08" + ], + "authored_date": "2014-02-27T09:54:21.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:54:21.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "d14d6c0abdd253381df51a723d58691b2ee1ab08", + "message": "Remove ds_store files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "c1acaa58bbcbc3eafe538cb8274ba387047b69f8" + ], + "authored_date": "2014-02-27T09:49:50.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:49:50.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + }, + { + "id": "c1acaa58bbcbc3eafe538cb8274ba387047b69f8", + "message": "Ignore DS files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "ae73cb07c9eeaf35924a10f713b364d32b2dd34f" + ], + "authored_date": "2014-02-27T09:48:32.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:48:32.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + } + ], + "st_diffs": [ + { + "diff": "Binary files a/.DS_Store and /dev/null differ\n", + "new_path": ".DS_Store", + "old_path": ".DS_Store", + "a_mode": "100644", + "b_mode": "0", + "new_file": false, + "renamed_file": false, + "deleted_file": true, + "too_large": false + }, + { + "diff": "--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n", + "new_path": ".gitignore", + "old_path": ".gitignore", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n", + "new_path": ".gitmodules", + "old_path": ".gitmodules", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "Binary files a/files/.DS_Store and /dev/null differ\n", + "new_path": "files/.DS_Store", + "old_path": "files/.DS_Store", + "a_mode": "100644", + "b_mode": "0", + "new_file": false, + "renamed_file": false, + "deleted_file": true, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/files/ruby/feature.rb\n@@ -0,0 +1,4 @@\n+# This file was changed in feature branch\n+# We put different code here to make merge conflict\n+class Conflict\n+end\n", + "new_path": "files/ruby/feature.rb", + "old_path": "files/ruby/feature.rb", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" =\u003e path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" =\u003e path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output \u003c\u003c stdout.read\n @cmd_output \u003c\u003c stderr.read\n", + "new_path": "files/ruby/popen.rb", + "old_path": "files/ruby/popen.rb", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n", + "new_path": "files/ruby/regex.rb", + "old_path": "files/ruby/regex.rb", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n", + "new_path": "gitlab-grack", + "old_path": "gitlab-grack", + "a_mode": "0", + "b_mode": "160000", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n", + "new_path": "gitlab-shell", + "old_path": "gitlab-shell", + "a_mode": "0", + "b_mode": "160000", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 85, + "created_at": "2016-03-22T15:19:44.810Z", + "updated_at": "2016-03-22T15:19:44.901Z", + "base_commit_sha": "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", + "real_size": "9" + } + }, + { + "id": 84, + "target_branch": "master", + "source_branch": "feature", + "source_project_id": 5, + "author_id": 1, + "assignee_id": null, + "title": "Can be automatically merged", + "created_at": "2016-03-22T15:19:44.482Z", + "updated_at": "2016-03-22T15:20:09.773Z", + "milestone_id": null, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 8, + "description": null, + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 646, + "note": "Temporibus debitis veniam est ut sit nihil.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:09.770Z", + "updated_at": "2016-03-22T15:20:09.770Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 645, + "note": "Ut assumenda dignissimos quibusdam veritatis sequi dolores.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:09.740Z", + "updated_at": "2016-03-22T15:20:09.740Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 644, + "note": "Velit quae quidem cupiditate laudantium nihil ut eveniet.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:09.717Z", + "updated_at": "2016-03-22T15:20:09.717Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 643, + "note": "Repellat quas porro sed mollitia laborum ut fugiat.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:09.690Z", + "updated_at": "2016-03-22T15:20:09.690Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 642, + "note": "Qui aut debitis perspiciatis et voluptatem.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:09.665Z", + "updated_at": "2016-03-22T15:20:09.665Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 641, + "note": "Quia id quia velit et.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:09.639Z", + "updated_at": "2016-03-22T15:20:09.639Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 640, + "note": "Corporis commodi doloremque itaque non animi.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:09.617Z", + "updated_at": "2016-03-22T15:20:09.617Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 639, + "note": "Possimus dignissimos voluptatum in tenetur.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:09.589Z", + "updated_at": "2016-03-22T15:20:09.589Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 84, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 84, + "state": "collected", + "st_commits": [ + { + "id": "0b4bc9a49b562e85de7cc9e834518ea6828729b9", + "message": "Feature added\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n", + "parent_ids": [ + "ae73cb07c9eeaf35924a10f713b364d32b2dd34f" + ], + "authored_date": "2014-02-27T09:26:01.000+01:00", + "author_name": "Dmitriy Zaporozhets", + "author_email": "dmitriy.zaporozhets@gmail.com", + "committed_date": "2014-02-27T09:26:01.000+01:00", + "committer_name": "Dmitriy Zaporozhets", + "committer_email": "dmitriy.zaporozhets@gmail.com" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/files/ruby/feature.rb\n@@ -0,0 +1,5 @@\n+class Feature\n+ def foo\n+ puts 'bar'\n+ end\n+end\n", + "new_path": "files/ruby/feature.rb", + "old_path": "files/ruby/feature.rb", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 84, + "created_at": "2016-03-22T15:19:44.485Z", + "updated_at": "2016-03-22T15:19:44.577Z", + "base_commit_sha": "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", + "real_size": "1" + } + }, + { + "id": 15, + "target_branch": "markdown", + "source_branch": "master", + "source_project_id": 5, + "author_id": 3, + "assignee_id": 3, + "title": "Nulla explicabo iure voluptas perferendis autem autem unde nemo totam optio.", + "created_at": "2016-03-22T15:13:45.689Z", + "updated_at": "2016-03-22T15:20:30.476Z", + "milestone_id": 10, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 7, + "description": "Doloribus dignissimos impedit qui et provident exercitationem. Veniam quis magni qui fugiat. Et quia voluptate et vel consequatur pariatur ea est.", + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 1231, + "note": "Rerum optio quibusdam provident possimus quis cum.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:30.472Z", + "updated_at": "2016-03-22T15:20:30.472Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 1230, + "note": "Quasi odit repudiandae ut officiis ut nihil illo.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:30.444Z", + "updated_at": "2016-03-22T15:20:30.444Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1229, + "note": "Aut vero dolores facere sed.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:30.412Z", + "updated_at": "2016-03-22T15:20:30.412Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1228, + "note": "Autem voluptatem et blanditiis accusantium deserunt et et.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:30.383Z", + "updated_at": "2016-03-22T15:20:30.383Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1227, + "note": "Voluptatem aliquam voluptatem molestiae est.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:30.352Z", + "updated_at": "2016-03-22T15:20:30.352Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 1226, + "note": "Ea aut cupiditate est consequatur animi error qui et.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:30.319Z", + "updated_at": "2016-03-22T15:20:30.319Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 1225, + "note": "Voluptates est voluptas et nostrum modi beatae inventore et.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:30.289Z", + "updated_at": "2016-03-22T15:20:30.289Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1224, + "note": "Quia est rerum adipisci cupiditate.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:30.260Z", + "updated_at": "2016-03-22T15:20:30.260Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 15, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 15, + "state": "collected", + "st_commits": [ + { + "id": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "message": "Merge branch 'master' into 'master'\r\n\r\nLFS object pointer.\r\n\r\n\r\n\r\nSee merge request !6", + "parent_ids": [ + "5f923865dde3436854e9ceb9cdb7815618d4e849", + "048721d90c449b244b7b4c53a9186b04330174ec" + ], + "authored_date": "2015-12-07T12:52:12.000+01:00", + "author_name": "Marin Jankovski", + "author_email": "marin@gitlab.com", + "committed_date": "2015-12-07T12:52:12.000+01:00", + "committer_name": "Marin Jankovski", + "committer_email": "marin@gitlab.com" + }, + { + "id": "048721d90c449b244b7b4c53a9186b04330174ec", + "message": "LFS object pointer.\n", + "parent_ids": [ + "5f923865dde3436854e9ceb9cdb7815618d4e849" + ], + "authored_date": "2015-12-07T11:54:28.000+01:00", + "author_name": "Marin Jankovski", + "author_email": "maxlazio@gmail.com", + "committed_date": "2015-12-07T11:54:28.000+01:00", + "committer_name": "Marin Jankovski", + "committer_email": "maxlazio@gmail.com" + }, + { + "id": "5f923865dde3436854e9ceb9cdb7815618d4e849", + "message": "GitLab currently doesn't support patches that involve a merge commit: add a commit here\n", + "parent_ids": [ + "d2d430676773caa88cdaf7c55944073b2fd5561a" + ], + "authored_date": "2015-11-13T16:27:12.000+01:00", + "author_name": "Stan Hu", + "author_email": "stanhu@gmail.com", + "committed_date": "2015-11-13T16:27:12.000+01:00", + "committer_name": "Stan Hu", + "committer_email": "stanhu@gmail.com" + }, + { + "id": "d2d430676773caa88cdaf7c55944073b2fd5561a", + "message": "Merge branch 'add-svg' into 'master'\r\n\r\nAdd GitLab SVG\r\n\r\nAdded to test preview of sanitized SVG images\r\n\r\nSee merge request !5", + "parent_ids": [ + "59e29889be61e6e0e5e223bfa9ac2721d31605b8", + "2ea1f3dec713d940208fb5ce4a38765ecb5d3f73" + ], + "authored_date": "2015-11-13T08:50:17.000+01:00", + "author_name": "Stan Hu", + "author_email": "stanhu@gmail.com", + "committed_date": "2015-11-13T08:50:17.000+01:00", + "committer_name": "Stan Hu", + "committer_email": "stanhu@gmail.com" + }, + { + "id": "2ea1f3dec713d940208fb5ce4a38765ecb5d3f73", + "message": "Add GitLab SVG\n", + "parent_ids": [ + "59e29889be61e6e0e5e223bfa9ac2721d31605b8" + ], + "authored_date": "2015-11-13T08:39:43.000+01:00", + "author_name": "Stan Hu", + "author_email": "stanhu@gmail.com", + "committed_date": "2015-11-13T08:39:43.000+01:00", + "committer_name": "Stan Hu", + "committer_email": "stanhu@gmail.com" + }, + { + "id": "59e29889be61e6e0e5e223bfa9ac2721d31605b8", + "message": "Merge branch 'whitespace' into 'master'\r\n\r\nadd whitespace test file\r\n\r\nSorry, I did a mistake.\r\nGit ignore empty files.\r\nSo I add a new whitespace test file.\r\n\r\nSee merge request !4", + "parent_ids": [ + "19e2e9b4ef76b422ce1154af39a91323ccc57434", + "66eceea0db202bb39c4e445e8ca28689645366c5" + ], + "authored_date": "2015-11-13T07:21:40.000+01:00", + "author_name": "Stan Hu", + "author_email": "stanhu@gmail.com", + "committed_date": "2015-11-13T07:21:40.000+01:00", + "committer_name": "Stan Hu", + "committer_email": "stanhu@gmail.com" + }, + { + "id": "66eceea0db202bb39c4e445e8ca28689645366c5", + "message": "add spaces in whitespace file\n", + "parent_ids": [ + "08f22f255f082689c0d7d39d19205085311542bc" + ], + "authored_date": "2015-11-13T06:01:27.000+01:00", + "author_name": "윤민식", + "author_email": "minsik.yoon@samsung.com", + "committed_date": "2015-11-13T06:01:27.000+01:00", + "committer_name": "윤민식", + "committer_email": "minsik.yoon@samsung.com" + }, + { + "id": "08f22f255f082689c0d7d39d19205085311542bc", + "message": "remove emtpy file.(beacase git ignore empty file)\nadd whitespace test file.\n", + "parent_ids": [ + "c642fe9b8b9f28f9225d7ea953fe14e74748d53b" + ], + "authored_date": "2015-11-13T06:00:16.000+01:00", + "author_name": "윤민식", + "author_email": "minsik.yoon@samsung.com", + "committed_date": "2015-11-13T06:00:16.000+01:00", + "committer_name": "윤민식", + "committer_email": "minsik.yoon@samsung.com" + }, + { + "id": "19e2e9b4ef76b422ce1154af39a91323ccc57434", + "message": "Merge branch 'whitespace' into 'master'\r\n\r\nadd spaces\r\n\r\nTo test this pull request.(https://github.com/gitlabhq/gitlabhq/pull/9757)\r\nJust add whitespaces.\r\n\r\nSee merge request !3", + "parent_ids": [ + "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", + "c642fe9b8b9f28f9225d7ea953fe14e74748d53b" + ], + "authored_date": "2015-11-13T05:23:14.000+01:00", + "author_name": "Stan Hu", + "author_email": "stanhu@gmail.com", + "committed_date": "2015-11-13T05:23:14.000+01:00", + "committer_name": "Stan Hu", + "committer_email": "stanhu@gmail.com" + }, + { + "id": "c642fe9b8b9f28f9225d7ea953fe14e74748d53b", + "message": "add whitespace in empty\n", + "parent_ids": [ + "9a944d90955aaf45f6d0c88f30e27f8d2c41cec0" + ], + "authored_date": "2015-11-13T05:08:45.000+01:00", + "author_name": "윤민식", + "author_email": "minsik.yoon@samsung.com", + "committed_date": "2015-11-13T05:08:45.000+01:00", + "committer_name": "윤민식", + "committer_email": "minsik.yoon@samsung.com" + }, + { + "id": "9a944d90955aaf45f6d0c88f30e27f8d2c41cec0", + "message": "add empty file\n", + "parent_ids": [ + "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd" + ], + "authored_date": "2015-11-13T05:08:04.000+01:00", + "author_name": "윤민식", + "author_email": "minsik.yoon@samsung.com", + "committed_date": "2015-11-13T05:08:04.000+01:00", + "committer_name": "윤민식", + "committer_email": "minsik.yoon@samsung.com" + }, + { + "id": "c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd", + "message": "Add ISO-8859 test file\n", + "parent_ids": [ + "e56497bb5f03a90a51293fc6d516788730953899" + ], + "authored_date": "2015-08-25T17:53:12.000+02:00", + "author_name": "Stan Hu", + "author_email": "stanhu@packetzoom.com", + "committed_date": "2015-08-25T17:53:12.000+02:00", + "committer_name": "Stan Hu", + "committer_email": "stanhu@packetzoom.com" + }, + { + "id": "e56497bb5f03a90a51293fc6d516788730953899", + "message": "Merge branch 'tree_helper_spec' into 'master'\n\nAdd directory structure for tree_helper spec\n\nThis directory structure is needed for a testing the method flatten_tree(tree) in the TreeHelper module\n\nSee [merge request #275](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/275#note_732774)\n\nSee merge request !2\n", + "parent_ids": [ + "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "4cd80ccab63c82b4bad16faa5193fbd2aa06df40" + ], + "authored_date": "2015-01-10T22:23:29.000+01:00", + "author_name": "Sytse Sijbrandij", + "author_email": "sytse@gitlab.com", + "committed_date": "2015-01-10T22:23:29.000+01:00", + "committer_name": "Sytse Sijbrandij", + "committer_email": "sytse@gitlab.com" + }, + { + "id": "4cd80ccab63c82b4bad16faa5193fbd2aa06df40", + "message": "add directory structure for tree_helper spec\n", + "parent_ids": [ + "5937ac0a7beb003549fc5fd26fc247adbce4a52e" + ], + "authored_date": "2015-01-10T21:28:18.000+01:00", + "author_name": "marmis85", + "author_email": "marmis85@gmail.com", + "committed_date": "2015-01-10T21:28:18.000+01:00", + "committer_name": "marmis85", + "committer_email": "marmis85@gmail.com" + } + ], + "st_diffs": [ + { + "diff": "--- a/CHANGELOG\n+++ b/CHANGELOG\n@@ -1,4 +1,6 @@\n-v 6.7.0\n+v6.8.0\n+\n+v6.7.0\n - Add support for Gemnasium as a Project Service (Olivier Gonzalez)\n - Add edit file button to MergeRequest diff\n - Public groups (Jason Hollingsworth)\n", + "new_path": "CHANGELOG", + "old_path": "CHANGELOG", + "a_mode": "100644", + "b_mode": "100644", + "new_file": false, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/encoding/iso8859.txt\n@@ -0,0 +1 @@\n+Äü\n", + "new_path": "encoding/iso8859.txt", + "old_path": "encoding/iso8859.txt", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/files/images/wm.svg\n@@ -0,0 +1,78 @@\n+\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?\u003e\n+\u003csvg width=\"1300px\" height=\"680px\" viewBox=\"0 0 1300 680\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\"\u003e\n+ \u003c!-- Generator: Sketch 3.2.2 (9983) - http://www.bohemiancoding.com/sketch --\u003e\n+ \u003ctitle\u003ewm\u003c/title\u003e\n+ \u003cdesc\u003eCreated with Sketch.\u003c/desc\u003e\n+ \u003cdefs\u003e\n+ \u003cpath id=\"path-1\" d=\"M-69.8,1023.54607 L1675.19996,1023.54607 L1675.19996,0 L-69.8,0 L-69.8,1023.54607 L-69.8,1023.54607 Z\"\u003e\u003c/path\u003e\n+ \u003c/defs\u003e\n+ \u003cg id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\"\u003e\n+ \u003cpath d=\"M1300,680 L0,680 L0,0 L1300,0 L1300,680 L1300,680 Z\" id=\"bg\" fill=\"#30353E\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003cg id=\"gitlab_logo\" sketch:type=\"MSLayerGroup\" transform=\"translate(-262.000000, -172.000000)\"\u003e\n+ \u003cg id=\"g10\" transform=\"translate(872.500000, 512.354581) scale(1, -1) translate(-872.500000, -512.354581) translate(0.000000, 0.290751)\"\u003e\n+ \u003cg id=\"g12\" transform=\"translate(1218.022652, 440.744871)\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\n+ \u003cpath d=\"M-50.0233338,141.900706 L-69.07059,141.900706 L-69.0100967,0.155858152 L8.04444805,0.155858152 L8.04444805,17.6840847 L-49.9628405,17.6840847 L-50.0233338,141.900706 L-50.0233338,141.900706 Z\" id=\"path14\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g16\"\u003e\n+ \u003cg id=\"g18-Clipped\"\u003e\n+ \u003cmask id=\"mask-2\" sketch:name=\"path22\" fill=\"white\"\u003e\n+ \u003cuse xlink:href=\"#path-1\"\u003e\u003c/use\u003e\n+ \u003c/mask\u003e\n+ \u003cg id=\"path22\"\u003e\u003c/g\u003e\n+ \u003cg id=\"g18\" mask=\"url(#mask-2)\"\u003e\n+ \u003cg transform=\"translate(382.736659, 312.879425)\"\u003e\n+ \u003cg id=\"g24\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(852.718192, 124.992771)\"\u003e\n+ \u003cpath d=\"M63.9833317,27.9148929 C59.2218085,22.9379001 51.2134221,17.9597442 40.3909323,17.9597442 C25.8888194,17.9597442 20.0453962,25.1013043 20.0453962,34.4074318 C20.0453962,48.4730484 29.7848226,55.1819277 50.5642821,55.1819277 C54.4602853,55.1819277 60.7364685,54.7492469 63.9833317,54.1002256 L63.9833317,27.9148929 L63.9833317,27.9148929 Z M44.2869356,113.827628 C28.9053426,113.827628 14.7975996,108.376082 3.78897657,99.301416 L10.5211864,87.6422957 C18.3131929,92.1866076 27.8374026,96.7320827 41.4728323,96.7320827 C57.0568452,96.7320827 63.9833317,88.7239978 63.9833317,75.3074024 L63.9833317,68.3821827 C60.9528485,69.0312039 54.6766653,69.4650479 50.7806621,69.4650479 C17.4476729,69.4650479 0.565379986,57.7791759 0.565379986,33.3245665 C0.565379986,11.4683685 13.9844297,0.43151772 34.3299658,0.43151772 C48.0351955,0.43151772 61.1692285,6.70771614 65.7143717,16.8780421 L69.1776149,3.02876588 L82.5978279,3.02876588 L82.5978279,75.5237428 C82.5978279,98.462806 72.6408582,113.827628 44.2869356,113.827628 L44.2869356,113.827628 Z\" id=\"path26\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g28\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(959.546624, 124.857151)\"\u003e\n+ \u003cpath d=\"M37.2266657,17.4468081 C30.0837992,17.4468081 23.8064527,18.3121698 19.0449295,20.4767371 L19.0449295,79.2306079 L19.0449295,86.0464943 C25.538656,91.457331 33.5470425,95.3526217 43.7203922,95.3526217 C62.1173451,95.3526217 69.2602116,82.3687072 69.2602116,61.3767077 C69.2602116,31.5135879 57.7885819,17.4468081 37.2266657,17.4468081 M45.2315622,113.963713 C28.208506,113.963713 19.0449295,102.384849 19.0449295,102.384849 L19.0449295,120.67143 L18.9844362,144.908535 L10.3967097,144.908535 L0.371103324,144.908535 L0.431596656,6.62629771 C9.73826309,2.73100702 22.5081728,0.567602823 36.3611458,0.567602823 C71.8579349,0.567602823 88.9566078,23.2891625 88.9566078,62.4584098 C88.9566078,93.4043948 73.1527248,113.963713 45.2315622,113.963713\" id=\"path30\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g32\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(509.576747, 125.294950)\"\u003e\n+ \u003cpath d=\"M68.636665,129.10638 C85.5189579,129.10638 96.3414476,123.480366 103.484314,117.853189 L111.669527,132.029302 C100.513161,141.811145 85.5073245,147.06845 69.5021849,147.06845 C29.0274926,147.06845 0.673569983,122.3975 0.673569983,72.6252464 C0.673569983,20.4709215 31.2622559,0.12910638 66.2553217,0.12910638 C83.7879179,0.12910638 98.7227909,4.24073748 108.462217,8.35236859 L108.063194,64.0763105 L108.063194,70.6502677 L108.063194,81.6057001 L56.1168719,81.6057001 L56.1168719,64.0763105 L89.2323178,64.0763105 L89.6313411,21.7701271 C85.3025779,19.6055598 77.7269514,17.8748364 67.554765,17.8748364 C39.4172223,17.8748364 20.5863462,35.5717154 20.5863462,72.8415868 C20.5863462,110.711628 40.0663623,129.10638 68.636665,129.10638\" id=\"path34\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g36\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(692.388992, 124.376085)\"\u003e\n+ \u003cpath d=\"M19.7766662,145.390067 L1.16216997,145.390067 L1.2226633,121.585642 L1.2226633,111.846834 L1.2226633,106.170806 L1.2226633,96.2656714 L1.2226633,39.5681976 L1.2226633,39.3518572 C1.2226633,16.4127939 11.1796331,1.04797161 39.5335557,1.04797161 C43.4504989,1.04797161 47.2836822,1.40388649 51.0051854,2.07965952 L51.0051854,18.7925385 C48.3109055,18.3796307 45.4351455,18.1446804 42.3476589,18.1446804 C26.763646,18.1446804 19.8371595,26.1516022 19.8371595,39.5681976 L19.8371595,96.2656714 L51.0051854,96.2656714 L51.0051854,111.846834 L19.8371595,111.846834 L19.7766662,145.390067 L19.7766662,145.390067 Z\" id=\"path38\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cpath d=\"M646.318899,128.021188 L664.933395,128.021188 L664.933395,236.223966 L646.318899,236.223966 L646.318899,128.021188 L646.318899,128.021188 Z\" id=\"path40\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003cpath d=\"M646.318899,251.154944 L664.933395,251.154944 L664.933395,269.766036 L646.318899,269.766036 L646.318899,251.154944 L646.318899,251.154944 Z\" id=\"path42\" fill=\"#8C929D\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003cg id=\"g44\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(0.464170, 0.676006)\"\u003e\n+ \u003cpath d=\"M429.269989,169.815599 L405.225053,243.802859 L357.571431,390.440955 C355.120288,397.984955 344.444378,397.984955 341.992071,390.440955 L294.337286,243.802859 L136.094873,243.802859 L88.4389245,390.440955 C85.9877812,397.984955 75.3118715,397.984955 72.8595648,390.440955 L25.2059427,243.802859 L1.16216997,169.815599 C-1.03187664,163.067173 1.37156997,155.674379 7.11261982,151.503429 L215.215498,0.336141836 L423.319539,151.503429 C429.060589,155.674379 431.462873,163.067173 429.269989,169.815599\" id=\"path46\" fill=\"#FC6D26\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g48\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(135.410135, 1.012147)\"\u003e\n+ \u003cpath d=\"M80.269998,0 L80.269998,0 L159.391786,243.466717 L1.14820997,243.466717 L80.269998,0 L80.269998,0 Z\" id=\"path50\" fill=\"#E24329\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g52\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(215.680133, 1.012147)\"\u003e\n+ \u003cg id=\"path54\"\u003e\u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g56\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(24.893471, 1.012613)\"\u003e\n+ \u003cpath d=\"M190.786662,0 L111.664874,243.465554 L0.777106647,243.465554 L190.786662,0 L190.786662,0 Z\" id=\"path58\" fill=\"#FC6D26\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g60\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(215.680133, 1.012613)\"\u003e\n+ \u003cg id=\"path62\"\u003e\u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g64\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(0.077245, 0.223203)\"\u003e\n+ \u003cpath d=\"M25.5933327,244.255313 L25.5933327,244.255313 L1.54839663,170.268052 C-0.644486651,163.519627 1.75779662,156.126833 7.50000981,151.957046 L215.602888,0.789758846 L25.5933327,244.255313 L25.5933327,244.255313 Z\" id=\"path66\" fill=\"#FCA326\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g68\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(215.680133, 1.012147)\"\u003e\n+ \u003cg id=\"path70\"\u003e\u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g72\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(25.670578, 244.478283)\"\u003e\n+ \u003cpath d=\"M0,0 L110.887767,0 L63.2329818,146.638096 C60.7806751,154.183259 50.1047654,154.183259 47.6536221,146.638096 L0,0 L0,0 Z\" id=\"path74\" fill=\"#E24329\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g76\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(215.680133, 1.012613)\"\u003e\n+ \u003cpath d=\"M0,0 L79.121788,243.465554 L190.009555,243.465554 L0,0 L0,0 Z\" id=\"path78\" fill=\"#FC6D26\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g80\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(214.902910, 0.223203)\"\u003e\n+ \u003cpath d=\"M190.786662,244.255313 L190.786662,244.255313 L214.831598,170.268052 C217.024481,163.519627 214.622198,156.126833 208.879985,151.957046 L0.777106647,0.789758846 L190.786662,244.255313 L190.786662,244.255313 Z\" id=\"path82\" fill=\"#FCA326\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003cg id=\"g84\" stroke-width=\"1\" fill=\"none\" sketch:type=\"MSLayerGroup\" transform=\"translate(294.009575, 244.478283)\"\u003e\n+ \u003cpath d=\"M111.679997,0 L0.79222998,0 L48.4470155,146.638096 C50.8993221,154.183259 61.5752318,154.183259 64.0263751,146.638096 L111.679997,0 L111.679997,0 Z\" id=\"path86\" fill=\"#E24329\" sketch:type=\"MSShapeGroup\"\u003e\u003c/path\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+ \u003c/g\u003e\n+\u003c/svg\u003e\n\\ No newline at end of file\n", + "new_path": "files/images/wm.svg", + "old_path": "files/images/wm.svg", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/files/lfs/lfs_object.iso\n@@ -0,0 +1,4 @@\n+version https://git-lfs.github.com/spec/v1\n+oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897\n+size 1575078\n+\n", + "new_path": "files/lfs/lfs_object.iso", + "old_path": "files/lfs/lfs_object.iso", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/files/whitespace\n@@ -0,0 +1 @@\n+test \n", + "new_path": "files/whitespace", + "old_path": "files/whitespace", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + }, + { + "diff": "--- /dev/null\n+++ b/foo/bar/.gitkeep\n", + "new_path": "foo/bar/.gitkeep", + "old_path": "foo/bar/.gitkeep", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 15, + "created_at": "2016-03-22T15:13:45.692Z", + "updated_at": "2016-03-22T15:13:45.808Z", + "base_commit_sha": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "real_size": "6" + } + }, + { + "id": 14, + "target_branch": "test-1", + "source_branch": "test-10", + "source_project_id": 5, + "author_id": 10, + "assignee_id": 1, + "title": "Tempore aliquid sit amet odit qui cum iusto voluptatibus asperiores.", + "created_at": "2016-03-22T15:13:45.442Z", + "updated_at": "2016-03-22T15:20:30.735Z", + "milestone_id": 10, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 6, + "description": "Quis et et autem saepe ut. Eum corporis tempore cum dolore. Molestiae pariatur voluptatem officia perferendis aut veniam.", + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 1239, + "note": "Aspernatur suscipit veritatis aliquid rerum.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:30.731Z", + "updated_at": "2016-03-22T15:20:30.731Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 1238, + "note": "Rerum deleniti omnis porro commodi.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:30.701Z", + "updated_at": "2016-03-22T15:20:30.701Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1237, + "note": "Eaque ut magnam rerum non dolores esse.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:30.667Z", + "updated_at": "2016-03-22T15:20:30.667Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1236, + "note": "Fugit et aut similique illum ut natus maiores et.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:30.637Z", + "updated_at": "2016-03-22T15:20:30.637Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1235, + "note": "Qui qui temporibus eos aliquam.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:30.608Z", + "updated_at": "2016-03-22T15:20:30.608Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 1234, + "note": "Voluptates hic dolorum aut inventore.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:30.575Z", + "updated_at": "2016-03-22T15:20:30.575Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 1233, + "note": "Dolorum iure at dolor dolores numquam iusto.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:30.548Z", + "updated_at": "2016-03-22T15:20:30.548Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1232, + "note": "Nihil est eum aspernatur amet minus et corporis consectetur.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:30.517Z", + "updated_at": "2016-03-22T15:20:30.517Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 14, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 14, + "state": "collected", + "st_commits": [ + { + "id": "bce96ecee98f51fa5d91021e6c42859a35a701ad", + "message": "fixes #10\n", + "parent_ids": [ + "be93687618e4b132087f430a4d8fc3a609c9b77c" + ], + "authored_date": "2016-01-19T15:40:05.000+01:00", + "author_name": "Test Lopez", + "author_email": "Test@Testlopez.es", + "committed_date": "2016-01-19T15:40:05.000+01:00", + "committer_name": "Test Lopez", + "committer_email": "Test@Testlopez.es" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/test\n", + "new_path": "test", + "old_path": "test", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 14, + "created_at": "2016-03-22T15:13:45.444Z", + "updated_at": "2016-03-22T15:13:45.486Z", + "base_commit_sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "real_size": "1" + } + }, + { + "id": 13, + "target_branch": "test-11", + "source_branch": "test-12", + "source_project_id": 5, + "author_id": 1, + "assignee_id": 26, + "title": "Voluptas minus sunt voluptatum quis quia ut velit distinctio itaque.", + "created_at": "2016-03-22T15:13:45.164Z", + "updated_at": "2016-03-22T15:20:30.994Z", + "milestone_id": 11, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 5, + "description": "Ea ut modi consectetur et minus beatae. Et sunt ducimus praesentium libero officia maiores voluptas cumque. Rerum in aut corporis et ullam omnis.", + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 1247, + "note": "Non error magnam placeat cupiditate eum.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:30.989Z", + "updated_at": "2016-03-22T15:20:30.989Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 1246, + "note": "Eos optio et architecto eligendi ea est nihil.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:30.957Z", + "updated_at": "2016-03-22T15:20:30.957Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1245, + "note": "Reprehenderit in atque dolor et repudiandae a est.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:30.928Z", + "updated_at": "2016-03-22T15:20:30.928Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1244, + "note": "Numquam fugit doloremque iure odio et.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:30.902Z", + "updated_at": "2016-03-22T15:20:30.902Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1243, + "note": "Doloribus laboriosam id harum voluptatum vitae ut quam.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:30.863Z", + "updated_at": "2016-03-22T15:20:30.863Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 1242, + "note": "Harum et ut ipsum dolore ea.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:30.832Z", + "updated_at": "2016-03-22T15:20:30.832Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 1241, + "note": "Corporis sed soluta ut est modi natus ab.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:30.802Z", + "updated_at": "2016-03-22T15:20:30.802Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1240, + "note": "Corrupti totam tenetur officiis ratione dolores est qui vel.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:30.771Z", + "updated_at": "2016-03-22T15:20:30.771Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 13, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 13, + "state": "collected", + "st_commits": [ + { + "id": "a4e5dfebf42e34596526acb8611bc7ed80e4eb3f", + "message": "fixes #10\n", + "parent_ids": [ + "be93687618e4b132087f430a4d8fc3a609c9b77c" + ], + "authored_date": "2016-01-19T15:44:02.000+01:00", + "author_name": "Test Lopez", + "author_email": "Test@Testlopez.es", + "committed_date": "2016-01-19T15:44:02.000+01:00", + "committer_name": "Test Lopez", + "committer_email": "Test@Testlopez.es" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/test\n", + "new_path": "test", + "old_path": "test", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 13, + "created_at": "2016-03-22T15:13:45.167Z", + "updated_at": "2016-03-22T15:13:45.216Z", + "base_commit_sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "real_size": "1" + } + }, + { + "id": 12, + "target_branch": "test-15", + "source_branch": "test-2", + "source_project_id": 5, + "author_id": 24, + "assignee_id": 12, + "title": "In assumenda nam quaerat qui eos sit facilis enim quia quis.", + "created_at": "2016-03-22T15:13:44.837Z", + "updated_at": "2016-03-22T15:20:31.258Z", + "milestone_id": 10, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 4, + "description": "Soluta excepturi quis iste vero delectus rerum. Consequatur possimus aliquam necessitatibus deleniti rerum est impedit. Eius rem et consequatur assumenda est commodi.", + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 1255, + "note": "Quibusdam rem aut similique ipsum recusandae ut accusamus.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:31.253Z", + "updated_at": "2016-03-22T15:20:31.253Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 1254, + "note": "Cumque sed omnis ipsa et magnam dolorem et.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:31.224Z", + "updated_at": "2016-03-22T15:20:31.224Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1253, + "note": "Molestiae beatae id consequatur nam minus quia.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:31.195Z", + "updated_at": "2016-03-22T15:20:31.195Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1252, + "note": "Voluptatem dolorem dignissimos itaque tempora quas ut.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:31.166Z", + "updated_at": "2016-03-22T15:20:31.166Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1251, + "note": "Debitis qui quibusdam voluptas repellat veritatis dicta rerum id.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:31.137Z", + "updated_at": "2016-03-22T15:20:31.137Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 1250, + "note": "Suscipit optio ad voluptatem dignissimos temporibus amet molestias ut.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:31.107Z", + "updated_at": "2016-03-22T15:20:31.107Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 1249, + "note": "Nemo aut vitae et ducimus autem ex dolores.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:31.073Z", + "updated_at": "2016-03-22T15:20:31.073Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1248, + "note": "Repellendus eaque ex molestiae laudantium placeat quidem vitae recusandae.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:31.038Z", + "updated_at": "2016-03-22T15:20:31.038Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 12, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 12, + "state": "collected", + "st_commits": [ + { + "id": "97a0df9696e2aebf10c31b3016f40214e0e8f243", + "message": "fixes #10\n", + "parent_ids": [ + "be93687618e4b132087f430a4d8fc3a609c9b77c" + ], + "authored_date": "2016-01-19T14:08:21.000+01:00", + "author_name": "Test Lopez", + "author_email": "Test@Testlopez.es", + "committed_date": "2016-01-19T14:08:21.000+01:00", + "committer_name": "Test Lopez", + "committer_email": "Test@Testlopez.es" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/test\n", + "new_path": "test", + "old_path": "test", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 12, + "created_at": "2016-03-22T15:13:44.840Z", + "updated_at": "2016-03-22T15:13:44.908Z", + "base_commit_sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "real_size": "1" + } + }, + { + "id": 11, + "target_branch": "test-3", + "source_branch": "test-5", + "source_project_id": 5, + "author_id": 26, + "assignee_id": 12, + "title": "Magni aut reprehenderit ut accusantium est eum.", + "created_at": "2016-03-22T15:13:44.494Z", + "updated_at": "2016-03-22T15:20:31.886Z", + "milestone_id": 10, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 3, + "description": "Et hic maxime harum ullam. Nulla velit pariatur libero recusandae. Dolor est earum laboriosam harum quo.", + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 1263, + "note": "Beatae incidunt exercitationem voluptates recusandae fuga quia enim.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:31.883Z", + "updated_at": "2016-03-22T15:20:31.883Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 1262, + "note": "Illum sunt id consequuntur fugit et quo ullam eum.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:31.860Z", + "updated_at": "2016-03-22T15:20:31.860Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1261, + "note": "Alias reiciendis autem ipsa sequi autem nemo odio.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:31.456Z", + "updated_at": "2016-03-22T15:20:31.456Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1260, + "note": "Maxime nisi odit eos nulla vel ex accusamus velit.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:31.426Z", + "updated_at": "2016-03-22T15:20:31.426Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1259, + "note": "Excepturi et qui sapiente ut ducimus sunt nesciunt.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:31.397Z", + "updated_at": "2016-03-22T15:20:31.397Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 1258, + "note": "Quis rerum dolores et dolorem modi neque ullam doloribus.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:31.364Z", + "updated_at": "2016-03-22T15:20:31.364Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 1257, + "note": "Voluptatum et mollitia neque aut.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:31.328Z", + "updated_at": "2016-03-22T15:20:31.328Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1256, + "note": "Rerum laudantium dolor natus doloribus voluptas aliquid a.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:31.298Z", + "updated_at": "2016-03-22T15:20:31.298Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 11, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 4" + } + } + ], + "merge_request_diff": { + "id": 11, + "state": "collected", + "st_commits": [ + { + "id": "f998ac87ac9244f15e9c15109a6f4e62a54b779d", + "message": "fixes #10\n", + "parent_ids": [ + "be93687618e4b132087f430a4d8fc3a609c9b77c" + ], + "authored_date": "2016-01-19T14:43:23.000+01:00", + "author_name": "Test Lopez", + "author_email": "Test@Testlopez.es", + "committed_date": "2016-01-19T14:43:23.000+01:00", + "committer_name": "Test Lopez", + "committer_email": "Test@Testlopez.es" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/test\n", + "new_path": "test", + "old_path": "test", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 11, + "created_at": "2016-03-22T15:13:44.497Z", + "updated_at": "2016-03-22T15:13:44.547Z", + "base_commit_sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "real_size": "1" + } + }, + { + "id": 10, + "target_branch": "test-6", + "source_branch": "test-7", + "source_project_id": 5, + "author_id": 22, + "assignee_id": 4, + "title": "Rerum commodi corporis quis qui fugit sed ut.", + "created_at": "2016-03-22T15:13:44.103Z", + "updated_at": "2016-03-22T15:20:32.096Z", + "milestone_id": 11, + "state": "opened", + "merge_status": "unchecked", + "target_project_id": 5, + "iid": 2, + "description": "Laudantium vel dignissimos aspernatur quis aut. Dolores et doloremque ipsa quia voluptate modi labore. Ipsa provident repellat error et nihil.", + "position": 0, + "locked_at": null, + "updated_by_id": null, + "merge_error": null, + "merge_params": { + + }, + "merge_when_build_succeeds": false, + "merge_user_id": null, + "merge_commit_sha": null, + "deleted_at": null, + "notes": [ + { + "id": 1271, + "note": "Quod ut ut quisquam et ut dolorem dolor.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:32.093Z", + "updated_at": "2016-03-22T15:20:32.093Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" + } + }, + { + "id": 1270, + "note": "Sed deserunt et explicabo rem repellat voluptatem.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:32.070Z", + "updated_at": "2016-03-22T15:20:32.070Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1269, + "note": "Veritatis architecto omnis consequatur et optio.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:32.046Z", + "updated_at": "2016-03-22T15:20:32.046Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1268, + "note": "Omnis suscipit odio molestiae debitis quia autem magni.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:32.019Z", + "updated_at": "2016-03-22T15:20:32.019Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1267, + "note": "Molestias est sunt est tempora consequatur cupiditate magnam.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:31.993Z", + "updated_at": "2016-03-22T15:20:31.993Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" + } + }, + { + "id": 1266, + "note": "Ratione blanditiis eveniet voluptatem nostrum rerum excepturi in molestiae.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:31.969Z", + "updated_at": "2016-03-22T15:20:31.969Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, + { + "id": 1265, + "note": "Illo voluptatibus vel odio ea.", + "noteable_type": "MergeRequest", + "author_id": 24, + "created_at": "2016-03-22T15:20:31.944Z", + "updated_at": "2016-03-22T15:20:31.944Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 10, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1264, + "note": "Earum veritatis quis facere itaque iure.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:31.919Z", + "updated_at": "2016-03-22T15:20:31.919Z", + "project_id": 5, "attachment": { "url": null }, "line_code": null, "commit_id": null, - "noteable_id": 1, + "noteable_id": 10, "system": false, "st_diff": null, "updated_by_id": null, - "is_award": false + "is_award": false, + "author": { + "name": "User 4" + } } - ] - } - ], - "labels": [ - { - "id": 1, - "title": "label1", - "color": "#990000", - "project_id": 6, - "created_at": "2016-04-13T14:40:34.704Z", - "updated_at": "2016-04-13T14:40:36.891Z", - "template": false, - "description": null - } - ], - "milestones": [ - { - "id": 1, - "title": "Milestone v1.2", - "project_id": 6, - "description": null, - "due_date": null, - "created_at": "2016-04-13T14:40:37.901Z", - "updated_at": "2016-04-13T14:40:37.901Z", - "state": "active", - "iid": 1 - } - ], - "snippets": [ - { - "id": 1, - "title": "Illo ipsa maxime magni aut.", - "content": "Excepturi delectus ut harum est molestiae dolor.", - "author_id": 10, - "project_id": 6, - "created_at": "2016-04-13T14:40:35.603Z", - "updated_at": "2016-04-13T14:40:36.903Z", - "file_name": "daphne.mraz", - "visibility_level": 0 - } - ], - "releases": [ - { - "id": 1, - "tag": "v1.1.0", - "description": "Awesome release", - "project_id": 6, - "created_at": "2016-04-13T14:40:36.223Z", - "updated_at": "2016-04-13T14:40:36.913Z" - } - ], - "events": [ - { - "id": 1, - "target_type": null, - "target_id": null, - "title": null, - "data": null, - "project_id": 6, - "created_at": "2016-04-13T14:40:40.122Z", - "updated_at": "2016-04-13T14:40:40.122Z", - "action": 8, - "author_id": 1 - } - ], - "project_members": [ - { - "id": 1, - "user": { - "id": 1, - "email": "norval.gulgowski@schambergerboyle.co.uk", - "created_at": "2016-04-13T14:40:30.963Z", - "updated_at": "2016-04-13T14:40:30.963Z", - "name": "Jalon Cormier DVM", - "admin": false, - "projects_limit": 42, - "skype": "", - "linkedin": "", - "twitter": "", - "authentication_token": "tt-mPSZFvRBu8QzkW1Ss", - "theme_id": 2, - "bio": null, - "username": "vance.turner1", - "can_create_group": true, - "can_create_team": false, - "state": "active", - "color_scheme_id": 1, - "notification_level": 1, - "password_expires_at": null, - "created_by_id": null, - "last_credential_check_at": null, - "avatar": { - "url": null - }, - "hide_no_ssh_key": false, - "website_url": "", - "notification_email": "norval.gulgowski@schambergerboyle.co.uk", - "hide_no_password": false, - "password_automatically_set": false, - "location": null, - "encrypted_otp_secret": null, - "encrypted_otp_secret_iv": null, - "encrypted_otp_secret_salt": null, - "otp_required_for_login": false, - "otp_backup_codes": null, - "public_email": "", - "dashboard": "projects", - "project_view": "readme", - "consumed_timestep": null, - "layout": "fixed", - "hide_project_limit": false, - "otp_grace_period_started_at": null, - "ldap_email": false, - "external": false + ], + "merge_request_diff": { + "id": 10, + "state": "collected", + "st_commits": [ + { + "id": "b42bb86cea49bdcef943e521584b7f417d8ddd3d", + "message": "fixes #10\n", + "parent_ids": [ + "be93687618e4b132087f430a4d8fc3a609c9b77c" + ], + "authored_date": "2016-01-19T15:03:09.000+01:00", + "author_name": "Test Lopez", + "author_email": "Test@Testlopez.es", + "committed_date": "2016-01-19T15:03:09.000+01:00", + "committer_name": "Test Lopez", + "committer_email": "Test@Testlopez.es" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/test\n", + "new_path": "test", + "old_path": "test", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 10, + "created_at": "2016-03-22T15:13:44.107Z", + "updated_at": "2016-03-22T15:13:44.190Z", + "base_commit_sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "real_size": "1" } - } - ], - "merge_requests": [ + }, { - "id": 1, - "target_branch": "feature", - "source_branch": "master", - "source_project_id": 2, - "author_id": 5, - "assignee_id": null, - "title": "Dignissimos officia sit aut id dolor iure voluptatem expedita.", - "created_at": "2016-04-13T14:40:33.381Z", - "updated_at": "2016-04-13T14:40:39.850Z", - "milestone_id": null, + "id": 9, + "target_branch": "test-8", + "source_branch": "test-9", + "source_project_id": 5, + "author_id": 24, + "assignee_id": 3, + "title": "Saepe et neque ut vero nobis et voluptatum facere qui minima.", + "created_at": "2016-03-22T15:13:43.792Z", + "updated_at": "2016-03-22T15:20:32.309Z", + "milestone_id": 10, "state": "opened", - "merge_status": "can_be_merged", - "target_project_id": 6, + "merge_status": "unchecked", + "target_project_id": 5, "iid": 1, - "description": null, + "description": "Autem enim aliquam labore qui voluptas ut voluptatem. Et corrupti sit fuga dolores alias iusto voluptatem. Excepturi ut saepe accusamus neque distinctio.", "position": 0, "locked_at": null, "updated_by_id": null, "merge_error": null, "merge_params": { + }, "merge_when_build_succeeds": false, "merge_user_id": null, "merge_commit_sha": null, "deleted_at": null, - "merge_request_diff": { - "id": 1, - "state": "collected", - "st_commits": [ - { - "id": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", - "message": "Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \n", - "parent_ids": [ - "570e7b2abdd848b95f2f578043fc23bd6f6fd24d" - ], - "authored_date": "2014-02-27T10:01:38.000+01:00", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "committed_date": "2014-02-27T10:01:38.000+01:00", - "committer_name": "Dmitriy Zaporozhets", - "committer_email": "dmitriy.zaporozhets@gmail.com" - }, - { - "id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d", - "message": "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \n", - "parent_ids": [ - "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9" - ], - "authored_date": "2014-02-27T09:57:31.000+01:00", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "committed_date": "2014-02-27T09:57:31.000+01:00", - "committer_name": "Dmitriy Zaporozhets", - "committer_email": "dmitriy.zaporozhets@gmail.com" - }, - { - "id": "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9", - "message": "More submodules\n\nSigned-off-by: Dmitriy Zaporozhets \n", - "parent_ids": [ - "d14d6c0abdd253381df51a723d58691b2ee1ab08" - ], - "authored_date": "2014-02-27T09:54:21.000+01:00", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "committed_date": "2014-02-27T09:54:21.000+01:00", - "committer_name": "Dmitriy Zaporozhets", - "committer_email": "dmitriy.zaporozhets@gmail.com" - }, - { - "id": "d14d6c0abdd253381df51a723d58691b2ee1ab08", - "message": "Remove ds_store files\n\nSigned-off-by: Dmitriy Zaporozhets \n", - "parent_ids": [ - "c1acaa58bbcbc3eafe538cb8274ba387047b69f8" - ], - "authored_date": "2014-02-27T09:49:50.000+01:00", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "committed_date": "2014-02-27T09:49:50.000+01:00", - "committer_name": "Dmitriy Zaporozhets", - "committer_email": "dmitriy.zaporozhets@gmail.com" + "notes": [ + { + "id": 1279, + "note": "A corrupti nesciunt pariatur ea.", + "noteable_type": "MergeRequest", + "author_id": 1, + "created_at": "2016-03-22T15:20:32.307Z", + "updated_at": "2016-03-22T15:20:32.307Z", + "project_id": 5, + "attachment": { + "url": null }, - { - "id": "c1acaa58bbcbc3eafe538cb8274ba387047b69f8", - "message": "Ignore DS files\n\nSigned-off-by: Dmitriy Zaporozhets \n", - "parent_ids": [ - "ae73cb07c9eeaf35924a10f713b364d32b2dd34f" - ], - "authored_date": "2014-02-27T09:48:32.000+01:00", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "committed_date": "2014-02-27T09:48:32.000+01:00", - "committer_name": "Dmitriy Zaporozhets", - "committer_email": "dmitriy.zaporozhets@gmail.com" + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Administrator" } - ], - "st_diffs": [ - { - "diff": "Binary files a/.DS_Store and /dev/null differ\n", - "new_path": ".DS_Store", - "old_path": ".DS_Store", - "a_mode": "100644", - "b_mode": "0", - "new_file": false, - "renamed_file": false, - "deleted_file": true, - "too_large": false - }, - { - "diff": "--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n", - "new_path": ".gitignore", - "old_path": ".gitignore", - "a_mode": "100644", - "b_mode": "100644", - "new_file": false, - "renamed_file": false, - "deleted_file": false, - "too_large": false - }, - { - "diff": "--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n", - "new_path": ".gitmodules", - "old_path": ".gitmodules", - "a_mode": "100644", - "b_mode": "100644", - "new_file": false, - "renamed_file": false, - "deleted_file": false, - "too_large": false - }, - { - "diff": "Binary files a/files/.DS_Store and /dev/null differ\n", - "new_path": "files/.DS_Store", - "old_path": "files/.DS_Store", - "a_mode": "100644", - "b_mode": "0", - "new_file": false, - "renamed_file": false, - "deleted_file": true, - "too_large": false + }, + { + "id": 1278, + "note": "Adipisci aut ut et voluptate numquam.", + "noteable_type": "MergeRequest", + "author_id": 3, + "created_at": "2016-03-22T15:20:32.281Z", + "updated_at": "2016-03-22T15:20:32.281Z", + "project_id": 5, + "attachment": { + "url": null }, - { - "diff": "--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" => path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" => path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output << stdout.read\n @cmd_output << stderr.read\n", - "new_path": "files/ruby/popen.rb", - "old_path": "files/ruby/popen.rb", - "a_mode": "100644", - "b_mode": "100644", - "new_file": false, - "renamed_file": false, - "deleted_file": false, - "too_large": false + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Alexie Trantow" + } + }, + { + "id": 1277, + "note": "Adipisci voluptatem quod ut placeat repellendus deleniti.", + "noteable_type": "MergeRequest", + "author_id": 4, + "created_at": "2016-03-22T15:20:32.255Z", + "updated_at": "2016-03-22T15:20:32.255Z", + "project_id": 5, + "attachment": { + "url": null }, - { - "diff": "--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n", - "new_path": "files/ruby/regex.rb", - "old_path": "files/ruby/regex.rb", - "a_mode": "100644", - "b_mode": "100644", - "new_file": false, - "renamed_file": false, - "deleted_file": false, - "too_large": false + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Julius Moore" + } + }, + { + "id": 1276, + "note": "Vitae et doloremque aut et aspernatur velit placeat sed.", + "noteable_type": "MergeRequest", + "author_id": 10, + "created_at": "2016-03-22T15:20:32.230Z", + "updated_at": "2016-03-22T15:20:32.230Z", + "project_id": 5, + "attachment": { + "url": null }, - { - "diff": "--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n", - "new_path": "gitlab-grack", - "old_path": "gitlab-grack", - "a_mode": "0", - "b_mode": "160000", - "new_file": true, - "renamed_file": false, - "deleted_file": false, - "too_large": false + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Robyn McCullough Jr." + } + }, + { + "id": 1275, + "note": "Quos cupiditate nesciunt expedita aspernatur.", + "noteable_type": "MergeRequest", + "author_id": 12, + "created_at": "2016-03-22T15:20:32.207Z", + "updated_at": "2016-03-22T15:20:32.207Z", + "project_id": 5, + "attachment": { + "url": null }, - { - "diff": "--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n", - "new_path": "gitlab-shell", - "old_path": "gitlab-shell", - "a_mode": "0", - "b_mode": "160000", - "new_file": true, - "renamed_file": false, - "deleted_file": false, - "too_large": false + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "Vladimir McCullough" } - ], - "merge_request_id": 1, - "created_at": "2016-04-13T14:40:33.474Z", - "updated_at": "2016-04-13T14:40:33.834Z", - "base_commit_sha": "ae73cb07c9eeaf35924a10f713b364d32b2dd34f", - "real_size": "8" - }, - "notes": [ + }, + { + "id": 1274, + "note": "Optio rem inventore dicta praesentium sit.", + "noteable_type": "MergeRequest", + "author_id": 22, + "created_at": "2016-03-22T15:20:32.181Z", + "updated_at": "2016-03-22T15:20:32.181Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 0" + } + }, { - "id": 2, - "note": ":+1: merge_request", + "id": 1273, + "note": "Sit incidunt molestiae maxime officiis rerum necessitatibus.", "noteable_type": "MergeRequest", "author_id": 24, - "created_at": "2016-04-13T14:40:39.832Z", - "updated_at": "2016-04-13T14:40:39.832Z", - "project_id": 9, + "created_at": "2016-03-22T15:20:32.159Z", + "updated_at": "2016-03-22T15:20:32.159Z", + "project_id": 5, + "attachment": { + "url": null + }, + "line_code": null, + "commit_id": null, + "noteable_id": 9, + "system": false, + "st_diff": null, + "updated_by_id": null, + "is_award": false, + "author": { + "name": "User 2" + } + }, + { + "id": 1272, + "note": "Autem ut non itaque molestiae nisi quia officiis doloribus.", + "noteable_type": "MergeRequest", + "author_id": 26, + "created_at": "2016-03-22T15:20:32.129Z", + "updated_at": "2016-03-22T15:20:32.129Z", + "project_id": 5, "attachment": { "url": null }, "line_code": null, "commit_id": null, - "noteable_id": 1, + "noteable_id": 9, "system": false, "st_diff": null, "updated_by_id": null, - "is_award": false + "is_award": false, + "author": { + "name": "User 4" + } } - ] + ], + "merge_request_diff": { + "id": 9, + "state": "collected", + "st_commits": [ + { + "id": "e239ba8c97b80b2874579a4d625ea9628f4c8ff5", + "message": "fixes #10\n", + "parent_ids": [ + "be93687618e4b132087f430a4d8fc3a609c9b77c" + ], + "authored_date": "2016-01-19T15:38:06.000+01:00", + "author_name": "Test Lopez", + "author_email": "Test@Testlopez.es", + "committed_date": "2016-01-19T15:38:06.000+01:00", + "committer_name": "Test Lopez", + "committer_email": "Test@Testlopez.es" + } + ], + "st_diffs": [ + { + "diff": "--- /dev/null\n+++ b/test\n", + "new_path": "test", + "old_path": "test", + "a_mode": "0", + "b_mode": "100644", + "new_file": true, + "renamed_file": false, + "deleted_file": false, + "too_large": false + } + ], + "merge_request_id": 9, + "created_at": "2016-03-22T15:13:43.794Z", + "updated_at": "2016-03-22T15:13:43.848Z", + "base_commit_sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "real_size": "1" + } } ], "ci_commits": [ { - "id": 2, - "project_id": 6, + "id": 36, + "project_id": 5, + "ref": "master", + "sha": "be93687618e4b132087f430a4d8fc3a609c9b77c", + "before_sha": null, + "push_data": null, + "created_at": "2016-03-22T15:20:35.755Z", + "updated_at": "2016-03-22T15:20:35.755Z", + "tag": null, + "yaml_errors": null, + "committed_at": null, + "gl_project_id": 5, + "status": "failed", + "started_at": null, + "finished_at": null, + "duration": null, + "statuses": [ + { + "id": 71, + "project_id": 5, + "status": "failed", + "finished_at": "2016-03-29T06:28:12.630Z", + "trace": null, + "created_at": "2016-03-22T15:20:35.772Z", + "updated_at": "2016-03-29T06:28:12.634Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 36, + "commands": "$ build command", + "job_id": null, + "name": "test build 1", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": null + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": null + }, + "erased_by_id": null, + "erased_at": null + }, + { + "id": 72, + "project_id": 5, + "status": "success", + "finished_at": null, + "trace": "Porro ea qui ut dolores. Labore ab nemo explicabo aspernatur quis voluptates corporis. Et quasi delectus est sit aperiam perspiciatis asperiores. Repudiandae cum aut consectetur accusantium officia sunt.\n\nQuidem dolore iusto quaerat ut aut inventore et molestiae. Libero voluptates atque nemo qui. Nulla temporibus ipsa similique facere.\n\nAliquam ipsam perferendis qui fugit accusantium omnis id voluptatum. Dignissimos aliquid dicta eos voluptatem assumenda quia. Sed autem natus unde dolor et non nisi et. Consequuntur nihil consequatur rerum est.\n\nSimilique neque est iste ducimus qui fuga cupiditate. Libero autem est aut fuga. Consectetur natus quis non ducimus ut dolore. Magni voluptatibus eius et maxime aut.\n\nAd officiis tempore voluptate vitae corrupti explicabo labore est. Consequatur expedita et sunt nihil aut. Deleniti porro iusto molestiae et beatae.\n\nDeleniti modi nulla qui et labore sequi corrupti. Qui voluptatem assumenda eum cupiditate et. Nesciunt ipsam ut ea possimus eum. Consectetur quidem suscipit atque dolore itaque voluptatibus et cupiditate.", + "created_at": "2016-03-22T15:20:35.777Z", + "updated_at": "2016-03-22T15:20:35.777Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 36, + "commands": "$ build command", + "job_id": null, + "name": "test build 2", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/72/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/72/p5_build_artifacts_metadata.gz" + }, + "erased_by_id": null, + "erased_at": null + } + ] + }, + { + "id": 37, + "project_id": 5, "ref": "master", - "sha": "5937ac0a7beb003549fc5fd26fc247adbce4a52e", + "sha": "048721d90c449b244b7b4c53a9186b04330174ec", "before_sha": null, "push_data": null, - "created_at": "2016-04-13T14:40:37.759Z", - "updated_at": "2016-04-13T14:40:37.759Z", - "tag": false, + "created_at": "2016-03-22T15:20:35.757Z", + "updated_at": "2016-03-22T15:20:35.757Z", + "tag": null, "yaml_errors": null, "committed_at": null, - "gl_project_id": 6, + "gl_project_id": 5, + "status": "failed", + "started_at": null, + "finished_at": null, + "duration": null, "statuses": [ { - "id": 1, - "project_id": null, + "id": 74, + "project_id": 5, "status": "success", - "finished_at": "2016-01-26T07:23:42.000Z", + "finished_at": null, + "trace": "Ad ut quod repudiandae iste dolor doloribus. Adipisci consequuntur deserunt omnis quasi eveniet et sed fugit. Aut nemo omnis molestiae impedit ex consequatur ducimus. Voluptatum exercitationem quia aut est et hic dolorem.\n\nQuasi repellendus et eaque magni eum facilis. Dolorem aperiam nam nihil pariatur praesentium ad aliquam. Commodi enim et eos tenetur. Odio voluptatibus laboriosam mollitia rerum exercitationem magnam consequuntur. Tenetur ea vel eum corporis.\n\nVoluptatibus optio in aliquid est voluptates. Ad a ut ab placeat vero blanditiis. Earum aspernatur quia beatae expedita voluptatem dignissimos provident. Quis minima id nemo ut aut est veritatis provident.\n\nRerum voluptatem quidem eius maiores magnam veniam. Voluptatem aperiam aut voluptate et nulla deserunt voluptas. Quaerat aut accusantium laborum est dolorem architecto reiciendis. Aliquam asperiores doloribus omnis maxime enim nesciunt. Eum aut rerum repellendus debitis et ut eius.\n\nQuaerat assumenda ea sit consequatur autem in. Cum eligendi voluptatem quo sed. Ut fuga iusto cupiditate autem sint.\n\nOfficia totam officiis architecto corporis molestiae amet ut. Tempora sed dolorum rerum omnis voluptatem accusantium sit eum. Quia debitis ipsum quidem aliquam inventore sunt consequatur qui.", + "created_at": "2016-03-22T15:20:35.846Z", + "updated_at": "2016-03-22T15:20:35.846Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 37, + "commands": "$ build command", + "job_id": null, + "name": "test build 2", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/74/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/74/p5_build_artifacts_metadata.gz" + }, + "erased_by_id": null, + "erased_at": null + }, + { + "id": 73, + "project_id": 5, + "status": "canceled", + "finished_at": null, "trace": null, - "created_at": "2016-04-13T14:40:37.717Z", - "updated_at": "2016-04-13T14:40:37.771Z", - "started_at": "2016-01-26T07:21:42.000Z", + "created_at": "2016-03-22T15:20:35.842Z", + "updated_at": "2016-03-22T15:20:35.842Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 37, + "commands": "$ build command", + "job_id": null, + "name": "test build 1", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": null + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": null + }, + "erased_by_id": null, + "erased_at": null + } + ] + }, + { + "id": 38, + "project_id": 5, + "ref": "master", + "sha": "5f923865dde3436854e9ceb9cdb7815618d4e849", + "before_sha": null, + "push_data": null, + "created_at": "2016-03-22T15:20:35.759Z", + "updated_at": "2016-03-22T15:20:35.759Z", + "tag": null, + "yaml_errors": null, + "committed_at": null, + "gl_project_id": 5, + "status": "failed", + "started_at": null, + "finished_at": null, + "duration": null, + "statuses": [ + { + "id": 76, + "project_id": 5, + "status": "success", + "finished_at": null, + "trace": "Et rerum quia ea cumque ut modi non. Libero eaque ipsam architecto maiores expedita deleniti. Ratione quia qui est id.\n\nQuod sit officiis sed unde inventore veniam quisquam velit. Ea harum cum quibusdam quisquam minima quo possimus non. Temporibus itaque aliquam aut rerum veritatis at.\n\nMagnam ipsum eius recusandae qui quis sit maiores eum. Et animi iusto aut itaque. Doloribus harum deleniti nobis accusantium et libero.\n\nRerum fuga perferendis magni commodi officiis id repudiandae. Consequatur ratione consequatur suscipit facilis sunt iure est dicta. Qui unde quasi facilis et quae nesciunt. Magnam iste et nobis officiis tenetur. Aspernatur quo et temporibus non in.\n\nNisi rerum velit est ad enim sint molestiae consequuntur. Quaerat nisi nesciunt quasi officiis. Possimus non blanditiis laborum quos.\n\nRerum laudantium facere animi qui. Ipsa est iusto magnam nihil. Enim omnis occaecati non dignissimos ut recusandae eum quasi. Qui maxime dolor et nemo voluptates incidunt quia.", + "created_at": "2016-03-22T15:20:35.882Z", + "updated_at": "2016-03-22T15:20:35.882Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 38, + "commands": "$ build command", + "job_id": null, + "name": "test build 2", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/76/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/76/p5_build_artifacts_metadata.gz" + }, + "erased_by_id": null, + "erased_at": null + }, + { + "id": 75, + "project_id": 5, + "status": "failed", + "finished_at": null, + "trace": "Sed et iste recusandae dicta corporis. Sunt alias porro fugit sunt. Fugiat omnis nihil dignissimos aperiam explicabo doloremque sit aut. Harum fugit expedita quia rerum ut consequatur laboriosam aliquam.\n\nNatus libero ut ut tenetur earum. Tempora omnis autem omnis et libero dolores illum autem. Deleniti eos sunt mollitia ipsam. Cum dolor repellendus dolorum sequi officia. Ullam sunt in aut pariatur excepturi.\n\nDolor nihil debitis et est eos. Cumque eos eum saepe ducimus autem. Alias architecto consequatur aut pariatur possimus. Aut quos aut incidunt quam velit et. Quas voluptatum ad dolorum dignissimos.\n\nUt voluptates consectetur illo et. Est commodi accusantium vel quo. Eos qui fugiat soluta porro.\n\nRatione possimus alias vel maxime sint totam est repellat. Ipsum corporis eos sint voluptatem eos odit. Temporibus libero nulla harum eligendi labore similique ratione magnam. Suscipit sequi in omnis neque.\n\nLaudantium dolor amet omnis placeat mollitia aut molestiae. Aut rerum similique ipsum quod illo quas unde. Sunt aut veritatis eos omnis porro. Rem veritatis mollitia praesentium dolorem. Consequatur sequi ad cumque earum omnis quia necessitatibus.", + "created_at": "2016-03-22T15:20:35.864Z", + "updated_at": "2016-03-22T15:20:35.864Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 38, + "commands": "$ build command", + "job_id": null, + "name": "test build 1", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/75/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/75/p5_build_artifacts_metadata.gz" + }, + "erased_by_id": null, + "erased_at": null + } + ] + }, + { + "id": 39, + "project_id": 5, + "ref": "master", + "sha": "d2d430676773caa88cdaf7c55944073b2fd5561a", + "before_sha": null, + "push_data": null, + "created_at": "2016-03-22T15:20:35.761Z", + "updated_at": "2016-03-22T15:20:35.761Z", + "tag": null, + "yaml_errors": null, + "committed_at": null, + "gl_project_id": 5, + "status": "failed", + "started_at": null, + "finished_at": null, + "duration": null, + "statuses": [ + { + "id": 78, + "project_id": 5, + "status": "success", + "finished_at": null, + "trace": "Dolorem deserunt quas quia error hic quo cum vel. Natus voluptatem cumque expedita numquam odit. Eos expedita nostrum corporis consequatur est recusandae.\n\nCulpa blanditiis rerum repudiandae alias voluptatem. Velit iusto est ullam consequatur doloribus porro. Corporis voluptas consectetur est veniam et quia quae.\n\nEt aut magni fuga nesciunt officiis molestias. Quaerat et nam necessitatibus qui rerum. Architecto quia officiis voluptatem laborum est recusandae. Quasi ducimus soluta odit necessitatibus labore numquam dignissimos. Quia facere sint temporibus inventore sunt nihil saepe dolorum.\n\nFacere dolores quis dolores a. Est minus nostrum nihil harum. Earum laborum et ipsum unde neque sit nemo. Corrupti est consequatur minima fugit. Illum voluptatem illo error ducimus officia qui debitis.\n\nDignissimos porro a autem harum aut. Aut id reprehenderit et exercitationem. Est et quisquam ipsa temporibus molestiae. Architecto natus dolore qui fugiat incidunt. Autem odit veniam excepturi et voluptatibus culpa ipsum eos.\n\nAmet quo quisquam dignissimos soluta modi dolores. Sint omnis eius optio corporis dolor. Eligendi animi porro quia placeat ut.", + "created_at": "2016-03-22T15:20:35.927Z", + "updated_at": "2016-03-22T15:20:35.927Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 39, + "commands": "$ build command", + "job_id": null, + "name": "test build 2", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/78/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/78/p5_build_artifacts_metadata.gz" + }, + "erased_by_id": null, + "erased_at": null + }, + { + "id": 77, + "project_id": 5, + "status": "failed", + "finished_at": null, + "trace": "Rerum ut et suscipit est perspiciatis. Inventore debitis cum eius vitae. Ex incidunt id velit aut quo nisi. Laboriosam repellat deserunt eius reiciendis architecto et. Est harum quos nesciunt nisi consectetur.\n\nAlias esse omnis sint officia est consequatur in nobis. Dignissimos dolorum vel eligendi nesciunt dolores sit. Veniam mollitia ducimus et exercitationem molestiae libero sed. Atque omnis debitis laudantium voluptatibus qui. Repellendus tempore est commodi pariatur.\n\nExpedita voluptate illum est alias non. Modi nesciunt ab assumenda laborum nulla consequatur molestias doloremque. Magnam quod officia vel explicabo accusamus ut voluptatem incidunt. Rerum ut aliquid ullam saepe. Est eligendi debitis beatae blanditiis reiciendis.\n\nQui fuga sit dolores libero maiores et suscipit. Consectetur asperiores omnis minima impedit eos fugiat. Similique omnis nisi sed vero inventore ipsum aliquam exercitationem.\n\nBlanditiis magni iure dolorum omnis ratione delectus molestiae. Atque officia dolor voluptatem culpa quod. Incidunt suscipit quidem possimus veritatis non vel. Iusto aliquid et id quia quasi.\n\nVel facere velit blanditiis incidunt cupiditate sed maiores consequuntur. Quasi quia dicta consequuntur et quia voluptatem iste id. Incidunt et rerum fuga esse sint.", + "created_at": "2016-03-22T15:20:35.905Z", + "updated_at": "2016-03-22T15:20:35.905Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 39, + "commands": "$ build command", + "job_id": null, + "name": "test build 1", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/77/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/77/p5_build_artifacts_metadata.gz" + }, + "erased_by_id": null, + "erased_at": null + } + ] + }, + { + "id": 40, + "project_id": 5, + "ref": "master", + "sha": "2ea1f3dec713d940208fb5ce4a38765ecb5d3f73", + "before_sha": null, + "push_data": null, + "created_at": "2016-03-22T15:20:35.763Z", + "updated_at": "2016-03-22T15:20:35.763Z", + "tag": null, + "yaml_errors": null, + "committed_at": null, + "gl_project_id": 5, + "status": "failed", + "started_at": null, + "finished_at": null, + "duration": null, + "statuses": [ + { + "id": 79, + "project_id": 5, + "status": "failed", + "finished_at": "2016-03-29T06:28:12.695Z", + "trace": "Sed culpa est et facere saepe vel id ab. Quas temporibus aut similique dolorem consequatur corporis aut praesentium. Cum officia molestiae sit earum excepturi.\n\nSint possimus aut ratione quia. Quis nesciunt ratione itaque illo. Tenetur est dolor assumenda possimus voluptatem quia minima. Accusamus reprehenderit ut et itaque non reiciendis incidunt.\n\nRerum suscipit quibusdam dolore nam omnis. Consequatur ipsa nihil ut enim blanditiis delectus. Nulla quis hic occaecati mollitia qui placeat. Quo rerum sed perferendis a accusantium consequatur commodi ut. Sit quae et cumque vel eius tempora nostrum.\n\nUllam dolorem et itaque sint est. Ea molestias quia provident dolorem vitae error et et. Ea expedita officiis iste non. Qui vitae odit saepe illum. Dolores enim ratione deserunt tempore expedita amet non neque.\n\nEligendi asperiores voluptatibus omnis repudiandae expedita distinctio qui aliquid. Autem aut doloremque distinctio ab. Nostrum sapiente repudiandae aspernatur ea et quae voluptas. Officiis perspiciatis nisi laudantium asperiores error eligendi ab. Eius quia amet magni omnis exercitationem voluptatum et.\n\nVoluptatem ullam labore quas dicta est ex voluptas. Pariatur ea modi voluptas consequatur dolores perspiciatis similique. Numquam in distinctio perspiciatis ut qui earum. Quidem omnis mollitia facere aut beatae. Ea est iure et voluptatem.", + "created_at": "2016-03-22T15:20:35.950Z", + "updated_at": "2016-03-29T06:28:12.696Z", + "started_at": null, + "runner_id": null, + "coverage": null, + "commit_id": 40, + "commands": "$ build command", + "job_id": null, + "name": "test build 1", + "deploy": false, + "options": null, + "allow_failure": false, + "stage": "test", + "trigger_request_id": null, + "stage_idx": 1, + "tag": null, + "ref": "master", + "user_id": null, + "target_url": null, + "description": null, + "artifacts_file": { + "url": null + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": null + }, + "erased_by_id": null, + "erased_at": null + }, + { + "id": 80, + "project_id": 5, + "status": "success", + "finished_at": null, + "trace": "Impedit et optio nemo ipsa. Non ad non quis ut sequi laudantium omnis velit. Corporis a enim illo eos. Quia totam tempore inventore ad est.\n\nNihil recusandae cupiditate eaque voluptatem molestias sint. Consequatur id voluptatem cupiditate harum. Consequuntur iusto quaerat reiciendis aut autem libero est. Quisquam dolores veritatis rerum et sint maxime ullam libero. Id quas porro ut perspiciatis rem amet vitae.\n\nNemo inventore minus blanditiis magnam. Modi consequuntur nostrum aut voluptatem ex. Sunt rerum rem optio mollitia qui aliquam officiis officia. Aliquid eos et id aut minus beatae reiciendis.\n\nDolores non in temporibus dicta. Fugiat voluptatem est aspernatur expedita voluptatum nam qui. Quia et eligendi sit quae sint tempore exercitationem eos. Est sapiente corrupti quidem at. Qui magni odio repudiandae saepe tenetur optio dolore.\n\nEos placeat soluta at dolorem adipisci provident. Quo commodi id reprehenderit possimus quo tenetur. Ipsum et quae eligendi laborum. Et qui nesciunt at quasi quidem voluptatem cum rerum. Excepturi non facilis aut sunt vero sed.\n\nQui explicabo ratione ut eligendi recusandae. Quis quasi quas molestiae consequatur voluptatem et voluptatem. Ex repellat saepe occaecati aperiam ea eveniet dignissimos facilis.", + "created_at": "2016-03-22T15:20:35.966Z", + "updated_at": "2016-03-22T15:20:35.966Z", + "started_at": null, "runner_id": null, "coverage": null, - "commit_id": 2, - "commands": null, + "commit_id": 40, + "commands": "$ build command", "job_id": null, - "name": "default", + "name": "test build 2", "deploy": false, "options": null, "allow_failure": false, - "stage": null, + "stage": "test", "trigger_request_id": null, - "stage_idx": null, + "stage_idx": 1, "tag": null, - "ref": null, + "ref": "master", "user_id": null, "target_url": null, - "description": "commit status", - "artifacts_file": null, - "gl_project_id": 7, - "artifacts_metadata": null, + "description": null, + "artifacts_file": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/80/p5_build_artifacts.zip" + }, + "gl_project_id": 5, + "artifacts_metadata": { + "url": "/Users/Test/Test/gitlab-development-kit/gitlab/shared/artifacts/2016_03/5/80/p5_build_artifacts_metadata.gz" + }, "erased_by_id": null, "erased_at": null } -- GitLab From c487e6d311957984da95d19ed8d63b068c6da228 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 13 May 2016 16:24:32 +0200 Subject: [PATCH 157/714] updated spec file --- .../import_export/test_project_export.tar.gz | Bin 338822 -> 339384 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz index f2c3c3cd2dc67ba456501a8ba754edf74cdaba9a..aef4af6998ee729c2eea80c9d2423fc787083950 100644 GIT binary patch delta 77228 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