From 9a5f40878c6d71e7fd4858f7fa1d948af6c371ae Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Aug 2016 11:32:29 +0300 Subject: Add API to list merge request diff versions Signed-off-by: Dmitriy Zaporozhets --- lib/api/api.rb | 1 + lib/api/entities.rb | 11 +++++++++++ lib/api/merge_request_diffs.rb | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 lib/api/merge_request_diffs.rb (limited to 'lib') diff --git a/lib/api/api.rb b/lib/api/api.rb index bd16806892b..9d8f297191f 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -67,5 +67,6 @@ module API mount ::API::Triggers mount ::API::Users mount ::API::Variables + mount ::API::MergeRequestDiffs end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 3e21b7a0b8a..af069063f0c 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -228,6 +228,17 @@ module API end end + class MergeRequestDiff < Grape::Entity + expose :id, :head_commit_sha, :base_commit_sha, :start_commit_sha, + :created_at, :merge_request_id, :state, :real_size + + expose :commits, using: Entities::RepoCommit + + expose :diffs, using: Entities::RepoDiff do |compare, _| + compare.diffs(all_diffs: true).to_a + end + end + class SSHKey < Grape::Entity expose :id, :title, :key, :created_at end diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb new file mode 100644 index 00000000000..4bd149d1603 --- /dev/null +++ b/lib/api/merge_request_diffs.rb @@ -0,0 +1,25 @@ +module API + # MergeRequestDiff API + class MergeRequestDiffs < Grape::API + before { authenticate! } + + resource :projects do + # List merge requests diff versions + # + # Parameters: + # id (required) - The ID of a project + # merge_request_id (required) - The ID of MR + # + # Example: + # GET /projects/:id/merge_requests/:merge_request_id/versions + # + get ":id/merge_requests/:merge_request_id/versions" do + merge_request = user_project.merge_requests. + find(params[:merge_request_id]) + + authorize! :read_merge_request, merge_request + present merge_request.merge_request_diffs, with: Entities::MergeRequestDiff + end + end + end +end -- cgit v1.2.1 From 69096ad9da77ce51d544a8f23f4e8873df273f4e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Aug 2016 11:58:09 +0300 Subject: Update merge request versions API to match styleguide Signed-off-by: Dmitriy Zaporozhets --- lib/api/merge_request_diffs.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index 4bd149d1603..be954ff96ac 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -4,15 +4,16 @@ module API before { authenticate! } resource :projects do - # List merge requests diff versions - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - The ID of MR - # - # Example: - # GET /projects/:id/merge_requests/:merge_request_id/versions - # + desc 'Get a list of merge request diff versions' do + detail 'This feature was introduced in GitLab 8.12.' + success Entities::MergeRequestDiff + end + + params do + requires :id, type: Integer, desc: 'The ID of a project' + requests :merge_request_id, type: Integer, desc: 'The ID of a merge request' + end + get ":id/merge_requests/:merge_request_id/versions" do merge_request = user_project.merge_requests. find(params[:merge_request_id]) -- cgit v1.2.1 From 08f5f897889dc7e7f00a65f56e988449350e60f2 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 3 Aug 2016 12:35:20 +0300 Subject: Fix project id param for merge request version API Signed-off-by: Dmitriy Zaporozhets --- lib/api/merge_request_diffs.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index be954ff96ac..a2f92f81107 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -10,8 +10,8 @@ module API end params do - requires :id, type: Integer, desc: 'The ID of a project' - requests :merge_request_id, type: Integer, desc: 'The ID of a merge request' + requires :id, type: String, desc: 'The ID of a project' + requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' end get ":id/merge_requests/:merge_request_id/versions" do -- cgit v1.2.1 From ac072132b8f0e36badf297208a5964109dbed126 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 12 Aug 2016 14:44:49 +0300 Subject: Add single merge request diff API endpoint Signed-off-by: Dmitriy Zaporozhets --- lib/api/entities.rb | 2 ++ lib/api/merge_request_diffs.rb | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index af069063f0c..f582b2ce250 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -231,7 +231,9 @@ module API class MergeRequestDiff < Grape::Entity expose :id, :head_commit_sha, :base_commit_sha, :start_commit_sha, :created_at, :merge_request_id, :state, :real_size + end + class MergeRequestDiffFull < MergeRequestDiff expose :commits, using: Entities::RepoCommit expose :diffs, using: Entities::RepoDiff do |compare, _| diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb index a2f92f81107..07435d78468 100644 --- a/lib/api/merge_request_diffs.rb +++ b/lib/api/merge_request_diffs.rb @@ -21,6 +21,25 @@ module API authorize! :read_merge_request, merge_request present merge_request.merge_request_diffs, with: Entities::MergeRequestDiff end + + desc 'Get a single merge request diff version' do + detail 'This feature was introduced in GitLab 8.12.' + success Entities::MergeRequestDiffFull + end + + params do + requires :id, type: String, desc: 'The ID of a project' + requires :merge_request_id, type: Integer, desc: 'The ID of a merge request' + requires :version_id, type: Integer, desc: 'The ID of a merge request diff version' + end + + get ":id/merge_requests/:merge_request_id/versions/:version_id" do + merge_request = user_project.merge_requests. + find(params[:merge_request_id]) + + authorize! :read_merge_request, merge_request + present merge_request.merge_request_diffs.find(params[:version_id]), with: Entities::MergeRequestDiffFull + end end end end -- cgit v1.2.1 From 643a368fa437725cbfffcfdc251055c4d125438c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 15 Aug 2016 17:57:19 +0300 Subject: Make merge request diff works with new FileCollection logic Signed-off-by: Dmitriy Zaporozhets --- lib/gitlab/diff/file_collection/merge_request.rb | 73 ---------------------- .../diff/file_collection/merge_request_diff.rb | 73 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 lib/gitlab/diff/file_collection/merge_request.rb create mode 100644 lib/gitlab/diff/file_collection/merge_request_diff.rb (limited to 'lib') diff --git a/lib/gitlab/diff/file_collection/merge_request.rb b/lib/gitlab/diff/file_collection/merge_request.rb deleted file mode 100644 index 4f946908e2f..00000000000 --- a/lib/gitlab/diff/file_collection/merge_request.rb +++ /dev/null @@ -1,73 +0,0 @@ -module Gitlab - module Diff - module FileCollection - class MergeRequest < Base - def initialize(merge_request, diff_options:) - @merge_request = merge_request - - super(merge_request, - project: merge_request.project, - diff_options: diff_options, - diff_refs: merge_request.diff_refs) - end - - def diff_files - super.tap { |_| store_highlight_cache } - end - - private - - # Extracted method to highlight in the same iteration to the diff_collection. - def decorate_diff!(diff) - diff_file = super - cache_highlight!(diff_file) if cacheable? - diff_file - end - - def highlight_diff_file_from_cache!(diff_file, cache_diff_lines) - diff_file.highlighted_diff_lines = cache_diff_lines.map do |line| - Gitlab::Diff::Line.init_from_hash(line) - end - end - - # - # If we find the highlighted diff files lines on the cache we replace existing diff_files lines (no highlighted) - # for the highlighted ones, so we just skip their execution. - # If the highlighted diff files lines are not cached we calculate and cache them. - # - # The content of the cache is a Hash where the key correspond to the file_path and the values are Arrays of - # hashes that represent serialized diff lines. - # - def cache_highlight!(diff_file) - file_path = diff_file.file_path - - if highlight_cache[file_path] - highlight_diff_file_from_cache!(diff_file, highlight_cache[file_path]) - else - highlight_cache[file_path] = diff_file.highlighted_diff_lines.map(&:to_hash) - end - end - - def highlight_cache - return @highlight_cache if defined?(@highlight_cache) - - @highlight_cache = Rails.cache.read(cache_key) || {} - @highlight_cache_was_empty = @highlight_cache.empty? - @highlight_cache - end - - def store_highlight_cache - Rails.cache.write(cache_key, highlight_cache) if @highlight_cache_was_empty - end - - def cacheable? - @merge_request.merge_request_diff.present? - end - - def cache_key - [@merge_request.merge_request_diff, 'highlighted-diff-files', diff_options] - end - end - end - end -end diff --git a/lib/gitlab/diff/file_collection/merge_request_diff.rb b/lib/gitlab/diff/file_collection/merge_request_diff.rb new file mode 100644 index 00000000000..36348b33943 --- /dev/null +++ b/lib/gitlab/diff/file_collection/merge_request_diff.rb @@ -0,0 +1,73 @@ +module Gitlab + module Diff + module FileCollection + class MergeRequestDiff < Base + def initialize(merge_request_diff, diff_options:) + @merge_request_diff = merge_request_diff + + super(merge_request_diff, + project: merge_request_diff.project, + diff_options: diff_options, + diff_refs: merge_request_diff.diff_refs) + end + + def diff_files + super.tap { |_| store_highlight_cache } + end + + private + + # Extracted method to highlight in the same iteration to the diff_collection. + def decorate_diff!(diff) + diff_file = super + cache_highlight!(diff_file) if cacheable? + diff_file + end + + def highlight_diff_file_from_cache!(diff_file, cache_diff_lines) + diff_file.highlighted_diff_lines = cache_diff_lines.map do |line| + Gitlab::Diff::Line.init_from_hash(line) + end + end + + # + # If we find the highlighted diff files lines on the cache we replace existing diff_files lines (no highlighted) + # for the highlighted ones, so we just skip their execution. + # If the highlighted diff files lines are not cached we calculate and cache them. + # + # The content of the cache is a Hash where the key correspond to the file_path and the values are Arrays of + # hashes that represent serialized diff lines. + # + def cache_highlight!(diff_file) + file_path = diff_file.file_path + + if highlight_cache[file_path] + highlight_diff_file_from_cache!(diff_file, highlight_cache[file_path]) + else + highlight_cache[file_path] = diff_file.highlighted_diff_lines.map(&:to_hash) + end + end + + def highlight_cache + return @highlight_cache if defined?(@highlight_cache) + + @highlight_cache = Rails.cache.read(cache_key) || {} + @highlight_cache_was_empty = @highlight_cache.empty? + @highlight_cache + end + + def store_highlight_cache + Rails.cache.write(cache_key, highlight_cache) if @highlight_cache_was_empty + end + + def cacheable? + @merge_request_diff.present? + end + + def cache_key + [@merge_request_diff, 'highlighted-diff-files', diff_options] + end + end + end + end +end -- cgit v1.2.1 From dde44b83ddeae75a5c14810d0571ee5c7ab0a26d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 22 Aug 2016 15:30:23 +0300 Subject: Fix merge request diff api Signed-off-by: Dmitriy Zaporozhets --- lib/api/entities.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 3f050a8fd81..3241cb7ca56 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -246,7 +246,7 @@ module API expose :commits, using: Entities::RepoCommit expose :diffs, using: Entities::RepoDiff do |compare, _| - compare.diffs(all_diffs: true).to_a + compare.raw_diffs(all_diffs: true).to_a end end -- cgit v1.2.1 From 31b2c1ef880349c9579f41e501de0346e59f0a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Dequ=C3=A8nes=20=28Duck=29?= Date: Mon, 22 Aug 2016 12:47:58 +0900 Subject: expose 'only_allow_merge_if_build_succeeds' project setting in the API --- lib/api/entities.rb | 1 + lib/api/projects.rb | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 66b85ab1793..0f6d28f1821 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -90,6 +90,7 @@ module API expose :shared_with_groups do |project, options| SharedGroup.represent(project.project_group_links.all, options) end + expose :only_allow_merge_if_build_succeeds end class Member < UserBasic diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 60cfc103afd..71efd4f33ca 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -123,7 +123,8 @@ module API :public, :visibility_level, :import_url, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(current_user, attrs).execute if @project.saved? @@ -172,7 +173,8 @@ module API :public, :visibility_level, :import_url, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(user, attrs).execute if @project.saved? @@ -234,7 +236,8 @@ module API :shared_runners_enabled, :public, :visibility_level, - :public_builds] + :public_builds, + :only_allow_merge_if_build_succeeds] attrs = map_public_to_visibility_level(attrs) authorize_admin_project authorize! :rename_project, user_project if attrs[:name].present? -- cgit v1.2.1 From ddbdf4e609c70dc6ed88860b5e1e65abde69ee94 Mon Sep 17 00:00:00 2001 From: winniehell Date: Wed, 24 Aug 2016 02:22:30 +0200 Subject: Restore get_id in ExtractsPath --- lib/extracts_path.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index a293fa2752f..a4558d157c0 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -94,9 +94,7 @@ module ExtractsPath @options = params.select {|key, value| allowed_options.include?(key) && !value.blank? } @options = HashWithIndifferentAccess.new(@options) - @id = params[:id] || params[:ref] - @id += "/" + params[:path] unless params[:path].blank? - + @id = get_id @ref, @path = extract_ref(@id) @repo = @project.repository if @options[:extended_sha1].blank? @@ -118,4 +116,13 @@ module ExtractsPath def tree @tree ||= @repo.tree(@commit.id, @path) end + + private + + # overriden in subclasses, do not remove + def get_id + id = params[:id] || params[:ref] + id += "/" + params[:path] unless params[:path].blank? + id + end end -- cgit v1.2.1 From 9b470aebb993d7a5745f0e9fc17b207fe46b16fe Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 11 Aug 2016 18:11:16 -0400 Subject: url_builder: handle project snippets --- lib/gitlab/url_builder.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index fe65c246101..99d0c28e749 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -22,6 +22,8 @@ module Gitlab note_url when WikiPage wiki_page_url + when ProjectSnippet + project_snippet_url(object) else raise NotImplementedError.new("No URL builder defined for #{object.class}") end -- cgit v1.2.1 From e43c4060b67c1996b917bc00afa72122d1d00004 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 2 Aug 2016 13:37:04 -0400 Subject: api: expose web_url for project entities This allows web hooks to have a URL back to entities without having to generate it themselves. --- lib/api/entities.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 66b85ab1793..e6bc23b97d7 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -177,6 +177,10 @@ module API # TODO (rspeicher): Deprecated; remove in 9.0 expose(:expires_at) { |snippet| nil } + + expose :web_url do |snippet, options| + Gitlab::UrlBuilder.build(snippet) + end end class ProjectEntity < Grape::Entity @@ -206,6 +210,10 @@ module API expose :user_notes_count expose :upvotes, :downvotes expose :due_date + + expose :web_url do |issue, options| + Gitlab::UrlBuilder.build(issue) + end end class ExternalIssue < Grape::Entity @@ -229,6 +237,10 @@ module API expose :user_notes_count expose :should_remove_source_branch?, as: :should_remove_source_branch expose :force_remove_source_branch?, as: :force_remove_source_branch + + expose :web_url do |merge_request, options| + Gitlab::UrlBuilder.build(merge_request) + end end class MergeRequestChanges < MergeRequest -- cgit v1.2.1 From 99c2f3b3c534386d1d8258fea23d3991695ff4fe Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 23 Aug 2016 14:54:44 -0400 Subject: api: expose wiki_page_events project hook field in the API --- lib/api/entities.rb | 2 +- lib/api/project_hooks.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 66b85ab1793..3ecdc7d448a 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -49,7 +49,7 @@ module API class ProjectHook < Hook expose :project_id, :push_events expose :issues_events, :merge_requests_events, :tag_push_events - expose :note_events, :build_events, :pipeline_events + expose :note_events, :build_events, :pipeline_events, :wiki_page_events expose :enable_ssl_verification end diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 3f63cd678e8..14f5be3b5f6 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -46,6 +46,7 @@ module API :note_events, :build_events, :pipeline_events, + :wiki_page_events, :enable_ssl_verification ] @hook = user_project.hooks.new(attrs) @@ -80,6 +81,7 @@ module API :note_events, :build_events, :pipeline_events, + :wiki_page_events, :enable_ssl_verification ] -- cgit v1.2.1 From 3c09000e18dcbf6a74ed1f749db3184e309cf081 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 10 Aug 2016 18:22:21 -0300 Subject: Does not halt the GitHub import process when an error occurs --- lib/gitlab/github_import/importer.rb | 82 +++++++++++++--------- lib/gitlab/github_import/pull_request_formatter.rb | 4 ++ 2 files changed, 53 insertions(+), 33 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index 9ddc8905bd6..86b49a5021a 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -3,12 +3,13 @@ module Gitlab class Importer include Gitlab::ShellAdapter - attr_reader :client, :project, :repo, :repo_url + attr_reader :client, :errors, :project, :repo, :repo_url def initialize(project) @project = project @repo = project.import_source @repo_url = project.import_url + @errors = [] if credentials @client = Client.new(credentials[:user]) @@ -18,8 +19,14 @@ module Gitlab end def execute - import_labels && import_milestones && import_issues && - import_pull_requests && import_wiki + import_labels + import_milestones + import_issues + import_pull_requests + import_wiki + handle_errors + + true end private @@ -28,22 +35,32 @@ module Gitlab @credentials ||= project.import_data.credentials if project.import_data end + def handle_errors + project.update_column(:import_error, errors.to_json) unless errors.empty? + end + def import_labels labels = client.labels(repo, per_page: 100) - labels.each { |raw| LabelFormatter.new(project, raw).create! } - true - rescue ActiveRecord::RecordInvalid => e - raise Projects::ImportService::Error, e.message + labels.each do |raw| + begin + LabelFormatter.new(project, raw).create! + rescue => e + errors << { type: :label, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message } + end + end end def import_milestones milestones = client.milestones(repo, state: :all, per_page: 100) - milestones.each { |raw| MilestoneFormatter.new(project, raw).create! } - true - rescue ActiveRecord::RecordInvalid => e - raise Projects::ImportService::Error, e.message + milestones.each do |raw| + begin + MilestoneFormatter.new(project, raw).create! + rescue => e + errors << { type: :milestone, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message } + end + end end def import_issues @@ -53,15 +70,15 @@ module Gitlab gh_issue = IssueFormatter.new(project, raw) if gh_issue.valid? - issue = gh_issue.create! - apply_labels(issue) - import_comments(issue) if gh_issue.has_comments? + begin + issue = gh_issue.create! + apply_labels(issue) + import_comments(issue) if gh_issue.has_comments? + rescue => e + errors << { type: :issue, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message } + end end end - - true - rescue ActiveRecord::RecordInvalid => e - raise Projects::ImportService::Error, e.message end def import_pull_requests @@ -77,14 +94,12 @@ module Gitlab apply_labels(merge_request) import_comments(merge_request) import_comments_on_diff(merge_request) - rescue ActiveRecord::RecordInvalid => e - raise Projects::ImportService::Error, e.message + rescue => e + errors << { type: :pull_request, url: Gitlab::UrlSanitizer.sanitize(pull_request.url), errors: e.message } ensure clean_up_restored_branches(pull_request) end end - - true end def restore_source_branch(pull_request) @@ -98,7 +113,7 @@ module Gitlab def remove_branch(name) project.repository.delete_branch(name) rescue Rugged::ReferenceError - nil + errors << { type: :remove_branch, name: name } end def clean_up_restored_branches(pull_request) @@ -112,9 +127,10 @@ module Gitlab issue = client.issue(repo, issuable.iid) if issue.labels.count > 0 - label_ids = issue.labels.map do |raw| - Label.find_by(LabelFormatter.new(project, raw).attributes).try(:id) - end + label_ids = issue.labels + .map { |raw| LabelFormatter.new(project, raw).attributes } + .map { |attrs| Label.find_by(attrs).try(:id) } + .compact issuable.update_attribute(:label_ids, label_ids) end @@ -132,8 +148,12 @@ module Gitlab def create_comments(issuable, comments) comments.each do |raw| - comment = CommentFormatter.new(project, raw) - issuable.notes.create!(comment.attributes) + begin + comment = CommentFormatter.new(project, raw) + issuable.notes.create!(comment.attributes) + rescue => e + errors << { type: :comment, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message } + end end end @@ -143,16 +163,12 @@ module Gitlab gitlab_shell.import_repository(project.repository_storage_path, wiki.path_with_namespace, wiki.import_url) project.update_attribute(:wiki_enabled, true) end - - true rescue Gitlab::Shell::Error => e # GitHub error message when the wiki repo has not been created, # this means that repo has wiki enabled, but have no pages. So, # we can skip the import. if e.message !~ /repository not exported/ - raise Projects::ImportService::Error, e.message - else - true + errors << { type: :wiki, errors: e.message } end end end diff --git a/lib/gitlab/github_import/pull_request_formatter.rb b/lib/gitlab/github_import/pull_request_formatter.rb index b84538a090a..04aa3664f64 100644 --- a/lib/gitlab/github_import/pull_request_formatter.rb +++ b/lib/gitlab/github_import/pull_request_formatter.rb @@ -56,6 +56,10 @@ module Gitlab end end + def url + raw_data.url + end + private def assigned? -- cgit v1.2.1 From 2986de7c8c63c0a90f750adbfd843d3b2d50e25f Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 24 Aug 2016 12:14:06 -0300 Subject: Add readable error message when remote data could not be fully imported --- lib/gitlab/github_import/importer.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index 86b49a5021a..02ffb43d89b 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -36,7 +36,12 @@ module Gitlab end def handle_errors - project.update_column(:import_error, errors.to_json) unless errors.empty? + return unless errors.any? + + project.update_column(:import_error, { + message: 'The remote data could not be fully imported.', + errors: errors + }.to_json) end def import_labels -- cgit v1.2.1 From 170885edd6f3ea52792511586778e0dce8021cf7 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 18 Aug 2016 17:06:33 -0700 Subject: Add Sentry logging to API calls Closes #21043 --- lib/api/api.rb | 12 ++---------- lib/api/helpers.rb | 32 ++++++++++++++++++++++++++++++++ lib/ci/api/api.rb | 12 ++---------- 3 files changed, 36 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/lib/api/api.rb b/lib/api/api.rb index 6b8bfbbdae6..ecbd5a6e2fa 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -18,22 +18,14 @@ module API end rescue_from :all do |exception| - # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60 - # why is this not wrapped in something reusable? - trace = exception.backtrace - - message = "\n#{exception.class} (#{exception.message}):\n" - message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) - message << " " << trace.join("\n ") - - API.logger.add Logger::FATAL, message - rack_response({ 'message' => '500 Internal Server Error' }.to_json, 500) + handle_api_exception(exception) end format :json content_type :txt, "text/plain" # Ensure the namespace is right, otherwise we might load Grape::API::Helpers + helpers ::SentryHelper helpers ::API::Helpers mount ::API::AccessRequests diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index d0469d6602d..da4b1bf9902 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -279,6 +279,24 @@ module API error!({ 'message' => message }, status) end + def handle_api_exception(exception) + if sentry_enabled? && report_exception?(exception) + define_params_for_grape_middleware + sentry_context + Raven.capture_exception(exception) + end + + # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60 + trace = exception.backtrace + + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << trace.join("\n ") + + API.logger.add Logger::FATAL, message + rack_response({ 'message' => '500 Internal Server Error' }.to_json, 500) + end + # Projects helpers def filter_projects(projects) @@ -419,5 +437,19 @@ module API Entities::Issue end end + + # The Grape Error Middleware only has access to env but no params. We workaround this by + # defining a method that returns the right value. + def define_params_for_grape_middleware + self.define_singleton_method(:params) { Rack::Request.new(env).params.symbolize_keys } + end + + # We could get a Grape or a standard Ruby exception. We should only report anything that + # is clearly an error. + def report_exception?(exception) + return true unless exception.respond_to?(:status) + + exception.status == 500 + end end end diff --git a/lib/ci/api/api.rb b/lib/ci/api/api.rb index 17bb99a2ae5..a6b9beecded 100644 --- a/lib/ci/api/api.rb +++ b/lib/ci/api/api.rb @@ -9,22 +9,14 @@ module Ci end rescue_from :all do |exception| - # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60 - # why is this not wrapped in something reusable? - trace = exception.backtrace - - message = "\n#{exception.class} (#{exception.message}):\n" - message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) - message << " " << trace.join("\n ") - - API.logger.add Logger::FATAL, message - rack_response({ 'message' => '500 Internal Server Error' }, 500) + handle_api_exception(exception) end content_type :txt, 'text/plain' content_type :json, 'application/json' format :json + helpers ::SentryHelper helpers ::Ci::API::Helpers helpers ::API::Helpers helpers Gitlab::CurrentSettings -- cgit v1.2.1 From bba85773519e972d036a933b1f054b6c76050c5f Mon Sep 17 00:00:00 2001 From: Drew Blessing Date: Tue, 26 Jul 2016 16:48:51 -0500 Subject: Add two factor recovery endpoint to internal API --- lib/api/internal.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'lib') diff --git a/lib/api/internal.rb b/lib/api/internal.rb index d8e9ac406c4..5b54c11ef62 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -101,6 +101,31 @@ module API {} end end + + post '/two_factor_recovery_codes' do + status 200 + + key = Key.find(params[:key_id]) + user = key.user + + # Make sure this isn't a deploy key + unless key.type.nil? + return { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' } + end + + unless user.present? + return { success: false, message: 'Could not find a user for the given key' } + end + + unless user.two_factor_enabled? + return { success: false, message: 'Two-factor authentication is not enabled for this user' } + end + + codes = user.generate_otp_backup_codes! + user.save! + + { success: true, recovery_codes: codes } + end end end end -- cgit v1.2.1 From 44eb3197a9c30503a00384b3d688b64558b80397 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 23 Aug 2016 16:37:14 +0100 Subject: Handle non-UTF-8 conflicts gracefully These can't be resolved in the UI because if they aren't in a UTF-8 compatible encoding, they can't be rendered as JSON. Even if they could, we would be implicitly changing the file encoding anyway, which seems like a bad idea. --- lib/gitlab/conflict/parser.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/conflict/parser.rb b/lib/gitlab/conflict/parser.rb index 6eccded7872..2d4d55daeeb 100644 --- a/lib/gitlab/conflict/parser.rb +++ b/lib/gitlab/conflict/parser.rb @@ -13,10 +13,19 @@ module Gitlab class UnmergeableFile < ParserError end + class UnsupportedEncoding < ParserError + end + def parse(text, our_path:, their_path:, parent_file: nil) raise UnmergeableFile if text.blank? # Typically a binary file raise UnmergeableFile if text.length > 102400 + begin + text.to_json + rescue Encoding::UndefinedConversionError + raise UnsupportedEncoding + end + line_obj_index = 0 line_old = 1 line_new = 1 -- cgit v1.2.1 From 4c8e9a8d27c34fe97216e12d17782f982818fb5c Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 18 Aug 2016 15:00:20 +0200 Subject: Remove gitorious --- lib/gitlab/current_settings.rb | 2 +- lib/gitlab/gitorious_import.rb | 5 ---- lib/gitlab/gitorious_import/client.rb | 29 --------------------- lib/gitlab/gitorious_import/project_creator.rb | 27 -------------------- lib/gitlab/gitorious_import/repository.rb | 35 -------------------------- lib/gitlab/import_sources.rb | 13 +++++----- 6 files changed, 7 insertions(+), 104 deletions(-) delete mode 100644 lib/gitlab/gitorious_import.rb delete mode 100644 lib/gitlab/gitorious_import/client.rb delete mode 100644 lib/gitlab/gitorious_import/project_creator.rb delete mode 100644 lib/gitlab/gitorious_import/repository.rb (limited to 'lib') diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 27acd817e51..12fbb78c53e 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -41,7 +41,7 @@ module Gitlab default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], domain_whitelist: Settings.gitlab['domain_whitelist'], - import_sources: %w[github bitbucket gitlab gitorious google_code fogbugz git gitlab_project], + import_sources: %w[github bitbucket gitlab 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/gitorious_import.rb b/lib/gitlab/gitorious_import.rb deleted file mode 100644 index 8d0132a744c..00000000000 --- a/lib/gitlab/gitorious_import.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Gitlab - module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - end -end diff --git a/lib/gitlab/gitorious_import/client.rb b/lib/gitlab/gitorious_import/client.rb deleted file mode 100644 index 99fe5bdebfc..00000000000 --- a/lib/gitlab/gitorious_import/client.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Gitlab - module GitoriousImport - class Client - attr_reader :repo_list - - def initialize(repo_list) - @repo_list = repo_list - end - - def authorize_url(redirect_uri) - "#{GITORIOUS_HOST}/gitlab-import?callback_url=#{redirect_uri}" - end - - def repos - @repos ||= repo_names.map { |full_name| GitoriousImport::Repository.new(full_name) } - end - - def repo(id) - repos.find { |repo| repo.id == id } - end - - private - - def repo_names - repo_list.to_s.split(',').map(&:strip).reject(&:blank?) - end - end - end -end diff --git a/lib/gitlab/gitorious_import/project_creator.rb b/lib/gitlab/gitorious_import/project_creator.rb deleted file mode 100644 index 8e22aa9286d..00000000000 --- a/lib/gitlab/gitorious_import/project_creator.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Gitlab - module GitoriousImport - class ProjectCreator - attr_reader :repo, :namespace, :current_user - - def initialize(repo, namespace, current_user) - @repo = repo - @namespace = namespace - @current_user = current_user - end - - def execute - ::Projects::CreateService.new( - current_user, - name: repo.name, - path: repo.path, - description: repo.description, - namespace_id: namespace.id, - visibility_level: Gitlab::VisibilityLevel::PUBLIC, - import_type: "gitorious", - import_source: repo.full_name, - import_url: repo.import_url - ).execute - end - end - end -end diff --git a/lib/gitlab/gitorious_import/repository.rb b/lib/gitlab/gitorious_import/repository.rb deleted file mode 100644 index c88f1ae358d..00000000000 --- a/lib/gitlab/gitorious_import/repository.rb +++ /dev/null @@ -1,35 +0,0 @@ -module Gitlab - module GitoriousImport - Repository = Struct.new(:full_name) do - def id - Digest::SHA1.hexdigest(full_name) - end - - def namespace - segments.first - end - - def path - segments.last - end - - def name - path.titleize - end - - def description - "" - end - - def import_url - "#{GITORIOUS_HOST}/#{full_name}.git" - end - - private - - def segments - full_name.split('/') - end - end - end -end diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index 59a05411fe9..94261b7eeed 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -14,13 +14,12 @@ module Gitlab def options { - 'GitHub' => 'github', - 'Bitbucket' => 'bitbucket', - 'GitLab.com' => 'gitlab', - 'Gitorious.org' => 'gitorious', - 'Google Code' => 'google_code', - 'FogBugz' => 'fogbugz', - 'Repo by URL' => 'git', + 'GitHub' => 'github', + 'Bitbucket' => 'bitbucket', + 'GitLab.com' => 'gitlab', + 'Google Code' => 'google_code', + 'FogBugz' => 'fogbugz', + 'Repo by URL' => 'git', 'GitLab export' => 'gitlab_project' } end -- cgit v1.2.1 From 4a3d1a5838685ff95a6c9416bb3e453ad143f50d Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Wed, 24 Aug 2016 15:20:06 +0100 Subject: Handle case where conflicts aren't on disk yet --- lib/gitlab/conflict/file.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index 0a1fd27ced5..dff9e29c6a5 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -181,6 +181,17 @@ module Gitlab sections: sections } end + + # Don't try to print merge_request or repository. + def inspect + instance_variables = [:merge_file_result, :their_path, :our_path, :our_mode].map do |instance_variable| + value = instance_variable_get("@#{instance_variable}") + + "#{instance_variable}=\"#{value}\"" + end + + "#<#{self.class} #{instance_variables.join(' ')}>" + end end end end -- cgit v1.2.1 From a5079f68e6aa3de4c6e430f96f7bf482bc4c492a Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Mon, 22 Aug 2016 17:56:46 +0200 Subject: Adds response mime type to transaction metric action when it's not HTML --- lib/gitlab/metrics/rack_middleware.rb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/metrics/rack_middleware.rb b/lib/gitlab/metrics/rack_middleware.rb index b4493bf44d2..01c96a6fe96 100644 --- a/lib/gitlab/metrics/rack_middleware.rb +++ b/lib/gitlab/metrics/rack_middleware.rb @@ -4,6 +4,17 @@ module Gitlab class RackMiddleware CONTROLLER_KEY = 'action_controller.instance' ENDPOINT_KEY = 'api.endpoint' + CONTENT_TYPES = { + 'text/html' => :html, + 'text/plain' => :txt, + 'application/json' => :json, + 'text/js' => :js, + 'application/atom+xml' => :atom, + 'image/png' => :png, + 'image/jpeg' => :jpeg, + 'image/gif' => :gif, + 'image/svg+xml' => :svg + } def initialize(app) @app = app @@ -46,8 +57,15 @@ module Gitlab end def tag_controller(trans, env) - controller = env[CONTROLLER_KEY] - trans.action = "#{controller.class.name}##{controller.action_name}" + controller = env[CONTROLLER_KEY] + action = "#{controller.class.name}##{controller.action_name}" + suffix = CONTENT_TYPES[controller.content_type] + + if suffix && suffix != :html + action += ".#{suffix}" + end + + trans.action = action end def tag_endpoint(trans, env) -- cgit v1.2.1 From a15e9f02b81f26cc07536d1458a576aede861529 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 11 Aug 2016 15:47:03 -0500 Subject: Reduce contributions calendar data payload --- lib/gitlab/contributions_calendar.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb index 9dc2602867e..bd681f03173 100644 --- a/lib/gitlab/contributions_calendar.rb +++ b/lib/gitlab/contributions_calendar.rb @@ -23,7 +23,6 @@ module Gitlab dates.each do |date| date_id = date.to_time.to_i.to_s - @timestamps[date_id] = 0 day_events = events.find { |day_events| day_events["date"] == date } if day_events -- cgit v1.2.1