summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/api.rb14
-rw-r--r--lib/api/award_emoji.rb6
-rw-r--r--lib/api/broadcast_messages.rb99
-rw-r--r--lib/api/commit_statuses.rb2
-rw-r--r--lib/api/entities.rb57
-rw-r--r--lib/api/groups.rb4
-rw-r--r--lib/api/helpers.rb44
-rw-r--r--lib/api/internal.rb29
-rw-r--r--lib/api/issues.rb34
-rw-r--r--lib/api/merge_request_diffs.rb45
-rw-r--r--lib/api/project_hooks.rb2
-rw-r--r--lib/api/projects.rb17
-rw-r--r--lib/api/users.rb2
-rw-r--r--lib/backup/repository.rb2
-rw-r--r--lib/banzai/filter/abstract_reference_filter.rb10
-rw-r--r--lib/banzai/filter/commit_range_reference_filter.rb2
-rw-r--r--lib/banzai/filter/commit_reference_filter.rb4
-rw-r--r--lib/banzai/filter/label_reference_filter.rb5
-rw-r--r--lib/banzai/filter/milestone_reference_filter.rb4
-rw-r--r--lib/banzai/filter/reference_filter.rb2
-rw-r--r--lib/banzai/reference_parser/base_parser.rb2
-rw-r--r--lib/ci/api/api.rb12
-rw-r--r--lib/extracts_path.rb13
-rw-r--r--lib/gitlab/badge/coverage/report.rb4
-rw-r--r--lib/gitlab/ci/config/node/hidden.rb (renamed from lib/gitlab/ci/config/node/hidden_job.rb)3
-rw-r--r--lib/gitlab/ci/config/node/jobs.rb2
-rw-r--r--lib/gitlab/conflict/file.rb11
-rw-r--r--lib/gitlab/conflict/parser.rb9
-rw-r--r--lib/gitlab/contributions_calendar.rb1
-rw-r--r--lib/gitlab/current_settings.rb3
-rw-r--r--lib/gitlab/diff/file_collection/merge_request_diff.rb (renamed from lib/gitlab/diff/file_collection/merge_request.rb)16
-rw-r--r--lib/gitlab/email/handler.rb3
-rw-r--r--lib/gitlab/github_import/importer.rb93
-rw-r--r--lib/gitlab/github_import/issue_formatter.rb6
-rw-r--r--lib/gitlab/github_import/milestone_formatter.rb36
-rw-r--r--lib/gitlab/github_import/project_creator.rb14
-rw-r--r--lib/gitlab/github_import/pull_request_formatter.rb15
-rw-r--r--lib/gitlab/gitorious_import.rb5
-rw-r--r--lib/gitlab/gitorious_import/client.rb29
-rw-r--r--lib/gitlab/gitorious_import/project_creator.rb27
-rw-r--r--lib/gitlab/gitorious_import/repository.rb35
-rw-r--r--lib/gitlab/import_export/import_export.yml7
-rw-r--r--lib/gitlab/import_sources.rb13
-rw-r--r--lib/gitlab/metrics/rack_middleware.rb22
-rw-r--r--lib/gitlab/middleware/rails_queue_duration.rb2
-rw-r--r--lib/gitlab/popen.rb4
-rw-r--r--lib/gitlab/project_search_results.rb5
-rw-r--r--lib/gitlab/search_results.rb9
-rw-r--r--lib/gitlab/sentry.rb27
-rw-r--r--lib/gitlab/snippet_search_results.rb4
-rw-r--r--lib/gitlab/url_builder.rb2
51 files changed, 501 insertions, 317 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 6b8bfbbdae6..e14464c1b0d 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -18,27 +18,20 @@ 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
mount ::API::AwardEmoji
mount ::API::Branches
+ mount ::API::BroadcastMessages
mount ::API::Builds
mount ::API::CommitStatuses
mount ::API::Commits
@@ -75,5 +68,6 @@ module API
mount ::API::Triggers
mount ::API::Users
mount ::API::Variables
+ mount ::API::MergeRequestDiffs
end
end
diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb
index 2efe7e3adf3..7c22b17e4e5 100644
--- a/lib/api/award_emoji.rb
+++ b/lib/api/award_emoji.rb
@@ -54,7 +54,7 @@ module API
post endpoint do
required_attributes! [:name]
- not_found!('Award Emoji') unless can_read_awardable?
+ not_found!('Award Emoji') unless can_read_awardable? && can_award_awardable?
award = awardable.create_award_emoji(params[:name], current_user)
@@ -92,6 +92,10 @@ module API
can?(current_user, ability, awardable)
end
+ def can_award_awardable?
+ awardable.user_can_award?(current_user, params[:name])
+ end
+
def awardable
@awardable ||=
begin
diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb
new file mode 100644
index 00000000000..fb2a4148011
--- /dev/null
+++ b/lib/api/broadcast_messages.rb
@@ -0,0 +1,99 @@
+module API
+ class BroadcastMessages < Grape::API
+ before { authenticate! }
+ before { authenticated_as_admin! }
+
+ resource :broadcast_messages do
+ helpers do
+ def find_message
+ BroadcastMessage.find(params[:id])
+ end
+ end
+
+ desc 'Get all broadcast messages' do
+ detail 'This feature was introduced in GitLab 8.12.'
+ success Entities::BroadcastMessage
+ end
+ params do
+ optional :page, type: Integer, desc: 'Current page number'
+ optional :per_page, type: Integer, desc: 'Number of messages per page'
+ end
+ get do
+ messages = BroadcastMessage.all
+
+ present paginate(messages), with: Entities::BroadcastMessage
+ end
+
+ desc 'Create a broadcast message' do
+ detail 'This feature was introduced in GitLab 8.12.'
+ success Entities::BroadcastMessage
+ end
+ params do
+ requires :message, type: String, desc: 'Message to display'
+ optional :starts_at, type: DateTime, desc: 'Starting time', default: -> { Time.zone.now }
+ optional :ends_at, type: DateTime, desc: 'Ending time', default: -> { 1.hour.from_now }
+ optional :color, type: String, desc: 'Background color'
+ optional :font, type: String, desc: 'Foreground color'
+ end
+ post do
+ create_params = declared(params, include_missing: false).to_h
+ message = BroadcastMessage.create(create_params)
+
+ if message.persisted?
+ present message, with: Entities::BroadcastMessage
+ else
+ render_validation_error!(message)
+ end
+ end
+
+ desc 'Get a specific broadcast message' do
+ detail 'This feature was introduced in GitLab 8.12.'
+ success Entities::BroadcastMessage
+ end
+ params do
+ requires :id, type: Integer, desc: 'Broadcast message ID'
+ end
+ get ':id' do
+ message = find_message
+
+ present message, with: Entities::BroadcastMessage
+ end
+
+ desc 'Update a broadcast message' do
+ detail 'This feature was introduced in GitLab 8.12.'
+ success Entities::BroadcastMessage
+ end
+ params do
+ requires :id, type: Integer, desc: 'Broadcast message ID'
+ optional :message, type: String, desc: 'Message to display'
+ optional :starts_at, type: DateTime, desc: 'Starting time'
+ optional :ends_at, type: DateTime, desc: 'Ending time'
+ optional :color, type: String, desc: 'Background color'
+ optional :font, type: String, desc: 'Foreground color'
+ end
+ put ':id' do
+ message = find_message
+ update_params = declared(params, include_missing: false).to_h
+
+ if message.update(update_params)
+ present message, with: Entities::BroadcastMessage
+ else
+ render_validation_error!(message)
+ end
+ end
+
+ desc 'Delete a broadcast message' do
+ detail 'This feature was introduced in GitLab 8.12.'
+ success Entities::BroadcastMessage
+ end
+ params do
+ requires :id, type: Integer, desc: 'Broadcast message ID'
+ end
+ delete ':id' do
+ message = find_message
+
+ present message.destroy, with: Entities::BroadcastMessage
+ end
+ end
+ end
+end
diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb
index 4df6ca8333e..5e3c9563703 100644
--- a/lib/api/commit_statuses.rb
+++ b/lib/api/commit_statuses.rb
@@ -64,7 +64,7 @@ module API
ref = branches.first
end
- pipeline = @project.ensure_pipeline(commit.sha, ref, current_user)
+ pipeline = @project.ensure_pipeline(ref, commit.sha, current_user)
name = params[:name] || params[:context]
status = GenericCommitStatus.running_or_pending.find_by(pipeline: pipeline, name: name, ref: params[:ref])
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 54ce2dcfa57..3faba79415b 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
@@ -76,20 +76,29 @@ module API
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, :container_registry_enabled
+ expose :container_registry_enabled
+
+ # Expose old field names with the new permissions methods to keep API compatible
+ expose(:issues_enabled) { |project, options| project.feature_available?(:issues, options[:user]) }
+ expose(:merge_requests_enabled) { |project, options| project.feature_available?(:merge_requests, options[:user]) }
+ expose(:wiki_enabled) { |project, options| project.feature_available?(:wiki, options[:user]) }
+ expose(:builds_enabled) { |project, options| project.feature_available?(:builds, options[:user]) }
+ expose(:snippets_enabled) { |project, options| project.feature_available?(:snippets, options[:user]) }
+
expose :created_at, :last_activity_at
- expose :shared_runners_enabled
+ expose :shared_runners_enabled, :lfs_enabled
expose :creator_id
expose :namespace
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
expose :avatar_url
expose :star_count, :forks_count
- expose :open_issues_count, if: lambda { |project, options| project.issues_enabled? && project.default_issues_tracker? }
+ expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:user]) && project.default_issues_tracker? }
expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] }
expose :public_builds
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
@@ -177,6 +186,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 +219,11 @@ module API
expose :user_notes_count
expose :upvotes, :downvotes
expose :due_date
+ expose :confidential
+
+ expose :web_url do |issue, options|
+ Gitlab::UrlBuilder.build(issue)
+ end
end
class ExternalIssue < Grape::Entity
@@ -223,12 +241,18 @@ module API
expose :milestone, using: Entities::Milestone
expose :merge_when_build_succeeds
expose :merge_status
+ expose :diff_head_sha, as: :sha
+ expose :merge_commit_sha
expose :subscribed do |merge_request, options|
merge_request.subscribed?(options[:current_user])
end
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
@@ -237,6 +261,19 @@ 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
+ end
+
+ class MergeRequestDiffFull < MergeRequestDiff
+ expose :commits, using: Entities::RepoCommit
+
+ expose :diffs, using: Entities::RepoDiff do |compare, _|
+ compare.raw_diffs(all_diffs: true).to_a
+ end
+ end
+
class SSHKey < Grape::Entity
expose :id, :title, :key, :created_at
end
@@ -514,13 +551,12 @@ module API
expose :duration
end
- class Environment < Grape::Entity
+ class EnvironmentBasic < Grape::Entity
expose :id, :name, :external_url
- expose :project, using: Entities::Project
end
- class EnvironmentBasic < Grape::Entity
- expose :id, :name, :external_url
+ class Environment < EnvironmentBasic
+ expose :project, using: Entities::Project
end
class Deployment < Grape::Entity
@@ -549,5 +585,10 @@ module API
class Template < Grape::Entity
expose :name, :content
end
+
+ class BroadcastMessage < Grape::Entity
+ expose :id, :message, :starts_at, :ends_at, :color, :font
+ expose :active?, as: :active
+ end
end
end
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 9d8b8d737a9..d2df77238d5 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -30,7 +30,7 @@ module API
# Example Request:
# POST /groups
post do
- authorize! :create_group, current_user
+ authorize! :create_group
required_attributes! [:name, :path]
attrs = attributes_for_keys [:name, :path, :description, :visibility_level]
@@ -97,7 +97,7 @@ module API
group = find_group(params[:id])
projects = GroupProjectsFinder.new(group).execute(current_user)
projects = paginate projects
- present projects, with: Entities::Project
+ present projects, with: Entities::Project, user: current_user
end
# Transfer a project to the Group namespace
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index d0469d6602d..6a20ba95a79 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -129,7 +129,7 @@ module API
forbidden! unless current_user.is_admin?
end
- def authorize!(action, subject)
+ def authorize!(action, subject = nil)
forbidden! unless can?(current_user, action, subject)
end
@@ -148,7 +148,7 @@ module API
end
def can?(object, action, subject)
- abilities.allowed?(object, action, subject)
+ Ability.allowed?(object, action, subject)
end
# Checks the occurrences of required attributes, each attribute must be present in the params hash
@@ -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)
@@ -390,14 +408,6 @@ module API
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
@@ -419,5 +429,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/api/internal.rb b/lib/api/internal.rb
index d8e9ac406c4..6e6efece7c4 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -101,6 +101,35 @@ module API
{}
end
end
+
+ post '/two_factor_recovery_codes' do
+ status 200
+
+ key = Key.find_by(id: params[:key_id])
+
+ unless key
+ return { 'success' => false, 'message' => 'Could not find the given key' }
+ end
+
+ if key.is_a?(DeployKey)
+ return { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' }
+ end
+
+ user = key.user
+
+ unless user
+ 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
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 077258faee1..556684187d8 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -140,12 +140,13 @@ module API
# labels (optional) - The labels of an issue
# created_at (optional) - Date time string, ISO 8601 formatted
# due_date (optional) - Date time string in the format YEAR-MONTH-DAY
+ # confidential (optional) - Boolean parameter if the issue should be confidential
# Example Request:
# POST /projects/:id/issues
post ':id/issues' do
required_attributes! [:title]
- keys = [:title, :description, :assignee_id, :milestone_id, :due_date]
+ keys = [:title, :description, :assignee_id, :milestone_id, :due_date, :confidential]
keys << :created_at if current_user.admin? || user_project.owner == current_user
attrs = attributes_for_keys(keys)
@@ -154,21 +155,19 @@ module API
render_api_error!({ labels: errors }, 400)
end
- project = user_project
+ attrs[:labels] = params[:labels] if params[:labels]
- issue = ::Issues::CreateService.new(project, current_user, attrs.merge(request: request, api: true)).execute
+ # Convert and filter out invalid confidential flags
+ attrs['confidential'] = to_boolean(attrs['confidential'])
+ attrs.delete('confidential') if attrs['confidential'].nil?
+
+ issue = ::Issues::CreateService.new(user_project, current_user, attrs.merge(request: request, api: true)).execute
if issue.spam?
render_api_error!({ error: 'Spam detected' }, 400)
end
if issue.valid?
- # Find or create labels and attach to issue. Labels are valid because
- # we already checked its name, so there can't be an error here
- if params[:labels].present?
- issue.add_labels_by_names(params[:labels].split(','))
- end
-
present issue, with: Entities::Issue, current_user: current_user
else
render_validation_error!(issue)
@@ -188,12 +187,13 @@ module API
# state_event (optional) - The state event of an issue (close|reopen)
# updated_at (optional) - Date time string, ISO 8601 formatted
# due_date (optional) - Date time string in the format YEAR-MONTH-DAY
+ # confidential (optional) - Boolean parameter if the issue should be confidential
# Example Request:
# PUT /projects/:id/issues/:issue_id
put ':id/issues/:issue_id' do
issue = user_project.issues.find(params[:issue_id])
authorize! :update_issue, issue
- keys = [:title, :description, :assignee_id, :milestone_id, :state_event, :due_date]
+ keys = [:title, :description, :assignee_id, :milestone_id, :state_event, :due_date, :confidential]
keys << :updated_at if current_user.admin? || user_project.owner == current_user
attrs = attributes_for_keys(keys)
@@ -202,17 +202,15 @@ module API
render_api_error!({ labels: errors }, 400)
end
+ attrs[:labels] = params[:labels] if params[:labels]
+
+ # Convert and filter out invalid confidential flags
+ attrs['confidential'] = to_boolean(attrs['confidential'])
+ attrs.delete('confidential') if attrs['confidential'].nil?
+
issue = ::Issues::UpdateService.new(user_project, current_user, attrs).execute(issue)
if issue.valid?
- # Find or create labels and attach to issue. Labels are valid because
- # we already checked its name, so there can't be an error here
- if params[:labels] && can?(current_user, :admin_issue, user_project)
- issue.remove_labels
- # Create and add labels to the new created issue
- issue.add_labels_by_names(params[:labels].split(','))
- end
-
present issue, with: Entities::Issue, current_user: current_user
else
render_validation_error!(issue)
diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb
new file mode 100644
index 00000000000..07435d78468
--- /dev/null
+++ b/lib/api/merge_request_diffs.rb
@@ -0,0 +1,45 @@
+module API
+ # MergeRequestDiff API
+ class MergeRequestDiffs < Grape::API
+ before { authenticate! }
+
+ resource :projects do
+ 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: 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
+ 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
+
+ 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
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
]
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 60cfc103afd..a1fd598414a 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -51,7 +51,7 @@ module API
@projects = current_user.viewable_starred_projects
@projects = filter_projects(@projects)
@projects = paginate @projects
- present @projects, with: Entities::Project
+ present @projects, with: Entities::Project, user: current_user
end
# Get all projects for admin user
@@ -105,6 +105,7 @@ module API
# visibility_level (optional) - 0 by default
# import_url (optional)
# public_builds (optional)
+ # lfs_enabled (optional)
# Example Request
# POST /projects
post do
@@ -123,7 +124,9 @@ module API
:public,
:visibility_level,
:import_url,
- :public_builds]
+ :public_builds,
+ :only_allow_merge_if_build_succeeds,
+ :lfs_enabled]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(current_user, attrs).execute
if @project.saved?
@@ -155,6 +158,7 @@ module API
# visibility_level (optional)
# import_url (optional)
# public_builds (optional)
+ # lfs_enabled (optional)
# Example Request
# POST /projects/user/:user_id
post "user/:user_id" do
@@ -172,7 +176,9 @@ module API
:public,
:visibility_level,
:import_url,
- :public_builds]
+ :public_builds,
+ :only_allow_merge_if_build_succeeds,
+ :lfs_enabled]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(user, attrs).execute
if @project.saved?
@@ -218,6 +224,7 @@ module API
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - visibility level of a project
# public_builds (optional)
+ # lfs_enabled (optional)
# Example Request
# PUT /projects/:id
put ':id' do
@@ -234,7 +241,9 @@ module API
:shared_runners_enabled,
:public,
:visibility_level,
- :public_builds]
+ :public_builds,
+ :only_allow_merge_if_build_succeeds,
+ :lfs_enabled]
attrs = map_public_to_visibility_level(attrs)
authorize_admin_project
authorize! :rename_project, user_project if attrs[:name].present?
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 8a376d3c2a3..c440305ff0f 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -327,7 +327,7 @@ module API
# Example Request:
# GET /user
get do
- present @current_user, with: Entities::UserLogin
+ present @current_user, with: Entities::UserFull
end
# Get currently authenticated user's keys
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index f117fc3d37d..9fcd9a3f999 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -55,7 +55,7 @@ module Backup
bk_repos_path = File.join(path, '..', 'repositories.old.' + Time.now.to_i.to_s)
FileUtils.mv(path, bk_repos_path)
# This is expected from gitlab:check
- FileUtils.mkdir_p(path, mode: 2770)
+ FileUtils.mkdir_p(path, mode: 02770)
end
Project.find_each(batch_size: 1000) do |project|
diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb
index d77a5e3ff09..16cd774c81a 100644
--- a/lib/banzai/filter/abstract_reference_filter.rb
+++ b/lib/banzai/filter/abstract_reference_filter.rb
@@ -18,10 +18,6 @@ module Banzai
@object_sym ||= object_name.to_sym
end
- def self.object_class_title
- @object_title ||= object_class.name.titleize
- end
-
# Public: Find references in text (like `!123` for merge requests)
#
# AnyReferenceFilter.references_in(text) do |match, id, project_ref, matches|
@@ -49,10 +45,6 @@ module Banzai
self.class.object_sym
end
- def object_class_title
- self.class.object_class_title
- end
-
def references_in(*args, &block)
self.class.references_in(*args, &block)
end
@@ -198,7 +190,7 @@ module Banzai
end
def object_link_title(object)
- "#{object_class_title}: #{object.title}"
+ object.title
end
def object_link_text(object, matches)
diff --git a/lib/banzai/filter/commit_range_reference_filter.rb b/lib/banzai/filter/commit_range_reference_filter.rb
index bbb88c979cc..4358bf45549 100644
--- a/lib/banzai/filter/commit_range_reference_filter.rb
+++ b/lib/banzai/filter/commit_range_reference_filter.rb
@@ -35,7 +35,7 @@ module Banzai
end
def object_link_title(range)
- range.reference_title
+ nil
end
end
end
diff --git a/lib/banzai/filter/commit_reference_filter.rb b/lib/banzai/filter/commit_reference_filter.rb
index 2ce1816672b..a26dd09c25a 100644
--- a/lib/banzai/filter/commit_reference_filter.rb
+++ b/lib/banzai/filter/commit_reference_filter.rb
@@ -28,10 +28,6 @@ module Banzai
only_path: context[:only_path])
end
- def object_link_title(commit)
- commit.link_title
- end
-
def object_link_text_extras(object, matches)
extras = super
diff --git a/lib/banzai/filter/label_reference_filter.rb b/lib/banzai/filter/label_reference_filter.rb
index e258dc8e2bf..8f262ef3d8d 100644
--- a/lib/banzai/filter/label_reference_filter.rb
+++ b/lib/banzai/filter/label_reference_filter.rb
@@ -70,6 +70,11 @@ module Banzai
def unescape_html_entities(text)
CGI.unescapeHTML(text.to_s)
end
+
+ def object_link_title(object)
+ # use title of wrapped element instead
+ nil
+ end
end
end
end
diff --git a/lib/banzai/filter/milestone_reference_filter.rb b/lib/banzai/filter/milestone_reference_filter.rb
index ca686c87d97..58fff496d00 100644
--- a/lib/banzai/filter/milestone_reference_filter.rb
+++ b/lib/banzai/filter/milestone_reference_filter.rb
@@ -59,6 +59,10 @@ module Banzai
html_safe
end
end
+
+ def object_link_title(object)
+ nil
+ end
end
end
end
diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb
index bf058241cda..2d221290f7e 100644
--- a/lib/banzai/filter/reference_filter.rb
+++ b/lib/banzai/filter/reference_filter.rb
@@ -52,7 +52,7 @@ module Banzai
end
def reference_class(type)
- "gfm gfm-#{type}"
+ "gfm gfm-#{type} has-tooltip"
end
# Ensure that a :project key exists in context
diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb
index 6cf218aaa0d..e8e03e4a98f 100644
--- a/lib/banzai/reference_parser/base_parser.rb
+++ b/lib/banzai/reference_parser/base_parser.rb
@@ -211,7 +211,7 @@ module Banzai
end
def can?(user, permission, subject)
- Ability.abilities.allowed?(user, permission, subject)
+ Ability.allowed?(user, permission, subject)
end
def find_projects_for_hash_keys(hash)
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
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
diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb
index 95d925dc7f3..9a0482306b7 100644
--- a/lib/gitlab/badge/coverage/report.rb
+++ b/lib/gitlab/badge/coverage/report.rb
@@ -12,9 +12,7 @@ module Gitlab
@ref = ref
@job = job
- @pipeline = @project.pipelines
- .latest_successful_for(@ref)
- .first
+ @pipeline = @project.pipelines.latest_successful_for(@ref)
end
def entity
diff --git a/lib/gitlab/ci/config/node/hidden_job.rb b/lib/gitlab/ci/config/node/hidden.rb
index 073044b66f8..fe4ee8a7fc6 100644
--- a/lib/gitlab/ci/config/node/hidden_job.rb
+++ b/lib/gitlab/ci/config/node/hidden.rb
@@ -5,11 +5,10 @@ module Gitlab
##
# Entry that represents a hidden CI/CD job.
#
- class HiddenJob < Entry
+ class Hidden < Entry
include Validatable
validations do
- validates :config, type: Hash
validates :config, presence: true
end
diff --git a/lib/gitlab/ci/config/node/jobs.rb b/lib/gitlab/ci/config/node/jobs.rb
index 51683c82ceb..a1a26d4fd8f 100644
--- a/lib/gitlab/ci/config/node/jobs.rb
+++ b/lib/gitlab/ci/config/node/jobs.rb
@@ -30,7 +30,7 @@ module Gitlab
def compose!
@config.each do |name, config|
- node = hidden?(name) ? Node::HiddenJob : Node::Job
+ node = hidden?(name) ? Node::Hidden : Node::Job
factory = Node::Factory.new(node)
.value(config || {})
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
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
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
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 735331df66c..12fbb78c53e 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -30,6 +30,7 @@ module Gitlab
signup_enabled: Settings.gitlab['signup_enabled'],
signin_enabled: Settings.gitlab['signin_enabled'],
gravatar_enabled: Settings.gravatar['enabled'],
+ koding_enabled: false,
sign_in_text: nil,
after_sign_up_text: nil,
help_page_text: nil,
@@ -40,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/diff/file_collection/merge_request.rb b/lib/gitlab/diff/file_collection/merge_request_diff.rb
index 4f946908e2f..36348b33943 100644
--- a/lib/gitlab/diff/file_collection/merge_request.rb
+++ b/lib/gitlab/diff/file_collection/merge_request_diff.rb
@@ -1,14 +1,14 @@
module Gitlab
module Diff
module FileCollection
- class MergeRequest < Base
- def initialize(merge_request, diff_options:)
- @merge_request = merge_request
+ class MergeRequestDiff < Base
+ def initialize(merge_request_diff, diff_options:)
+ @merge_request_diff = merge_request_diff
- super(merge_request,
- project: merge_request.project,
+ super(merge_request_diff,
+ project: merge_request_diff.project,
diff_options: diff_options,
- diff_refs: merge_request.diff_refs)
+ diff_refs: merge_request_diff.diff_refs)
end
def diff_files
@@ -61,11 +61,11 @@ module Gitlab
end
def cacheable?
- @merge_request.merge_request_diff.present?
+ @merge_request_diff.present?
end
def cache_key
- [@merge_request.merge_request_diff, 'highlighted-diff-files', diff_options]
+ [@merge_request_diff, 'highlighted-diff-files', diff_options]
end
end
end
diff --git a/lib/gitlab/email/handler.rb b/lib/gitlab/email/handler.rb
index bd3267e2a80..5cf9d5ebe28 100644
--- a/lib/gitlab/email/handler.rb
+++ b/lib/gitlab/email/handler.rb
@@ -4,7 +4,8 @@ require 'gitlab/email/handler/create_issue_handler'
module Gitlab
module Email
module Handler
- HANDLERS = [CreateNoteHandler, CreateIssueHandler]
+ # The `CreateIssueHandler` feature is disabled for the time being.
+ HANDLERS = [CreateNoteHandler]
def self.for(mail, mail_key)
HANDLERS.find do |klass|
diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb
index 9ddc8905bd6..4fdc2f46be0 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,37 @@ module Gitlab
@credentials ||= project.import_data.credentials if project.import_data
end
+ def handle_errors
+ 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
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 +75,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 +99,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 +118,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 +132,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
@@ -131,9 +152,15 @@ module Gitlab
end
def create_comments(issuable, comments)
- comments.each do |raw|
- comment = CommentFormatter.new(project, raw)
- issuable.notes.create!(comment.attributes)
+ ActiveRecord::Base.no_touching do
+ comments.each do |raw|
+ 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
end
@@ -141,18 +168,14 @@ module Gitlab
unless project.wiki_enabled?
wiki = WikiFormatter.new(project)
gitlab_shell.import_repository(project.repository_storage_path, wiki.path_with_namespace, wiki.import_url)
- project.update_attribute(:wiki_enabled, true)
+ project.project.update_attribute(:wiki_access_level, ProjectFeature::ENABLED)
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/issue_formatter.rb b/lib/gitlab/github_import/issue_formatter.rb
index 835ec858b35..07edbe37a13 100644
--- a/lib/gitlab/github_import/issue_formatter.rb
+++ b/lib/gitlab/github_import/issue_formatter.rb
@@ -12,7 +12,7 @@ module Gitlab
author_id: author_id,
assignee_id: assignee_id,
created_at: raw_data.created_at,
- updated_at: updated_at
+ updated_at: raw_data.updated_at
}
end
@@ -69,10 +69,6 @@ module Gitlab
def state
raw_data.state == 'closed' ? 'closed' : 'opened'
end
-
- def updated_at
- state == 'closed' ? raw_data.closed_at : raw_data.updated_at
- end
end
end
end
diff --git a/lib/gitlab/github_import/milestone_formatter.rb b/lib/gitlab/github_import/milestone_formatter.rb
index 53d4b3102d1..b2fa524cf5b 100644
--- a/lib/gitlab/github_import/milestone_formatter.rb
+++ b/lib/gitlab/github_import/milestone_formatter.rb
@@ -3,14 +3,14 @@ module Gitlab
class MilestoneFormatter < BaseFormatter
def attributes
{
- iid: number,
+ iid: raw_data.number,
project: project,
- title: title,
- description: description,
- due_date: due_date,
+ title: raw_data.title,
+ description: raw_data.description,
+ due_date: raw_data.due_on,
state: state,
- created_at: created_at,
- updated_at: updated_at
+ created_at: raw_data.created_at,
+ updated_at: raw_data.updated_at
}
end
@@ -20,33 +20,9 @@ module Gitlab
private
- def number
- raw_data.number
- end
-
- def title
- raw_data.title
- end
-
- def description
- raw_data.description
- end
-
- def due_date
- raw_data.due_on
- end
-
def state
raw_data.state == 'closed' ? 'closed' : 'active'
end
-
- def created_at
- raw_data.created_at
- end
-
- def updated_at
- state == 'closed' ? raw_data.closed_at : raw_data.updated_at
- end
end
end
end
diff --git a/lib/gitlab/github_import/project_creator.rb b/lib/gitlab/github_import/project_creator.rb
index f4221003db5..e9725880c5e 100644
--- a/lib/gitlab/github_import/project_creator.rb
+++ b/lib/gitlab/github_import/project_creator.rb
@@ -11,18 +11,24 @@ module Gitlab
end
def execute
- ::Projects::CreateService.new(
+ project = ::Projects::CreateService.new(
current_user,
name: repo.name,
path: repo.name,
description: repo.description,
namespace_id: namespace.id,
- visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : Gitlab::VisibilityLevel::PUBLIC,
+ visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : ApplicationSetting.current.default_project_visibility,
import_type: "github",
import_source: repo.full_name,
- import_url: repo.clone_url.sub("https://", "https://#{@session_data[:github_access_token]}@"),
- wiki_enabled: !repo.has_wiki? # If repo has wiki we'll import it later
+ import_url: repo.clone_url.sub("https://", "https://#{@session_data[:github_access_token]}@")
).execute
+
+ # If repo has wiki we'll import it later
+ if repo.has_wiki? && project
+ project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED)
+ end
+
+ project
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..d9d436d7490 100644
--- a/lib/gitlab/github_import/pull_request_formatter.rb
+++ b/lib/gitlab/github_import/pull_request_formatter.rb
@@ -20,7 +20,7 @@ module Gitlab
author_id: author_id,
assignee_id: assignee_id,
created_at: raw_data.created_at,
- updated_at: updated_at
+ updated_at: raw_data.updated_at
}
end
@@ -56,6 +56,10 @@ module Gitlab
end
end
+ def url
+ raw_data.url
+ end
+
private
def assigned?
@@ -99,15 +103,6 @@ module Gitlab
'opened'
end
end
-
- def updated_at
- case state
- when 'merged' then raw_data.merged_at
- when 'closed' then raw_data.closed_at
- else
- raw_data.updated_at
- end
- end
end
end
end
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_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index 1da51043611..c2e8a1ca5dd 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -39,15 +39,12 @@ project_tree:
- :labels
- milestones:
- :events
+ - :project_feature
# Only include the following attributes for the models specified.
included_attributes:
project:
- :description
- - :issues_enabled
- - :merge_requests_enabled
- - :wiki_enabled
- - :snippets_enabled
- :visibility_level
- :archived
user:
@@ -72,4 +69,4 @@ methods:
statuses:
- :type
merge_request_diff:
- - :utf8_st_diffs \ No newline at end of file
+ - :utf8_st_diffs
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
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)
diff --git a/lib/gitlab/middleware/rails_queue_duration.rb b/lib/gitlab/middleware/rails_queue_duration.rb
index 56608b1b276..5d2d7d0026c 100644
--- a/lib/gitlab/middleware/rails_queue_duration.rb
+++ b/lib/gitlab/middleware/rails_queue_duration.rb
@@ -11,7 +11,7 @@ module Gitlab
def call(env)
trans = Gitlab::Metrics.current_transaction
- proxy_start = env['HTTP_GITLAB_WORHORSE_PROXY_START'].presence
+ proxy_start = env['HTTP_GITLAB_WORKHORSE_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)
diff --git a/lib/gitlab/popen.rb b/lib/gitlab/popen.rb
index ca23ccef25b..a0fd41161a5 100644
--- a/lib/gitlab/popen.rb
+++ b/lib/gitlab/popen.rb
@@ -21,9 +21,9 @@ module Gitlab
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
- # We are not using stdin so we should close it, in case the command we
- # are running waits for input.
+ yield(stdin) if block_given?
stdin.close
+
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb
index 183bd10d6a3..5b9cfaeb2f8 100644
--- a/lib/gitlab/project_search_results.rb
+++ b/lib/gitlab/project_search_results.rb
@@ -28,11 +28,6 @@ module Gitlab
end
end
- def total_count
- @total_count ||= issues_count + merge_requests_count + blobs_count +
- notes_count + wiki_blobs_count + commits_count
- end
-
def blobs_count
@blobs_count ||= blobs.count
end
diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb
index f8ab2b1f09e..2690938fe82 100644
--- a/lib/gitlab/search_results.rb
+++ b/lib/gitlab/search_results.rb
@@ -27,11 +27,6 @@ module Gitlab
end
end
- def total_count
- @total_count ||= projects_count + issues_count + merge_requests_count +
- milestones_count
- end
-
def projects_count
@projects_count ||= projects.count
end
@@ -48,10 +43,6 @@ module Gitlab
@milestones_count ||= milestones.count
end
- def empty?
- total_count.zero?
- end
-
private
def projects
diff --git a/lib/gitlab/sentry.rb b/lib/gitlab/sentry.rb
new file mode 100644
index 00000000000..117fc508135
--- /dev/null
+++ b/lib/gitlab/sentry.rb
@@ -0,0 +1,27 @@
+module Gitlab
+ module Sentry
+ def self.enabled?
+ Rails.env.production? && current_application_settings.sentry_enabled?
+ end
+
+ def self.context(current_user = nil)
+ return unless self.enabled?
+
+ if current_user
+ Raven.user_context(
+ id: current_user.id,
+ email: current_user.email,
+ username: current_user.username,
+ )
+ end
+ end
+
+ def self.program_context
+ if Sidekiq.server?
+ 'sidekiq'
+ else
+ 'rails'
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/snippet_search_results.rb b/lib/gitlab/snippet_search_results.rb
index e0e74ff8359..9e01f02029c 100644
--- a/lib/gitlab/snippet_search_results.rb
+++ b/lib/gitlab/snippet_search_results.rb
@@ -20,10 +20,6 @@ module Gitlab
end
end
- def total_count
- @total_count ||= snippet_titles_count + snippet_blobs_count
- end
-
def snippet_titles_count
@snippet_titles_count ||= snippet_titles.count
end
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