summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop.yml361
-rw-r--r--.rubocop_todo.yml462
-rw-r--r--CHANGELOG24
-rw-r--r--CONTRIBUTING.md3
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock30
-rw-r--r--app/assets/javascripts/application.js.coffee1
-rw-r--r--app/assets/javascripts/compare_autocomplete.js.coffee41
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee2
-rw-r--r--app/assets/javascripts/gl_dropdown.js.coffee23
-rw-r--r--app/assets/javascripts/issuable.js.coffee4
-rw-r--r--app/assets/javascripts/projects_list.js.coffee11
-rw-r--r--app/assets/javascripts/shortcuts.js.coffee13
-rw-r--r--app/assets/javascripts/u2f/authenticate.js.coffee18
-rw-r--r--app/assets/javascripts/u2f/util.js.coffee3
-rw-r--r--app/assets/javascripts/u2f/util.js.coffee.erb15
-rw-r--r--app/assets/javascripts/users_select.js.coffee6
-rw-r--r--app/assets/stylesheets/framework/blank.scss11
-rw-r--r--app/assets/stylesheets/framework/blocks.scss6
-rw-r--r--app/assets/stylesheets/framework/common.scss15
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss8
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/pages/admin.scss8
-rw-r--r--app/assets/stylesheets/pages/groups.scss27
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss20
-rw-r--r--app/assets/stylesheets/pages/projects.scss10
-rw-r--r--app/assets/stylesheets/pages/search.scss2
-rw-r--r--app/assets/stylesheets/pages/tree.scss3
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb10
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb3
-rw-r--r--app/controllers/projects/issues_controller.rb6
-rw-r--r--app/controllers/projects/merge_requests_controller.rb5
-rw-r--r--app/helpers/blob_helper.rb9
-rw-r--r--app/helpers/issuables_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb7
-rw-r--r--app/helpers/search_helper.rb2
-rw-r--r--app/helpers/u2f_helper.rb5
-rw-r--r--app/models/ci/pipeline.rb2
-rw-r--r--app/models/concerns/issuable.rb6
-rw-r--r--app/models/concerns/mentionable.rb8
-rw-r--r--app/models/concerns/participable.rb7
-rw-r--r--app/models/legacy_diff_note.rb4
-rw-r--r--app/models/project.rb10
-rw-r--r--app/services/projects/import_export/export_service.rb2
-rw-r--r--app/services/projects/import_service.rb2
-rw-r--r--app/services/todo_service.rb3
-rw-r--r--app/views/admin/groups/_group.html.haml40
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/admin/projects/index.html.haml2
-rw-r--r--app/views/admin/users/_user.html.haml2
-rw-r--r--app/views/dashboard/projects/_zero_authorized_projects.html.haml87
-rw-r--r--app/views/dashboard/projects/index.html.haml3
-rw-r--r--app/views/devise/sessions/two_factor.html.haml4
-rw-r--r--app/views/errors/access_denied.html.haml2
-rw-r--r--app/views/groups/group_members/_new_group_member.html.haml2
-rw-r--r--app/views/help/_shortcuts.html.haml4
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/_search.html.haml2
-rw-r--r--app/views/layouts/header/_default.html.haml18
-rw-r--r--app/views/notify/note_merge_request_email.html.haml2
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml4
-rw-r--r--app/views/projects/ci/pipelines/_pipeline.html.haml24
-rw-r--r--app/views/projects/compare/_form.html.haml18
-rw-r--r--app/views/projects/compare/_ref_dropdown.html.haml4
-rw-r--r--app/views/projects/new.html.haml7
-rw-r--r--app/views/projects/project_members/_new_project_member.html.haml2
-rw-r--r--app/views/projects/protected_branches/index.html.haml4
-rw-r--r--app/views/shared/_import_form.html.haml2
-rw-r--r--app/views/shared/icons/_group.svg.erb (renamed from app/views/shared/icons/_group.svg)9
-rw-r--r--app/views/shared/icons/_project.svg10
-rw-r--r--app/views/shared/icons/_project.svg.erb3
-rw-r--r--app/views/shared/issuable/_form.html.haml9
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml2
-rw-r--r--app/workers/git_garbage_collect_worker.rb4
-rw-r--r--config/application.rb1
-rw-r--r--db/migrate/20160707104333_add_lock_to_issuables.rb17
-rw-r--r--db/schema.rb22
-rw-r--r--doc/ci/yaml/README.md4
-rw-r--r--doc/development/doc_styleguide.md2
-rw-r--r--doc/development/ui_guide.md48
-rw-r--r--doc/integration/oauth_provider.md3
-rw-r--r--features/project/merge_requests.feature2
-rw-r--r--lib/api/internal.rb7
-rw-r--r--lib/banzai/filter/syntax_highlight_filter.rb15
-rw-r--r--lib/banzai/filter/user_reference_filter.rb10
-rw-r--r--lib/gitlab/database/migration_helpers.rb10
-rw-r--r--lib/gitlab/gitlab_import/importer.rb53
-rw-r--r--lib/gitlab/highlight.rb43
-rw-r--r--lib/gitlab/import_export.rb7
-rw-r--r--lib/gitlab/import_export/project_tree_restorer.rb5
-rw-r--r--lib/gitlab/import_export/relation_factory.rb8
-rw-r--r--lib/gitlab/import_export/saver.rb5
-rw-r--r--lib/rouge/formatters/html_gitlab.rb168
-rw-r--r--spec/features/compare_spec.rb42
-rw-r--r--spec/features/groups_spec.rb20
-rw-r--r--spec/features/issues_spec.rb11
-rw-r--r--spec/features/merge_requests/edit_mr_spec.rb11
-rw-r--r--spec/features/u2f_spec.rb55
-rw-r--r--spec/fixtures/parallel_diff_result.yml12
-rw-r--r--spec/helpers/blob_helper_spec.rb32
-rw-r--r--spec/helpers/events_helper_spec.rb2
-rw-r--r--spec/javascripts/u2f/authenticate_spec.coffee3
-rw-r--r--spec/javascripts/u2f/register_spec.js.coffee1
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb34
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb4
-rw-r--r--spec/lib/gitlab/diff/highlight_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/import_export_spec.rb21
-rw-r--r--spec/lib/gitlab/import_export/project.json1
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb8
-rw-r--r--spec/models/legacy_diff_note_spec.rb8
-rw-r--r--spec/models/project_spec.rb22
-rw-r--r--spec/requests/api/internal_spec.rb14
-rw-r--r--spec/services/todo_service_spec.rb53
-rw-r--r--spec/support/fake_u2f_device.rb4
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb5
116 files changed, 1249 insertions, 1055 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 3aac8401848..db0bcfadcf4 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,6 +2,8 @@ require:
- rubocop-rspec
- ./rubocop/rubocop
+inherit_from: .rubocop_todo.yml
+
AllCops:
TargetRubyVersion: 2.1
# Cop names are not displayed in offense messages by default. Change behavior
@@ -52,14 +54,6 @@ Style/AlignArray:
Style/AlignHash:
Enabled: true
-# Align the parameters of a method call if they span more than one line.
-Style/AlignParameters:
- Enabled: false
-
-# Use &&/|| instead of and/or.
-Style/AndOr:
- Enabled: false
-
# Use `Array#join` instead of `Array#*`.
Style/ArrayJoin:
Enabled: true
@@ -80,10 +74,6 @@ Style/Attr:
Style/BeginBlock:
Enabled: true
-# Checks if usage of %() or %Q() matches configuration.
-Style/BarePercentLiterals:
- Enabled: false
-
# Do not use block comments.
Style/BlockComments:
Enabled: true
@@ -97,14 +87,6 @@ Style/BlockEndNewline:
Style/BlockDelimiters:
Enabled: true
-# Enforce braces style around hash parameters.
-Style/BracesAroundHashParameters:
- Enabled: false
-
-# Avoid explicit use of the case equality operator(===).
-Style/CaseEquality:
- Enabled: false
-
# Indentation of when in a case/when/[else/]end.
Style/CaseIndentation:
Enabled: true
@@ -133,24 +115,10 @@ Style/ClassMethods:
Style/ClassVars:
Enabled: true
-# Do not use :: for method call.
-Style/ColonMethodCall:
- Enabled: false
-
-# Checks formatting of special comments (TODO, FIXME, OPTIMIZE, HACK, REVIEW).
-Style/CommentAnnotation:
- Enabled: false
-
# Indentation of comments.
Style/CommentIndentation:
Enabled: true
-# Use the return value of `if` and `case` statements for assignment to a
-# variable and variable comparison instead of assigning that variable
-# inside of each branch.
-Style/ConditionalAssignment:
- Enabled: false
-
# Constants should use SCREAMING_SNAKE_CASE.
Style/ConstantName:
Enabled: true
@@ -159,34 +127,14 @@ Style/ConstantName:
Style/DefWithParentheses:
Enabled: true
-# Checks for use of deprecated Hash methods.
-Style/DeprecatedHashMethods:
- Enabled: false
-
# Document classes and non-namespace modules.
Style/Documentation:
Enabled: false
-# Checks the position of the dot in multi-line method calls.
-Style/DotPosition:
- Enabled: false
-
-# Checks for uses of double negation (!!).
-Style/DoubleNegation:
- Enabled: false
-
-# Prefer `each_with_object` over `inject` or `reduce`.
-Style/EachWithObject:
- Enabled: false
-
# Align elses and elsifs correctly.
Style/ElseAlignment:
Enabled: true
-# Avoid empty else-clauses.
-Style/EmptyElse:
- Enabled: false
-
# Use empty lines between defs.
Style/EmptyLineBetweenDefs:
Enabled: false
@@ -215,10 +163,6 @@ Style/EmptyLinesAroundModuleBody:
Style/EmptyLinesAroundMethodBody:
Enabled: false
-# Prefer literals to Array.new/Hash.new/String.new.
-Style/EmptyLiteral:
- Enabled: false
-
# Avoid the use of END blocks.
Style/EndBlock:
Enabled: true
@@ -231,10 +175,6 @@ Style/EndOfLine:
Style/EvenOdd:
Enabled: true
-# Do not use unnecessary spacing.
-Style/ExtraSpacing:
- Enabled: false
-
# Use snake_case for source file names.
Style/FileName:
Enabled: true
@@ -252,31 +192,15 @@ Style/FlipFlop:
Style/For:
Enabled: true
-# Enforce the use of Kernel#sprintf, Kernel#format or String#%.
-Style/FormatString:
- Enabled: false
-
# Do not introduce global variables.
Style/GlobalVars:
Enabled: true
-# Check for conditionals that can be replaced with guard clauses.
-Style/GuardClause:
- Enabled: false
-
# Prefer Ruby 1.9 hash syntax `{ a: 1, b: 2 }`
# over 1.8 syntax `{ :a => 1, :b => 2 }`.
Style/HashSyntax:
Enabled: true
-# Finds if nodes inside else, which can be converted to elsif.
-Style/IfInsideElse:
- Enabled: false
-
-# Favor modifier if/unless usage when you have a single-line body.
-Style/IfUnlessModifier:
- Enabled: false
-
# Do not use if x; .... Use the ternary operator instead.
Style/IfWithSemicolon:
Enabled: true
@@ -299,22 +223,10 @@ Style/IndentationConsistency:
Style/IndentationWidth:
Enabled: true
-# Checks the indentation of the first element in an array literal.
-Style/IndentArray:
- Enabled: false
-
-# Checks the indentation of the first key in a hash literal.
-Style/IndentHash:
- Enabled: false
-
# Use Kernel#loop for infinite loops.
Style/InfiniteLoop:
Enabled: true
-# Use the new lambda literal syntax for single-line blocks.
-Style/Lambda:
- Enabled: false
-
# Use lambda.call(...) instead of lambda.(...).
Style/LambdaCall:
Enabled: true
@@ -323,14 +235,6 @@ Style/LambdaCall:
Style/LeadingCommentSpace:
Enabled: true
-# Use \ instead of + or << to concatenate two string literals at line end.
-Style/LineEndConcatenation:
- Enabled: false
-
-# Do not use parentheses for method calls with no arguments.
-Style/MethodCallParentheses:
- Enabled: false
-
# Checks if the method definitions have or don't have parentheses.
Style/MethodDefParentheses:
Enabled: true
@@ -387,39 +291,18 @@ Style/MultilineMethodDefinitionBraceLayout:
Style/MultilineOperationIndentation:
Enabled: false
-# Avoid multi-line `? :` (the ternary operator), use if/unless instead.
-Style/MultilineTernaryOperator:
- Enabled: false
-
-# Do not assign mutable objects to constants.
-Style/MutableConstant:
- Enabled: false
-
# Favor unless over if for negative conditions (or control flow or).
Style/NegatedIf:
Enabled: true
-# Favor until over while for negative conditions.
-Style/NegatedWhile:
- Enabled: false
-
# Avoid using nested modifiers.
Style/NestedModifier:
Enabled: true
-# Parenthesize method calls which are nested inside the argument list of
-# another parenthesized method call.
-Style/NestedParenthesizedCalls:
- Enabled: false
-
# Use one expression per branch in a ternary operator.
Style/NestedTernaryOperator:
Enabled: true
-# Use `next` to skip iteration instead of a condition at the end.
-Style/Next:
- Enabled: false
-
# Prefer x.nil? to x == nil.
Style/NilComparison:
Enabled: true
@@ -444,51 +327,10 @@ Style/OneLineConditional:
Style/OpMethod:
Enabled: true
-# Check for simple usages of parallel assignment. It will only warn when
-# the number of variables matches on both sides of the assignment.
-Style/ParallelAssignment:
- Enabled: false
-
# Don't use parentheses around the condition of an if/unless/while.
Style/ParenthesesAroundCondition:
Enabled: true
-# Use `%`-literal delimiters consistently.
-Style/PercentLiteralDelimiters:
- Enabled: false
-
-# Checks if uses of %Q/%q match the configured preference.
-Style/PercentQLiterals:
- Enabled: false
-
-# Avoid Perl-style regex back references.
-Style/PerlBackrefs:
- Enabled: false
-
-# Check the names of predicate methods.
-Style/PredicateName:
- Enabled: false
-
-# Use proc instead of Proc.new.
-Style/Proc:
- Enabled: false
-
-# Checks the arguments passed to raise/fail.
-Style/RaiseArgs:
- Enabled: false
-
-# Don't use begin blocks when they are not needed.
-Style/RedundantBegin:
- Enabled: false
-
-# Checks for an obsolete RuntimeException argument in raise/fail.
-Style/RedundantException:
- Enabled: false
-
-# Checks usages of Object#freeze on immutable objects.
-Style/RedundantFreeze:
- Enabled: false
-
# Checks for parentheses that seem not to serve any purpose.
Style/RedundantParentheses:
Enabled: true
@@ -497,24 +339,6 @@ Style/RedundantParentheses:
Style/RedundantReturn:
Enabled: true
-# Don't use self where it's not needed.
-Style/RedundantSelf:
- Enabled: false
-
-# Use %r for regular expressions matching more than `MaxSlashes` '/'
-# characters. Use %r only for regular expressions matching more
-# than `MaxSlashes` '/' character.
-Style/RegexpLiteral:
- Enabled: false
-
-# Avoid using rescue in its modifier form.
-Style/RescueModifier:
- Enabled: false
-
-# Checks for places where self-assignment shorthand should have been used.
-Style/SelfAssignment:
- Enabled: false
-
# Don't use semicolons to terminate expressions.
Style/Semicolon:
Enabled: true
@@ -524,14 +348,6 @@ Style/SignalException:
EnforcedStyle: only_raise
Enabled: true
-# Enforces the names of some block params.
-Style/SingleLineBlockParams:
- Enabled: false
-
-# Avoid single-line methods.
-Style/SingleLineMethods:
- Enabled: false
-
# Use spaces after colons.
Style/SpaceAfterColon:
Enabled: true
@@ -553,11 +369,6 @@ Style/SpaceAfterNot:
Style/SpaceAfterSemicolon:
Enabled: true
-# Checks that the equals signs in parameter default assignments have or don't
-# have surrounding space depending on configuration.
-Style/SpaceAroundEqualsInParameterDefault:
- Enabled: false
-
# Use a space around keywords if appropriate.
Style/SpaceAroundKeyword:
Enabled: true
@@ -566,10 +377,6 @@ Style/SpaceAroundKeyword:
Style/SpaceAroundOperators:
Enabled: true
-# Checks that the left block brace has or doesn't have space before it.
-Style/SpaceBeforeBlockBraces:
- Enabled: false
-
# No spaces before commas.
Style/SpaceBeforeComma:
Enabled: true
@@ -578,33 +385,14 @@ Style/SpaceBeforeComma:
Style/SpaceBeforeComment:
Enabled: true
-# Checks that exactly one space is used between a method name and the first
-# argument for method calls without parentheses.
-Style/SpaceBeforeFirstArg:
- Enabled: false
-
# No spaces before semicolons.
Style/SpaceBeforeSemicolon:
Enabled: true
-# Checks that block braces have or don't have surrounding space.
-# For blocks taking parameters, checks that the left brace has or doesn't
-# have trailing space.
-Style/SpaceInsideBlockBraces:
- Enabled: false
-
-# No spaces after [ or before ].
-Style/SpaceInsideBrackets:
- Enabled: false
-
# Use spaces inside hash literal braces - or don't.
Style/SpaceInsideHashLiteralBraces:
Enabled: true
-# No spaces after ( or before ).
-Style/SpaceInsideParens:
- Enabled: false
-
# No spaces inside range literals.
Style/SpaceInsideRangeLiteral:
Enabled: true
@@ -614,10 +402,6 @@ Style/SpaceInsideStringInterpolation:
EnforcedStyle: no_space
Enabled: true
-# Avoid Perl-style global variables.
-Style/SpecialGlobalVars:
- Enabled: false
-
# Check for the usage of parentheses around stabby lambda arguments.
Style/StabbyLambdaParentheses:
EnforcedStyle: require_parentheses
@@ -627,25 +411,12 @@ Style/StabbyLambdaParentheses:
Style/StringLiterals:
Enabled: false
-# Checks if uses of quotes inside expressions in interpolated strings match the
-# configured preference.
-Style/StringLiteralsInInterpolation:
- Enabled: false
-
# Checks if configured preferred methods are used over non-preferred.
Style/StringMethods:
PreferredMethods:
intern: to_sym
Enabled: true
-# Use %i or %I for arrays of symbols.
-Style/SymbolArray:
- Enabled: false
-
-# Use symbols as procs instead of blocks when possible.
-Style/SymbolProc:
- Enabled: false
-
# No hard tabs.
Style/Tab:
Enabled: true
@@ -654,40 +425,10 @@ Style/Tab:
Style/TrailingBlankLines:
Enabled: true
-# Checks for trailing comma in array and hash literals.
-Style/TrailingCommaInLiteral:
- Enabled: false
-
-# Checks for trailing comma in argument lists.
-Style/TrailingCommaInArguments:
- Enabled: false
-
-# Avoid trailing whitespace.
-Style/TrailingWhitespace:
- Enabled: false
-
-# Checks for the usage of unneeded trailing underscores at the end of
-# parallel variable assignment.
-Style/TrailingUnderscoreVariable:
- Enabled: false
-
-# Prefer attr_* methods to trivial readers/writers.
-Style/TrivialAccessors:
- Enabled: false
-
-# Do not use unless with else. Rewrite these with the positive case first.
-Style/UnlessElse:
- Enabled: false
-
# Checks for %W when interpolation is not needed.
Style/UnneededCapitalW:
Enabled: true
-# TODO: Enable UnneededInterpolation Cop.
-# Checks for strings that are just an interpolated expression.
-Style/UnneededInterpolation:
- Enabled: false
-
# Checks for %q/%Q when single quotes or double quotes would do.
Style/UnneededPercentQ:
Enabled: false
@@ -717,12 +458,6 @@ Style/WhileUntilModifier:
Style/WordArray:
Enabled: false
-# TODO: Enable ZeroLengthPredicate Cop.
-# Use #empty? when testing for objects of length 0.
-Style/ZeroLengthPredicate:
- Enabled: false
-
-
#################### Metrics ################################
# A calculated magnitude based on number of assignments,
@@ -776,15 +511,6 @@ Metrics/PerceivedComplexity:
Lint/AmbiguousOperator:
Enabled: true
-# Checks for ambiguous regexp literals in the first argument of a method
-# invocation without parentheses.
-Lint/AmbiguousRegexpLiteral:
- Enabled: false
-
-# Don't use assignment in conditions.
-Lint/AssignmentInCondition:
- Enabled: false
-
# Align block ends correctly.
Lint/BlockAlignment:
Enabled: true
@@ -810,14 +536,6 @@ Lint/DefEndAlignment:
Lint/DeprecatedClassMethods:
Enabled: true
-# Check for duplicate method definitions.
-Lint/DuplicateMethods:
- Enabled: false
-
-# Check for duplicate keys in hash literals.
-Lint/DuplicatedKey:
- Enabled: false
-
# Check for immutable argument given to each_with_object.
Lint/EachWithObjectArgument:
Enabled: true
@@ -830,10 +548,6 @@ Lint/ElseLayout:
Lint/EmptyEnsure:
Enabled: true
-# Checks for empty string interpolation.
-Lint/EmptyInterpolation:
- Enabled: false
-
# Align ends correctly.
Lint/EndAlignment:
Enabled: true
@@ -858,21 +572,11 @@ Lint/FloatOutOfRange:
Lint/FormatParameterMismatch:
Enabled: true
-# Don't suppress exception.
-Lint/HandleExceptions:
- Enabled: false
-
# Checks for adjacent string literals on the same line, which could better be
# represented as a single string literal.
Lint/ImplicitStringConcatenation:
Enabled: true
-# TODO: Enable IneffectiveAccessModifier Cop.
-# Checks for attempts to use `private` or `protected` to set the visibility
-# of a class method, which does not work.
-Lint/IneffectiveAccessModifier:
- Enabled: false
-
# Checks for invalid character literals with a non-escaped whitespace
# character.
Lint/InvalidCharacterLiteral:
@@ -886,11 +590,6 @@ Lint/LiteralInCondition:
Lint/LiteralInInterpolation:
Enabled: true
-# Use Kernel#loop with break rather than begin/end/until or begin/end/while
-# for post-loop tests.
-Lint/Loop:
- Enabled: false
-
# Do not use nested method definitions.
Lint/NestedMethodDefinition:
Enabled: true
@@ -916,13 +615,8 @@ Lint/RequireParentheses:
Lint/RescueException:
Enabled: true
-# Do not use the same name as outer local variable for block arguments
-# or block local variables.
-Lint/ShadowingOuterLocalVariable:
- Enabled: false
-
-# 'Checks for Object#to_s usage in string interpolation.
-Lint/StringConversionInInterpolation:
+# Checks for the order which exceptions are rescued to avoid rescueing a less specific exception before a more specific exception.
+Lint/ShadowedException:
Enabled: false
# Do not use prefix `_` for a variable that is used.
@@ -935,22 +629,10 @@ Lint/UnderscorePrefixedVariableName:
Lint/UnneededDisable:
Enabled: false
-# Checks for unused block arguments.
-Lint/UnusedBlockArgument:
- Enabled: false
-
-# Checks for unused method arguments.
-Lint/UnusedMethodArgument:
- Enabled: false
-
# Unreachable code.
Lint/UnreachableCode:
Enabled: true
-# Checks for useless access modifiers.
-Lint/UselessAccessModifier:
- Enabled: false
-
# Checks for useless assignment to a local variable.
Lint/UselessAssignment:
Enabled: true
@@ -983,11 +665,6 @@ Performance/Casecmp:
Performance/DoubleStartEndWith:
Enabled: true
-# TODO: Enable EndWith Cop.
-# Use `end_with?` instead of a regex match anchored to the end of a string.
-Performance/EndWith:
- Enabled: false
-
# Use `strip` instead of `lstrip.rstrip`.
Performance/LstripRstrip:
Enabled: true
@@ -996,24 +673,6 @@ Performance/LstripRstrip:
Performance/RangeInclude:
Enabled: true
-# TODO: Enable RedundantBlockCall Cop.
-# Use `yield` instead of `block.call`.
-Performance/RedundantBlockCall:
- Enabled: false
-
-# TODO: Enable RedundantMatch Cop.
-# Use `=~` instead of `String#match` or `Regexp#match` in a context where the
-# returned `MatchData` is not needed.
-Performance/RedundantMatch:
- Enabled: false
-
-# TODO: Enable RedundantMerge Cop.
-# Use `Hash#[]=`, rather than `Hash#merge!` with a single key-value pair.
-Performance/RedundantMerge:
- # Max number of key-value pairs to consider an offense
- MaxKeyValuePairs: 2
- Enabled: false
-
# Use `sort` instead of `sort_by { |x| x }`.
Performance/RedundantSortBy:
Enabled: true
@@ -1082,18 +741,6 @@ Rails/ReadWriteAttribute:
Rails/ScopeArgs:
Enabled: true
-# Checks the correct usage of time zone aware methods.
-# http://danilenko.org/2012/7/6/rails_timezones
-Rails/TimeZone:
- Enabled: false
-
-# Use validates :attribute, hash of validations.
-Rails/Validation:
- Enabled: false
-
-Rails/UniqBeforePluck:
- Enabled: false
-
##################### RSpec ##################################
# Check that instances are not being stubbed globally.
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
new file mode 100644
index 00000000000..9310e711889
--- /dev/null
+++ b/.rubocop_todo.yml
@@ -0,0 +1,462 @@
+# This configuration was generated by
+# `rubocop --auto-gen-config --exclude-limit 0`
+# on 2016-07-13 12:36:08 -0600 using RuboCop version 0.41.2.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
+
+# Offense count: 154
+Lint/AmbiguousRegexpLiteral:
+ Enabled: false
+
+# Offense count: 43
+# Configuration parameters: AllowSafeAssignment.
+Lint/AssignmentInCondition:
+ Enabled: false
+
+# Offense count: 14
+Lint/HandleExceptions:
+ Enabled: false
+
+# Offense count: 21
+Lint/IneffectiveAccessModifier:
+ Enabled: false
+
+# Offense count: 2
+Lint/Loop:
+ Enabled: false
+
+# Offense count: 15
+Lint/ShadowingOuterLocalVariable:
+ Enabled: false
+
+# Offense count: 3
+# Cop supports --auto-correct.
+Lint/StringConversionInInterpolation:
+ Enabled: false
+
+# Offense count: 44
+# Cop supports --auto-correct.
+# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
+Lint/UnusedBlockArgument:
+ Enabled: false
+
+# Offense count: 129
+# Cop supports --auto-correct.
+# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
+Lint/UnusedMethodArgument:
+ Enabled: false
+
+# Offense count: 11
+Lint/UselessAccessModifier:
+ Enabled: false
+
+# Offense count: 12
+# Cop supports --auto-correct.
+Performance/PushSplat:
+ Enabled: false
+
+# Offense count: 2
+# Cop supports --auto-correct.
+Performance/RedundantBlockCall:
+ Enabled: false
+
+# Offense count: 4
+# Cop supports --auto-correct.
+Performance/RedundantMatch:
+ Enabled: false
+
+# Offense count: 24
+# Cop supports --auto-correct.
+# Configuration parameters: MaxKeyValuePairs.
+Performance/RedundantMerge:
+ Enabled: false
+
+# Offense count: 60
+Rails/OutputSafety:
+ Enabled: false
+
+# Offense count: 128
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: strict, flexible
+Rails/TimeZone:
+ Enabled: false
+
+# Offense count: 12
+# Cop supports --auto-correct.
+# Configuration parameters: Include.
+# Include: app/models/**/*.rb
+Rails/Validation:
+ Enabled: false
+
+# Offense count: 217
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
+# SupportedStyles: with_first_parameter, with_fixed_indentation
+Style/AlignParameters:
+ Enabled: false
+
+# Offense count: 32
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: always, conditionals
+Style/AndOr:
+ Enabled: false
+
+# Offense count: 47
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: percent_q, bare_percent
+Style/BarePercentLiterals:
+ Enabled: false
+
+# Offense count: 258
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: braces, no_braces, context_dependent
+Style/BracesAroundHashParameters:
+ Enabled: false
+
+# Offense count: 5
+Style/CaseEquality:
+ Enabled: false
+
+# Offense count: 19
+# Cop supports --auto-correct.
+Style/ColonMethodCall:
+ Enabled: false
+
+# Offense count: 3
+# Cop supports --auto-correct.
+# Configuration parameters: Keywords.
+# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW
+Style/CommentAnnotation:
+ Enabled: false
+
+# Offense count: 34
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly.
+# SupportedStyles: assign_to_condition, assign_inside_condition
+Style/ConditionalAssignment:
+ Enabled: false
+
+# Offense count: 789
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: leading, trailing
+Style/DotPosition:
+ Enabled: false
+
+# Offense count: 13
+Style/DoubleNegation:
+ Enabled: false
+
+# Offense count: 3
+Style/EachWithObject:
+ Enabled: false
+
+# Offense count: 30
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: empty, nil, both
+Style/EmptyElse:
+ Enabled: false
+
+# Offense count: 3
+# Cop supports --auto-correct.
+Style/EmptyLiteral:
+ Enabled: false
+
+# Offense count: 123
+# Cop supports --auto-correct.
+# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
+Style/ExtraSpacing:
+ Enabled: false
+
+# Offense count: 7
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: format, sprintf, percent
+Style/FormatString:
+ Enabled: false
+
+# Offense count: 48
+# Configuration parameters: MinBodyLength.
+Style/GuardClause:
+ Enabled: false
+
+# Offense count: 11
+Style/IfInsideElse:
+ Enabled: false
+
+# Offense count: 177
+# Cop supports --auto-correct.
+# Configuration parameters: MaxLineLength.
+Style/IfUnlessModifier:
+ Enabled: false
+
+# Offense count: 52
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
+# SupportedStyles: special_inside_parentheses, consistent, align_brackets
+Style/IndentArray:
+ Enabled: false
+
+# Offense count: 89
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
+# SupportedStyles: special_inside_parentheses, consistent, align_braces
+Style/IndentHash:
+ Enabled: false
+
+# Offense count: 12
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: line_count_dependent, lambda, literal
+Style/Lambda:
+ Enabled: false
+
+# Offense count: 6
+# Cop supports --auto-correct.
+Style/LineEndConcatenation:
+ Enabled: false
+
+# Offense count: 13
+# Cop supports --auto-correct.
+Style/MethodCallParentheses:
+ Enabled: false
+
+# Offense count: 3
+Style/MultilineTernaryOperator:
+ Enabled: false
+
+# Offense count: 62
+# Cop supports --auto-correct.
+Style/MutableConstant:
+ Enabled: false
+
+# Offense count: 10
+# Cop supports --auto-correct.
+Style/NestedParenthesizedCalls:
+ Enabled: false
+
+# Offense count: 12
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
+# SupportedStyles: skip_modifier_ifs, always
+Style/Next:
+ Enabled: false
+
+# Offense count: 8
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles.
+# SupportedOctalStyles: zero_with_o, zero_only
+Style/NumericLiteralPrefix:
+ Enabled: false
+
+# Offense count: 29
+# Cop supports --auto-correct.
+Style/ParallelAssignment:
+ Enabled: false
+
+# Offense count: 208
+# Cop supports --auto-correct.
+# Configuration parameters: PreferredDelimiters.
+Style/PercentLiteralDelimiters:
+ Enabled: false
+
+# Offense count: 11
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: lower_case_q, upper_case_q
+Style/PercentQLiterals:
+ Enabled: false
+
+# Offense count: 13
+# Cop supports --auto-correct.
+Style/PerlBackrefs:
+ Enabled: false
+
+# Offense count: 32
+# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
+# NamePrefix: is_, has_, have_
+# NamePrefixBlacklist: is_, has_, have_
+# NameWhitelist: is_a?
+Style/PredicateName:
+ Enabled: false
+
+# Offense count: 28
+# Cop supports --auto-correct.
+Style/PreferredHashMethods:
+ Enabled: false
+
+# Offense count: 6
+# Cop supports --auto-correct.
+Style/Proc:
+ Enabled: false
+
+# Offense count: 20
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: compact, exploded
+Style/RaiseArgs:
+ Enabled: false
+
+# Offense count: 3
+# Cop supports --auto-correct.
+Style/RedundantBegin:
+ Enabled: false
+
+# Offense count: 1
+# Cop supports --auto-correct.
+Style/RedundantException:
+ Enabled: false
+
+# Offense count: 23
+# Cop supports --auto-correct.
+Style/RedundantFreeze:
+ Enabled: false
+
+# Offense count: 377
+# Cop supports --auto-correct.
+Style/RedundantSelf:
+ Enabled: false
+
+# Offense count: 94
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
+# SupportedStyles: slashes, percent_r, mixed
+Style/RegexpLiteral:
+ Enabled: false
+
+# Offense count: 17
+# Cop supports --auto-correct.
+Style/RescueModifier:
+ Enabled: false
+
+# Offense count: 2
+# Cop supports --auto-correct.
+Style/SelfAssignment:
+ Enabled: false
+
+# Offense count: 2
+# Configuration parameters: Methods.
+# Methods: {"reduce"=>["a", "e"]}, {"inject"=>["a", "e"]}
+Style/SingleLineBlockParams:
+ Enabled: false
+
+# Offense count: 50
+# Cop supports --auto-correct.
+# Configuration parameters: AllowIfMethodIsEmpty.
+Style/SingleLineMethods:
+ Enabled: false
+
+# Offense count: 14
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: space, no_space
+Style/SpaceAroundEqualsInParameterDefault:
+ Enabled: false
+
+# Offense count: 119
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: space, no_space
+Style/SpaceBeforeBlockBraces:
+ Enabled: false
+
+# Offense count: 11
+# Cop supports --auto-correct.
+# Configuration parameters: AllowForAlignment.
+Style/SpaceBeforeFirstArg:
+ Enabled: false
+
+# Offense count: 130
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
+# SupportedStyles: space, no_space
+Style/SpaceInsideBlockBraces:
+ Enabled: false
+
+# Offense count: 98
+# Cop supports --auto-correct.
+Style/SpaceInsideBrackets:
+ Enabled: false
+
+# Offense count: 60
+# Cop supports --auto-correct.
+Style/SpaceInsideParens:
+ Enabled: false
+
+# Offense count: 5
+# Cop supports --auto-correct.
+Style/SpaceInsidePercentLiteralDelimiters:
+ Enabled: false
+
+# Offense count: 36
+# Cop supports --auto-correct.
+# Configuration parameters: SupportedStyles.
+# SupportedStyles: use_perl_names, use_english_names
+Style/SpecialGlobalVars:
+ EnforcedStyle: use_perl_names
+
+# Offense count: 30
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: single_quotes, double_quotes
+Style/StringLiteralsInInterpolation:
+ Enabled: false
+
+# Offense count: 24
+# Cop supports --auto-correct.
+# Configuration parameters: IgnoredMethods.
+# IgnoredMethods: respond_to, define_method
+Style/SymbolProc:
+ Enabled: false
+
+# Offense count: 23
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
+# SupportedStyles: comma, consistent_comma, no_comma
+Style/TrailingCommaInArguments:
+ Enabled: false
+
+# Offense count: 113
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
+# SupportedStyles: comma, consistent_comma, no_comma
+Style/TrailingCommaInLiteral:
+ Enabled: false
+
+# Offense count: 7
+# Cop supports --auto-correct.
+# Configuration parameters: AllowNamedUnderscoreVariables.
+Style/TrailingUnderscoreVariable:
+ Enabled: false
+
+# Offense count: 90
+# Cop supports --auto-correct.
+Style/TrailingWhitespace:
+ Enabled: false
+
+# Offense count: 2
+# Cop supports --auto-correct.
+# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
+# Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym
+Style/TrivialAccessors:
+ Enabled: false
+
+# Offense count: 3
+# Cop supports --auto-correct.
+Style/UnlessElse:
+ Enabled: false
+
+# Offense count: 13
+# Cop supports --auto-correct.
+Style/UnneededInterpolation:
+ Enabled: false
+
+# Offense count: 8
+# Cop supports --auto-correct.
+Style/ZeroLengthPredicate:
+ Enabled: false
diff --git a/CHANGELOG b/CHANGELOG
index 139444ef70e..57ee5361281 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,10 +2,11 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.10.0 (unreleased)
- Expose {should,force}_remove_source_branch (Ben Boeckel)
+ - Disable PostgreSQL statement timeout during migrations
- Fix projects dropdown loading performance with a simplified api cal. !5113 (tiagonbotelho)
- Fix commit builds API, return all builds for all pipelines for given commit. !4849
- Replace Haml with Hamlit to make view rendering faster. !3666
- - Expire the branch cache after `git gc` runs
+ - Refresh the branch cache after `git gc` runs
- Refactor repository paths handling to allow multiple git mount points
- Optimize system note visibility checking by memoizing the visible reference count !5070
- Add Application Setting to configure default Repository Path for new projects
@@ -14,6 +15,7 @@ v 8.10.0 (unreleased)
- Wrap code blocks on Activies and Todos page. !4783 (winniehell)
- Align flash messages with left side of page content !4959 (winniehell)
- Display tooltip for "Copy to Clipboard" button !5164 (winniehell)
+ - Use default cursor for table header of project files !5165 (winniehell)
- Display last commit of deleted branch in push events !4699 (winniehell)
- Escape file extension when parsing search results !5141 (winniehell)
- Apply the trusted_proxies config to the rack request object for use with rack_attack
@@ -21,17 +23,22 @@ v 8.10.0 (unreleased)
- Add Sidekiq queue duration to transaction metrics.
- Add a new column `artifacts_size` to table `ci_builds` !4964
- Let Workhorse serve format-patch diffs
+ - Display tooltip for mentioned users and groups !5261 (winniehell)
- Added day name to contribution calendar tooltips
- Make images fit to the size of the viewport !4810
- Fix check for New Branch button on Issue page !4630 (winniehell)
- Fix MR-auto-close text added to description. !4836
+ - Support U2F devices in Firefox. !5177
- Fix issue, preventing users w/o push access to sort tags !5105 (redetection)
- Add Spring EmojiOne updates.
- Add syntax for multiline blockquote using `>>>` fence !3954
- Fix viewing notification settings when a project is pending deletion
+ - Updated compare dropdown menus to use GL dropdown
+ - Eager load award emoji on notes
- Fix pagination when sorting by columns with lots of ties (like priority)
- The Markdown reference parsers now re-use query results to prevent running the same queries multiple times !5020
- Updated project header design
+ - Issuable collapsed assignee tooltip is now the users name
- Exclude email check from the standard health check
- Updated layout for Projects, Groups, Users on Admin area !4424
- Fix changing issue state columns in milestone view
@@ -52,6 +59,7 @@ v 8.10.0 (unreleased)
- Throttle the update of `project.pushes_since_gc` to 1 minute.
- Allow expanding and collapsing files in diff view (!4990)
- Collapse large diffs by default (!4990)
+ - Fix mentioned users list on diff notes
- Check for conflicts with existing Project's wiki path when creating a new project.
- Show last push widget in upstream after push to fork
- Cache todos pending/done dashboard query counts.
@@ -80,7 +88,6 @@ v 8.10.0 (unreleased)
- Fix importer for GitHub Pull Requests when a branch was reused across Pull Requests
- Add date when user joined the team on the member page
- Fix 404 redirect after validation fails importing a GitLab project
- - Fix 404 redirect after validation fails importing a GitLab project
- Added setting to set new users by default as external !4545 (Dravere)
- Add min value for project limit field on user's form !3622 (jastkand)
- Reset project pushes_since_gc when we enqueue the git gc call
@@ -92,6 +99,11 @@ v 8.10.0 (unreleased)
- Redesign Builds and Pipelines pages
- Change status color and icon for running builds
- Fix markdown rendering for: consecutive labels references, label references that begin with a digit or contains `.`
+ - Project export filename now includes the project and namespace path
+ - Fix last update timestamp on issues not preserved on gitlab.com and project imports
+ - Fix issues importing projects from EE to CE
+ - Fix creating group with space in group path
+ - Create Todos for Issue author when assign or mention himself (Katarzyna Kobierska)
v 8.9.6
- Fix importing of events under notes for GitLab projects. !5154
@@ -101,7 +113,10 @@ v 8.9.6
- Overwrite Host and X-Forwarded-Host headers in NGINX !5213
- Keeps issue number when importing from Gitlab.com
-v 8.9.6 (unreleased)
+v 8.9.7 (unreleased)
+ - Fix import_data wrongly saved as a result of an invalid import_url
+
+v 8.9.6
- Fix importing of events under notes for GitLab projects
v 8.9.5
@@ -263,6 +278,7 @@ v 8.9.0
- Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database
- Changed the Slack build message to use the singular duration if necessary (Aran Koning)
- Fix race condition on merge when build succeeds
+ - Added shortcut to focus filter search fields and added documentation #18120
- Links from a wiki page to other wiki pages should be rewritten as expected
- Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos)
- Added navigation shortcuts to the project pipelines, milestones, builds and forks page. !4393
@@ -2224,8 +2240,6 @@ v 7.7.0
- Fixes for edit comments: drag-n-drop images, preview mode, selecting images, save & update
- Remove password strength indicator
-
-
v 7.6.0
- Fork repository to groups
- New rugged version
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f4472214778..14ff05c9aa3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -145,7 +145,8 @@ might be edited to make them small and simple.
You are encouraged to use the template below for feature proposals.
```
-## Description including problem, use cases, benefits, and/or goals
+## Description
+Include problem, use cases, benefits, and/or goals
## Proposal
diff --git a/Gemfile b/Gemfile
index ee23f712f05..81e8ff60ad5 100644
--- a/Gemfile
+++ b/Gemfile
@@ -61,7 +61,7 @@ gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: 'omniauth-ldap'
# Git Wiki
# Required manually in config/initializers/gollum.rb to control load order
-gem 'gollum-lib', '~> 4.1.0', require: false
+gem 'gollum-lib', '~> 4.2', require: false
gem 'gollum-rugged_adapter', '~> 0.4.2', require: false
# Language detection
@@ -105,7 +105,7 @@ gem 'seed-fu', '~> 2.3.5'
# Markdown and HTML processing
gem 'html-pipeline', '~> 1.11.0'
gem 'task_list', '~> 1.0.2', require: 'task_list/railtie'
-gem 'github-markup', '~> 1.3.1'
+gem 'github-markup', '~> 1.4'
gem 'redcarpet', '~> 3.3.3'
gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~>3.6'
@@ -113,7 +113,7 @@ gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.2'
-gem 'rouge', '~> 1.11'
+gem 'rouge', '~> 2.0'
# See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s
# and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM
@@ -299,7 +299,7 @@ group :development, :test do
gem 'spring-commands-spinach', '~> 1.1.0'
gem 'spring-commands-teaspoon', '~> 0.0.2'
- gem 'rubocop', '~> 0.40.0', require: false
+ gem 'rubocop', '~> 0.41.2', require: false
gem 'rubocop-rspec', '~> 1.5.0', require: false
gem 'scss_lint', '~> 0.47.0', require: false
gem 'simplecov', '~> 0.11.0', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 67c0645c3d9..0987fd5665a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -58,7 +58,7 @@ GEM
faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0)
asciidoctor (1.5.3)
- ast (2.2.0)
+ ast (2.3.0)
attr_encrypted (3.0.1)
encryptor (~> 3.0.0)
attr_required (1.0.0)
@@ -264,7 +264,7 @@ GEM
escape_utils (~> 1.1.0)
mime-types (>= 1.19)
rugged (>= 0.23.0b)
- github-markup (1.3.3)
+ github-markup (1.4.0)
gitlab-flowdock-git-hook (1.0.1)
flowdock (~> 0.7)
gitlab-grit (>= 2.4.1)
@@ -287,13 +287,13 @@ GEM
rubyntlm (~> 0.3)
globalid (0.3.6)
activesupport (>= 4.1.0)
- gollum-grit_adapter (1.0.0)
+ gollum-grit_adapter (1.0.1)
gitlab-grit (~> 2.7, >= 2.7.1)
- gollum-lib (4.1.0)
- github-markup (~> 1.3.3)
+ gollum-lib (4.2.1)
+ github-markup (~> 1.4.0)
gollum-grit_adapter (~> 1.0)
nokogiri (~> 1.6.4)
- rouge (~> 1.9)
+ rouge (~> 2.0)
sanitize (~> 2.1.0)
stringex (~> 2.5.1)
gollum-rugged_adapter (0.4.2)
@@ -473,7 +473,7 @@ GEM
orm_adapter (0.5.0)
paranoia (2.1.4)
activerecord (~> 4.0)
- parser (2.3.1.0)
+ parser (2.3.1.2)
ast (~> 2.2)
pg (0.18.4)
pkg-config (1.1.7)
@@ -578,7 +578,7 @@ GEM
railties (>= 4.2.0, < 5.1)
rinku (2.0.0)
rotp (2.1.2)
- rouge (1.11.0)
+ rouge (2.0.3)
rqrcode (0.7.0)
chunky_png
rqrcode-rails3 (0.1.7)
@@ -606,8 +606,8 @@ GEM
rspec-retry (0.4.5)
rspec-core
rspec-support (3.5.0)
- rubocop (0.40.0)
- parser (>= 2.3.1.0, < 3.0)
+ rubocop (0.41.2)
+ parser (>= 2.3.1.1, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7)
@@ -758,7 +758,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.7.2)
- unicode-display_width (1.0.5)
+ unicode-display_width (1.1.0)
unicorn (4.9.0)
kgio (~> 2.6)
rack
@@ -859,12 +859,12 @@ DEPENDENCIES
gemnasium-gitlab-service (~> 0.2)
gemojione (~> 2.6)
github-linguist (~> 4.7.0)
- github-markup (~> 1.3.1)
+ github-markup (~> 1.4)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab_git (~> 10.2)
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (~> 1.2.1)
- gollum-lib (~> 4.1.0)
+ gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.2)
gon (~> 6.0.1)
grape (~> 0.13.0)
@@ -933,11 +933,11 @@ DEPENDENCIES
request_store (~> 1.3.0)
rerun (~> 0.11.0)
responders (~> 2.0)
- rouge (~> 1.11)
+ rouge (~> 2.0)
rqrcode-rails3 (~> 0.1.7)
rspec-rails (~> 3.5.0)
rspec-retry (~> 0.4.5)
- rubocop (~> 0.40.0)
+ rubocop (~> 0.41.2)
rubocop-rspec (~> 1.5.0)
ruby-fogbugz (~> 0.2.1)
sanitize (~> 2.0)
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index c98763d6271..eceff6d91d5 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -53,7 +53,6 @@
#= require_directory ./u2f
#= require_directory .
#= require fuzzaldrin-plus
-#= require u2f
window.slugify = (text) ->
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
diff --git a/app/assets/javascripts/compare_autocomplete.js.coffee b/app/assets/javascripts/compare_autocomplete.js.coffee
new file mode 100644
index 00000000000..7ad9fd97637
--- /dev/null
+++ b/app/assets/javascripts/compare_autocomplete.js.coffee
@@ -0,0 +1,41 @@
+class @CompareAutocomplete
+ constructor: ->
+ @initDropdown()
+
+ initDropdown: ->
+ $('.js-compare-dropdown').each ->
+ $dropdown = $(@)
+ selected = $dropdown.data('selected')
+
+ $dropdown.glDropdown(
+ data: (term, callback) ->
+ $.ajax(
+ url: $dropdown.data('refs-url')
+ data:
+ ref: $dropdown.data('ref')
+ ).done (refs) ->
+ callback(refs)
+ selectable: true
+ filterable: true
+ filterByText: true
+ fieldName: $dropdown.attr('name')
+ filterInput: 'input[type="text"]'
+ renderRow: (ref) ->
+ if ref.header?
+ $('<li />')
+ .addClass('dropdown-header')
+ .text(ref.header)
+ else
+ link = $('<a />')
+ .attr('href', '#')
+ .addClass(if ref is selected then 'is-active' else '')
+ .text(ref)
+ .attr('data-ref', escape(ref))
+
+ $('<li />')
+ .append(link)
+ id: (obj, $el) ->
+ $el.attr('data-ref')
+ toggleLabel: (obj, $el) ->
+ $el.text().trim()
+ )
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 74fd77cf7ab..afaa6407b05 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -137,6 +137,8 @@ class Dispatcher
new Project()
new ProjectAvatar()
switch path[1]
+ when 'compare'
+ new CompareAutocomplete()
when 'edit'
shortcut_handler = new ShortcutsNavigation()
new ProjectNew()
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index 1c65e833d47..1b0d0db8954 100644
--- a/app/assets/javascripts/gl_dropdown.js.coffee
+++ b/app/assets/javascripts/gl_dropdown.js.coffee
@@ -456,6 +456,8 @@ class GitLabDropdown
rowClicked: (el) ->
fieldName = @options.fieldName
+ isInput = $(@el).is('input')
+
if @renderedData
groupName = el.data('group')
if groupName
@@ -466,10 +468,19 @@ class GitLabDropdown
selectedObject = @renderedData[selectedIndex]
value = if @options.id then @options.id(selectedObject, el) else selectedObject.id
- field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']")
+
+ if isInput
+ field = $(@el)
+ else
+ field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']")
+
if el.hasClass(ACTIVE_CLASS)
el.removeClass(ACTIVE_CLASS)
- field.remove()
+
+ if isInput
+ field.val('')
+ else
+ field.remove()
# Toggle the dropdown label
if @options.toggleLabel
@@ -490,7 +501,9 @@ class GitLabDropdown
else
if not @options.multiSelect or el.hasClass('dropdown-clear-active')
@dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS
- @dropdown.parent().find("input[name='#{fieldName}']").remove()
+
+ unless isInput
+ @dropdown.parent().find("input[name='#{fieldName}']").remove()
if !value?
field.remove()
@@ -505,7 +518,9 @@ class GitLabDropdown
if !field.length and fieldName
@addInput(fieldName, value)
else
- field.val value
+ field
+ .val value
+ .trigger 'change'
return selectedObject
diff --git a/app/assets/javascripts/issuable.js.coffee b/app/assets/javascripts/issuable.js.coffee
index c71d4ecf505..7f795f8096b 100644
--- a/app/assets/javascripts/issuable.js.coffee
+++ b/app/assets/javascripts/issuable.js.coffee
@@ -32,13 +32,11 @@ issuable_created = false
$search = $('#issue_search')
$form = $('.js-filter-form')
$input = $("input[name='#{$search.attr('name')}']", $form)
-
if $input.length is 0
$form.append "<input type='hidden' name='#{$search.attr('name')}' value='#{_.escape($search.val())}'/>"
else
$input.val $search.val()
-
- Issuable.filterResults $form
+ Issuable.filterResults $form if $search.val() isnt ''
, 500)
initLabelFilterRemove: ->
diff --git a/app/assets/javascripts/projects_list.js.coffee b/app/assets/javascripts/projects_list.js.coffee
index e4c4bf3b273..a7d78d9e461 100644
--- a/app/assets/javascripts/projects_list.js.coffee
+++ b/app/assets/javascripts/projects_list.js.coffee
@@ -5,13 +5,12 @@
this.initPagination()
initSearch: ->
- @timer = null
- $(".projects-list-filter").on('keyup', ->
- clearTimeout(@timer)
- @timer = setTimeout(ProjectsList.filterResults, 500)
- )
+ projectsListFilter = $('.projects-list-filter')
+ debounceFilter = _.debounce ProjectsList.filterResults, 500
+ projectsListFilter.on 'keyup', (e) ->
+ debounceFilter() if projectsListFilter.val() isnt ''
- filterResults: =>
+ filterResults: ->
$('.projects-list-holder').fadeTo(250, 0.5)
form = null
diff --git a/app/assets/javascripts/shortcuts.js.coffee b/app/assets/javascripts/shortcuts.js.coffee
index 3319a67a79d..8c8689bacee 100644
--- a/app/assets/javascripts/shortcuts.js.coffee
+++ b/app/assets/javascripts/shortcuts.js.coffee
@@ -2,9 +2,10 @@ class @Shortcuts
constructor: (skipResetBindings) ->
@enabledHelp = []
Mousetrap.reset() if not skipResetBindings
- Mousetrap.bind('?', @onToggleHelp)
- Mousetrap.bind('s', Shortcuts.focusSearch)
- Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview)
+ Mousetrap.bind '?', @onToggleHelp
+ Mousetrap.bind 's', Shortcuts.focusSearch
+ Mousetrap.bind 'f', (e) => @focusFilter e
+ Mousetrap.bind ['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview
Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL?
onToggleHelp: (e) =>
@@ -32,10 +33,16 @@ class @Shortcuts
$('.js-more-help-button').remove()
)
+ focusFilter: (e) ->
+ @filterInput ?= $('input[type=search]', '.nav-controls')
+ @filterInput.focus()
+ e.preventDefault()
+
@focusSearch: (e) ->
$('#search').focus()
e.preventDefault()
+
$(document).on 'click.more_help', '.js-more-help-button', (e) ->
$(@).remove()
$('.hidden-shortcut').show()
diff --git a/app/assets/javascripts/u2f/authenticate.js.coffee b/app/assets/javascripts/u2f/authenticate.js.coffee
index 6deb902c8de..918c0a560fd 100644
--- a/app/assets/javascripts/u2f/authenticate.js.coffee
+++ b/app/assets/javascripts/u2f/authenticate.js.coffee
@@ -6,8 +6,20 @@
class @U2FAuthenticate
constructor: (@container, u2fParams) ->
@appId = u2fParams.app_id
- @challenges = u2fParams.challenges
- @signRequests = u2fParams.sign_requests
+ @challenge = u2fParams.challenge
+
+ # The U2F Javascript API v1.1 requires a single challenge, with
+ # _no challenges per-request_. The U2F Javascript API v1.0 requires a
+ # challenge per-request, which is done by copying the single challenge
+ # into every request.
+ #
+ # In either case, we don't need the per-request challenges that the server
+ # has generated, so we can remove them.
+ #
+ # Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
+ # This can be removed once we upgrade.
+ # https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
+ @signRequests = u2fParams.sign_requests.map (request) -> _(request).omit('challenge')
start: () =>
if U2FUtil.isU2FSupported()
@@ -16,7 +28,7 @@ class @U2FAuthenticate
@renderNotSupported()
authenticate: () =>
- u2f.sign(@appId, @challenges, @signRequests, (response) =>
+ u2f.sign(@appId, @challenge, @signRequests, (response) =>
if response.errorCode
error = new U2FError(response.errorCode)
@renderError(error);
diff --git a/app/assets/javascripts/u2f/util.js.coffee b/app/assets/javascripts/u2f/util.js.coffee
new file mode 100644
index 00000000000..5ef324f609d
--- /dev/null
+++ b/app/assets/javascripts/u2f/util.js.coffee
@@ -0,0 +1,3 @@
+class @U2FUtil
+ @isU2FSupported: ->
+ window.u2f
diff --git a/app/assets/javascripts/u2f/util.js.coffee.erb b/app/assets/javascripts/u2f/util.js.coffee.erb
deleted file mode 100644
index d59341c38b9..00000000000
--- a/app/assets/javascripts/u2f/util.js.coffee.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-# Helper class for U2F (universal 2nd factor) device registration and authentication.
-
-class @U2FUtil
- @isU2FSupported: ->
- if @testMode
- true
- else
- gon.u2f.browser_supports_u2f
-
- @enableTestMode: ->
- @testMode = true
-
-<% if Rails.env.test? %>
-U2FUtil.enableTestMode();
-<% end %>
diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee
index 4e032ab1ff1..344be811e0d 100644
--- a/app/assets/javascripts/users_select.js.coffee
+++ b/app/assets/javascripts/users_select.js.coffee
@@ -56,6 +56,11 @@ class @UsersSelect
username: ''
avatar: ''
$value.html(assigneeTemplate(user))
+
+ $collapsedSidebar
+ .attr('title', user.name)
+ .tooltip('fixTitle')
+
$collapsedSidebar.html(collapsedAssigneeTemplate(user))
@@ -63,7 +68,6 @@ class @UsersSelect
'<% if( avatar ) { %>
<a class="author_link" href="/u/<%- username %>">
<img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>">
- <span class="author">Toni Boehm</span>
</a>
<% } else { %>
<i class="fa fa-user"></i>
diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss
index d28cda6d62d..540718197e0 100644
--- a/app/assets/stylesheets/framework/blank.scss
+++ b/app/assets/stylesheets/framework/blank.scss
@@ -20,9 +20,12 @@
.blank-state-icon {
padding-bottom: 20px;
+ color: $gray-darkest;
+ font-size: 56px;
- path {
- fill: $gray-darkest;
+ path,
+ polygon {
+ fill: currentColor;
}
}
@@ -37,6 +40,10 @@
margin-top: 0;
margin-bottom: $gl-padding;
font-size: 15px;
+
+ > strong {
+ font-weight: 600;
+ }
}
.blank-state-welcome-title {
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index 24b1ebab4b0..ad94e457cfd 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -16,8 +16,14 @@
font-weight: normal;
font-size: 16px;
line-height: 36px;
+
&.diff-collapsed {
+ padding: 5px;
cursor: pointer;
+
+ &:hover {
+ background-color: $row-hover;
+ }
}
}
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index f8aecd0558d..c1e5305644b 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -270,21 +270,6 @@ table {
}
}
-.dashboard-intro-icon {
- float: left;
- text-align: center;
- font-size: 32px;
- color: #aaa;
- width: 60px;
-}
-
-.dashboard-intro-text {
- display: inline-block;
- margin-left: -60px;
- padding-left: 60px;
- width: 100%;
-}
-
.btn-sign-in {
text-shadow: none;
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index cec52678495..d52e8f00172 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -55,10 +55,6 @@
overflow-y: auto;
overflow-x: hidden;
- @media (min-width: $sidebar-breakpoint) {
- bottom: 50px;
- }
-
&.navbar-collapse {
padding: 0 !important;
}
@@ -76,7 +72,7 @@
}
a {
- padding: 7px 16px;
+ padding: 7px $gl-sidebar-padding;
font-size: $gl-font-size;
line-height: 24px;
display: block;
@@ -143,7 +139,7 @@
}
.nav-header-btn {
- padding: 10px 16px;
+ padding: 10px $gl-sidebar-padding;
color: inherit;
transition-duration: .3s;
position: absolute;
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 09d3caa0e6a..f0e7002e4cd 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -64,6 +64,7 @@ $gl-btn-padding: 10px;
$gl-input-padding: 10px;
$gl-vert-padding: 6px;
$gl-padding-top: 10px;
+$gl-sidebar-padding: 22px;
/*
* Misc
diff --git a/app/assets/stylesheets/pages/admin.scss b/app/assets/stylesheets/pages/admin.scss
index 1d34a7f79ae..5607239d92d 100644
--- a/app/assets/stylesheets/pages/admin.scss
+++ b/app/assets/stylesheets/pages/admin.scss
@@ -88,13 +88,7 @@
.user-name {
display: inline-block;
- font-weight: bold;
- }
-
- .controls {
- > .btn, > .dropdown {
- margin-left: 5px;
- }
+ font-weight: 600;
}
.dropdown {
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index 701b9388454..2a3acc3eb4c 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -38,33 +38,6 @@
margin-right: 15px;
}
}
-
- &.group-admin {
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
-
- .group-avatar, .group-details, .group-controls {
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- }
-
- .group-details {
- flex: 1 1 auto;
- flex-direction: column;
- min-width: 0;
- }
-
- .group-controls {
- align-items: center;
-
- a {
- margin-left: 5px;
- }
- }
- }
-
}
.ldap-group-links {
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index cbf8297f387..a0334207c68 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -43,6 +43,13 @@
border-top-width: 1px;
}
+ .commit-link {
+
+ a:hover {
+ text-decoration: none;
+ }
+ }
+
.branch-commit {
.branch-name {
@@ -80,7 +87,12 @@
margin-left: 0;
}
+ .label {
+ margin-right: 4px;
+ }
+
.label-container {
+ font-size: 0;
.label {
margin-top: 5px;
@@ -116,6 +128,14 @@
color: $table-text-gray;
}
+ .cancel-retry-btns {
+ vertical-align: middle;
+
+ .btn:not(:first-child) {
+ margin-left: 8px;
+ }
+ }
+
.dropdown-toggle,
.dropdown-menu {
color: $table-text-gray;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 5be911dc562..ea9f7cf0540 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -482,6 +482,10 @@ pre.light-well {
a:hover {
text-decoration: none;
}
+
+ > span {
+ margin-left: 10px;
+ }
}
}
@@ -639,3 +643,9 @@ pre.light-well {
width: 300px;
}
}
+
+.compare-form-group {
+ .dropdown-menu {
+ width: 300px;
+ }
+}
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 9e9b18fdbb8..c9d436d72ba 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -185,7 +185,7 @@
padding-right: $gl-padding + 15px;
}
- .btn-search {
+ .btn-search, .btn-new {
width: 100%;
margin-top: 5px;
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index 5b61270daa8..42a20e9775f 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -23,12 +23,11 @@
}
&:hover {
- cursor: pointer;
-
td {
background-color: $row-hover;
border-top: 1px solid $row-hover-border;
border-bottom: 1px solid $row-hover-border;
+ cursor: pointer;
}
}
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9cc31620d9f..a1004d9bcea 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -344,10 +344,6 @@ class ApplicationController < ActionController::Base
session[:skip_tfa] && session[:skip_tfa] > Time.current
end
- def browser_supports_u2f?
- browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile?
- end
-
def redirect_to_home_page_url?
# If user is not signed-in and tries to access root_path - redirect him to landing page
# Don't redirect to the default URL to prevent endless redirections
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb
index 998b8adc411..ba07cea569c 100644
--- a/app/controllers/concerns/authenticates_with_two_factor.rb
+++ b/app/controllers/concerns/authenticates_with_two_factor.rb
@@ -57,7 +57,7 @@ module AuthenticatesWithTwoFactor
# Authenticate using the response from a U2F (universal 2nd factor) device
def authenticate_with_two_factor_via_u2f(user)
- if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenges])
+ if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge])
# Remove any lingering user data from login
session.delete(:otp_user_id)
session.delete(:challenges)
@@ -77,11 +77,9 @@ module AuthenticatesWithTwoFactor
if key_handles.present?
sign_requests = u2f.authentication_requests(key_handles)
- challenges = sign_requests.map(&:challenge)
- session[:challenges] = challenges
- gon.push(u2f: { challenges: challenges, app_id: u2f_app_id,
- sign_requests: sign_requests,
- browser_supports_u2f: browser_supports_u2f? })
+ session[:challenge] ||= u2f.challenge
+ gon.push(u2f: { challenge: session[:challenge], app_id: u2f_app_id,
+ sign_requests: sign_requests })
end
end
end
diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb
index 6a358fdcc05..e37e9e136db 100644
--- a/app/controllers/profiles/two_factor_auths_controller.rb
+++ b/app/controllers/profiles/two_factor_auths_controller.rb
@@ -100,7 +100,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
gon.push(u2f: { challenges: session[:challenges], app_id: u2f_app_id,
register_requests: registration_requests,
- sign_requests: sign_requests,
- browser_supports_u2f: browser_supports_u2f? })
+ sign_requests: sign_requests })
end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index f7ada5cfee4..b6e80762e3c 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -119,10 +119,6 @@ class Projects::IssuesController < Projects::ApplicationController
render json: @issue.to_json(include: { milestone: {}, assignee: { methods: :avatar_url }, labels: { methods: :text_color } })
end
end
-
- rescue ActiveRecord::StaleObjectError
- @conflict = true
- render :edit
end
def referenced_merge_requests
@@ -220,7 +216,7 @@ class Projects::IssuesController < Projects::ApplicationController
def issue_params
params.require(:issue).permit(
:title, :assignee_id, :position, :description, :confidential,
- :milestone_id, :due_date, :state_event, :task_num, :lock_version, label_ids: []
+ :milestone_id, :due_date, :state_event, :task_num, label_ids: []
)
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 2deb7959700..df659bb8c3b 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -196,9 +196,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
else
render "edit"
end
- rescue ActiveRecord::StaleObjectError
- @conflict = true
- render :edit
end
def remove_wip
@@ -427,7 +424,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
:title, :assignee_id, :source_project_id, :source_branch,
:target_project_id, :target_branch, :milestone_id,
:state_event, :description, :task_num, :force_remove_source_branch,
- :lock_version, label_ids: []
+ label_ids: []
)
end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 428a42266d0..abe115d8c68 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,10 +1,7 @@
module BlobHelper
- def highlighter(blob_name, blob_content, repository: nil, nowrap: false)
- Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap, repository: repository)
- end
-
- def highlight(blob_name, blob_content, repository: nil, nowrap: false, plain: false)
- Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap, plain: plain, repository: repository)
+ def highlight(blob_name, blob_content, repository: nil, plain: false)
+ highlighted = Gitlab::Highlight.highlight(blob_name, blob_content, plain: plain, repository: repository)
+ raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>)
end
def no_highlight_files
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 294b7e92b8d..47d174361db 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -61,7 +61,7 @@ module IssuablesHelper
output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier"
output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
output << content_tag(:strong) do
- author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs")
+ author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs", tooltip: true)
author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg")
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 3bbbb26cff2..a733dff1579 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -19,7 +19,7 @@ module ProjectsHelper
end
def link_to_member(project, author, opts = {}, &block)
- default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" }
+ default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name", tooltip: false }
opts = default_opts.merge(opts)
return "(deleted)" unless author
@@ -33,7 +33,8 @@ module ProjectsHelper
if opts[:by_username]
author_html << content_tag(:span, sanitize("@#{author.username}"), class: opts[:author_class]) if opts[:name]
else
- author_html << content_tag(:span, sanitize(author.name), class: opts[:author_class]) if opts[:name]
+ tooltip_data = { placement: 'top' }
+ author_html << content_tag(:span, sanitize(author.name), class: [opts[:author_class], ('has-tooltip' if opts[:tooltip])], title: (author.to_reference if opts[:tooltip]), data: (tooltip_data if opts[:tooltip])) if opts[:name]
end
author_html << capture(&block) if block
@@ -60,7 +61,7 @@ module ProjectsHelper
project_link = link_to simple_sanitize(project.name), project_path(project), { class: "project-item-select-holder" }
if current_user
- project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" })
+ project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", aria: { label: "Toggle switch project dropdown" }, data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" })
end
full_title = "#{namespace_link} / #{project_link}".html_safe
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index b165b569372..fcb2703e837 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -45,7 +45,7 @@ module SearchHelper
[
{ category: "Help", label: "API Help", url: help_page_path("api/README") },
{ category: "Help", label: "Markdown Help", url: help_page_path("markdown/markdown") },
- { category: "Help", label: "Permissions Help", url: help_page_path("permissions/permissions") },
+ { category: "Help", label: "Permissions Help", url: help_page_path("user/permissions") },
{ category: "Help", label: "Public Access Help", url: help_page_path("public_access/public_access") },
{ category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") },
{ category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") },
diff --git a/app/helpers/u2f_helper.rb b/app/helpers/u2f_helper.rb
new file mode 100644
index 00000000000..143b4ca6b51
--- /dev/null
+++ b/app/helpers/u2f_helper.rb
@@ -0,0 +1,5 @@
+module U2fHelper
+ def inject_u2f_api?
+ browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile?
+ end
+end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index fa4071e2482..7d743ce99f0 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -215,6 +215,8 @@ module Ci
end
def keep_around_commits
+ return unless project
+
project.repository.keep_around(self.sha)
project.repository.keep_around(self.before_sha)
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index fb49bd7dd64..acb6f5a2998 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -87,12 +87,6 @@ module Issuable
User.find(assignee_id_was).update_cache_counts if assignee_id_was
assignee.update_cache_counts if assignee
end
-
- # We want to use optimistic lock for cases when only title or description are involved
- # http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
- def locking_enabled?
- title_changed? || description_changed?
- end
end
module ClassMethods
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 8cac47246db..ec9e0f1b1d0 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -14,14 +14,14 @@ module Mentionable
attr = attr.to_s
mentionable_attrs << [attr, options]
end
+ end
+ included do
# Accessor for attributes marked mentionable.
- def mentionable_attrs
- @mentionable_attrs ||= []
+ cattr_accessor :mentionable_attrs, instance_accessor: false do
+ []
end
- end
- included do
if self < Participable
participant -> (user, ext) { all_references(user, extractor: ext) }
end
diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb
index 9822844357d..70740c76e43 100644
--- a/app/models/concerns/participable.rb
+++ b/app/models/concerns/participable.rb
@@ -41,9 +41,12 @@ module Participable
def participant(attr)
participant_attrs << attr
end
+ end
- def participant_attrs
- @participant_attrs ||= []
+ included do
+ # Accessor for participant attributes.
+ cattr_accessor :participant_attrs, instance_accessor: false do
+ []
end
end
diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb
index 790dfd4d480..04a651d50ab 100644
--- a/app/models/legacy_diff_note.rb
+++ b/app/models/legacy_diff_note.rb
@@ -38,7 +38,7 @@ class LegacyDiffNote < Note
end
def diff_line
- @diff_line ||= diff_file.line_for_line_code(self.line_code)
+ @diff_line ||= diff_file.line_for_line_code(self.line_code) if diff_file
end
def for_line?(line)
@@ -55,7 +55,7 @@ class LegacyDiffNote < Note
def active?
return @active if defined?(@active)
return true if for_commit?
- return true unless self.diff
+ return true unless diff_line
return false unless noteable
noteable_diff = find_noteable_diff
diff --git a/app/models/project.rb b/app/models/project.rb
index a66b750cd48..e7b9835692d 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -162,7 +162,7 @@ class Project < ActiveRecord::Base
validates :namespace, presence: true
validates_uniqueness_of :name, scope: :namespace_id
validates_uniqueness_of :path, scope: :namespace_id
- validates :import_url, addressable_url: true, if: :external_import?
+ validates :import_url, addressable_url: true, if: :import_url
validates :star_count, numericality: { greater_than_or_equal_to: 0 }
validate :check_limit, on: :create
validate :avatar_type,
@@ -464,8 +464,8 @@ class Project < ActiveRecord::Base
return super(value) unless Gitlab::UrlSanitizer.valid?(value)
import_url = Gitlab::UrlSanitizer.new(value)
- create_or_update_import_data(credentials: import_url.credentials)
super(import_url.sanitized_url)
+ create_or_update_import_data(credentials: import_url.credentials)
end
def import_url
@@ -477,7 +477,13 @@ class Project < ActiveRecord::Base
end
end
+ def valid_import_url?
+ valid? || errors.messages[:import_url].nil?
+ end
+
def create_or_update_import_data(data: nil, credentials: nil)
+ return unless valid_import_url?
+
project_import_data = import_data || build_import_data
if data
project_import_data.data ||= {}
diff --git a/app/services/projects/import_export/export_service.rb b/app/services/projects/import_export/export_service.rb
index 6afc048576d..998789d64d2 100644
--- a/app/services/projects/import_export/export_service.rb
+++ b/app/services/projects/import_export/export_service.rb
@@ -10,7 +10,7 @@ module Projects
def save_all
if [version_saver, project_tree_saver, uploads_saver, repo_saver, wiki_repo_saver].all?(&:save)
- Gitlab::ImportExport::Saver.save(shared: @shared)
+ Gitlab::ImportExport::Saver.save(project: project, shared: @shared)
notify_success
else
cleanup_and_notify
diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb
index 163ebf26c84..cdad0426b02 100644
--- a/app/services/projects/import_service.rb
+++ b/app/services/projects/import_service.rb
@@ -43,7 +43,7 @@ module Projects
def import_repository
begin
gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
- rescue Gitlab::Shell::Error => e
+ rescue => e
raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
end
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index 6bb0a72d30e..6b48d68cccb 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -194,7 +194,7 @@ class TodoService
end
def create_assignment_todo(issuable, author)
- if issuable.assignee && issuable.assignee != author
+ if issuable.assignee
attributes = attributes_for_todo(issuable.project, issuable, author, Todo::ASSIGNED)
create_todos(issuable.assignee, attributes)
end
@@ -239,7 +239,6 @@ class TodoService
def filter_mentioned_users(project, target, author)
mentioned_users = target.mentioned_users(author)
mentioned_users = reject_users_without_access(mentioned_users, project, target)
- mentioned_users.delete(author)
mentioned_users.uniq
end
diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml
index 59fd6c3fea0..77a11e49e20 100644
--- a/app/views/admin/groups/_group.html.haml
+++ b/app/views/admin/groups/_group.html.haml
@@ -1,20 +1,26 @@
-- css_class = '' unless local_assigns[:css_class]
+- css_class = 'no-description' if group.description.blank?
-%li.group-row.group-admin{ class: css_class }
- .group-avatar
- = image_tag group_icon(group), class: 'avatar hidden-xs'
- .group-details
- .title
- = link_to [:admin, group], class: 'group-name' do
- = group.name
- .group-stats
- %span>= pluralize(number_with_delimiter(group.projects.count), 'project')
- ,
- %span= pluralize(number_with_delimiter(group.users.count), 'member')
-
- - if group.description.present?
- .description
- = markdown(group.description, pipeline: :description)
- .group-controls.hidden-xs
+%li.group-row{ class: css_class }
+ .controls
= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
= link_to 'Delete', [:admin, group], data: { confirm: "Are you sure you want to remove #{group.name}?" }, method: :delete, class: 'btn btn-remove'
+ .stats
+ %span
+ = icon('bookmark')
+ = number_with_delimiter(group.projects.count)
+
+ %span
+ = icon('users')
+ = number_with_delimiter(group.users.count)
+
+ %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)}
+ = visibility_level_icon(group.visibility_level, fw: false)
+
+ = image_tag group_icon(group), class: "avatar s40 hidden-xs"
+ .title
+ = link_to [:admin, group], class: 'group-name' do
+ = group.name
+
+ - if group.description.present?
+ .description
+ = markdown(group.description, pipeline: :description)
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 40c8169ad9d..bb374694400 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -79,7 +79,7 @@
.panel-body.form-holder
%p.light
Read more about project permissions
- %strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink"
+ %strong= link_to "here", help_page_path("user/permissions"), class: "vlink"
= form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
%div
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 7fbce25b2c4..1e755785d90 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -66,7 +66,7 @@
%ul.projects-list.content-list
- @projects.each_with_index do |project|
%li.project-row
- .controls.pull-right
+ .controls
- if project.archived
%span.label.label-warning archived
%span.label.label-gray
diff --git a/app/views/admin/users/_user.html.haml b/app/views/admin/users/_user.html.haml
index d3519f616f6..4bf1c9cde3c 100644
--- a/app/views/admin/users/_user.html.haml
+++ b/app/views/admin/users/_user.html.haml
@@ -14,7 +14,7 @@
%span It's you!
.user-email
= mail_to user.email, user.email
- .controls.pull-right
+ .controls
= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn'
- unless user == current_user
.dropdown.inline
diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml
index d54c7cad7be..fdea834ff45 100644
--- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml
+++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml
@@ -1,53 +1,46 @@
- publicish_project_count = ProjectsFinder.new.execute(current_user).count
-%h3.page-title Welcome to GitLab!
-%p.light Self hosted Git management application.
-%hr
-%div
- .dashboard-intro-icon
- %i.fa.fa-bookmark-o
- .dashboard-intro-text
- %p.slead
- You don't have access to any projects right now.
- %br
- - if current_user.can_create_project?
- You can create up to
- %strong= pluralize(number_with_delimiter(current_user.projects_limit), "project") + "."
- - else
- If you are added to a project, it will be displayed here.
-
+.blank-state.blank-state-welcome
+ %h2.blank-state-welcome-title
+ Welcome to GitLab
+ %p.blank-state-text
+ Code, test, and deploy together
+.blank-state
+ .blank-state-icon
+ = custom_icon("project", size: 50)
+ %h3.blank-state-title
+ You don't have access to any projects right now
+ %p.blank-state-text
- if current_user.can_create_project?
- .link_holder
- = link_to new_project_path, class: "btn btn-new" do
- = icon('plus')
- New Project
+ You can create up to
+ %strong= number_with_delimiter(current_user.projects_limit)
+ = succeed "." do
+ = "project".pluralize(current_user.projects_limit)
+ - else
+ If you are added to a project, it will be displayed here.
+ - if current_user.can_create_project?
+ = link_to new_project_path, class: "btn btn-new" do
+ New project
- if current_user.can_create_group?
- %hr
- %div
- .dashboard-intro-icon
- %i.fa.fa-users
- .dashboard-intro-text
- %p.slead
- You can create a group for several dependent projects.
- %br
- Groups are the best way to manage projects and members.
- .link_holder
- = link_to new_group_path, class: "btn btn-new" do
- %i.fa.fa-plus
- New Group
+ .blank-state
+ .blank-state-icon
+ = custom_icon("group", size: 50)
+ %h3.blank-state-title
+ You can create a group for several dependent projects.
+ %p.blank-state-text
+ Groups are the best way to manage projects and members.
+ = link_to new_group_path, class: "btn btn-new" do
+ New group
-if publicish_project_count > 0
- %hr
- %div
- .dashboard-intro-icon
- %i.fa.fa-globe
- .dashboard-intro-text
- %p.slead
- There are
- %strong= number_with_delimiter(publicish_project_count)
- public projects on this server.
- %br
- Public projects are an easy way to allow everyone to have read-only access.
- .link_holder
- = link_to trending_explore_projects_path, class: "btn btn-new" do
- Browse public projects
+ .blank-state
+ .blank-state-icon
+ = icon("globe")
+ %h3.blank-state-title
+ There are
+ = number_with_delimiter(publicish_project_count)
+ public projects on this server.
+ %p.blank-state-text
+ Public projects are an easy way to allow everyone to have read-only access.
+ = link_to trending_explore_projects_path, class: "btn btn-new" do
+ Browse projects
diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml
index 4565e752c1f..4f36a4a1c73 100644
--- a/app/views/dashboard/projects/index.html.haml
+++ b/app/views/dashboard/projects/index.html.haml
@@ -5,7 +5,8 @@
- page_title "Projects"
- header_title "Projects", dashboard_projects_path
-= render 'dashboard/projects_head'
+- if @projects.any? || params[:filter_projects]
+ = render 'dashboard/projects_head'
- if @last_push
= render "events/event_last_push", event: @last_push
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index a373f61bd3c..4debd3d608f 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -1,3 +1,7 @@
+- if inject_u2f_api?
+ - content_for :page_specific_javascripts do
+ = page_specific_javascript_tag('u2f.js')
+
%div
.login-box
.login-heading
diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml
index 2febeef99d3..c034bbe430e 100644
--- a/app/views/errors/access_denied.html.haml
+++ b/app/views/errors/access_denied.html.haml
@@ -3,4 +3,4 @@
%h3 Access Denied
%hr
%p You are not allowed to access this page.
-%p Read more about project permissions #{link_to "here", help_page_path("permissions/permissions"), class: "vlink"}
+%p Read more about project permissions #{link_to "here", help_page_path("user/permissions"), class: "vlink"}
diff --git a/app/views/groups/group_members/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml
index 13ded2bc455..9bb9f962177 100644
--- a/app/views/groups/group_members/_new_group_member.html.haml
+++ b/app/views/groups/group_members/_new_group_member.html.haml
@@ -12,7 +12,7 @@
= select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2"
.help-block
Read more about role permissions
- %strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink"
+ %strong= link_to "here", help_page_path("user/permissions"), class: "vlink"
.form-actions
= f.submit 'Add users to group', class: "btn btn-create"
diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml
index 8cc0b59edeb..ce4536ebdc6 100644
--- a/app/views/help/_shortcuts.html.haml
+++ b/app/views/help/_shortcuts.html.haml
@@ -20,6 +20,10 @@
%td Focus Search
%tr
%td.shortcut
+ .key f
+ %td Focus Filter
+ %tr
+ %td.shortcut
.key ?
%td Show/hide this dialog
%tr
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 90c1fa4c87c..a1a71c2fb33 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -6,7 +6,7 @@
= icon('bars')
= link_to '#', class: "nav-header-btn pin-nav-btn has-tooltip #{'is-active' if pinned_nav?} js-nav-pin", title: pinned_nav? ? "Unpin navigation" : "Pin Navigation", data: {placement: 'right', container: 'body'} do
%span.sr-only Toggle navigation pinning
- = icon('thumb-tack')
+ = icon('fw thumb-tack')
- if defined?(sidebar) && sidebar
= render "layouts/nav/#{sidebar}"
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index 245b9c3b4d4..f7580f00159 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -44,7 +44,7 @@
name: "#{j(@project.name)}"
};
- - if @group and @group.path
+ - if @group && @group.persisted? && @group.path
:javascript
gl.groupOptions = gl.groupOptions || {};
gl.groupOptions["#{j(@group.path)}"] = {
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 11cee421a99..94c53882623 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -1,7 +1,7 @@
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
%div{ class: fluid_layout ? "container-fluid" : "container-fluid" }
.header-content
- %button.side-nav-toggle{type: 'button'}
+ %button.side-nav-toggle{ type: 'button', "aria-label" => "Toggle global navigation" }
%span.sr-only Toggle navigation
= icon('bars')
%button.navbar-toggle{type: 'button'}
@@ -13,25 +13,25 @@
%li.hidden-sm.hidden-xs
= render 'layouts/search' unless current_controller?(:search)
%li.visible-sm.visible-xs
- = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('search')
- if current_user
- if session[:impersonator_id]
%li.impersonation
- = link_to admin_impersonation_path, method: :delete, title: 'Stop Impersonation', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
+ = link_to admin_impersonation_path, method: :delete, title: "Stop Impersonation", aria: { label: 'Stop Impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= icon('user-secret fw')
- if current_user.is_admin?
%li
- = link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw')
%li
- = link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('bell fw')
%span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) }
= todos_pending_count
- if current_user.can_create_project?
%li
- = link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
+ = link_to new_project_path, title: 'New project', aria: { label: "New project" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('plus fw')
- if Gitlab::Sherlock.enabled?
%li
@@ -45,12 +45,12 @@
.dropdown-menu-nav.dropdown-menu-align-right
%ul
%li
- = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
+ = link_to "Profile", current_user, class: 'profile-link', aria: { label: "Profile" }, data: { user: current_user.username }
%li
- = link_to "Profile Settings", profile_path
+ = link_to "Profile Settings", profile_path, aria: { label: "Profile Settings" }
%li.divider
%li
- = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", title: 'Sign out'
+ = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", aria: { label: "Sign out" }
- else
%li
%div
diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml
index 35c4b862bb7..ea7e3d199fd 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -1,4 +1,4 @@
-- if @note.diff_note?
+- if @note.diff_note? && @note.diff_file
%p.details
New comment on diff for
= link_to @note.diff_file.file_path, @target_url
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 8780da1dec4..366f1fed35b 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -2,6 +2,10 @@
- header_title "Two-Factor Authentication", profile_two_factor_auth_path
= render 'profiles/head'
+- if inject_u2f_api?
+ - content_for :page_specific_javascripts do
+ = page_specific_javascript_tag('u2f.js')
+
.row.prepend-top-default
.col-lg-3
%h4.prepend-top-0
diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml
index 4ef72ff5d2a..631873fb0a3 100644
--- a/app/views/projects/ci/pipelines/_pipeline.html.haml
+++ b/app/views/projects/ci/pipelines/_pipeline.html.haml
@@ -58,16 +58,7 @@
.controls.hidden-xs.pull-right
- artifacts = pipeline.builds.latest.select { |b| b.artifacts? }
- if artifacts.present?
- .btn-group.inline
- .btn-group
- %a.dropdown-toggle.btn.btn-default{type: 'button', 'data-toggle' => 'dropdown'}
- = icon("play")
- %b.caret
- %ul.dropdown-menu.dropdown-menu-align-right
- %li
- = link_to '#' do
- = icon("play")
- %span Deploy to production
+ .inline
.btn-group
%a.dropdown-toggle.btn.btn-default.build-artifacts{type: 'button', 'data-toggle' => 'dropdown'}
= icon("download")
@@ -80,9 +71,10 @@
%span Download '#{build.name}' artifacts
- if can?(current_user, :update_pipeline, @project)
- - if pipeline.retryable?
- = link_to retry_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn has-tooltip', title: "Retry", method: :post do
- = icon("repeat")
- - if pipeline.cancelable?
- = link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
- = icon("remove")
+ .cancel-retry-btns.inline
+ - if pipeline.retryable?
+ = link_to retry_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn has-tooltip', title: "Retry", method: :post do
+ = icon("repeat")
+ - if pipeline.cancelable?
+ = link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
+ = icon("remove")
diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml
index dd590a4b8ec..af09b3418ea 100644
--- a/app/views/projects/compare/_form.html.haml
+++ b/app/views/projects/compare/_form.html.haml
@@ -2,15 +2,17 @@
.clearfix
- if params[:to] && params[:from]
= link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has-tooltip', title: 'Switch base of comparison'}
- .form-group
+ .form-group.dropdown.compare-form-group.js-compare-from-dropdown
.input-group.inline-input-group
%span.input-group-addon from
- = text_field_tag :from, params[:from], class: "form-control", required: true
+ = text_field_tag :from, params[:from], class: "form-control js-compare-dropdown", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from].presence }
+ = render "ref_dropdown"
= "..."
- .form-group
+ .form-group.dropdown.compare-form-group.js-compare-to-dropdown
.input-group.inline-input-group
%span.input-group-addon to
- = text_field_tag :to, params[:to], class: "form-control", required: true
+ = text_field_tag :to, params[:to], class: "form-control js-compare-dropdown", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to].presence }
+ = render "ref_dropdown"
&nbsp;
= button_tag "Compare", class: "btn btn-create commits-compare-btn"
- if @merge_request.present?
@@ -19,11 +21,3 @@
= link_to create_mr_path, class: 'prepend-left-10 btn' do
= icon("plus")
Create Merge Request
-
-:javascript
- var availableTags = #{@project.repository.ref_names.to_json};
-
- $("#from, #to").autocomplete({
- source: availableTags,
- minLength: 1
- });
diff --git a/app/views/projects/compare/_ref_dropdown.html.haml b/app/views/projects/compare/_ref_dropdown.html.haml
new file mode 100644
index 00000000000..c604c6d0135
--- /dev/null
+++ b/app/views/projects/compare/_ref_dropdown.html.haml
@@ -0,0 +1,4 @@
+.dropdown-menu.dropdown-menu-selectable
+ = dropdown_title "Select branch/tag"
+ = dropdown_content
+ = dropdown_loading
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 9b00bdedc27..c72d0140bb9 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -154,4 +154,9 @@
$('.import_gitlab_project').attr('disabled',true);
$('.import_gitlab_project').attr('title', 'Project path required.');
}
- })
+ });
+
+ $('.import_git').click(function( event ) {
+ $projectImportUrl = $('#project_import_url')
+ $projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'))
+ }); \ No newline at end of file
diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml
index ea3d82d858e..978c4dfc5ec 100644
--- a/app/views/projects/project_members/_new_project_member.html.haml
+++ b/app/views/projects/project_members/_new_project_member.html.haml
@@ -12,7 +12,7 @@
= select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "project-access-select select2"
.help-block
Read more about role permissions
- %strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink"
+ %strong= link_to "here", help_page_path("user/permissions"), class: "vlink"
.form-actions
= f.submit 'Add users to project', class: "btn btn-create"
diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml
index 3fab95751e0..883d3e3af1e 100644
--- a/app/views/projects/protected_branches/index.html.haml
+++ b/app/views/projects/protected_branches/index.html.haml
@@ -8,10 +8,10 @@
%p.prepend-top-20
Protected branches are designed to:
%ul
- %li prevent pushes from everybody except #{link_to "masters", help_page_path("permissions/permissions"), class: "vlink"}
+ %li prevent pushes from everybody except #{link_to "masters", help_page_path("user/permissions"), class: "vlink"}
%li prevent anyone from force pushing to the branch
%li prevent anyone from deleting the branch
- %p.append-bottom-0 Read more about #{link_to "project permissions", help_page_path("permissions/permissions"), class: "underlined-link"}
+ %p.append-bottom-0 Read more about #{link_to "project permissions", help_page_path("user/permissions"), class: "underlined-link"}
.col-lg-9
%h5.prepend-top-0
Protect a branch
diff --git a/app/views/shared/_import_form.html.haml b/app/views/shared/_import_form.html.haml
index 627814bcfae..65a3a6bddab 100644
--- a/app/views/shared/_import_form.html.haml
+++ b/app/views/shared/_import_form.html.haml
@@ -2,7 +2,7 @@
= f.label :import_url, class: 'control-label' do
%span Git repository URL
.col-sm-10
- = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git'
+ = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git', disabled: true
.well.prepend-top-20
%ul
diff --git a/app/views/shared/icons/_group.svg b/app/views/shared/icons/_group.svg.erb
index 75cae0d16c8..53635016900 100644
--- a/app/views/shared/icons/_group.svg
+++ b/app/views/shared/icons/_group.svg.erb
@@ -1,9 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <!-- Generator: Sketch 3.7.2 (28276) - http://www.bohemiancoding.com/sketch -->
- <title>Group</title>
- <desc>Created with Sketch.</desc>
- <defs></defs>
+<svg width="<%= size %>" height="<%= size %>" viewBox="0 0 16 16">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" fill="#303030">
<path d="M15.6667,10.0105 L10.3337,10.0105 C10.1497,10.0105 9.9997,10.1775 9.9997,10.3845 L9.9997,15.6145 C9.9997,15.8215 10.1497,15.9885 10.3337,15.9885 L15.6667,15.9885 C15.8507,15.9885 15.9997,15.8215 15.9997,15.6145 L15.9997,10.3845 C15.9997,10.1775 15.8507,10.0105 15.6667,10.0105 L15.6667,10.0105 L15.6667,10.0105 Z M11.9997,14.0105 L13.9997,14.0105 L13.9997,12.0105 L11.9997,12.0105 L11.9997,14.0105 L11.9997,14.0105 Z" id="Fill-11"></path>
@@ -15,4 +10,4 @@
<path d="M11.6667,6.21724894e-15 L4.3337,6.21724894e-15 C4.1497,6.21724894e-15 3.9997,0.167 3.9997,0.374 L3.9997,6.604 C3.9997,6.811 4.1497,6.978 4.3337,6.978 L11.6667,6.978 C11.8507,6.978 11.9997,6.811 11.9997,6.604 L11.9997,0.374 C11.9997,0.167 11.8507,6.21724894e-15 11.6667,6.21724894e-15 L11.6667,6.21724894e-15 L11.6667,6.21724894e-15 Z M5.9997,5 L9.9997,5 L9.9997,2 L5.9997,2 L5.9997,5 L5.9997,5 Z" id="Fill-14"></path>
</g>
</g>
-</svg> \ No newline at end of file
+</svg>
diff --git a/app/views/shared/icons/_project.svg b/app/views/shared/icons/_project.svg
deleted file mode 100644
index 1e8b43f8c6b..00000000000
--- a/app/views/shared/icons/_project.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
- <title>Page 1</title>
- <desc>Created with Sketch.</desc>
- <defs></defs>
- <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
- <path d="M6,6 L12,6 L12,5 L6,5 L6,6 Z M6,8 L12,8 L12,7 L6,7 L6,8 Z M6,10 L12,10 L12,9 L6,9 L6,10 Z M6,12 L12,12 L12,11 L6,11 L6,12 Z M4,6 L5,6 L5,5 L4,5 L4,6 Z M4,8 L5,8 L5,7 L4,7 L4,8 Z M4,10 L5,10 L5,9 L4,9 L4,10 Z M4,12 L5,12 L5,11 L4,11 L4,12 Z M13,3 L10,3 L10,4 L6,4 L6,3 L3,3 L3,13 L13,13 L13,3 Z M2,14 L14,14 L14,2 L2,2 L2,14 Z M1,0 C0.448,0 0,0.448 0,1 L0,15 C0,15.552 0.448,16 1,16 L15,16 C15.552,16 16,15.552 16,15 L16,1 C16,0.448 15.552,0 15,0 L1,0 Z" fill="#7F7E7E"></path>
- </g>
-</svg> \ No newline at end of file
diff --git a/app/views/shared/icons/_project.svg.erb b/app/views/shared/icons/_project.svg.erb
new file mode 100644
index 00000000000..2f60bb7245e
--- /dev/null
+++ b/app/views/shared/icons/_project.svg.erb
@@ -0,0 +1,3 @@
+<svg width="<%= size %>" height="<%= size %>" viewBox="0 0 16 16">
+ <path d="M6,6 L12,6 L12,5 L6,5 L6,6 Z M6,8 L12,8 L12,7 L6,7 L6,8 Z M6,10 L12,10 L12,9 L6,9 L6,10 Z M6,12 L12,12 L12,11 L6,11 L6,12 Z M4,6 L5,6 L5,5 L4,5 L4,6 Z M4,8 L5,8 L5,7 L4,7 L4,8 Z M4,10 L5,10 L5,9 L4,9 L4,10 Z M4,12 L5,12 L5,11 L4,11 L4,12 Z M13,3 L10,3 L10,4 L6,4 L6,3 L3,3 L3,13 L13,13 L13,3 Z M2,14 L14,14 L14,2 L2,2 L2,14 Z M1,0 C0.448,0 0,0.448 0,1 L0,15 C0,15.552 0.448,16 1,16 L15,16 C15.552,16 16,15.552 16,15 L16,1 C16,0.448 15.552,0 15,0 L1,0 Z" fill="#7F7E7E" fill-rule="evenodd"></path>
+</svg>
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 98bbb12eaec..c30bdb0ae91 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -1,12 +1,5 @@
= form_errors(issuable)
-- if @conflict
- .alert.alert-danger
- Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
- Please check out
- = link_to "the #{issuable.class.model_name.human.downcase}", polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), target: "_blank"
- and make sure your changes will not unintentionally remove theirs
-
.form-group
= f.label :title, class: 'control-label'
.col-sm-10
@@ -156,5 +149,3 @@
= link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" },
method: :delete, class: 'btn btn-danger btn-grouped'
= link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel'
-
-= f.hidden_field :lock_version
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index adfab1af53e..e020a7d4d00 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -19,7 +19,7 @@
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, format: :json, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
.block.assignee
- .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.to_reference if issuable.assignee)}
+ .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.name if issuable.assignee)}
- if issuable.assignee
= link_to_member(@project, issuable.assignee, size: 24)
- else
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index 2fa3c838f55..a6cefd4d601 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -8,7 +8,9 @@ class GitGarbageCollectWorker
project = Project.find(project_id)
gitlab_shell.gc(project.repository_storage_path, project.path_with_namespace)
- # Expire the branch cache in case garbage collection caused a ref lookup to fail
+ # Refresh the branch cache in case garbage collection caused a ref lookup to fail
project.repository.after_create_branch
+ project.repository.branch_names
+ project.repository.has_visible_content?
end
end
diff --git a/config/application.rb b/config/application.rb
index 21e7cc7b6e8..5f7b6a3c049 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -87,6 +87,7 @@ module Gitlab
config.assets.precompile << "profile/application.js"
config.assets.precompile << "lib/utils/*.js"
config.assets.precompile << "lib/*.js"
+ config.assets.precompile << "u2f.js"
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
diff --git a/db/migrate/20160707104333_add_lock_to_issuables.rb b/db/migrate/20160707104333_add_lock_to_issuables.rb
deleted file mode 100644
index cb516672800..00000000000
--- a/db/migrate/20160707104333_add_lock_to_issuables.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# See http://doc.gitlab.com/ce/development/migration_style_guide.html
-# for more information on how to write migrations for GitLab.
-
-class AddLockToIssuables < ActiveRecord::Migration
- include Gitlab::Database::MigrationHelpers
- disable_ddl_transaction!
-
- def up
- add_column_with_default :issues, :lock_version, :integer, default: 0
- add_column_with_default :merge_requests, :lock_version, :integer, default: 0
- end
-
- def down
- remove_column :issues, :lock_version
- remove_column :merge_requests, :lock_version
- end
-end
diff --git a/db/schema.rb b/db/schema.rb
index f24e47b85b2..8c12898eec9 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -70,11 +70,11 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.string "recaptcha_site_key"
t.string "recaptcha_private_key"
t.integer "metrics_port", default: 8089
+ t.boolean "akismet_enabled", default: false
+ t.string "akismet_api_key"
t.integer "metrics_sample_interval", default: 15
t.boolean "sentry_enabled", default: false
t.string "sentry_dsn"
- t.boolean "akismet_enabled", default: false
- t.string "akismet_api_key"
t.boolean "email_author_in_body", default: false
t.integer "default_group_visibility"
t.boolean "repository_checks_enabled", default: false
@@ -84,10 +84,10 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.string "health_check_access_token"
t.boolean "send_user_confirmation_email", default: false
t.integer "container_registry_token_expire_delay", default: 5
+ t.boolean "user_default_external", default: false, null: false
t.text "after_sign_up_text"
t.string "repository_storage", default: "default"
t.string "enabled_git_access_protocol"
- t.boolean "user_default_external", default: false, null: false
end
create_table "audit_events", force: :cascade do |t|
@@ -165,8 +165,8 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.text "artifacts_metadata"
t.integer "erased_by_id"
t.datetime "erased_at"
- t.datetime "artifacts_expire_at"
t.string "environment"
+ t.datetime "artifacts_expire_at"
t.integer "artifacts_size"
end
@@ -481,11 +481,10 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.string "state"
t.integer "iid"
t.integer "updated_by_id"
- t.integer "moved_to_id"
t.boolean "confidential", default: false
t.datetime "deleted_at"
t.date "due_date"
- t.integer "lock_version", default: 0, null: false
+ t.integer "moved_to_id"
end
add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree
@@ -625,7 +624,6 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.integer "merge_user_id"
t.string "merge_commit_sha"
t.datetime "deleted_at"
- t.integer "lock_version", default: 0, null: false
end
add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
@@ -775,10 +773,10 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.integer "user_id", null: false
t.string "token", null: false
t.string "name", null: false
- t.boolean "revoked", default: false
- t.datetime "expires_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.boolean "revoked", default: false
+ t.datetime "expires_at"
end
add_index "personal_access_tokens", ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree
@@ -898,9 +896,9 @@ ActiveRecord::Schema.define(version: 20160712171823) do
t.string "type"
t.string "title"
t.integer "project_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.boolean "active", null: false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.boolean "active", default: false, null: false
t.text "properties"
t.boolean "template", default: false
t.boolean "push_events", default: true
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 16a1461a7e4..50fa263f693 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -985,11 +985,11 @@ directive defined in `.postgres_services` and `.mysql_services` respectively:
- ruby
test:postgres:
- << *job_definition
+ <<: *job_definition
services: *postgres_definition
test:mysql:
- << *job_definition
+ <<: *job_definition
services: *mysql_definition
```
diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md
index 975bb82c37d..fac35ec964d 100644
--- a/doc/development/doc_styleguide.md
+++ b/doc/development/doc_styleguide.md
@@ -44,7 +44,7 @@ it organized and easy to find.
- When introducing a new document, be careful for the headings to be
grammatically and syntactically correct. It is advised to mention one or all
of the following GitLab members for a review: `@axil`, `@rspeicher`,
- `@dblessing`, `@ashleys`, `@nearlythere`. This is to ensure that no document
+ `@dblessing`, `@ashleys`. This is to ensure that no document
with wrong heading is going live without an audit, thus preventing dead links
and redirection issues when corrected
- Leave exactly one newline after a heading
diff --git a/doc/development/ui_guide.md b/doc/development/ui_guide.md
index 8d02c52c477..65252288019 100644
--- a/doc/development/ui_guide.md
+++ b/doc/development/ui_guide.md
@@ -1,45 +1,45 @@
-# UI Guide for building GitLab
+# UI Guide for building GitLab
## GitLab UI development kit
We created a page inside GitLab where you can check commonly used html and css elements.
-When you run GitLab instance locally - just visit http://localhost:3000/help/ui page to see UI examples
+When you run GitLab instance locally - just visit http://localhost:3000/help/ui page to see UI examples
you can use during GitLab development.
## Design repository
-All design files are stored in the [gitlab-design](https://gitlab.com/gitlab-org/gitlab-design)
-repository and maintained by GitLab UX designers.
+All design files are stored in the [gitlab-design](https://gitlab.com/gitlab-org/gitlab-design)
+repository and maintained by GitLab UX designers.
## Navigation
-GitLab's layout contains 2 sections: the left sidebar and the content. The left sidebar contains a static navigation menu.
-This menu will be visible regardless of what page you visit. The left sidebar also contains the GitLab logo
-and the current user's profile picture. The content section contains a header and the content itself.
-The header describes the current GitLab page and what navigation is
-available to user in this area. Depending on the area (project, group, profile setting) the header name and navigation may change. For example when user visits one of the
+GitLab's layout contains 2 sections: the left sidebar and the content. The left sidebar contains a static navigation menu.
+This menu will be visible regardless of what page you visit. The left sidebar also contains the GitLab logo
+and the current user's profile picture. The content section contains a header and the content itself.
+The header describes the current GitLab page and what navigation is
+available to user in this area. Depending on the area (project, group, profile setting) the header name and navigation may change. For example when user visits one of the
project pages the header will contain a project name and navigation for that project. When the user visits a group page it will contain a group name and navigation related to this group.
### Adding new tab to header navigation
-We try to keep the amount of tabs in the header navigation between 5 and 10 so that it fits on a typical laptop screen. We also try not to confuse the user with too many options. Ideally each
-tab should represent separate functionality. Everything related to the issue
-tracker should be under the 'Issues' tab while everything related to the wiki should
+We try to keep the amount of tabs in the header navigation between 5 and 10 so that it fits on a typical laptop screen. We also try not to confuse the user with too many options. Ideally each
+tab should represent separate functionality. Everything related to the issue
+tracker should be under the 'Issues' tab while everything related to the wiki should
be under 'Wiki' tab and so on and so forth.
-When adding a new tab to the header don't use more than 2 words for text in the link.
+When adding a new tab to the header don't use more than 2 words for text in the link.
We want to keep links short and easy to remember and fit all of them in the small screen.
-## Mobile screen size
+## Mobile screen size
-We want GitLab to work well on small mobile screens as well. Size limitations make it is impossible to fit everything on a mobile screen. In this case it is OK to hide
-part of the UI for smaller resolutions in favor of a better user experience.
+We want GitLab to work well on small mobile screens as well. Size limitations make it is impossible to fit everything on a mobile screen. In this case it is OK to hide
+part of the UI for smaller resolutions in favor of a better user experience.
However core functionality like browsing files, creating issues, writing comments, should
be available on all resolutions.
## Icons
-* `trash` icon for button or link that does destructive action like removing
+* `trash` icon for button or link that does destructive action like removing
information from database or file system
* `x` icon for closing/hiding UI element. For example close modal window
* `pencil` icon for edit button or link
@@ -52,8 +52,14 @@ information from database or file system
* Button should contain icon or text. Exceptions should be approved by UX designer.
* Use red button for destructive actions (not revertable). For example removing issue.
-* Use green or blue button for primary action. Primary button should be only one.
-Do not use both green and blue button in one form.
-* For all other cases use default white button.
-* Text button should have only first word capitalized. So should be "Create issue" instead of "Create Issue"
+* Use green or blue button for primary action. Primary button should be only one.
+Do not use both green and blue button in one form.
+* For all other cases use default white button.
+* Text button should have only first word capitalized. So should be "Create issue" instead of "Create Issue"
+## Counts
+
+* Always use the [`number_with_delimiter`][number_with_delimiter] helper to
+ display counts in the UI.
+
+[number_with_delimiter]: http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_with_delimiter
diff --git a/doc/integration/oauth_provider.md b/doc/integration/oauth_provider.md
index 5f8bb57365c..0c53584d201 100644
--- a/doc/integration/oauth_provider.md
+++ b/doc/integration/oauth_provider.md
@@ -28,7 +28,8 @@ GitLab supports two ways of adding a new OAuth2 application to an instance. You
can either add an application as a regular user or add it in the admin area.
What this means is that GitLab can actually have instance-wide and a user-wide
applications. There is no difference between them except for the different
-permission levels they are set (user/admin).
+permission levels they are set (user/admin). The default callback URL is
+`http://your-gitlab.example.com/users/auth/gitlab/callback`
## Adding an application through the profile
diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature
index 8176ec5ab45..21768c15c17 100644
--- a/features/project/merge_requests.feature
+++ b/features/project/merge_requests.feature
@@ -89,7 +89,7 @@ Feature: Project Merge Requests
Then The list should be sorted by "Oldest updated"
@javascript
- Scenario: Visiting Merge Requests from a different Project after sorting
+ Scenario: Visiting Merge Requests from a differente Project after sorting
Given I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I visit dashboard merge requests page
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index d5dfba5e0cc..959b700de78 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -63,7 +63,12 @@ module API
if access_status.status
# Return the repository full path so that gitlab-shell has it when
# handling ssh commands
- response[:repository_path] = project.repository.path_to_repo
+ response[:repository_path] =
+ if wiki?
+ project.wiki.repository.path_to_repo
+ else
+ project.repository.path_to_repo
+ end
end
response
diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb
index 536b478979f..91f0159f9a1 100644
--- a/lib/banzai/filter/syntax_highlight_filter.rb
+++ b/lib/banzai/filter/syntax_highlight_filter.rb
@@ -19,14 +19,22 @@ module Banzai
language = node.attr('class')
code = node.text
+ css_classes = "code highlight"
+
+ lexer = Rouge::Lexer.find_fancy(language) || Rouge::Lexers::PlainText
+ formatter = Rouge::Formatters::HTML.new
+
begin
- highlighted = block_code(code, language)
+ code = formatter.format(lexer.lex(code))
+
+ css_classes << " js-syntax-highlight #{lexer.tag}"
rescue
# Gracefully handle syntax highlighter bugs/errors to ensure
# users can still access an issue/comment/etc.
- highlighted = "<pre>#{code}</pre>"
end
+ highlighted = %(<pre class="#{css_classes}"><code>#{code}</code></pre>)
+
# Extracted to a method to measure it
replace_parent_pre_element(node, highlighted)
end
@@ -40,8 +48,7 @@ module Banzai
# Override Rouge::Plugins::Redcarpet#rouge_formatter
def rouge_formatter(lexer)
- Rouge::Formatters::HTMLGitlab.new(
- cssclass: "code highlight js-syntax-highlight #{lexer.tag}")
+ Rouge::Formatters::HTML.new
end
end
end
diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb
index 5b0a6d8541b..e1ca7f4d24b 100644
--- a/lib/banzai/filter/user_reference_filter.rb
+++ b/lib/banzai/filter/user_reference_filter.rb
@@ -112,7 +112,7 @@ module Banzai
data = data_attribute(project: project.id, author: author.try(:id))
text = link_text || User.reference_prefix + 'all'
- link_tag(url, data, text)
+ link_tag(url, data, text, 'All Project and Group Members')
end
def link_to_namespace(namespace, link_text: nil)
@@ -128,7 +128,7 @@ module Banzai
data = data_attribute(group: namespace.id)
text = link_text || Group.reference_prefix + group
- link_tag(url, data, text)
+ link_tag(url, data, text, namespace.name)
end
def link_to_user(user, namespace, link_text: nil)
@@ -136,11 +136,11 @@ module Banzai
data = data_attribute(user: namespace.owner_id)
text = link_text || User.reference_prefix + user
- link_tag(url, data, text)
+ link_tag(url, data, text, namespace.owner_name)
end
- def link_tag(url, data, text)
- %(<a href="#{url}" #{data} class="#{link_class}">#{escape_once(text)}</a>)
+ def link_tag(url, data, text, title)
+ %(<a href="#{url}" #{data} class="#{link_class}" title="#{escape_once(title)}">#{escape_once(text)}</a>)
end
end
end
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index dec20d8659b..927f9dad20b 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -20,11 +20,19 @@ module Gitlab
if Database.postgresql?
options = options.merge({ algorithm: :concurrently })
+ disable_statement_timeout
end
add_index(table_name, column_name, options)
end
+ # Long-running migrations may take more than the timeout allowed by
+ # the database. Disable the session's statement timeout to ensure
+ # migrations don't get killed prematurely. (PostgreSQL only)
+ def disable_statement_timeout
+ ActiveRecord::Base.connection.execute('SET statement_timeout TO 0') if Database.postgresql?
+ end
+
# Updates the value of a column in batches.
#
# This method updates the table in batches of 5% of the total row count.
@@ -133,6 +141,8 @@ module Gitlab
'in the body of your migration class'
end
+ disable_statement_timeout
+
transaction do
add_column(table, column, type, default: nil)
diff --git a/lib/gitlab/gitlab_import/importer.rb b/lib/gitlab/gitlab_import/importer.rb
index e6d31ea04c0..46d40f75be6 100644
--- a/lib/gitlab/gitlab_import/importer.rb
+++ b/lib/gitlab/gitlab_import/importer.rb
@@ -15,32 +15,35 @@ module Gitlab
end
def execute
- project_identifier = CGI.escape(project.import_source)
-
- # Issues && Comments
- issues = client.issues(project_identifier)
-
- issues.each do |issue|
- body = @formatter.author_line(issue["author"]["name"])
- body += issue["description"]
-
- comments = client.issue_comments(project_identifier, issue["id"])
-
- if comments.any?
- body += @formatter.comments_header
+ ActiveRecord::Base.no_touching do
+ project_identifier = CGI.escape(project.import_source)
+
+ # Issues && Comments
+ issues = client.issues(project_identifier)
+
+ issues.each do |issue|
+ body = @formatter.author_line(issue["author"]["name"])
+ body += issue["description"]
+
+ comments = client.issue_comments(project_identifier, issue["id"])
+
+ if comments.any?
+ body += @formatter.comments_header
+ end
+
+ comments.each do |comment|
+ body += @formatter.comment(comment["author"]["name"], comment["created_at"], comment["body"])
+ end
+
+ project.issues.create!(
+ iid: issue["iid"],
+ description: body,
+ title: issue["title"],
+ state: issue["state"],
+ updated_at: issue["updated_at"],
+ author_id: gl_user_id(project, issue["author"]["id"])
+ )
end
-
- comments.each do |comment|
- body += @formatter.comment(comment["author"]["name"], comment["created_at"], comment["body"])
- end
-
- project.issues.create!(
- iid: issue["iid"],
- description: body,
- title: issue["title"],
- state: issue["state"],
- author_id: gl_user_id(project, issue["author"]["id"])
- )
end
true
diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb
index 41296415e35..9360afedfcb 100644
--- a/lib/gitlab/highlight.rb
+++ b/lib/gitlab/highlight.rb
@@ -1,7 +1,7 @@
module Gitlab
class Highlight
- def self.highlight(blob_name, blob_content, repository: nil, nowrap: true, plain: false)
- new(blob_name, blob_content, nowrap: nowrap, repository: repository).
+ def self.highlight(blob_name, blob_content, repository: nil, plain: false)
+ new(blob_name, blob_content, repository: repository).
highlight(blob_content, continue: false, plain: plain)
end
@@ -13,30 +13,34 @@ module Gitlab
highlight(file_name, blob.data, repository: repository).lines.map!(&:html_safe)
end
- attr_reader :lexer
- def initialize(blob_name, blob_content, repository: nil, nowrap: true)
+ def initialize(blob_name, blob_content, repository: nil)
+ @formatter = Rouge::Formatters::HTMLGitlab.new
+ @repository = repository
@blob_name = blob_name
@blob_content = blob_content
- @repository = repository
- @formatter = rouge_formatter(nowrap: nowrap)
-
- @lexer = custom_language || begin
- Rouge::Lexer.guess(filename: blob_name, source: blob_content).new
- rescue Rouge::Lexer::AmbiguousGuess => e
- e.alternatives.sort_by(&:tag).first
- end
end
def highlight(text, continue: true, plain: false)
if plain
- @formatter.format(Rouge::Lexers::PlainText.lex(text)).html_safe
+ hl_lexer = Rouge::Lexers::PlainText
+ continue = false
else
- @formatter.format(@lexer.lex(text, continue: continue)).html_safe
+ hl_lexer = self.lexer
end
+
+ @formatter.format(hl_lexer.lex(text, continue: continue)).html_safe
rescue
@formatter.format(Rouge::Lexers::PlainText.lex(text)).html_safe
end
+ def lexer
+ @lexer ||= custom_language || begin
+ Rouge::Lexer.guess(filename: @blob_name, source: @blob_content).new
+ rescue Rouge::Guesser::Ambiguous => e
+ e.alternatives.sort_by(&:tag).first
+ end
+ end
+
private
def custom_language
@@ -46,16 +50,5 @@ module Gitlab
Rouge::Lexer.find_fancy(language_name)
end
-
- def rouge_formatter(options = {})
- options = options.reverse_merge(
- nowrap: true,
- cssclass: 'code highlight',
- lineanchors: true,
- lineanchorsid: 'LC'
- )
-
- Rouge::Formatters::HTMLGitlab.new(options)
- end
end
end
diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb
index 588647e5adb..bab2ea73c4f 100644
--- a/lib/gitlab/import_export.rb
+++ b/lib/gitlab/import_export.rb
@@ -3,6 +3,7 @@ module Gitlab
extend self
VERSION = '0.1.1'
+ FILENAME_LIMIT = 50
def export_path(relative_path:)
File.join(storage_path, relative_path)
@@ -28,6 +29,12 @@ module Gitlab
'VERSION'
end
+ def export_filename(project:)
+ basename = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_#{project.namespace.path}_#{project.path}"
+
+ "#{basename[0..FILENAME_LIMIT]}_export.tar.gz"
+ end
+
def version
VERSION
end
diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
index 025ecc12f9f..051110c23cf 100644
--- a/lib/gitlab/import_export/project_tree_restorer.rb
+++ b/lib/gitlab/import_export/project_tree_restorer.rb
@@ -12,7 +12,10 @@ module Gitlab
json = IO.read(@path)
@tree_hash = ActiveSupport::JSON.decode(json)
@project_members = @tree_hash.delete('project_members')
- create_relations
+
+ ActiveRecord::Base.no_touching do
+ create_relations
+ end
rescue => e
@shared.error(e)
false
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index 9824df3f274..6ba25a31641 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -87,7 +87,7 @@ module Gitlab
project_id = @relation_hash.delete('project_id')
# project_id may not be part of the export, but we always need to populate it if required.
- @relation_hash['project_id'] = project_id if relation_class.column_names.include?('project_id')
+ @relation_hash['project_id'] = project_id
@relation_hash['gl_project_id'] = project_id if @relation_hash['gl_project_id']
@relation_hash['target_project_id'] = project_id if @relation_hash['target_project_id']
@relation_hash['source_project_id'] = -1 if @relation_hash['source_project_id']
@@ -111,7 +111,7 @@ module Gitlab
end
def imported_object
- imported_object = relation_class.new(@relation_hash)
+ imported_object = relation_class.new(parsed_relation_hash)
yield(imported_object) if block_given?
imported_object.importing = true if imported_object.respond_to?(:importing)
imported_object
@@ -125,6 +125,10 @@ module Gitlab
def admin_user?
@user.is_admin?
end
+
+ def parsed_relation_hash
+ @relation_hash.reject { |k, _v| !relation_class.attribute_method?(k) }
+ end
end
end
end
diff --git a/lib/gitlab/import_export/saver.rb b/lib/gitlab/import_export/saver.rb
index 6a60b65071f..6130c124dd1 100644
--- a/lib/gitlab/import_export/saver.rb
+++ b/lib/gitlab/import_export/saver.rb
@@ -7,7 +7,8 @@ module Gitlab
new(*args).save
end
- def initialize(shared:)
+ def initialize(project:, shared:)
+ @project = project
@shared = shared
end
@@ -36,7 +37,7 @@ module Gitlab
end
def archive_file
- @archive_file ||= File.join(@shared.export_path, '..', "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_project_export.tar.gz")
+ @archive_file ||= File.join(@shared.export_path, '..', Gitlab::ImportExport.export_filename(project: @project))
end
end
end
diff --git a/lib/rouge/formatters/html_gitlab.rb b/lib/rouge/formatters/html_gitlab.rb
index 3358ed6773e..f818dc78d34 100644
--- a/lib/rouge/formatters/html_gitlab.rb
+++ b/lib/rouge/formatters/html_gitlab.rb
@@ -1,171 +1,27 @@
-require 'cgi'
-
module Rouge
module Formatters
- class HTMLGitlab < Rouge::Formatter
+ class HTMLGitlab < Rouge::Formatters::HTML
tag 'html_gitlab'
# Creates a new <tt>Rouge::Formatter::HTMLGitlab</tt> instance.
#
- # [+nowrap+] If set to True, don't wrap the output at all, not
- # even inside a <tt><pre></tt> tag (default: false).
- # [+cssclass+] CSS class for the wrapping <tt><div></tt> tag
- # (default: 'highlight').
- # [+linenos+] If set to 'table', output line numbers as a table
- # with two cells, one containing the line numbers,
- # the other the whole code. This is copy paste friendly,
- # but may cause alignment problems with some browsers
- # or fonts. If set to 'inline', the line numbers will
- # be integrated in the <tt><pre></tt> tag that contains
- # the code (default: nil).
# [+linenostart+] The line number for the first line (default: 1).
- # [+lineanchors+] If set to true the formatter will wrap each output
- # line in an anchor tag with a name of L-linenumber.
- # This allows easy linking to certain lines
- # (default: false).
- # [+lineanchorsid+] If lineanchors is true the name of the anchors can
- # be changed with lineanchorsid to e.g. foo-linenumber
- # (default: 'L').
- # [+anchorlinenos+] If set to true, will wrap line numbers in <tt><a></tt>
- # tags. Used in combination with linenos and lineanchors
- # (default: false).
- # [+inline_theme+] Inline CSS styles for the <pre> tag (default: false).
- def initialize(
- nowrap: false,
- cssclass: 'highlight',
- linenos: nil,
- linenostart: 1,
- lineanchors: false,
- lineanchorsid: 'L',
- anchorlinenos: false,
- inline_theme: nil
- )
- @nowrap = nowrap
- @cssclass = cssclass
- @linenos = linenos
+ def initialize(linenostart: 1)
@linenostart = linenostart
- @lineanchors = lineanchors
- @lineanchorsid = lineanchorsid
- @anchorlinenos = anchorlinenos
- @inline_theme = Theme.find(inline_theme).new if inline_theme.is_a?(String)
- end
-
- def render(tokens)
- case @linenos
- when 'table'
- render_tableized(tokens)
- when 'inline'
- render_untableized(tokens)
- else
- render_untableized(tokens)
- end
- end
-
- alias_method :format, :render
-
- private
-
- def render_untableized(tokens)
- data = process_tokens(tokens)
-
- html = ''
- html << "<pre class=\"#{@cssclass}\"><code>" unless @nowrap
- html << wrap_lines(data[:code])
- html << "</code></pre>\n" unless @nowrap
- html
+ @line_number = linenostart
end
- def render_tableized(tokens)
- data = process_tokens(tokens)
-
- html = ''
- html << "<div class=\"#{@cssclass}\">" unless @nowrap
- html << '<table><tbody>'
- html << "<td class=\"linenos\"><pre>"
- html << wrap_linenos(data[:numbers])
- html << '</pre></td>'
- html << "<td class=\"lines\"><pre><code>"
- html << wrap_lines(data[:code])
- html << '</code></pre></td>'
- html << '</tbody></table>'
- html << '</div>' unless @nowrap
- html
- end
-
- def process_tokens(tokens)
- rendered = []
- current_line = ''
-
- tokens.each do |tok, val|
- # In the case of multi-line values (e.g. comments), we need to apply
- # styling to each line since span elements are inline.
- val.lines.each do |line|
- stripped = line.chomp
- current_line << span(tok, stripped)
-
- if line.end_with?("\n")
- rendered << current_line
- current_line = ''
- end
- end
- end
-
- # Add leftover text
- rendered << current_line if current_line.present?
-
- num_lines = rendered.size
- numbers = (@linenostart..num_lines + @linenostart - 1).to_a
-
- { numbers: numbers, code: rendered }
- end
-
- def wrap_linenos(numbers)
- if @anchorlinenos
- numbers.map! do |number|
- "<a href=\"##{@lineanchorsid}#{number}\">#{number}</a>"
- end
- end
- numbers.join("\n")
- end
-
- def wrap_lines(lines)
- if @lineanchors
- lines = lines.each_with_index.map do |line, index|
- number = index + @linenostart
-
- if @linenos == 'inline'
- "<a name=\"L#{number}\"></a>" \
- "<span class=\"linenos\">#{number}</span>" \
- "<span id=\"#{@lineanchorsid}#{number}\" class=\"line\">#{line}" \
- '</span>'
- else
- "<span id=\"#{@lineanchorsid}#{number}\" class=\"line\">#{line}" \
- '</span>'
- end
- end
- elsif @linenos == 'inline'
- lines = lines.each_with_index.map do |line, index|
- number = index + @linenostart
- "<span class=\"linenos\">#{number}</span>#{line}"
- end
- end
-
- lines.join("\n")
- end
+ def stream(tokens, &b)
+ is_first = true
+ token_lines(tokens) do |line|
+ yield "\n" unless is_first
+ is_first = false
- def span(tok, val)
- # http://stackoverflow.com/a/1600584/2587286
- val = CGI.escapeHTML(val)
+ yield %(<span id="LC#{@line_number}" class="line">)
+ line.each { |token, value| yield span(token, value) }
+ yield %(</span>)
- if tok.shortname.empty?
- val
- else
- if @inline_theme
- rules = @inline_theme.style_for(tok).rendered_rules
- "<span style=\"#{rules.to_a.join(';')}\"#{val}</span>"
- else
- "<span class=\"#{tok.shortname}\">#{val}</span>"
- end
+ @line_number += 1
end
end
end
diff --git a/spec/features/compare_spec.rb b/spec/features/compare_spec.rb
new file mode 100644
index 00000000000..c62556948e0
--- /dev/null
+++ b/spec/features/compare_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+
+describe "Compare", js: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+
+ before do
+ project.team << [user, :master]
+ login_as user
+ visit namespace_project_compare_index_path(project.namespace, project, from: "master", to: "master")
+ end
+
+ describe "branches" do
+ it "should pre-populate fields" do
+ expect(page.find_field("from").value).to eq("master")
+ end
+
+ it "should compare branches" do
+ fill_in "from", with: "fea"
+ find("#from").click
+
+ click_link "feature"
+ expect(page.find_field("from").value).to eq("feature")
+
+ click_button "Compare"
+ expect(page).to have_content "Commits"
+ end
+ end
+
+ describe "tags" do
+ it "should compare tags" do
+ fill_in "from", with: "v1.0"
+ find("#from").click
+
+ click_link "v1.0.0"
+ expect(page.find_field("from").value).to eq("v1.0.0")
+
+ click_button "Compare"
+ expect(page).to have_content "Commits"
+ end
+ end
+end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 891df65216d..2d8b59472e8 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -1,14 +1,26 @@
require 'spec_helper'
feature 'Group', feature: true do
+ before do
+ login_as(:admin)
+ end
+
+ describe 'creating a group with space in group path' do
+ it 'renders new group form with validation errors' do
+ visit new_group_path
+ fill_in 'Group path', with: 'space group'
+
+ click_button 'Create group'
+
+ expect(current_path).to eq(groups_path)
+ expect(page).to have_content("Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-' or end in '.'.")
+ end
+ end
+
describe 'description' do
let(:group) { create(:group) }
let(:path) { group_path(group) }
- before do
- login_as(:admin)
- end
-
it 'parses Markdown' do
group.update_attribute(:description, 'This is **my** group')
visit path
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index cfe6349a1a1..d51c9abea19 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -121,17 +121,6 @@ describe 'Issues', feature: true do
expect(page).to have_content date.to_s(:medium)
end
end
-
- it 'warns about version conflict' do
- issue.update(title: "New title")
-
- fill_in 'issue_title', with: 'bug 345'
- fill_in 'issue_description', with: 'bug description'
-
- click_button 'Save changes'
-
- expect(page).to have_content 'Someone edited the issue the same time you did'
- end
end
end
diff --git a/spec/features/merge_requests/edit_mr_spec.rb b/spec/features/merge_requests/edit_mr_spec.rb
index 8ad884492d1..9e007ab7635 100644
--- a/spec/features/merge_requests/edit_mr_spec.rb
+++ b/spec/features/merge_requests/edit_mr_spec.rb
@@ -17,16 +17,5 @@ feature 'Edit Merge Request', feature: true do
it 'form should have class js-quick-submit' do
expect(page).to have_selector('.js-quick-submit')
end
-
- it 'warns about version conflict' do
- merge_request.update(title: "New title")
-
- fill_in 'merge_request_title', with: 'bug 345'
- fill_in 'merge_request_description', with: 'bug description'
-
- click_button 'Save changes'
-
- expect(page).to have_content 'Someone edited the merge request the same time you did'
- end
end
end
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index 14613754f74..9335f5bf120 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature: true, js: true do
+ before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) }
+
def register_u2f_device(u2f_device = nil)
u2f_device ||= FakeU2fDevice.new(page)
u2f_device.respond_to_u2f_registration
@@ -208,21 +210,52 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
expect(page.body).to match('Authentication via U2F device failed')
end
end
- end
- describe "when two-factor authentication is disabled" do
- let(:user) { create(:user) }
+ describe "when more than one device has been registered by the same user" do
+ it "allows logging in with either device" do
+ # Register first device
+ user = login_as(:user)
+ user.update_attribute(:otp_required_for_login, true)
+ visit profile_two_factor_auth_path
+ expect(page).to have_content("Your U2F device needs to be set up.")
+ first_device = register_u2f_device
+
+ # Register second device
+ visit profile_two_factor_auth_path
+ expect(page).to have_content("Your U2F device needs to be set up.")
+ second_device = register_u2f_device
+ logout
+
+ # Authenticate as both devices
+ [first_device, second_device].each do |device|
+ login_as(user)
+ device.respond_to_u2f_authentication
+ click_on "Login Via U2F Device"
+ expect(page.body).to match('We heard back from your U2F device')
+ click_on "Authenticate via U2F Device"
- before do
- login_as(user)
- user.update_attribute(:otp_required_for_login, true)
- visit profile_account_path
- click_on 'Manage Two-Factor Authentication'
- register_u2f_device
+ expect(page.body).to match('Signed in successfully')
+
+ logout
+ end
+ end
end
- it "deletes u2f registrations" do
- expect { click_on "Disable" }.to change { U2fRegistration.count }.from(1).to(0)
+ describe "when two-factor authentication is disabled" do
+ let(:user) { create(:user) }
+
+ before do
+ user = login_as(:user)
+ user.update_attribute(:otp_required_for_login, true)
+ visit profile_account_path
+ click_on 'Manage Two-Factor Authentication'
+ expect(page).to have_content("Your U2F device needs to be set up.")
+ register_u2f_device
+ end
+
+ it "deletes u2f registrations" do
+ expect { click_on "Disable" }.to change { U2fRegistration.count }.by(-1)
+ end
end
end
end
diff --git a/spec/fixtures/parallel_diff_result.yml b/spec/fixtures/parallel_diff_result.yml
index 333eda1191a..37066c8e930 100644
--- a/spec/fixtures/parallel_diff_result.yml
+++ b/spec/fixtures/parallel_diff_result.yml
@@ -121,7 +121,7 @@
:type: old
:number: 9
:text: |
- -<span id="LC9" class="line"> <span class="k">raise</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>
+ -<span id="LC9" class="line"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>
:line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9
:position: !ruby/object:Gitlab::Diff::Position
attributes:
@@ -136,7 +136,7 @@
:type: new
:number: 9
:text: |
- +<span id="LC9" class="line"> <span class="k">raise</span> <span class="no"><span class='idiff left'>RuntimeError</span></span><span class="p"><span class='idiff'>,</span></span><span class='idiff right'> </span><span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>
+ +<span id="LC9" class="line"> <span class="k">raise</span> <span class="no"><span class='idiff left'>RuntimeError</span></span><span class="p"><span class='idiff'>,</span></span><span class='idiff right'> </span><span class="s2">"System commands must be given as an array of strings"</span></span>
:line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9
:position: !ruby/object:Gitlab::Diff::Position
attributes:
@@ -241,7 +241,7 @@
:type: old
:number: 13
:text: |
- -<span id="LC13" class="line"> <span class="n">vars</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;PWD&quot;</span> <span class="o">=&gt;</span> <span class="n">path</span> <span class="p">}</span></span>
+ -<span id="LC13" class="line"> <span class="n">vars</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"PWD"</span> <span class="o">=&gt;</span> <span class="n">path</span> <span class="p">}</span></span>
:line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_13_13
:position: !ruby/object:Gitlab::Diff::Position
attributes:
@@ -315,7 +315,7 @@
:type: new
:number: 15
:text: |
- +<span id="LC15" class="line"> <span class="s2">&quot;PWD&quot;</span> <span class="o">=&gt;</span> <span class="n">path</span></span>
+ +<span id="LC15" class="line"> <span class="s2">"PWD"</span> <span class="o">=&gt;</span> <span class="n">path</span></span>
:line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15
:position: !ruby/object:Gitlab::Diff::Position
attributes:
@@ -623,7 +623,7 @@
:type:
:number: 20
:text: |2
- <span id="LC26" class="line"> <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span></span>
+ <span id="LC26" class="line"> <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">""</span></span>
:line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26
:position: !ruby/object:Gitlab::Diff::Position
attributes:
@@ -638,7 +638,7 @@
:type:
:number: 26
:text: |2
- <span id="LC26" class="line"> <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span></span>
+ <span id="LC26" class="line"> <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">""</span></span>
:line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26
:position: !ruby/object:Gitlab::Diff::Position
attributes:
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index 6d1c02db297..bd0108f9938 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -16,19 +16,19 @@ describe BlobHelper do
describe '#highlight' do
it 'should return plaintext for unknown lexer context' do
- result = helper.highlight(blob_name, no_context_content, nowrap: true)
- expect(result).to eq('<span id="LC1" class="line">:type &quot;assem&quot;))</span>')
+ result = helper.highlight(blob_name, no_context_content)
+ expect(result).to eq(%[<pre class="code highlight"><code><span id="LC1" class="line">:type "assem"))</span></code></pre>])
end
it 'should highlight single block' do
- expected = %Q[<span id="LC1" class="line"><span class="p">(</span><span class="nb">make-pathname</span> <span class="ss">:defaults</span> <span class="nv">name</span></span>
-<span id="LC2" class="line"><span class="ss">:type</span> <span class="s">&quot;assem&quot;</span><span class="p">))</span></span>]
+ expected = %Q[<pre class="code highlight"><code><span id="LC1" class="line"><span class="p">(</span><span class="nb">make-pathname</span> <span class="ss">:defaults</span> <span class="nv">name</span></span>
+<span id="LC2" class="line"><span class="ss">:type</span> <span class="s">"assem"</span><span class="p">))</span></span></code></pre>]
- expect(helper.highlight(blob_name, blob_content, nowrap: true)).to eq(expected)
+ expect(helper.highlight(blob_name, blob_content)).to eq(expected)
end
it 'should highlight multi-line comments' do
- result = helper.highlight(blob_name, multiline_content, nowrap: true)
+ result = helper.highlight(blob_name, multiline_content)
html = Nokogiri::HTML(result)
lines = html.search('.s')
expect(lines.count).to eq(3)
@@ -41,33 +41,19 @@ describe BlobHelper do
let(:blob_name) { 'test.diff' }
let(:blob_content) { "+aaa\n+bbb\n- ccc\n ddd\n"}
let(:expected) do
- %q(<span id="LC1" class="line"><span class="gi">+aaa</span></span>
+ %q(<pre class="code highlight"><code><span id="LC1" class="line"><span class="gi">+aaa</span></span>
<span id="LC2" class="line"><span class="gi">+bbb</span></span>
<span id="LC3" class="line"><span class="gd">- ccc</span></span>
-<span id="LC4" class="line"> ddd</span>)
+<span id="LC4" class="line"> ddd</span></code></pre>)
end
it 'should highlight each line properly' do
- result = helper.highlight(blob_name, blob_content, nowrap: true)
+ result = helper.highlight(blob_name, blob_content)
expect(result).to eq(expected)
end
end
end
- describe "#highlighter" do
- it 'should highlight continued blocks' do
- # Both lines have LC1 as ID since formatter doesn't support continue at the moment
- expected = [
- '<span id="LC1" class="line"><span class="p">(</span><span class="nb">make-pathname</span> <span class="ss">:defaults</span> <span class="nv">name</span></span>',
- '<span id="LC1" class="line"><span class="ss">:type</span> <span class="s">&quot;assem&quot;</span><span class="p">))</span></span>'
- ]
-
- highlighter = helper.highlighter(blob_name, blob_content, nowrap: true)
- result = split_content.map{ |content| highlighter.highlight(content) }
- expect(result).to eq(expected)
- end
- end
-
describe "#sanitize_svg" do
let(:input_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'unsanitized.svg') }
let(:data) { open(input_svg_path).read }
diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb
index c0d2be98e85..6b5e3d93d48 100644
--- a/spec/helpers/events_helper_spec.rb
+++ b/spec/helpers/events_helper_spec.rb
@@ -57,7 +57,7 @@ describe EventsHelper do
expected = '<pre class="code highlight js-syntax-highlight ruby">' \
"<code><span class=\"k\">def</span> <span class=\"nf\">test</span>\n" \
" <span class=\"s1\">\'hello world\'</span>\n" \
- "<span class=\"k\">end</span>" \
+ "<span class=\"k\">end</span>\n" \
'</code></pre>'
expect(helper.event_note(input)).to eq(expected)
end
diff --git a/spec/javascripts/u2f/authenticate_spec.coffee b/spec/javascripts/u2f/authenticate_spec.coffee
index e8a2892d678..8ffeda11704 100644
--- a/spec/javascripts/u2f/authenticate_spec.coffee
+++ b/spec/javascripts/u2f/authenticate_spec.coffee
@@ -5,13 +5,12 @@
#= require ./mock_u2f_device
describe 'U2FAuthenticate', ->
- U2FUtil.enableTestMode()
fixture.load('u2f/authenticate')
beforeEach ->
@u2fDevice = new MockU2FDevice
@container = $("#js-authenticate-u2f")
- @component = new U2FAuthenticate(@container, {}, "token")
+ @component = new U2FAuthenticate(@container, {sign_requests: []}, "token")
@component.start()
it 'allows authenticating via a U2F device', ->
diff --git a/spec/javascripts/u2f/register_spec.js.coffee b/spec/javascripts/u2f/register_spec.js.coffee
index 0858abeca1a..87dc769792b 100644
--- a/spec/javascripts/u2f/register_spec.js.coffee
+++ b/spec/javascripts/u2f/register_spec.js.coffee
@@ -5,7 +5,6 @@
#= require ./mock_u2f_device
describe 'U2FRegister', ->
- U2FUtil.enableTestMode()
fixture.load('u2f/register')
beforeEach ->
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index 407617f3307..b1370bca833 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -3,15 +3,35 @@ require 'spec_helper'
describe Banzai::Filter::SyntaxHighlightFilter, lib: true do
include FilterSpecHelper
- it 'highlights valid code blocks' do
- result = filter('<pre><code>def fun end</code>')
- expect(result.to_html).to eq("<pre class=\"code highlight js-syntax-highlight plaintext\"><code>def fun end</code></pre>\n")
+ context "when no language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre><code>def fun end</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext"><code>def fun end</code></pre>')
+ end
end
- it 'passes through invalid code blocks' do
- allow_any_instance_of(described_class).to receive(:block_code).and_raise(StandardError)
+ context "when a valid language is specified" do
+ it "highlights as that language" do
+ result = filter('<pre><code class="ruby">def fun end</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight ruby"><code><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></code></pre>')
+ end
+ end
+
+ context "when an invalid language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre><code class="gnuplot">This is a test</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext"><code>This is a test</code></pre>')
+ end
+ end
+
+ context "when Rouge formatting fails" do
+ before do
+ allow_any_instance_of(Rouge::Formatter).to receive(:format).and_raise(StandardError)
+ end
- result = filter('<pre><code>This is a test</code></pre>')
- expect(result.to_html).to eq('<pre>This is a test</pre>')
+ it "highlights as plaintext" do
+ result = filter('<pre><code class="ruby">This is a test</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight"><code>This is a test</code></pre>')
+ end
end
end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 9096ad101b0..4ec3f19e03f 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -13,6 +13,10 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
context 'outside a transaction' do
before do
expect(model).to receive(:transaction_open?).and_return(false)
+
+ unless Gitlab::Database.postgresql?
+ allow_any_instance_of(Gitlab::Database::MigrationHelpers).to receive(:disable_statement_timeout)
+ end
end
context 'using PostgreSQL' do
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index fb5d50a5c68..88e4115c453 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -28,13 +28,13 @@ describe Gitlab::Diff::Highlight, lib: true do
end
it 'highlights and marks removed lines' do
- code = %Q{-<span id="LC9" class="line"> <span class="k">raise</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>\n}
+ code = %Q{-<span id="LC9" class="line"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n}
expect(subject[4].text).to eq(code)
end
it 'highlights and marks added lines' do
- code = %Q{+<span id="LC9" class="line"> <span class="k">raise</span> <span class="no"><span class='idiff left'>RuntimeError</span></span><span class="p"><span class='idiff'>,</span></span><span class='idiff right'> </span><span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>\n}
+ code = %Q{+<span id="LC9" class="line"> <span class="k">raise</span> <span class="no"><span class='idiff left'>RuntimeError</span></span><span class="p"><span class='idiff'>,</span></span><span class='idiff right'> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
expect(subject[5].text).to eq(code)
end
diff --git a/spec/lib/gitlab/import_export/import_export_spec.rb b/spec/lib/gitlab/import_export/import_export_spec.rb
new file mode 100644
index 00000000000..d6409a29550
--- /dev/null
+++ b/spec/lib/gitlab/import_export/import_export_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Gitlab::ImportExport, services: true do
+ describe 'export filename' do
+ let(:project) { create(:project, :public, path: 'project-path') }
+
+ it 'contains the project path' do
+ expect(described_class.export_filename(project: project)).to include(project.path)
+ end
+
+ it 'contains the namespace path' do
+ expect(described_class.export_filename(project: project)).to include(project.namespace.path)
+ end
+
+ it 'does not go over a certain length' do
+ project.path = 'a' * 100
+
+ expect(described_class.export_filename(project: project).length).to be < 70
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 7286b0c39c0..4113d829c3c 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -26,6 +26,7 @@
"deleted_at": null,
"due_date": null,
"moved_to_id": null,
+ "test_ee_field": "test",
"notes": [
{
"id": 351,
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 05ffec8ea0a..877be300262 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -30,6 +30,14 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
expect(Event.where.not(data: nil).first.data[:ref]).not_to be_empty
end
+ it 'preserves updated_at on issues' do
+ restored_project_json
+
+ issue = Issue.where(description: 'Aliquam enim illo et possimus.').first
+
+ expect(issue.reload.updated_at.to_s).to eq('2016-06-14 15:02:47 UTC')
+ end
+
context 'event at forth level of the tree' do
let(:event) { Event.where(title: 'test levels').first }
diff --git a/spec/models/legacy_diff_note_spec.rb b/spec/models/legacy_diff_note_spec.rb
index d64d89edbd3..d23fc06c3ad 100644
--- a/spec/models/legacy_diff_note_spec.rb
+++ b/spec/models/legacy_diff_note_spec.rb
@@ -16,10 +16,10 @@ describe LegacyDiffNote, models: true do
end
describe '#active?' do
- it 'is always true when the note has no associated diff' do
+ it 'is always true when the note has no associated diff line' do
note = build(:legacy_diff_note_on_merge_request)
- expect(note).to receive(:diff).and_return(nil)
+ expect(note).to receive(:diff_line).and_return(nil)
expect(note).to be_active
end
@@ -27,7 +27,7 @@ describe LegacyDiffNote, models: true do
it 'is never true when the note has no noteable associated' do
note = build(:legacy_diff_note_on_merge_request)
- expect(note).to receive(:diff).and_return(double)
+ expect(note).to receive(:diff_line).and_return(double)
expect(note).to receive(:noteable).and_return(nil)
expect(note).not_to be_active
@@ -47,7 +47,7 @@ describe LegacyDiffNote, models: true do
merge = build_stubbed(:merge_request, :simple)
note = build(:legacy_diff_note_on_merge_request, noteable: merge)
- allow(note).to receive(:diff).and_return(double)
+ allow(note).to receive(:diff_line).and_return(double)
expect(note).to receive(:find_noteable_diff).and_return(nil)
expect(note).not_to be_active
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d2269854354..e842c58dd82 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -130,17 +130,35 @@ describe Project, models: true do
end
end
- it 'should not allow an invalid URI as import_url' do
+ it 'does not allow an invalid URI as import_url' do
project2 = build(:project, import_url: 'invalid://')
expect(project2).not_to be_valid
end
- it 'should allow a valid URI as import_url' do
+ it 'does allow a valid URI as import_url' do
project2 = build(:project, import_url: 'ssh://test@gitlab.com/project.git')
expect(project2).to be_valid
end
+
+ it 'does not allow to introduce an empty URI' do
+ project2 = build(:project, import_url: '')
+
+ expect(project2).not_to be_valid
+ end
+
+ it 'does not produce import data on an empty URI' do
+ project2 = build(:project, import_url: '')
+
+ expect(project2.import_data).to be_nil
+ end
+
+ it 'does not produce import data on an invalid URI' do
+ project2 = build(:project, import_url: 'test://')
+
+ expect(project2.import_data).to be_nil
+ end
end
describe 'default_scope' do
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index e567d36afa8..f6f85d6e95e 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -56,13 +56,21 @@ describe API::API, api: true do
context "git push with project.wiki" do
it 'responds with success' do
- project_wiki = create(:project, name: 'my.wiki', path: 'my.wiki')
- project_wiki.team << [user, :developer]
+ push(key, project.wiki)
- push(key, project_wiki)
+ expect(response).to have_http_status(200)
+ expect(json_response["status"]).to be_truthy
+ expect(json_response["repository_path"]).to eq(project.wiki.repository.path_to_repo)
+ end
+ end
+
+ context "git pull with project.wiki" do
+ it 'responds with success' do
+ pull(key, project.wiki)
expect(response).to have_http_status(200)
expect(json_response["status"]).to be_truthy
+ expect(json_response["repository_path"]).to eq(project.wiki.repository.path_to_repo)
end
end
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index b4522536724..34d8ea9090e 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -35,8 +35,11 @@ describe TodoService, services: true do
should_not_create_any_todo { service.new_issue(unassigned_issue, author) }
end
- it 'does not create a todo if assignee is the current user' do
- should_not_create_any_todo { service.new_issue(unassigned_issue, john_doe) }
+ it 'creates a todo if assignee is the current user' do
+ unassigned_issue.update_attribute(:assignee, john_doe)
+ service.new_issue(unassigned_issue, john_doe)
+
+ should_create_todo(user: john_doe, target: unassigned_issue, author: john_doe, action: Todo::ASSIGNED)
end
it 'creates a todo for each valid mentioned user' do
@@ -44,7 +47,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: issue, action: Todo::MENTIONED)
should_create_todo(user: guest, target: issue, action: Todo::MENTIONED)
- should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
+ should_create_todo(user: author, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: non_member, target: issue, action: Todo::MENTIONED)
end
@@ -57,7 +60,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
- should_not_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
+ should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
end
context 'when a private group is mentioned' do
@@ -87,7 +90,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: issue, action: Todo::MENTIONED)
should_create_todo(user: guest, target: issue, action: Todo::MENTIONED)
should_create_todo(user: john_doe, target: issue, action: Todo::MENTIONED)
- should_not_create_todo(user: author, target: issue, action: Todo::MENTIONED)
+ should_create_todo(user: author, target: issue, action: Todo::MENTIONED)
should_not_create_todo(user: non_member, target: issue, action: Todo::MENTIONED)
end
@@ -105,7 +108,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
- should_not_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
+ should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED)
end
context 'issues with a task list' do
@@ -156,10 +159,11 @@ describe TodoService, services: true do
should_not_create_any_todo { service.reassigned_issue(issue, author) }
end
- it 'does not create a todo if new assignee is the current user' do
+ it 'creates a todo if new assignee is the current user' do
unassigned_issue.update_attribute(:assignee, john_doe)
+ service.reassigned_issue(unassigned_issue, john_doe)
- should_not_create_any_todo { service.reassigned_issue(unassigned_issue, john_doe) }
+ should_create_todo(user: john_doe, target: unassigned_issue, author: john_doe, action: Todo::ASSIGNED)
end
end
@@ -250,7 +254,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_create_todo(user: guest, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_create_todo(user: author, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
- should_not_create_todo(user: john_doe, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
+ should_create_todo(user: john_doe, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
should_not_create_todo(user: non_member, target: issue, author: john_doe, action: Todo::MENTIONED, note: note)
end
@@ -262,7 +266,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_create_todo(user: admin, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
should_not_create_todo(user: guest, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
- should_not_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
+ should_create_todo(user: john_doe, target: confidential_issue, author: john_doe, action: Todo::MENTIONED, note: note_on_confidential_issue)
end
it 'creates a todo for each valid mentioned user when leaving a note on commit' do
@@ -270,7 +274,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit)
should_create_todo(user: author, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit)
- should_not_create_todo(user: john_doe, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit)
+ should_create_todo(user: john_doe, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit)
should_not_create_todo(user: non_member, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit)
end
@@ -312,7 +316,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: mr_assigned, action: Todo::MENTIONED)
should_create_todo(user: guest, target: mr_assigned, action: Todo::MENTIONED)
- should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
+ should_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: non_member, target: mr_assigned, action: Todo::MENTIONED)
end
@@ -325,7 +329,7 @@ describe TodoService, services: true do
should_create_todo(user: member, target: mr_assigned, action: Todo::MENTIONED)
should_create_todo(user: guest, target: mr_assigned, action: Todo::MENTIONED)
should_create_todo(user: john_doe, target: mr_assigned, action: Todo::MENTIONED)
- should_not_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
+ should_create_todo(user: author, target: mr_assigned, action: Todo::MENTIONED)
should_not_create_todo(user: non_member, target: mr_assigned, action: Todo::MENTIONED)
end
@@ -382,10 +386,11 @@ describe TodoService, services: true do
should_not_create_any_todo { service.reassigned_merge_request(mr_assigned, author) }
end
- it 'does not create a todo if new assignee is the current user' do
+ it 'creates a todo if new assignee is the current user' do
mr_assigned.update_attribute(:assignee, john_doe)
+ service.reassigned_merge_request(mr_assigned, john_doe)
- should_not_create_any_todo { service.reassigned_merge_request(mr_assigned, john_doe) }
+ should_create_todo(user: john_doe, target: mr_assigned, author: john_doe, action: Todo::ASSIGNED)
end
end
@@ -435,6 +440,24 @@ describe TodoService, services: true do
should_create_todo(user: author, target: mr_unassigned, action: Todo::MARKED)
end
end
+
+ describe '#new_note' do
+ let(:mention) { john_doe.to_reference }
+ let(:diff_note_on_merge_request) { create(:diff_note_on_merge_request, project: project, noteable: mr_unassigned, author: author, note: "Hey #{mention}") }
+ let(:legacy_diff_note_on_merge_request) { create(:legacy_diff_note_on_merge_request, project: project, noteable: mr_unassigned, author: author, note: "Hey #{mention}") }
+
+ it 'creates a todo for mentioned user on new diff note' do
+ service.new_note(diff_note_on_merge_request, author)
+
+ should_create_todo(user: john_doe, target: mr_unassigned, author: author, action: Todo::MENTIONED, note: diff_note_on_merge_request)
+ end
+
+ it 'creates a todo for mentioned user on legacy diff note' do
+ service.new_note(legacy_diff_note_on_merge_request, author)
+
+ should_create_todo(user: john_doe, target: mr_unassigned, author: author, action: Todo::MENTIONED, note: legacy_diff_note_on_merge_request)
+ end
+ end
end
it 'updates cached counts when a todo is created' do
diff --git a/spec/support/fake_u2f_device.rb b/spec/support/fake_u2f_device.rb
index 553fe9f1fbc..f550e9a0160 100644
--- a/spec/support/fake_u2f_device.rb
+++ b/spec/support/fake_u2f_device.rb
@@ -18,8 +18,8 @@ class FakeU2fDevice
def respond_to_u2f_authentication
app_id = @page.evaluate_script('gon.u2f.app_id')
- challenges = @page.evaluate_script('gon.u2f.challenges')
- json_response = u2f_device(app_id).sign_response(challenges[0])
+ challenge = @page.evaluate_script('gon.u2f.challenge')
+ json_response = u2f_device(app_id).sign_response(challenge)
@page.execute_script("
u2f.sign = function(appId, challenges, signRequests, callback) {
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index a9cce8b8b59..c9f5aae0815 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -16,7 +16,10 @@ describe GitGarbageCollectWorker do
project.repository_storage_path,
project.path_with_namespace).
and_return(true)
- expect_any_instance_of(Repository).to receive(:after_create_branch)
+ expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
+ expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
+ expect_any_instance_of(Repository).to receive(:branch_count).and_call_original
+ expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
subject.perform(project.id)
end