Commit 41d6b370 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'master' into fix-milestone-snippet-header

parents 4df8477a d60047bb
......@@ -76,7 +76,7 @@ Style/BlockEndNewline:
Description: 'Put end statement of multiline block on its own line.'
Enabled: true
Style/Blocks:
Style/BlockDelimiters:
Description: >-
Avoid using {...} for multi-line blocks (multiline chaining is
always ugly).
......@@ -232,6 +232,10 @@ Style/EvenOdd:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods'
Enabled: false
Style/ExtraSpacing:
Description: 'Do not use unnecessary spacing.'
Enabled: false
Style/FileName:
Description: 'Use snake_case for source file names.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files'
......@@ -431,6 +435,14 @@ Style/OpMethod:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg'
Enabled: false
Style/ParallelAssignment:
Description: >-
Check for simple usages of parallel assignment.
It will only warn when the number of variables
matches on both sides of the assignment.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parallel-assignment'
Enabled: false
Style/ParenthesesAroundCondition:
Description: >-
Don't use parentheses around the condition of an
......@@ -669,6 +681,13 @@ Style/TrailingWhitespace:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace'
Enabled: false
Style/TrailingUnderscoreVariable:
Description: >-
Checks for the usage of unneeded trailing underscores at the
end of parallel variable assignment.
AllowNamedUnderscoreVariables: true
Enabled: false
Style/TrivialAccessors:
Description: 'Prefer attr_* methods to trivial readers/writers.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr_family'
......@@ -690,11 +709,6 @@ Style/UnneededPercentQ:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q'
Enabled: false
Style/UnneededPercentX:
Description: 'Checks for %x when `` would do.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-x'
Enabled: false
Style/VariableInterpolation:
Description: >-
Don't interpolate global, instance and class variables
......@@ -778,6 +792,10 @@ Metrics/MethodLength:
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods'
Enabled: false
Metrics/ModuleLength:
Description: 'Avoid modules longer than 100 lines of code.'
Enabled: false
#################### Lint ################################
### Warnings
......@@ -961,6 +979,12 @@ Rails/ActionFilter:
Description: 'Enforces consistent use of action filter methods.'
Enabled: true
Rails/Date:
Description: >-
Checks the correct usage of date aware methods,
such as Date.today, Date.current etc.
Enabled: false
Rails/DefaultScope:
Description: 'Checks if the argument passed to default_scope is a block.'
Enabled: false
......@@ -987,6 +1011,12 @@ Rails/ScopeArgs:
Description: 'Checks the arguments of ActiveRecord scopes.'
Enabled: false
Rails/TimeZone:
Description: 'Checks the correct usage of time zone aware methods.'
StyleGuide: 'https://github.com/bbatsov/rails-style-guide#time'
Reference: 'http://danilenko.org/2012/7/6/rails_timezones'
Enabled: false
Rails/Validation:
Description: 'Use validates :attribute, hash of validations.'
Enabled: false
......
......@@ -62,8 +62,6 @@ v 8.2.3
- Update documentation for "Guest" permissions
- Properly convert Emoji-only comments into Award Emojis
- Enable devise paranoid mode to prevent user enumeration attack
v 8.2.3
- Webhook payload has an added, modified and removed properties for each commit
- Fix 500 error when creating a merge request that removes a submodule
......
......@@ -261,7 +261,7 @@ group :development, :test do
gem 'spring-commands-spinach', '~> 1.0.0'
gem 'spring-commands-teaspoon', '~> 0.0.2'
gem 'rubocop', '~> 0.28.0', require: false
gem 'rubocop', '~> 0.35.0', require: false
gem 'coveralls', '~> 0.8.2', require: false
gem 'simplecov', '~> 0.10.0', require: false
gem 'flog', require: false
......
......@@ -513,7 +513,7 @@ GEM
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
posix-spawn (0.3.11)
powerpack (0.0.9)
powerpack (0.1.1)
pry (0.10.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
......@@ -637,12 +637,13 @@ GEM
rspec-mocks (~> 3.3.0)
rspec-support (~> 3.3.0)
rspec-support (3.3.0)
rubocop (0.28.0)
rubocop (0.35.1)
astrolabe (~> 1.3)
parser (>= 2.2.0.pre.7, < 3.0)
powerpack (~> 0.0.6)
parser (>= 2.2.3.0, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4)
ruby-progressbar (~> 1.7)
tins (<= 1.6.0)
ruby-fogbugz (0.2.1)
crack (~> 0.4)
ruby-progressbar (1.7.5)
......@@ -945,7 +946,7 @@ DEPENDENCIES
rouge (~> 1.10.1)
rqrcode-rails3 (~> 0.1.7)
rspec-rails (~> 3.3.0)
rubocop (~> 0.28.0)
rubocop (~> 0.35.0)
ruby-fogbugz (~> 0.2.1)
sanitize (~> 2.0)
sass-rails (~> 4.0.5)
......
......@@ -401,6 +401,11 @@ table {
border-bottom: 1px solid $border-color;
height: 57px;
}
&.wide {
margin-left: -$gl-padding;
margin-right: -$gl-padding;
}
}
.center-middle-menu {
......
......@@ -3,7 +3,6 @@
.panel-heading {
padding: 7px $gl-padding;
line-height: 42px !important;
}
.panel-body {
......@@ -15,3 +14,7 @@
}
}
}
.container-blank .panel .panel-heading {
line-height: 42px !important;
}
......@@ -19,7 +19,7 @@ $border-color: #dce0e6;
$table-border-color: #eef0f2;
$background-color: #F7F8FA;
$header-height: 58px;
$fixed-layout-width: 1200px;
$fixed-layout-width: 1280px;
$gl-gray: #7f8fa4;
$gl-padding: 16px;
$gl-avatar-size: 46px;
......
......@@ -191,7 +191,7 @@
.btn-clipboard {
@extend .pull-right;
margin-right: 18px;
margin-right: 20px;
margin-top: 5px;
position: absolute;
right: 0;
......
class Dashboard::SnippetsController < Dashboard::ApplicationController
def index
@snippets = SnippetsFinder.new.execute(current_user,
@snippets = SnippetsFinder.new.execute(
current_user,
filter: :by_user,
user: current_user,
scope: params[:scope]
......
......@@ -69,7 +69,7 @@ class Projects::NotesController < Projects::ApplicationController
data = {
author: current_user,
is_award: true,
note: note_params[:note].gsub(":", '')
note: note_params[:note].delete(":")
}
note = noteable.notes.find_by(data)
......
......@@ -21,7 +21,7 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
if protected_branch &&
protected_branch.update_attributes(
developers_can_push: params[:developers_can_push]
developers_can_push: params[:developers_can_push]
)
respond_to do |format|
......
......@@ -61,7 +61,7 @@ module ApplicationHelper
options[:class] ||= ''
options[:class] << ' identicon'
bg_key = project.id % 7
style = "background-color: ##{ allowed_colors.values[bg_key] }; color: #555"
style = "background-color: ##{allowed_colors.values[bg_key]}; color: #555"
content_tag(:div, class: options[:class], style: style) do
project.name[0, 1].upcase
......@@ -204,12 +204,16 @@ module ApplicationHelper
# Returns an HTML-safe String
def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false)
element = content_tag :time, time.to_s,
class: "#{html_class} js-timeago",
class: "#{html_class} js-timeago js-timeago-pending",
datetime: time.getutc.iso8601,
title: time.in_time_zone.stamp('Aug 21, 2011 9:23pm'),
data: { toggle: 'tooltip', placement: placement, container: 'body' }
element += javascript_tag "$('.js-timeago').last().timeago()" unless skip_js
unless skip_js
element << javascript_tag(
"$('.js-timeago-pending').removeClass('js-timeago-pending').timeago()"
)
end
element
end
......
......@@ -10,8 +10,8 @@ module ButtonHelper
# # => "<button class='...' data-clipboard-text='Foo'>...</button>"
#
# # Define the target element
# clipboard_button(clipboard_target: "#foo")
# # => "<button class='...' data-clipboard-target='#foo'>...</button>"
# clipboard_button(clipboard_target: "div#foo")
# # => "<button class='...' data-clipboard-target='div#foo'>...</button>"
#
# See http://clipboardjs.com/#usage
def clipboard_button(data = {})
......
module ExternalWikiHelper
def get_project_wiki_path(project)
external_wiki_service = project.services.
select { |service| service.to_param == 'external_wiki' }.first
find { |service| service.to_param == 'external_wiki' }
if external_wiki_service.present? && external_wiki_service.active?
external_wiki_service.properties['external_wiki_url']
else
......
......@@ -20,7 +20,7 @@ module GitlabMarkdownHelper
end
user = current_user if defined?(current_user)
gfm_body = Gitlab::Markdown.render(escaped_body, project: @project, current_user: user, pipeline: :single_line)
gfm_body = Banzai.render(escaped_body, project: @project, current_user: user, pipeline: :single_line)
fragment = Nokogiri::HTML::DocumentFragment.parse(gfm_body)
if fragment.children.size == 1 && fragment.children[0].name == 'a'
......@@ -50,7 +50,7 @@ module GitlabMarkdownHelper
context[:project] ||= @project
html = Gitlab::Markdown.render(text, context)
html = Banzai.render(text, context)
context.merge!(
current_user: (current_user if defined?(current_user)),
......@@ -61,11 +61,12 @@ module GitlabMarkdownHelper
ref: @ref
)
Gitlab::Markdown.post_process(html, context)
Banzai.post_process(html, context)
end
def asciidoc(text)
Gitlab::Asciidoc.render(text,
Gitlab::Asciidoc.render(
text,
project: @project,
current_user: (current_user if defined?(current_user)),
......
......@@ -121,6 +121,6 @@ module IssuesHelper
end
end
# Required for Gitlab::Markdown::IssueReferenceFilter
# Required for Banzai::Filter::IssueReferenceFilter
module_function :url_for_issue
end
......@@ -107,6 +107,6 @@ module LabelsHelper
options_from_collection_for_select(grouped_labels, 'name', 'title', params[:label_name])
end
# Required for Gitlab::Markdown::LabelReferenceFilter
# Required for Banzai::Filter::LabelReferenceFilter
module_function :render_colored_label, :text_color_for_bg, :escape_once
end
......@@ -330,10 +330,9 @@ module ProjectsHelper
def filename_path(project, filename)
if project && blob = project.repository.send(filename)
namespace_project_blob_path(
project.namespace,
project,
tree_join(project.default_branch,
blob.name)
project.namespace,
project,
tree_join(project.default_branch, blob.name)
)
end
end
......
......@@ -79,7 +79,7 @@ module TreeHelper
part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links
next if parts.count > max_links && !parts.last(2).include?(part)
yield(part, tree_join(@ref, part_path))
end
end
......
......@@ -17,7 +17,7 @@ class Notify < BaseMailer
subject: subject,
body: body.html_safe,
content_type: 'text/html'
)
)
end
# Splits "gitlab.corp.company.com" up into "gitlab.corp.company.com",
......
......@@ -126,12 +126,12 @@ class ApplicationSetting < ActiveRecord::Base
def restricted_signup_domains_raw=(values)
self.restricted_signup_domains = []
self.restricted_signup_domains = values.split(
/\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace
| # or
\s # any whitespace character
| # or
[\r\n] # any number of newline characters
/x)
/\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace
| # or
\s # any whitespace character
| # or
[\r\n] # any number of newline characters
/x)
self.restricted_signup_domains.reject! { |d| d.empty? }
end
end
......@@ -23,7 +23,7 @@ module Mentionable
included do
if self < Participable
participant ->(current_user) { mentioned_users(current_user, load_lazy_references: false) }
participant ->(current_user) { mentioned_users(current_user) }
end
end
......@@ -43,9 +43,9 @@ module Mentionable
self
end
def all_references(current_user = self.author, text = nil, load_lazy_references: true)
ext = Gitlab::ReferenceExtractor.new(self.project, current_user, load_lazy_references: load_lazy_references)
def all_references(current_user = self.author, text = nil)
ext = Gitlab::ReferenceExtractor.new(self.project, current_user)
if text
ext.analyze(text)
else
......@@ -59,13 +59,13 @@ module Mentionable
ext
end
def mentioned_users(current_user = nil, load_lazy_references: true)
all_references(current_user, load_lazy_references: load_lazy_references).users
def mentioned_users(current_user = nil)
all_references(current_user).users
end
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
def referenced_mentionables(current_user = self.author, text = nil, load_lazy_references: true)
refs = all_references(current_user, text, load_lazy_references: load_lazy_references)
def referenced_mentionables(current_user = self.author, text = nil)
refs = all_references(current_user, text)
refs = (refs.issues + refs.merge_requests + refs.commits)
# We're using this method instead of Array diffing because that requires
......
......@@ -38,20 +38,21 @@ module Participable
# 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, load_lazy_references: true)
participants = self.class.participant_attrs.flat_map do |attr|
value =
if attr.respond_to?(:call)
instance_exec(current_user, &attr)
else
send(attr)
end
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
participants_for(value, current_user)
end.compact.uniq
if load_lazy_references
participants = Gitlab::Markdown::ReferenceFilter::LazyReference.load(participants).uniq
participants_for(value, current_user)
end.compact.uniq
end
unless Gitlab::ReferenceExtractor.lazy?
participants.select! do |user|
user.can?(:read_project, project)
end
......@@ -64,12 +65,12 @@ module Participable
def participants_for(value, current_user = nil)
case value
when User, Gitlab::Markdown::ReferenceFilter::LazyReference
when User, Banzai::LazyReference
[value]
when Enumerable, ActiveRecord::Relation
value.flat_map { |v| participants_for(v, current_user) }
when Participable
value.participants(current_user, load_lazy_references: false)
value.participants(current_user)
end
end
end
......@@ -13,7 +13,7 @@ module TokenAuthenticatable
@token_fields << token_field
define_singleton_method("find_by_#{token_field}") do |token|
where(token_field => token).first if token
find_by(token_field => token) if token
end
define_method("ensure_#{token_field}") do
......@@ -37,7 +37,7 @@ module TokenAuthenticatable
def generate_token_for(token_field)
loop do
token = Devise.friendly_token
break token unless self.class.unscoped.where(token_field => token).first
break token unless self.class.unscoped.find_by(token_field => token)
end
end
end
......@@ -84,11 +84,11 @@ class Issue < ActiveRecord::Base
end
def referenced_merge_requests
references = [self, *notes].flat_map do |note|
note.all_references(load_lazy_references: false).merge_requests
end.uniq
Gitlab::Markdown::ReferenceFilter::LazyReference.load(references).uniq.sort_by(&:iid)
Gitlab::ReferenceExtractor.lazily do
[self, *notes].flat_map do |note|
note.all_references(load_lazy_references: false).merge_requests
end
end.sort_by(&:iid)
end
# Reset issue events cache
......
......@@ -194,9 +194,7 @@ class MergeRequest < ActiveRecord::Base
similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id
if similar_mrs.any?
errors.add :validate_branches,
"Cannot Create: This merge request already exists: #{
similar_mrs.pluck(:title)
}"
"Cannot Create: This merge request already exists: #{similar_mrs.pluck(:title)}"
end
end
end
......
......@@ -45,7 +45,7 @@ class Namespace < ActiveRecord::Base
class << self
def by_path(path)
where('lower(path) = :value', value: path.downcase).first
find_by('lower(path) = :value', value: path.downcase)
end
# Case insensetive search for namespace by path or name
......@@ -148,6 +148,6 @@ class Namespace < ActiveRecord::Base
end
def find_fork_of(project)
projects.joins(:forked_project_link).where('forked_project_links.forked_from_project_id = ?', project.id).first
projects.joins(:forked_project_link).find_by('forked_project_links.forked_from_project_id = ?', project.id)
end
end
......@@ -373,11 +373,11 @@ class Note < ActiveRecord::Base
end
def contains_emoji_only?
note =~ /\A#{Gitlab::Markdown::EmojiFilter.emoji_pattern}\s?\Z/
note =~ /\A#{Banzai::Filter::EmojiFilter.emoji_pattern}\s?\Z/
end
def award_emoji_name
original_name = note.match(Gitlab::Markdown::EmojiFilter.emoji_pattern)[1]
original_name = note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1]
AwardEmoji.normilize_emoji_name(original_name)
end
end
......@@ -265,7 +265,7 @@ class Project < ActiveRecord::Base
joins(:namespace).
iwhere('namespaces.path' => namespace_path)
projects.where('projects.path' => project_path).take ||
projects.find_by('projects.path' => project_path) ||
projects.iwhere('projects.path' => project_path).take
end
......@@ -450,7 +450,7 @@ class Project < ActiveRecord::Base
end
def external_issue_tracker
@external_issues_tracker ||= external_issues_trackers.select(&:activated?).first
@external_issues_tracker ||= external_issues_trackers.find(&:activated?)
end
def can_have_issues_tracker_id?
......@@ -496,7 +496,7 @@ class Project < ActiveRecord::Base
end
def ci_service
@ci_service ||= ci_services.select(&:activated?).first
@ci_service ||= ci_services.find(&:activated?)
end
def avatar_type
......@@ -547,7 +547,7 @@ class Project < ActiveRecord::Base
end
def project_member_by_name_or_email(name = nil, email = nil)
user = users.where('name like ? or email like ?', name, email).first
user = users.find_by('name like ? or email like ?', name, email)
project_members.where(user: user) if user
end
......@@ -722,7 +722,7 @@ class Project < ActiveRecord::Base
end
def project_member(user)
project_members.where(user_id: user).first
project_members.find_by(user_id: user)
end
def default_branch
......
......@@ -27,12 +27,10 @@ class BambooService < CiService
validates :build_key, presence: true, if: :activated?
validates :username,
presence: true,
if: ->(service) { service.password? },
if: :activated?
if: ->(service) { service.activated? && service.password }
validates :password,
presence: true,
if: ->(service) { service.username? },
if: :activated?
if: ->(service) { service.activated? && service.username }
attr_accessor :response
......
......@@ -58,6 +58,6 @@ class FlowdockService < Service
repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}",
commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s",
diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s",
)
)
end
end
......@@ -57,6 +57,6 @@ class GemnasiumService < Service
token: token,
api_key: api_key,
repo: project.repository.path_to_repo
)
)
end
end
......@@ -27,12 +27,10 @@ class TeamcityService < CiService
validates :build_type, presence: true, if: :activated?
validates :username,
presence: true,
if: ->(service) { service.password? },
if: :activated?
if: ->(service) { service.activated? && service.password }
validates :password,
presence: true,
if: ->(service) { service.username? },
if: :activated?
if: ->(service) { service.activated? && service.username }
attr_accessor :response
......@@ -147,6 +145,6 @@ class TeamcityService < CiService
'</build>',
headers: { 'Content-type' => 'application/xml' },
basic_auth: auth
)
)
end
end
......@@ -220,9 +220,9 @@ class User < ActiveRecord::Base
def find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { value: login.downcase }]).first
where(conditions).find_by("lower(username) = :value OR lower(email) = :value", value: login.downcase)
else
where(conditions).first
find_by(conditions)
end
end
......@@ -285,7 +285,7 @@ class User < ActiveRecord::Base
end
def by_username_or_id(name_or_id)
where('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i).first
find_by('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i)
end
def build_user(attrs = {})
......
......@@ -112,7 +112,7 @@ module MergeRequests
merge_requests_for_source_branch.each do |merge_request|
SystemNoteService.change_branch_presence(
merge_request, merge_request.project, @current_user,
merge_request, merge_request.project, @current_user,
:source, @branch_name, presence)
end
end
......
%div
"#{link_to @note.author_name, user_url(@note.author)} wrote:"
%div
= markdown(@note.note, pipeline: :email)
......@@ -20,8 +20,8 @@
%p
%span.light Commit
= link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace", data: { clipboard_text: @commit.id }
= clipboard_button
= link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace"
= clipboard_button(clipboard_text: @commit.id)
.commit-info-row
%span.light Authored by
%strong
......
......@@ -8,8 +8,8 @@
%p
%strong Step 1.
Fetch and check out the branch for this merge request
= clipboard_button
%pre.dark
= clipboard_button(clipboard_target: 'pre#merge-info-1')
%pre.dark#merge-info-1
- if @merge_request.for_fork?
:preserve
git fetch #{h @merge_request.source_project.http_url_to_repo} #{h @merge_request.source_branch}
......@@ -25,8 +25,8 @@
%p
%strong Step 3.
Merge the branch and fix any conflicts that come up
= clipboard_button
%pre.dark
= clipboard_button(clipboard_target: 'pre#merge-info-3')
%pre.dark#merge-info-3
- if @merge_request.for_fork?
:preserve
git checkout #{h @merge_request.target_branch}
......@@ -38,8 +38,8 @@
%p
%strong Step 4.
Push the result of the merge to GitLab
= clipboard_button
%pre.dark
= clipboard_button(clipboard_target: 'pre#merge-info-4')
%pre.dark#merge-info-4
:preserve
git push origin #{h @merge_request.target_branch}
- unless @merge_request.can_be_merged_by?(current_user)
......
......@@ -73,7 +73,7 @@
.user-calendar-activities
%ul.center-top-menu.no-top.no-bottom.bottom-border
%ul.center-top-menu.no-top.no-bottom.bottom-border.wide
%li.active
= link_to "#activity", 'data-toggle' => 'tab' do
Activity
......
......@@ -31,11 +31,11 @@ if File.exists?(aws_file)
if Rails.env.test?
Fog.mock!
connection = ::Fog::Storage.new(
aws_access_key_id: AWS_CONFIG['access_key_id'],
aws_secret_access_key: AWS_CONFIG['secret_access_key'],
provider: 'AWS',
region: AWS_CONFIG['region']
)
aws_access_key_id: AWS_CONFIG['access_key_id'],
aws_secret_access_key: AWS_CONFIG['secret_access_key'],
provider: 'AWS',
region: AWS_CONFIG['region']
)
connection.directories.create(key: AWS_CONFIG['bucket'])
end
end
......@@ -441,7 +441,7 @@ Rails.application.routes.draw do
scope do
post(
'/create_dir/*id',
'/create_dir/*id',
to: 'tree#create_dir',
constraints: { id: /.+/ },
as: 'create_dir'
......
......@@ -7,6 +7,7 @@
- [GitLab Basics](gitlab-basics/README.md) Find step by step how to start working on your commandline and on GitLab.
- [Importing to GitLab](workflow/importing/README.md).
- [Markdown](markdown/markdown.md) GitLab's advanced formatting system.
- [Migrating from SVN](migration/README.md) Convert a SVN repository to Git and GitLab
- [Permissions](permissions/permissions.md) Learn what each role in a project (guest/reporter/developer/master/owner) can do.
- [Profile Settings](profile/README.md)
- [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat.
......
......@@ -348,7 +348,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 0.4.2
sudo -u git -H git checkout 0.5.0
sudo -u git -H make
### Initialize Database and Activate Advanced Features
......
# Rake tasks
- [Backup restore](backup_restore.md)
- [Check](check.md)
- [Cleanup](cleanup.md)
- [Features](features.md)
- [Maintenance](maintenance.md) and self-checks
- [User management](user_management.md)
- [Web hooks](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
\ No newline at end of file
- [Rebuild authorized_keys file](http://doc.gitlab.com/ce/raketasks/maintenance.html#rebuild-authorized_keys-file) task for administrators
# Check Rake Tasks
## Repository Integrity
Even though Git is very resilient and tries to prevent data integrity issues,
there are times when things go wrong. The following Rake tasks intend to
help GitLab administrators diagnose problem repositories so they can be fixed.
There are 3 things that are checked to determine integrity.
1. Git repository file system check ([git fsck](https://git-scm.com/docs/git-fsck)).
This step verifies the connectivity and validity of objects in the repository.
1. Check for `config.lock` in the repository directory.
1. Check for any branch/references lock files in `refs/heads`.
It's important to note that the existence of `config.lock` or reference locks
alone do not necessarily indicate a problem. Lock files are routinely created
and removed as Git and GitLab perform operations on the repository. They serve
to prevent data integrity issues. However, if a Git operation is interrupted these
locks may not be cleaned up properly.
The following symptoms may indicate a problem with repository integrity. If users
experience these symptoms you may use the rake tasks described below to determine
exactly which repositories are causing the trouble.
- Receiving an error when trying to push code - `remote: error: cannot lock ref`
- A 500 error when viewing the GitLab dashboard or when accessing a specific project.
### Check all GitLab repositories
This task loops through all repositories on the GitLab server and runs the
3 integrity checks described previously.
```
# omnibus-gitlab
sudo gitlab-rake gitlab:repo:check
# installation from source
bundle exec rake gitlab:repo:check RAILS_ENV=production
```
### Check repositories for a specific user
This task checks all repositories that a specific user has access to. This is important
because sometimes you know which user is experiencing trouble but you don't know
which project might be the cause.
If the rake task is executed without brackets at the end, you will be prompted
to enter a username.
```bash
# omnibus-gitlab
sudo gitlab-rake gitlab:user:check_repos
sudo gitlab-rake gitlab:user:check_repos[<username>]
# installation from source
bundle exec rake gitlab:user:check_repos RAILS_ENV=production
bundle exec rake gitlab:user:check_repos[<username>] RAILS_ENV=production
```
Example output:
![gitlab:user:check_repos output](check_repos_output.png)
......@@ -78,7 +78,7 @@ 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 0.4.2
sudo -u git -H git checkout 0.5.0
sudo -u git -H make
```
......@@ -115,6 +115,12 @@ git diff origin/8-2-stable:config/gitlab.yml.example origin/8-3-stable:config/gi
#### Nginx configuration
GitLab 8.3 introduces major changes in the NGINX configuration.
Because all HTTP requests pass through gitlab-workhorse now a lot of
directives need to be removed from NGINX. During future upgrades there
should be much less changes in the NGINX configuration because of
this.
View changes between the previous recommended Nginx configuration and the
current one:
......@@ -134,6 +140,18 @@ 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-3-stable/lib/support/init.d/gitlab.default.example#L34
#### Init script
We updated the init script for GitLab in order to pass new
configuration options to gitlab-workhorse. We let gitlab-workhorse
connect to the Rails application via a Unix domain socket and we tell
it where the 'public' directory of GitLab is.
```
cd /home/git/gitlab
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
```
### 8. Use Redis v2.8.0+
Previous versions of GitLab allowed Redis versions >= 2.0 to be used, but
......
......@@ -19,3 +19,4 @@
- ["Work In Progress" Merge Requests](wip_merge_requests.md)
- [Merge When Build Succeeds](merge_when_build_succeeds.md)
- [Manage large binaries with Git LFS](lfs/manage_large_binaries_with_git_lfs.md)
- [Importing from SVN, GitHub, BitBucket, etc](importing/README.md)
# Migrating projects to a GitLab instance
1. [Bitbucket](import_projects_from_bitbucket.md)
2. [GitHub](import_projects_from_github.md)
3. [GitLab.com](import_projects_from_gitlab_com.md)
4. [FogBugz](import_projects_from_fogbugz.md)
4. [SVN](migrating_from_svn.md)
1. [GitHub](import_projects_from_github.md)
1. [GitLab.com](import_projects_from_gitlab_com.md)
1. [FogBugz](import_projects_from_fogbugz.md)
1. [SVN](migrating_from_svn.md)
### Note
* If you'd like to migrate from a self-hosted GitLab instance to GitLab.com, you can copy your repos by changing the remote and pushing to the new server; but issues and merge requests can't be imported.
In addition to the specific migration documentation above, you can import any
Git repository via HTTP from the New Project page. Be aware that if the
repository is too large the import can timeout.
### Migrating from self-hosted GitLab to GitLab.com
You can copy your repos by changing the remote and pushing to the new server;
but issues and merge requests can't be imported.
* You can import any Git repository via HTTP from the New Project page.
If the repository is too large, it can timeout.
# Migrating from SVN to GitLab
SVN stands for Subversion and is a version control system (VCS).
Git is a distributed version control system.
Subversion (SVN) is a central version control system (VCS) while
Git is a distributed version control system. There are some major differences
between the two, for more information consult your favorite search engine.
There are some major differences between the two, for more information consult your favorite search engine.
If you are currently using an SVN repository, you can migrate the repository
to Git and GitLab. We recommend a hard cut over - run the migration command once
and then have all developers start using the new GitLab repository immediately.
Otherwise, it's hard to keep changing in sync in both directions. The conversion
process should be run on a local workstation.
Git has tools for migrating SVN repositories to git, namely `git svn`. You can read more about this at
[git documentation pages](https://git-scm.com/book/en/Git-and-Other-Systems-Git-and-Subversion).
Install `svn2git`. On all systems you can install as a Ruby gem if you already
have Ruby and Git installed.
Apart from the [official git documentation](https://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git) there is also
user created step by step guide for migrating from SVN to GitLab.
```bash
sudo gem install svn2git
```
[Benjamin New](https://github.com/leftclickben) wrote [a guide that shows how to do a migration](https://gist.github.com/leftclickben/322b7a3042cbe97ed2af). Mirrors can be found [here](https://gitlab.com/snippets/2168) and [here](https://gist.github.com/maxlazio/f1b593b0d00aa966e9ca).
On Debian-based Linux distributions you can install the native packages:
```bash
sudo apt-get install git-core git-svn ruby
```
Optionally, prepare an authors file so `svn2git` can map SVN authors to Git authors.
If you choose not to create the authors file then commits will not be attributed
to the correct GitLab user. Some users may not consider this a big issue while
others will want to ensure they complete this step. If you choose to map authors
you will be required to map every author that is present on changes in the SVN
repository. If you don't, the conversion will fail and you will have to update
the author file accordingly. The following command will search through the
repository and output a list of authors.
```bash
svn log --quiet | grep -E "r[0-9]+ \| .+ \|" | cut -d'|' -f2 | sed 's/ //g' | sort | uniq
```
Use the output from the last command to construct the authors file.
Create a file called `authors.txt` and add one mapping per line.
```
janedoe = Jane Doe <janedoe@example.com>
johndoe = John Doe <johndoe@example.com>
```
If your SVN repository is in the standard format (trunk, branches, tags,
not nested) the conversion is simple. For a non-standard repository see
[svn2git documentation](https://github.com/nirvdrum/svn2git). The following
command will checkout the repository and do the conversion in the current
working directory. Be sure to create a new directory for each repository before
running the `svn2git` command. The conversion process will take some time.
```bash
svn2git https://svn.example.com/path/to/repo --authors /path/to/authors.txt
```
If your SVN repository requires a username and password add the
`--username <username>` and `--password <password` flags to the above command.
`svn2git` also supports excluding certain file paths, branches, tags, etc. See
[svn2git documentation](https://github.com/nirvdrum/svn2git) or run
`svn2git --help` for full documentation on all of the available options.
Create a new GitLab project, where you will eventually push your converted code.
Copy the SSH or HTTP(S) repository URL from the project page. Add the GitLab
repository as a Git remote and push all the changes. This will push all commits,
branches and tags.
```bash
git remote add origin git@gitlab.com:<group>/<project>.git
git push --all origin
```
## Contribute to this guide
We welcome all contributions that would expand this guide with instructions on how to migrate from SVN and other version control systems.
We welcome all contributions that would expand this guide with instructions on
how to migrate from SVN and other version control systems.
......@@ -75,18 +75,18 @@ class Spinach::Features::ExploreGroups < Spinach::FeatureSteps
name: projectname,
path: "#{groupname}-#{projectname}",
visibility_level: visibility_level
)
)
create(:issue,
title: "#{projectname} feature",
project: project
)
)
create(:merge_request,
title: "#{projectname} feature implemented",
source_project: project,
target_project: project
)
)
create(:closed_issue_event,
project: project
)
)
end
end
......@@ -61,11 +61,11 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
create(:issue,
title: "Bug",
project: public_project
)
)
create(:issue,
title: "New feature",
project: public_project
)
)
visit namespace_project_issues_path(public_project.namespace, public_project)
end
......@@ -80,11 +80,11 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
create(:issue,
title: "Internal Bug",
project: internal_project
)
)
create(:issue,
title: "New internal feature",
project: internal_project
)
)
visit namespace_project_issues_path(internal_project.namespace, internal_project)
end
......@@ -104,7 +104,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
title: "Bug fix for public project",
source_project: public_project,
target_project: public_project,
)
)
end
step 'I should see list of merge requests for "Community" project' do
......@@ -121,7 +121,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
title: "Feature implemented",
source_project: internal_project,
target_project: internal_project
)
)
end
step 'I should see list of merge requests for "Internal" project' do
......
......@@ -85,7 +85,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
step 'I should see new group "Owned" avatar' do
expect(owned_group.avatar).to be_instance_of AvatarUploader
expect(owned_group.avatar.url).to eq "/uploads/group/avatar/#{ Group.find_by(name:"Owned").id }/banana_sample.gif"
expect(owned_group.avatar.url).to eq "/uploads/group/avatar/#{Group.find_by(name:"Owned").id}/banana_sample.gif"
end
step 'I should see the "Remove avatar" button' do
......
......@@ -34,7 +34,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
step 'I should see new avatar' do
expect(@user.avatar).to be_instance_of AvatarUploader
expect(@user.avatar.url).to eq "/uploads/user/avatar/#{ @user.id }/banana_sample.gif"
expect(@user.avatar.url).to eq "/uploads/user/avatar/#{@user.id}/banana_sample.gif"
end
step 'I should see the "Remove avatar" button' do
......
......@@ -37,7 +37,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps
step 'I should see new project avatar' do
expect(@project.avatar).to be_instance_of AvatarUploader
url = @project.avatar.url
expect(url).to eq "/uploads/project/avatar/#{ @project.id }/banana_sample.gif"
expect(url).to eq "/uploads/project/avatar/#{@project.id}/banana_sample.gif"
end
step 'I should see the "Remove avatar" button' do
......
......@@ -238,13 +238,13 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step 'I am redirected to the new file' do
expect(current_path).to eq(namespace_project_blob_path(
@project.namespace, @project, 'master/' + new_file_name))
expect(current_path).to eq(
namespace_project_blob_path(@project.namespace, @project, 'master/' + new_file_name))
end
step 'I am redirected to the new file with directory' do
expect(current_path).to eq(namespace_project_blob_path(
@project.namespace, @project, 'master/' + new_file_name_with_directory))
expect(current_path).to eq(
namespace_project_blob_path(@project.namespace, @project, 'master/' + new_file_name_with_directory))
end
step 'I am redirected to the new merge request page' do
......@@ -252,8 +252,8 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step 'I am redirected to the root directory' do
expect(current_path).to eq(namespace_project_tree_path(
@project.namespace, @project, 'master/'))
expect(current_path).to eq(
namespace_project_tree_path(@project.namespace, @project, 'master/'))
end
step "I don't see the permalink link" do
......
......@@ -212,8 +212,8 @@ module SharedPaths
end
step 'I visit a binary file in the repo' do
visit namespace_project_blob_path(@project.namespace, @project, File.join(
root_ref, 'files/images/logo-black.png'))
visit namespace_project_blob_path(@project.namespace, @project,
File.join(root_ref, 'files/images/logo-black.png'))
end
step "I visit my project's commits page" do
......@@ -316,8 +316,8 @@ module SharedPaths
end
step 'I am on the ".gitignore" edit file page' do
expect(current_path).to eq(namespace_project_edit_blob_path(
@project.namespace, @project, File.join(root_ref, '.gitignore')))
expect(current_path).to eq(
namespace_project_edit_blob_path(@project.namespace, @project, File.join(root_ref, '.gitignore')))
end
step 'I visit project source page for "6d39438"' do
......
......@@ -67,7 +67,7 @@ module API
expose :shared_runners_enabled
expose :creator_id
expose :namespace
expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ | project, options | project.forked? }
expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ |project, options| project.forked? }
expose :avatar_url
expose :star_count, :forks_count
end
......
module Banzai
def self.render(text, context = {})
Renderer.render(text, context)
end
def self.render_result(text, context = {})
Renderer.render_result(text, context)
end
def self.post_process(html, context)
Renderer.post_process(html, context)
end
end
require 'banzai'
module Banzai
# Common methods for ReferenceFilters that support an optional cross-project
# reference.
module CrossProjectReference
# Given a cross-project reference string, get the Project record
#
# Defaults to value of `context[:project]` if:
# * No reference is given OR
# * Reference given doesn't exist
#
# ref - String reference.
#
# Returns a Project, or nil if the reference can't be found
def project_from_ref(ref)
return context[:project] unless ref
Project.find_with_namespace(ref)
end
end
end
require 'active_support/core_ext/string/output_safety'
require 'banzai'
module Banzai
module Filter
def self.[](name)
const_get("#{name.to_s.camelize}Filter")
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# Issues, Merge Requests, Snippets, Commits and Commit Ranges share
# similar functionality in reference filtering.
class AbstractReferenceFilter < ReferenceFilter
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML Filter for auto-linking URLs in HTML.
#
# Based on HTML::Pipeline::AutolinkFilter
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces commit range references with links.
#
# This filter supports cross-project references.
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces commit references with links.
#
# This filter supports cross-project references.
......
require 'action_controller'
require 'gitlab/markdown'
require 'banzai'
require 'gitlab_emoji'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces :emoji: with images.
#
# Based on HTML::Pipeline::EmojiFilter
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces external issue tracker references with links.
# References are ignored if the project doesn't use an external issue
# tracker.
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML Filter to add a `rel="nofollow"` attribute to external links
#
class ExternalLinkFilter < HTML::Pipeline::Filter
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces issue references with links. References to
# issues that do not exist are ignored.
#
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces label references with links.
class LabelReferenceFilter < ReferenceFilter
# Public: Find label references in text
......
module Gitlab
module Markdown
require 'banzai'
require 'html/pipeline/filter'
module Banzai
module Filter
class MarkdownFilter < HTML::Pipeline::TextFilter
def initialize(text, context = nil, result = nil)
super text, context, result
@text = @text.gsub "\r", ''
@text = @text.delete "\r"
end
def call
......@@ -11,8 +14,8 @@ module Gitlab
html.rstrip!
html
end
private
private
def self.redcarpet_options
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces merge request references with links. References
# to merge requests that do not exist are ignored.
#
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that removes references to records that the current user does
# not have permission to view.
#
......@@ -27,7 +27,7 @@ module Gitlab
def user_can_reference?(node)
if node.has_attribute?('data-reference-filter')
reference_type = node.attr('data-reference-filter')
reference_filter = Gitlab::Markdown.const_get(reference_type)
reference_filter = Banzai::Filter.const_get(reference_type)
reference_filter.user_can_reference?(current_user, node, context)
else
......
require 'active_support/core_ext/string/output_safety'
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# Base class for GitLab Flavored Markdown reference filters.
#
# References within <pre>, <code>, <a>, and <style> elements are ignored.
......@@ -12,27 +12,6 @@ module Gitlab
# :project (required) - Current project, ignored if reference is cross-project.
# :only_path - Generate path-only links.
class ReferenceFilter < HTML::Pipeline::Filter
LazyReference = Struct.new(:klass, :ids) do
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
def load
self.klass.where(id: self.ids)
end
end
def self.[](name)
Markdown.const_get("#{name.to_s.camelize}ReferenceFilter")
end
def self.user_can_reference?(user, node, context)
if node.has_attribute?('data-project')
project_id = node.attr('data-project').to_i
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that gathers all referenced records that the current user has
# permission to view.
#
......@@ -20,7 +20,7 @@ module Gitlab
gather_references(node)
end
load_lazy_references unless context[:load_lazy_references] == false
load_lazy_references unless ReferenceExtractor.lazy?
doc
end
......@@ -31,7 +31,7 @@ module Gitlab
return unless node.has_attribute?('data-reference-filter')
reference_type = node.attr('data-reference-filter')
reference_filter = Gitlab::Markdown.const_get(reference_type)
reference_filter = Banzai::Filter.const_get(reference_type)
return if context[:reference_filter] && reference_filter != context[:reference_filter]
......@@ -47,11 +47,10 @@ module Gitlab
end
end
# Will load all references of one type using one query.
def load_lazy_references
refs = result[:references]
refs.each do |type, values|
refs[type] = ReferenceFilter::LazyReference.load(values)
refs[type] = ReferenceExtractor.lazily(values)
end
end
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that "fixes" relative links to files in a repository.
#
# Context options:
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'html/pipeline/sanitization_filter'
module Gitlab
module Markdown
module Banzai
module Filter
# Sanitize HTML
#
# Extends HTML::Pipeline::SanitizationFilter with a custom whitelist.
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces snippet references with links. References to
# snippets that do not exist are ignored.
#
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'rouge/plugins/redcarpet'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML Filter to highlight fenced code blocks
#
class SyntaxHighlightFilter < HTML::Pipeline::Filter
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that adds an anchor child element to all Headers in a
# document, so that they can be linked to.
#
......@@ -31,7 +31,7 @@ module Gitlab
id = text.downcase
id.gsub!(PUNCTUATION_REGEXP, '') # remove punctuation
id.gsub!(' ', '-') # replace spaces with dash
id.tr!(' ', '-') # replace spaces with dash
id.squeeze!('-') # replace multiple dashes with one
uniq = (headers[id] > 0) ? "-#{headers[id]}" : ''
......
require 'gitlab/markdown'
require 'banzai'
require 'task_list/filter'
module Gitlab
module Markdown
module Banzai
module Filter
# Work around a bug in the default TaskList::Filter that adds a `task-list`
# class to every list element, regardless of whether or not it contains a
# task list.
......
require 'gitlab/markdown'
require 'banzai'
require 'html/pipeline/filter'
require 'uri'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that "fixes" relative upload links to files.
# Context options:
# :project (required) - Current project
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Filter
# HTML filter that replaces user or group references with links.
#
# A special `@all` reference is also supported.
......
require 'banzai'
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
require 'banzai'
module Banzai
module Pipeline
def self.[](name)
name ||= :full
const_get("#{name.to_s.camelize}Pipeline")
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
class AsciidocPipeline < Pipeline
module Banzai
module Pipeline
class AsciidocPipeline < BasePipeline
def self.filters
[
Gitlab::Markdown::RelativeLinkFilter
Filter::RelativeLinkFilter
]
end
end
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class AtomPipeline < FullPipeline
def self.transform_context(context)
super(context).merge(
only_path: false,
xhtml: true
super(context).merge(
only_path: false,
xhtml: true
)
end
end
......
require 'banzai'
require 'html/pipeline'
module Banzai
module Pipeline
class BasePipeline
def self.filters
[]
end
def self.transform_context(context)
context
end
def self.html_pipeline
@html_pipeline ||= HTML::Pipeline.new(filters)
end
class << self
%i(call to_document to_html).each do |meth|
define_method(meth) do |text, context|
context = transform_context(context)
html_pipeline.send(meth, text, context)
end
end
end
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
module CombinedPipeline
def self.new(*pipelines)
Class.new(Pipeline) do
Class.new(BasePipeline) do
const_set :PIPELINES, pipelines
def self.pipelines
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class DescriptionPipeline < FullPipeline
def self.transform_context(context)
super(context).merge(
super(context).merge(
# SanitizationFilter
inline_sanitization: true
)
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class EmailPipeline < FullPipeline
def self.transform_context(context)
super(context).merge(
super(context).merge(
only_path: false
)
end
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class FullPipeline < CombinedPipeline.new(PlainMarkdownPipeline, GfmPipeline)
end
......
require 'banzai'
module Banzai
module Pipeline
class GfmPipeline < BasePipeline
def self.filters
@filters ||= [
Filter::SyntaxHighlightFilter,
Filter::SanitizationFilter,
Filter::UploadLinkFilter,
Filter::EmojiFilter,
Filter::TableOfContentsFilter,
Filter::AutolinkFilter,
Filter::ExternalLinkFilter,
Filter::UserReferenceFilter,
Filter::IssueReferenceFilter,
Filter::ExternalIssueReferenceFilter,
Filter::MergeRequestReferenceFilter,
Filter::SnippetReferenceFilter,
Filter::CommitRangeReferenceFilter,
Filter::CommitReferenceFilter,
Filter::LabelReferenceFilter,
Filter::TaskListFilter
]
end
def self.transform_context(context)
context.merge(
only_path: true,
# EmojiFilter
asset_host: Gitlab::Application.config.asset_host,
asset_root: Gitlab.config.gitlab.base_url
)
end
end
end
end
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class NotePipeline < FullPipeline
def self.transform_context(context)
super(context).merge(
super(context).merge(
# TableOfContentsFilter
no_header_anchors: true
)
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
class PlainMarkdownPipeline < Pipeline
module Banzai
module Pipeline
class PlainMarkdownPipeline < BasePipeline
def self.filters
[
Gitlab::Markdown::MarkdownFilter
Filter::MarkdownFilter
]
end
end
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
class PostProcessPipeline < Pipeline
module Banzai
module Pipeline
class PostProcessPipeline < BasePipeline
def self.filters
[
Gitlab::Markdown::RelativeLinkFilter,
Gitlab::Markdown::RedactorFilter
Filter::RelativeLinkFilter,
Filter::RedactorFilter
]
end
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
class ReferenceExtractionPipeline < Pipeline
module Banzai
module Pipeline
class ReferenceExtractionPipeline < BasePipeline
def self.filters
[
Gitlab::Markdown::ReferenceGathererFilter
Filter::ReferenceGathererFilter
]
end
end
......
require 'gitlab/markdown'
require 'banzai'
module Gitlab
module Markdown
module Banzai
module Pipeline
class SingleLinePipeline < GfmPipeline
end
end
end
require 'banzai'
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
def analyze(text, context = {})
@texts << Renderer.render(text, context)
end
def references(type, context = {})
filter = Banzai::Filter["#{type}_reference"]
context.merge!(
pipeline: :reference_extraction,
# ReferenceGathererFilter
reference_filter: filter
)
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
end
end
end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment