Merge branch 'master' into 'docs-specific-review-examples'
# Conflicts: # doc/development/code_review.md
This commit is contained in:
commit
9ba8685ea7
|
@ -96,6 +96,7 @@ stages:
|
||||||
- export KNAPSACK_GENERATE_REPORT=true
|
- export KNAPSACK_GENERATE_REPORT=true
|
||||||
- export CACHE_CLASSES=true
|
- export CACHE_CLASSES=true
|
||||||
- cp ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
- cp ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
|
||||||
|
- scripts/gitaly-test-spawn
|
||||||
- knapsack rspec "--color --format documentation"
|
- knapsack rspec "--color --format documentation"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
|
@ -221,6 +222,7 @@ setup-test-env:
|
||||||
- bundle exec rake gettext:po_to_json
|
- bundle exec rake gettext:po_to_json
|
||||||
- bundle exec rake gitlab:assets:compile
|
- bundle exec rake gitlab:assets:compile
|
||||||
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
|
- bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
|
||||||
|
- scripts/gitaly-test-build # Do not use 'bundle exec' here
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 7d
|
expire_in: 7d
|
||||||
paths:
|
paths:
|
||||||
|
@ -486,6 +488,7 @@ karma:
|
||||||
BABEL_ENV: "coverage"
|
BABEL_ENV: "coverage"
|
||||||
CHROME_LOG_FILE: "chrome_debug.log"
|
CHROME_LOG_FILE: "chrome_debug.log"
|
||||||
script:
|
script:
|
||||||
|
- scripts/gitaly-test-spawn
|
||||||
- bundle exec rake gettext:po_to_json
|
- bundle exec rake gettext:po_to_json
|
||||||
- bundle exec rake karma
|
- bundle exec rake karma
|
||||||
coverage: '/^Statements *: (\d+\.\d+%)/'
|
coverage: '/^Statements *: (\d+\.\d+%)/'
|
||||||
|
|
454
.rubocop.yml
454
.rubocop.yml
|
@ -6,6 +6,7 @@ inherit_from: .rubocop_todo.yml
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 2.3
|
TargetRubyVersion: 2.3
|
||||||
|
TargetRailsVersion: 4.2
|
||||||
# Cop names are not d§splayed in offense messages by default. Change behavior
|
# Cop names are not d§splayed in offense messages by default. Change behavior
|
||||||
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
|
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
|
||||||
# option.
|
# option.
|
||||||
|
@ -29,12 +30,221 @@ AllCops:
|
||||||
Bundler/OrderedGems:
|
Bundler/OrderedGems:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Style #######################################################################
|
# Layout ######################################################################
|
||||||
|
|
||||||
# Check indentation of private/protected visibility modifiers.
|
# Check indentation of private/protected visibility modifiers.
|
||||||
Style/AccessModifierIndentation:
|
Layout/AccessModifierIndentation:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
# Align the elements of an array literal if they span more than one line.
|
||||||
|
Layout/AlignArray:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Align the elements of a hash literal if they span more than one line.
|
||||||
|
Layout/AlignHash:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Here we check if the parameters on a multi-line method call or
|
||||||
|
# definition are aligned.
|
||||||
|
Layout/AlignParameters:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Put end statement of multiline block on its own line.
|
||||||
|
Layout/BlockEndNewline:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Indentation of when in a case/when/[else/]end.
|
||||||
|
Layout/CaseIndentation:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Indentation of comments.
|
||||||
|
Layout/CommentIndentation:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Multi-line method chaining should be done with leading dots.
|
||||||
|
Layout/DotPosition:
|
||||||
|
Enabled: true
|
||||||
|
EnforcedStyle: leading
|
||||||
|
|
||||||
|
# Align elses and elsifs correctly.
|
||||||
|
Layout/ElseAlignment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Add an empty line after magic comments to separate them from code.
|
||||||
|
Layout/EmptyLineAfterMagicComment:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Use empty lines between defs.
|
||||||
|
Layout/EmptyLineBetweenDefs:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Don't use several empty lines in a row.
|
||||||
|
Layout/EmptyLines:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Keep blank lines around access modifiers.
|
||||||
|
Layout/EmptyLinesAroundAccessModifier:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Keeps track of empty lines around block bodies.
|
||||||
|
Layout/EmptyLinesAroundBlockBody:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Keeps track of empty lines around class bodies.
|
||||||
|
Layout/EmptyLinesAroundClassBody:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Keeps track of empty lines around exception handling keywords.
|
||||||
|
Layout/EmptyLinesAroundExceptionHandlingKeywords:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Keeps track of empty lines around method bodies.
|
||||||
|
Layout/EmptyLinesAroundMethodBody:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Keeps track of empty lines around module bodies.
|
||||||
|
Layout/EmptyLinesAroundModuleBody:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use Unix-style line endings.
|
||||||
|
Layout/EndOfLine:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks for a line break before the first parameter in a multi-line method
|
||||||
|
# parameter definition.
|
||||||
|
Layout/FirstMethodParameterLineBreak:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Keep indentation straight.
|
||||||
|
Layout/IndentationConsistency:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use 2 spaces for indentation.
|
||||||
|
Layout/IndentationWidth:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks the indentation of the first line of the right-hand-side of a
|
||||||
|
# multi-line assignment.
|
||||||
|
Layout/IndentAssignment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# This cops checks the indentation of the here document bodies.
|
||||||
|
Layout/IndentHeredoc:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Comments should start with a space.
|
||||||
|
Layout/LeadingCommentSpace:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks that the closing brace in an array literal is either on the same line
|
||||||
|
# as the last array element, or a new line.
|
||||||
|
Layout/MultilineArrayBraceLayout:
|
||||||
|
Enabled: true
|
||||||
|
EnforcedStyle: symmetrical
|
||||||
|
|
||||||
|
# Ensures newlines after multiline block do statements.
|
||||||
|
Layout/MultilineBlockLayout:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks that the closing brace in a hash literal is either on the same line as
|
||||||
|
# the last hash element, or a new line.
|
||||||
|
Layout/MultilineHashBraceLayout:
|
||||||
|
Enabled: true
|
||||||
|
EnforcedStyle: symmetrical
|
||||||
|
|
||||||
|
# Checks that the closing brace in a method call is either on the same line as
|
||||||
|
# the last method argument, or a new line.
|
||||||
|
Layout/MultilineMethodCallBraceLayout:
|
||||||
|
Enabled: false
|
||||||
|
EnforcedStyle: symmetrical
|
||||||
|
|
||||||
|
# Checks indentation of method calls with the dot operator that span more than
|
||||||
|
# one line.
|
||||||
|
Layout/MultilineMethodCallIndentation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Checks that the closing brace in a method definition is symmetrical with
|
||||||
|
# respect to the opening brace and the method parameters.
|
||||||
|
Layout/MultilineMethodDefinitionBraceLayout:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Checks indentation of binary operations that span more than one line.
|
||||||
|
Layout/MultilineOperationIndentation:
|
||||||
|
Enabled: true
|
||||||
|
EnforcedStyle: indented
|
||||||
|
|
||||||
|
# Use spaces after colons.
|
||||||
|
Layout/SpaceAfterColon:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use spaces after commas.
|
||||||
|
Layout/SpaceAfterComma:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Do not put a space between a method name and the opening parenthesis in a
|
||||||
|
# method definition.
|
||||||
|
Layout/SpaceAfterMethodName:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Tracks redundant space after the ! operator.
|
||||||
|
Layout/SpaceAfterNot:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use spaces after semicolons.
|
||||||
|
Layout/SpaceAfterSemicolon:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use space around equals in parameter default
|
||||||
|
Layout/SpaceAroundEqualsInParameterDefault:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use a space around keywords if appropriate.
|
||||||
|
Layout/SpaceAroundKeyword:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use a single space around operators.
|
||||||
|
Layout/SpaceAroundOperators:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# No spaces before commas.
|
||||||
|
Layout/SpaceBeforeComma:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks for missing space between code and a comment on the same line.
|
||||||
|
Layout/SpaceBeforeComment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# No spaces before semicolons.
|
||||||
|
Layout/SpaceBeforeSemicolon:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks for spaces inside square brackets.
|
||||||
|
Layout/SpaceInsideBrackets:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Use spaces inside hash literal braces - or don't.
|
||||||
|
Layout/SpaceInsideHashLiteralBraces:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# No spaces inside range literals.
|
||||||
|
Layout/SpaceInsideRangeLiteral:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks for padding/surrounding spaces inside string interpolation.
|
||||||
|
Layout/SpaceInsideStringInterpolation:
|
||||||
|
EnforcedStyle: no_space
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# No hard tabs.
|
||||||
|
Layout/Tab:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Checks trailing blank lines and final newline.
|
||||||
|
Layout/TrailingBlankLines:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
# Style #######################################################################
|
||||||
|
|
||||||
# Check the naming of accessor methods for get_/set_.
|
# Check the naming of accessor methods for get_/set_.
|
||||||
Style/AccessorMethodName:
|
Style/AccessorMethodName:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -44,19 +254,6 @@ Style/Alias:
|
||||||
EnforcedStyle: prefer_alias_method
|
EnforcedStyle: prefer_alias_method
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Align the elements of an array literal if they span more than one line.
|
|
||||||
Style/AlignArray:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Align the elements of a hash literal if they span more than one line.
|
|
||||||
Style/AlignHash:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Here we check if the parameters on a multi-line method call or
|
|
||||||
# definition are aligned.
|
|
||||||
Style/AlignParameters:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Whether `and` and `or` are banned only in conditionals (conditionals)
|
# Whether `and` and `or` are banned only in conditionals (conditionals)
|
||||||
# or completely (always).
|
# or completely (always).
|
||||||
Style/AndOr:
|
Style/AndOr:
|
||||||
|
@ -91,10 +288,6 @@ Style/BlockComments:
|
||||||
Style/BlockDelimiters:
|
Style/BlockDelimiters:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Put end statement of multiline block on its own line.
|
|
||||||
Style/BlockEndNewline:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# This cop checks for braces around the last parameter in a method call
|
# This cop checks for braces around the last parameter in a method call
|
||||||
# if the last parameter is a hash.
|
# if the last parameter is a hash.
|
||||||
Style/BracesAroundHashParameters:
|
Style/BracesAroundHashParameters:
|
||||||
|
@ -104,10 +297,6 @@ Style/BracesAroundHashParameters:
|
||||||
Style/CaseEquality:
|
Style/CaseEquality:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Indentation of when in a case/when/[else/]end.
|
|
||||||
Style/CaseIndentation:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for uses of character literals.
|
# Checks for uses of character literals.
|
||||||
Style/CharacterLiteral:
|
Style/CharacterLiteral:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -142,10 +331,6 @@ Style/ColonMethodCall:
|
||||||
Style/CommentAnnotation:
|
Style/CommentAnnotation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Indentation of comments.
|
|
||||||
Style/CommentIndentation:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Check for `if` and `case` statements where each branch is used for
|
# Check for `if` and `case` statements where each branch is used for
|
||||||
# assignment to the same variable when using the return of the
|
# assignment to the same variable when using the return of the
|
||||||
# condition can be used instead.
|
# condition can be used instead.
|
||||||
|
@ -164,57 +349,16 @@ Style/DefWithParentheses:
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Multi-line method chaining should be done with leading dots.
|
|
||||||
Style/DotPosition:
|
|
||||||
Enabled: true
|
|
||||||
EnforcedStyle: leading
|
|
||||||
|
|
||||||
# This cop checks for uses of double negation (!!) to convert something
|
# This cop checks for uses of double negation (!!) to convert something
|
||||||
# to a boolean value. As this is both cryptic and usually redundant, it
|
# to a boolean value. As this is both cryptic and usually redundant, it
|
||||||
# should be avoided.
|
# should be avoided.
|
||||||
Style/DoubleNegation:
|
Style/DoubleNegation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Align elses and elsifs correctly.
|
|
||||||
Style/ElseAlignment:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use empty lines between defs.
|
|
||||||
Style/EmptyLineBetweenDefs:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Don't use several empty lines in a row.
|
|
||||||
Style/EmptyLines:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keep blank lines around access modifiers.
|
|
||||||
Style/EmptyLinesAroundAccessModifier:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keeps track of empty lines around block bodies.
|
|
||||||
Style/EmptyLinesAroundBlockBody:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keeps track of empty lines around class bodies.
|
|
||||||
Style/EmptyLinesAroundClassBody:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keeps track of empty lines around method bodies.
|
|
||||||
Style/EmptyLinesAroundMethodBody:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keeps track of empty lines around module bodies.
|
|
||||||
Style/EmptyLinesAroundModuleBody:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid the use of END blocks.
|
# Avoid the use of END blocks.
|
||||||
Style/EndBlock:
|
Style/EndBlock:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Use Unix-style line endings.
|
|
||||||
Style/EndOfLine:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Favor the use of Fixnum#even? && Fixnum#odd?
|
# Favor the use of Fixnum#even? && Fixnum#odd?
|
||||||
Style/EvenOdd:
|
Style/EvenOdd:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -223,11 +367,6 @@ Style/EvenOdd:
|
||||||
Style/FileName:
|
Style/FileName:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Checks for a line break before the first parameter in a multi-line method
|
|
||||||
# parameter definition.
|
|
||||||
Style/FirstMethodParameterLineBreak:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for flip flops.
|
# Checks for flip flops.
|
||||||
Style/FlipFlop:
|
Style/FlipFlop:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -236,6 +375,10 @@ Style/FlipFlop:
|
||||||
Style/For:
|
Style/For:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
# Use a consistent style for format string tokens.
|
||||||
|
Style/FormatStringToken:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Checks if there is a magic comment to enforce string literals
|
# Checks if there is a magic comment to enforce string literals
|
||||||
Style/FrozenStringLiteralComment:
|
Style/FrozenStringLiteralComment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -261,31 +404,19 @@ Style/IdenticalConditionalBranches:
|
||||||
Style/IfWithSemicolon:
|
Style/IfWithSemicolon:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Checks the indentation of the first line of the right-hand-side of a
|
|
||||||
# multi-line assignment.
|
|
||||||
Style/IndentAssignment:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keep indentation straight.
|
|
||||||
Style/IndentationConsistency:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use 2 spaces for indentation.
|
|
||||||
Style/IndentationWidth:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use Kernel#loop for infinite loops.
|
# Use Kernel#loop for infinite loops.
|
||||||
Style/InfiniteLoop:
|
Style/InfiniteLoop:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
# Use the inverse method instead of `!.method`
|
||||||
|
# if an inverse method is defined.
|
||||||
|
Style/InverseMethods:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Use lambda.call(...) instead of lambda.(...).
|
# Use lambda.call(...) instead of lambda.(...).
|
||||||
Style/LambdaCall:
|
Style/LambdaCall:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Comments should start with a space.
|
|
||||||
Style/LeadingCommentSpace:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks if the method definitions have or don't have parentheses.
|
# Checks if the method definitions have or don't have parentheses.
|
||||||
Style/MethodDefParentheses:
|
Style/MethodDefParentheses:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -298,55 +429,23 @@ Style/MethodName:
|
||||||
Style/ModuleFunction:
|
Style/ModuleFunction:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Checks that the closing brace in an array literal is either on the same line
|
|
||||||
# as the last array element, or a new line.
|
|
||||||
Style/MultilineArrayBraceLayout:
|
|
||||||
Enabled: true
|
|
||||||
EnforcedStyle: symmetrical
|
|
||||||
|
|
||||||
# Avoid multi-line chains of blocks.
|
# Avoid multi-line chains of blocks.
|
||||||
Style/MultilineBlockChain:
|
Style/MultilineBlockChain:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Ensures newlines after multiline block do statements.
|
|
||||||
Style/MultilineBlockLayout:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks that the closing brace in a hash literal is either on the same line as
|
|
||||||
# the last hash element, or a new line.
|
|
||||||
Style/MultilineHashBraceLayout:
|
|
||||||
Enabled: true
|
|
||||||
EnforcedStyle: symmetrical
|
|
||||||
|
|
||||||
# Do not use then for multi-line if/unless.
|
# Do not use then for multi-line if/unless.
|
||||||
Style/MultilineIfThen:
|
Style/MultilineIfThen:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Checks that the closing brace in a method call is either on the same line as
|
|
||||||
# the last method argument, or a new line.
|
|
||||||
Style/MultilineMethodCallBraceLayout:
|
|
||||||
Enabled: false
|
|
||||||
EnforcedStyle: symmetrical
|
|
||||||
|
|
||||||
# Checks indentation of method calls with the dot operator that span more than
|
|
||||||
# one line.
|
|
||||||
Style/MultilineMethodCallIndentation:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Checks that the closing brace in a method definition is symmetrical with
|
|
||||||
# respect to the opening brace and the method parameters.
|
|
||||||
Style/MultilineMethodDefinitionBraceLayout:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Checks indentation of binary operations that span more than one line.
|
|
||||||
Style/MultilineOperationIndentation:
|
|
||||||
Enabled: true
|
|
||||||
EnforcedStyle: indented
|
|
||||||
|
|
||||||
# Avoid multi-line `? :` (the ternary operator), use if/unless instead.
|
# Avoid multi-line `? :` (the ternary operator), use if/unless instead.
|
||||||
Style/MultilineTernaryOperator:
|
Style/MultilineTernaryOperator:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
# Avoid comparing a variable with multiple items in a conditional,
|
||||||
|
# use Array#include? instead.
|
||||||
|
Style/MultipleComparison:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# This cop checks whether some constant value isn't a
|
# This cop checks whether some constant value isn't a
|
||||||
# mutable literal (e.g. array or hash).
|
# mutable literal (e.g. array or hash).
|
||||||
Style/MutableConstant:
|
Style/MutableConstant:
|
||||||
|
@ -421,68 +520,6 @@ Style/SignalException:
|
||||||
EnforcedStyle: only_raise
|
EnforcedStyle: only_raise
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# Use spaces after colons.
|
|
||||||
Style/SpaceAfterColon:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use spaces after commas.
|
|
||||||
Style/SpaceAfterComma:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not put a space between a method name and the opening parenthesis in a
|
|
||||||
# method definition.
|
|
||||||
Style/SpaceAfterMethodName:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Tracks redundant space after the ! operator.
|
|
||||||
Style/SpaceAfterNot:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use spaces after semicolons.
|
|
||||||
Style/SpaceAfterSemicolon:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use space around equals in parameter default
|
|
||||||
Style/SpaceAroundEqualsInParameterDefault:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use a space around keywords if appropriate.
|
|
||||||
Style/SpaceAroundKeyword:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use a single space around operators.
|
|
||||||
Style/SpaceAroundOperators:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# No spaces before commas.
|
|
||||||
Style/SpaceBeforeComma:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for missing space between code and a comment on the same line.
|
|
||||||
Style/SpaceBeforeComment:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# No spaces before semicolons.
|
|
||||||
Style/SpaceBeforeSemicolon:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for spaces inside square brackets.
|
|
||||||
Style/SpaceInsideBrackets:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use spaces inside hash literal braces - or don't.
|
|
||||||
Style/SpaceInsideHashLiteralBraces:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# No spaces inside range literals.
|
|
||||||
Style/SpaceInsideRangeLiteral:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for padding/surrounding spaces inside string interpolation.
|
|
||||||
Style/SpaceInsideStringInterpolation:
|
|
||||||
EnforcedStyle: no_space
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Check for the usage of parentheses around stabby lambda arguments.
|
# Check for the usage of parentheses around stabby lambda arguments.
|
||||||
Style/StabbyLambdaParentheses:
|
Style/StabbyLambdaParentheses:
|
||||||
EnforcedStyle: require_parentheses
|
EnforcedStyle: require_parentheses
|
||||||
|
@ -498,13 +535,9 @@ Style/StringMethods:
|
||||||
intern: to_sym
|
intern: to_sym
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
# No hard tabs.
|
# Use %i or %I for arrays of symbols.
|
||||||
Style/Tab:
|
Style/SymbolArray:
|
||||||
Enabled: true
|
Enabled: false
|
||||||
|
|
||||||
# Checks trailing blank lines and final newline.
|
|
||||||
Style/TrailingBlankLines:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# This cop checks for trailing comma in array and hash literals.
|
# This cop checks for trailing comma in array and hash literals.
|
||||||
Style/TrailingCommaInLiteral:
|
Style/TrailingCommaInLiteral:
|
||||||
|
@ -553,6 +586,10 @@ Style/WhileUntilModifier:
|
||||||
Style/WordArray:
|
Style/WordArray:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
# Do not use literals as the first operand of a comparison.
|
||||||
|
Style/YodaCondition:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Use `proc` instead of `Proc.new`.
|
# Use `proc` instead of `Proc.new`.
|
||||||
Style/Proc:
|
Style/Proc:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -608,6 +645,11 @@ Metrics/PerceivedComplexity:
|
||||||
|
|
||||||
# Lint ########################################################################
|
# Lint ########################################################################
|
||||||
|
|
||||||
|
# Checks for ambiguous block association with method when param passed without
|
||||||
|
# parentheses.
|
||||||
|
Lint/AmbiguousBlockAssociation:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Checks for ambiguous operators in the first argument of a method invocation
|
# Checks for ambiguous operators in the first argument of a method invocation
|
||||||
# without parentheses.
|
# without parentheses.
|
||||||
Lint/AmbiguousOperator:
|
Lint/AmbiguousOperator:
|
||||||
|
@ -809,6 +851,10 @@ Lint/Void:
|
||||||
|
|
||||||
# Performance #################################################################
|
# Performance #################################################################
|
||||||
|
|
||||||
|
# Use `caller(n..n)` instead of `caller`.
|
||||||
|
Performance/Caller:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Use `casecmp` rather than `downcase ==`.
|
# Use `casecmp` rather than `downcase ==`.
|
||||||
Performance/Casecmp:
|
Performance/Casecmp:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
@ -883,6 +929,14 @@ Rails/ActionFilter:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
EnforcedStyle: action
|
EnforcedStyle: action
|
||||||
|
|
||||||
|
# Check that models subclass ApplicationRecord.
|
||||||
|
Rails/ApplicationRecord:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Enforce using `blank?` and `present?`.
|
||||||
|
Rails/Blank:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Checks the correct usage of date aware methods, such as `Date.today`,
|
# Checks the correct usage of date aware methods, such as `Date.today`,
|
||||||
# `Date.current`, etc.
|
# `Date.current`, etc.
|
||||||
Rails/Date:
|
Rails/Date:
|
||||||
|
@ -939,10 +993,18 @@ Rails/OutputSafety:
|
||||||
Rails/PluralizationGrammar:
|
Rails/PluralizationGrammar:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
# Enforce using `blank?` and `present?`.
|
||||||
|
Rails/Present:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Checks for `read_attribute(:attr)` and `write_attribute(:attr, val)`.
|
# Checks for `read_attribute(:attr)` and `write_attribute(:attr, val)`.
|
||||||
Rails/ReadWriteAttribute:
|
Rails/ReadWriteAttribute:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
# Do not assign relative date to constants.
|
||||||
|
Rails/RelativeDateConstant:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Checks the arguments of ActiveRecord scopes.
|
# Checks the arguments of ActiveRecord scopes.
|
||||||
Rails/ScopeArgs:
|
Rails/ScopeArgs:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
|
@ -1,26 +1,89 @@
|
||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config --exclude-limit 0`
|
# `rubocop --auto-gen-config --exclude-limit 0`
|
||||||
# on 2017-04-07 20:17:35 -0400 using RuboCop version 0.47.1.
|
# on 2017-07-10 01:48:30 +0900 using RuboCop version 0.49.1.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
# versions of RuboCop, may require this file to be generated again.
|
# versions of RuboCop, may require this file to be generated again.
|
||||||
|
|
||||||
# Offense count: 233
|
# Offense count: 181
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
|
||||||
|
Layout/ExtraSpacing:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 119
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||||
|
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
|
||||||
|
Layout/IndentArray:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 208
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
||||||
|
# SupportedStyles: special_inside_parentheses, consistent, align_braces
|
||||||
|
Layout/IndentHash:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 174
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
|
# SupportedStyles: space, no_space
|
||||||
|
Layout/SpaceBeforeBlockBraces:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 8
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: AllowForAlignment.
|
||||||
|
Layout/SpaceBeforeFirstArg:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 64
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
|
# SupportedStyles: require_no_space, require_space
|
||||||
|
Layout/SpaceInLambdaLiteral:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 256
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters.
|
||||||
|
# SupportedStyles: space, no_space
|
||||||
|
# SupportedStylesForEmptyBraces: space, no_space
|
||||||
|
Layout/SpaceInsideBlockBraces:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 135
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
Layout/SpaceInsideParens:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 14
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
Layout/SpaceInsidePercentLiteralDelimiters:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 89
|
||||||
|
# Cop supports --auto-correct.
|
||||||
|
Layout/TrailingWhitespace:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Offense count: 272
|
||||||
RSpec/EmptyLineAfterFinalLet:
|
RSpec/EmptyLineAfterFinalLet:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 167
|
# Offense count: 181
|
||||||
RSpec/EmptyLineAfterSubject:
|
RSpec/EmptyLineAfterSubject:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 72
|
# Offense count: 78
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: implicit, each, example
|
# SupportedStyles: implicit, each, example
|
||||||
RSpec/HookArgument:
|
RSpec/HookArgument:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 11
|
# Offense count: 9
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: it_behaves_like, it_should_behave_like
|
# SupportedStyles: it_behaves_like, it_should_behave_like
|
||||||
RSpec/ItBehavesLike:
|
RSpec/ItBehavesLike:
|
||||||
|
@ -30,19 +93,19 @@ RSpec/ItBehavesLike:
|
||||||
RSpec/IteratedExpectation:
|
RSpec/IteratedExpectation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 3
|
# Offense count: 2
|
||||||
RSpec/OverwritingSetup:
|
RSpec/OverwritingSetup:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 34
|
# Offense count: 36
|
||||||
RSpec/RepeatedExample:
|
RSpec/RepeatedExample:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 43
|
# Offense count: 86
|
||||||
RSpec/ScatteredLet:
|
RSpec/ScatteredLet:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 32
|
# Offense count: 20
|
||||||
RSpec/ScatteredSetup:
|
RSpec/ScatteredSetup:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
@ -50,7 +113,7 @@ RSpec/ScatteredSetup:
|
||||||
RSpec/SharedContext:
|
RSpec/SharedContext:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 150
|
# Offense count: 115
|
||||||
Rails/FilePath:
|
Rails/FilePath:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
@ -60,90 +123,71 @@ Rails/FilePath:
|
||||||
Rails/ReversibleMigration:
|
Rails/ReversibleMigration:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 302
|
# Offense count: 336
|
||||||
# Configuration parameters: Blacklist.
|
# Configuration parameters: Blacklist.
|
||||||
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
|
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
|
||||||
Rails/SkipsModelValidations:
|
Rails/SkipsModelValidations:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 7
|
# Offense count: 11
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Security/YAMLLoad:
|
Security/YAMLLoad:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 59
|
# Offense count: 58
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: percent_q, bare_percent
|
# SupportedStyles: percent_q, bare_percent
|
||||||
Style/BarePercentLiterals:
|
Style/BarePercentLiterals:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 5
|
# Offense count: 6
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/EachWithObject:
|
Style/EachWithObject:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 28
|
# Offense count: 31
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: empty, nil, both
|
# SupportedStyles: empty, nil, both
|
||||||
Style/EmptyElse:
|
Style/EmptyElse:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 4
|
# Offense count: 9
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/EmptyLiteral:
|
Style/EmptyLiteral:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 59
|
# Offense count: 78
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: compact, expanded
|
# SupportedStyles: compact, expanded
|
||||||
Style/EmptyMethod:
|
Style/EmptyMethod:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 214
|
# Offense count: 23
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
|
|
||||||
Style/ExtraSpacing:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 9
|
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: format, sprintf, percent
|
# SupportedStyles: format, sprintf, percent
|
||||||
Style/FormatString:
|
Style/FormatString:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 285
|
# Offense count: 301
|
||||||
# Configuration parameters: MinBodyLength.
|
# Configuration parameters: MinBodyLength.
|
||||||
Style/GuardClause:
|
Style/GuardClause:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 16
|
# Offense count: 18
|
||||||
Style/IfInsideElse:
|
Style/IfInsideElse:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 186
|
# Offense count: 182
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: MaxLineLength.
|
# Configuration parameters: MaxLineLength.
|
||||||
Style/IfUnlessModifier:
|
Style/IfUnlessModifier:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 99
|
# 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: 160
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
|
||||||
# SupportedStyles: special_inside_parentheses, consistent, align_braces
|
|
||||||
Style/IndentHash:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 50
|
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: line_count_dependent, lambda, literal
|
# SupportedStyles: line_count_dependent, lambda, literal
|
||||||
|
@ -155,63 +199,63 @@ Style/Lambda:
|
||||||
Style/LineEndConcatenation:
|
Style/LineEndConcatenation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 34
|
# Offense count: 40
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/MethodCallWithoutArgsParentheses:
|
Style/MethodCallWithoutArgsParentheses:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 10
|
# Offense count: 13
|
||||||
Style/MethodMissing:
|
Style/MethodMissing:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 3
|
# Offense count: 6
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/MultilineIfModifier:
|
Style/MultilineIfModifier:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 24
|
# Offense count: 26
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/NestedParenthesizedCalls:
|
Style/NestedParenthesizedCalls:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 18
|
# Offense count: 20
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
||||||
# SupportedStyles: skip_modifier_ifs, always
|
# SupportedStyles: skip_modifier_ifs, always
|
||||||
Style/Next:
|
Style/Next:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 37
|
# Offense count: 45
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles.
|
# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles.
|
||||||
# SupportedOctalStyles: zero_with_o, zero_only
|
# SupportedOctalStyles: zero_with_o, zero_only
|
||||||
Style/NumericLiteralPrefix:
|
Style/NumericLiteralPrefix:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 88
|
# Offense count: 98
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: predicate, comparison
|
# SupportedStyles: predicate, comparison
|
||||||
Style/NumericPredicate:
|
Style/NumericPredicate:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 36
|
# Offense count: 42
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/ParallelAssignment:
|
Style/ParallelAssignment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 570
|
# Offense count: 800
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: PreferredDelimiters.
|
# Configuration parameters: PreferredDelimiters.
|
||||||
Style/PercentLiteralDelimiters:
|
Style/PercentLiteralDelimiters:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 14
|
# Offense count: 15
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/PerlBackrefs:
|
Style/PerlBackrefs:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 83
|
# Offense count: 105
|
||||||
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
|
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
|
||||||
# NamePrefix: is_, has_, have_
|
# NamePrefix: is_, has_, have_
|
||||||
# NamePrefixBlacklist: is_, has_, have_
|
# NamePrefixBlacklist: is_, has_, have_
|
||||||
|
@ -219,47 +263,47 @@ Style/PerlBackrefs:
|
||||||
Style/PredicateName:
|
Style/PredicateName:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 65
|
# Offense count: 58
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: compact, exploded
|
# SupportedStyles: compact, exploded
|
||||||
Style/RaiseArgs:
|
Style/RaiseArgs:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 5
|
# Offense count: 6
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/RedundantBegin:
|
Style/RedundantBegin:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 32
|
# Offense count: 37
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/RedundantFreeze:
|
Style/RedundantFreeze:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 15
|
# Offense count: 14
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AllowMultipleReturnValues.
|
# Configuration parameters: AllowMultipleReturnValues.
|
||||||
Style/RedundantReturn:
|
Style/RedundantReturn:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 382
|
# Offense count: 406
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/RedundantSelf:
|
Style/RedundantSelf:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 111
|
# Offense count: 115
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
||||||
# SupportedStyles: slashes, percent_r, mixed
|
# SupportedStyles: slashes, percent_r, mixed
|
||||||
Style/RegexpLiteral:
|
Style/RegexpLiteral:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 24
|
# Offense count: 29
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/RescueModifier:
|
Style/RescueModifier:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 7
|
# Offense count: 8
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/SelfAssignment:
|
Style/SelfAssignment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -270,101 +314,58 @@ Style/SelfAssignment:
|
||||||
Style/SingleLineMethods:
|
Style/SingleLineMethods:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 168
|
# Offense count: 64
|
||||||
# Cop supports --auto-correct.
|
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
||||||
# SupportedStyles: space, no_space
|
|
||||||
Style/SpaceBeforeBlockBraces:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 8
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
# Configuration parameters: AllowForAlignment.
|
|
||||||
Style/SpaceBeforeFirstArg:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 46
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
|
||||||
# SupportedStyles: require_no_space, require_space
|
|
||||||
Style/SpaceInLambdaLiteral:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 229
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters.
|
|
||||||
# SupportedStyles: space, no_space
|
|
||||||
# SupportedStylesForEmptyBraces: space, no_space
|
|
||||||
Style/SpaceInsideBlockBraces:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 116
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/SpaceInsideParens:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 12
|
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/SpaceInsidePercentLiteralDelimiters:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 57
|
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: SupportedStyles.
|
# Configuration parameters: SupportedStyles.
|
||||||
# SupportedStyles: use_perl_names, use_english_names
|
# SupportedStyles: use_perl_names, use_english_names
|
||||||
Style/SpecialGlobalVars:
|
Style/SpecialGlobalVars:
|
||||||
EnforcedStyle: use_perl_names
|
EnforcedStyle: use_perl_names
|
||||||
|
|
||||||
# Offense count: 42
|
# Offense count: 44
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||||
# SupportedStyles: single_quotes, double_quotes
|
# SupportedStyles: single_quotes, double_quotes
|
||||||
Style/StringLiteralsInInterpolation:
|
Style/StringLiteralsInInterpolation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 64
|
# Offense count: 84
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: IgnoredMethods.
|
# Configuration parameters: IgnoredMethods.
|
||||||
# IgnoredMethods: respond_to, define_method
|
# IgnoredMethods: respond_to, define_method
|
||||||
Style/SymbolProc:
|
Style/SymbolProc:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 6
|
# Offense count: 8
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment.
|
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment.
|
||||||
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
||||||
Style/TernaryParentheses:
|
Style/TernaryParentheses:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 18
|
# Offense count: 17
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: AllowNamedUnderscoreVariables.
|
# Configuration parameters: AllowNamedUnderscoreVariables.
|
||||||
Style/TrailingUnderscoreVariable:
|
Style/TrailingUnderscoreVariable:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 78
|
# Offense count: 4
|
||||||
# Cop supports --auto-correct.
|
|
||||||
Style/TrailingWhitespace:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Offense count: 3
|
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
|
# 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
|
# 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:
|
Style/TrivialAccessors:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 6
|
# Offense count: 5
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/UnlessElse:
|
Style/UnlessElse:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 24
|
# Offense count: 28
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/UnneededInterpolation:
|
Style/UnneededInterpolation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 8
|
# Offense count: 11
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/ZeroLengthPredicate:
|
Style/ZeroLengthPredicate:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -2,6 +2,16 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
## 9.4.3 (2017-07-31)
|
||||||
|
|
||||||
|
- Fix Prometheus client PID reuse bug. !13130
|
||||||
|
- Improve deploy environment chatops slash command. !13150
|
||||||
|
- Fix asynchronous javascript paths when GitLab is installed under a relative URL. !13165
|
||||||
|
- Fix LDAP authentication to Git repository or container registry.
|
||||||
|
- Fixed new navigation breadcrumb title on help pages.
|
||||||
|
- Ensure filesystem metrics test files are deleted.
|
||||||
|
- Properly affixes nav bar in job view in microsoft edge.
|
||||||
|
|
||||||
## 9.4.2 (2017-07-28)
|
## 9.4.2 (2017-07-28)
|
||||||
|
|
||||||
- Fix job merge request link to a forked source project. !12965
|
- Fix job merge request link to a forked source project. !12965
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.25.0
|
0.26.0
|
||||||
|
|
4
Gemfile
4
Gemfile
|
@ -339,8 +339,8 @@ group :development, :test do
|
||||||
gem 'spring-commands-rspec', '~> 1.0.4'
|
gem 'spring-commands-rspec', '~> 1.0.4'
|
||||||
gem 'spring-commands-spinach', '~> 1.1.0'
|
gem 'spring-commands-spinach', '~> 1.1.0'
|
||||||
|
|
||||||
gem 'rubocop', '~> 0.47.1', require: false
|
gem 'rubocop', '~> 0.49.1', require: false
|
||||||
gem 'rubocop-rspec', '~> 1.15.0', require: false
|
gem 'rubocop-rspec', '~> 1.15.1', require: false
|
||||||
gem 'scss_lint', '~> 0.54.0', require: false
|
gem 'scss_lint', '~> 0.54.0', require: false
|
||||||
gem 'haml_lint', '~> 0.21.0', require: false
|
gem 'haml_lint', '~> 0.21.0', require: false
|
||||||
gem 'simplecov', '~> 0.14.0', require: false
|
gem 'simplecov', '~> 0.14.0', require: false
|
||||||
|
|
14
Gemfile.lock
14
Gemfile.lock
|
@ -323,7 +323,7 @@ GEM
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
retriable (~> 1.4)
|
retriable (~> 1.4)
|
||||||
signet (~> 0.6)
|
signet (~> 0.6)
|
||||||
google-protobuf (3.2.0.2)
|
google-protobuf (3.3.0)
|
||||||
googleauth (0.5.1)
|
googleauth (0.5.1)
|
||||||
faraday (~> 0.9)
|
faraday (~> 0.9)
|
||||||
jwt (~> 1.4)
|
jwt (~> 1.4)
|
||||||
|
@ -545,6 +545,7 @@ GEM
|
||||||
rubypants (~> 0.2)
|
rubypants (~> 0.2)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
os (0.9.6)
|
os (0.9.6)
|
||||||
|
parallel (1.11.2)
|
||||||
paranoia (2.3.1)
|
paranoia (2.3.1)
|
||||||
activerecord (>= 4.0, < 5.2)
|
activerecord (>= 4.0, < 5.2)
|
||||||
parser (2.4.0.0)
|
parser (2.4.0.0)
|
||||||
|
@ -730,13 +731,14 @@ GEM
|
||||||
pg
|
pg
|
||||||
rails
|
rails
|
||||||
sqlite3
|
sqlite3
|
||||||
rubocop (0.47.1)
|
rubocop (0.49.1)
|
||||||
|
parallel (~> 1.10)
|
||||||
parser (>= 2.3.3.1, < 3.0)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||||
rubocop-rspec (1.15.0)
|
rubocop-rspec (1.15.1)
|
||||||
rubocop (>= 0.42.0)
|
rubocop (>= 0.42.0)
|
||||||
ruby-fogbugz (0.2.1)
|
ruby-fogbugz (0.2.1)
|
||||||
crack (~> 0.4)
|
crack (~> 0.4)
|
||||||
|
@ -868,7 +870,7 @@ GEM
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.2)
|
unf_ext (0.0.7.2)
|
||||||
unicode-display_width (1.1.3)
|
unicode-display_width (1.3.0)
|
||||||
unicorn (5.1.0)
|
unicorn (5.1.0)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
|
@ -1078,8 +1080,8 @@ DEPENDENCIES
|
||||||
rspec-retry (~> 0.4.5)
|
rspec-retry (~> 0.4.5)
|
||||||
rspec-set (~> 0.1.3)
|
rspec-set (~> 0.1.3)
|
||||||
rspec_profiling (~> 0.0.5)
|
rspec_profiling (~> 0.0.5)
|
||||||
rubocop (~> 0.47.1)
|
rubocop (~> 0.49.1)
|
||||||
rubocop-rspec (~> 1.15.0)
|
rubocop-rspec (~> 1.15.1)
|
||||||
ruby-fogbugz (~> 0.2.1)
|
ruby-fogbugz (~> 0.2.1)
|
||||||
ruby-prof (~> 0.16.2)
|
ruby-prof (~> 0.16.2)
|
||||||
ruby_parser (~> 3.8)
|
ruby_parser (~> 3.8)
|
||||||
|
|
20
PROCESS.md
20
PROCESS.md
|
@ -128,7 +128,7 @@ information, see
|
||||||
|
|
||||||
### After the 7th
|
### After the 7th
|
||||||
|
|
||||||
Once the stable branch is frozen, only fixes for regressions (bugs introduced in that same release)
|
Once the stable branch is frozen, only fixes for [regressions](#regressions)
|
||||||
and security issues will be cherry-picked into the stable branch.
|
and security issues will be cherry-picked into the stable branch.
|
||||||
Any merge requests cherry-picked into the stable branch for a previous release will also be picked into the latest stable branch.
|
Any merge requests cherry-picked into the stable branch for a previous release will also be picked into the latest stable branch.
|
||||||
These fixes will be shipped in the next RC for that release if it is before the 22nd.
|
These fixes will be shipped in the next RC for that release if it is before the 22nd.
|
||||||
|
@ -158,6 +158,24 @@ release should have the correct milestone assigned _and_ have the label
|
||||||
Merge requests without a milestone and this label will
|
Merge requests without a milestone and this label will
|
||||||
not be merged into any stable branches.
|
not be merged into any stable branches.
|
||||||
|
|
||||||
|
### Regressions
|
||||||
|
|
||||||
|
A regression for a particular monthly release is a bug that exists in that
|
||||||
|
release, but wasn't present in the release before. This includes bugs in
|
||||||
|
features that were only added in that monthly release. Every regression **must**
|
||||||
|
have the milestone of the release it was introduced in - if a regression doesn't
|
||||||
|
have a milestone, it might be 'just' a bug!
|
||||||
|
|
||||||
|
For instance, if 10.5.0 adds a feature, and that feature doesn't work correctly,
|
||||||
|
then this is a regression in 10.5. If 10.5.1 then fixes that, but 10.5.3 somehow
|
||||||
|
reintroduces the bug, then this bug is still a regression in 10.5.
|
||||||
|
|
||||||
|
Because GitLab.com runs release candidates of new releases, a regression can be
|
||||||
|
reported in a release before its 'official' release date on the 22nd of the
|
||||||
|
month. When we say 'the most recent monthly release', this can refer to either
|
||||||
|
the version currently running on GitLab.com, or the most recent version
|
||||||
|
available in the package repositories.
|
||||||
|
|
||||||
## Release retrospective and kickoff
|
## Release retrospective and kickoff
|
||||||
|
|
||||||
### Retrospective
|
### Retrospective
|
||||||
|
|
|
@ -8,6 +8,7 @@ import BlobFileDropzone from '../blob/blob_file_dropzone';
|
||||||
$(() => {
|
$(() => {
|
||||||
const editBlobForm = $('.js-edit-blob-form');
|
const editBlobForm = $('.js-edit-blob-form');
|
||||||
const uploadBlobForm = $('.js-upload-blob-form');
|
const uploadBlobForm = $('.js-upload-blob-form');
|
||||||
|
const deleteBlobForm = $('.js-delete-blob-form');
|
||||||
|
|
||||||
if (editBlobForm.length) {
|
if (editBlobForm.length) {
|
||||||
const urlRoot = editBlobForm.data('relative-url-root');
|
const urlRoot = editBlobForm.data('relative-url-root');
|
||||||
|
@ -30,4 +31,8 @@ $(() => {
|
||||||
'.btn-upload-file',
|
'.btn-upload-file',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (deleteBlobForm.length) {
|
||||||
|
new NewCommitForm(deleteBlobForm);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,7 +64,7 @@ window.Build = (function () {
|
||||||
$(window)
|
$(window)
|
||||||
.off('scroll')
|
.off('scroll')
|
||||||
.on('scroll', () => {
|
.on('scroll', () => {
|
||||||
const contentHeight = this.$buildTraceOutput.prop('scrollHeight');
|
const contentHeight = this.$buildTraceOutput.height();
|
||||||
if (contentHeight > this.windowSize) {
|
if (contentHeight > this.windowSize) {
|
||||||
// means the user did not scroll, the content was updated.
|
// means the user did not scroll, the content was updated.
|
||||||
this.windowSize = contentHeight;
|
this.windowSize = contentHeight;
|
||||||
|
@ -105,16 +105,17 @@ window.Build = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Build.prototype.canScroll = function () {
|
Build.prototype.canScroll = function () {
|
||||||
return document.body.scrollHeight > window.innerHeight;
|
return $(document).height() > $(window).height();
|
||||||
};
|
};
|
||||||
|
|
||||||
Build.prototype.toggleScroll = function () {
|
Build.prototype.toggleScroll = function () {
|
||||||
const currentPosition = document.body.scrollTop;
|
const currentPosition = $(document).scrollTop();
|
||||||
const windowHeight = window.innerHeight;
|
const scrollHeight = $(document).height();
|
||||||
|
|
||||||
|
const windowHeight = $(window).height();
|
||||||
if (this.canScroll()) {
|
if (this.canScroll()) {
|
||||||
if (currentPosition > 0 &&
|
if (currentPosition > 0 &&
|
||||||
(document.body.scrollHeight - currentPosition !== windowHeight)) {
|
(scrollHeight - currentPosition !== windowHeight)) {
|
||||||
// User is in the middle of the log
|
// User is in the middle of the log
|
||||||
|
|
||||||
this.toggleDisableButton(this.$scrollTopBtn, false);
|
this.toggleDisableButton(this.$scrollTopBtn, false);
|
||||||
|
@ -124,7 +125,7 @@ window.Build = (function () {
|
||||||
|
|
||||||
this.toggleDisableButton(this.$scrollTopBtn, true);
|
this.toggleDisableButton(this.$scrollTopBtn, true);
|
||||||
this.toggleDisableButton(this.$scrollBottomBtn, false);
|
this.toggleDisableButton(this.$scrollBottomBtn, false);
|
||||||
} else if (document.body.scrollHeight - currentPosition === windowHeight) {
|
} else if (scrollHeight - currentPosition === windowHeight) {
|
||||||
// User is at the bottom of the build log.
|
// User is at the bottom of the build log.
|
||||||
|
|
||||||
this.toggleDisableButton(this.$scrollTopBtn, false);
|
this.toggleDisableButton(this.$scrollTopBtn, false);
|
||||||
|
@ -137,7 +138,7 @@ window.Build = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Build.prototype.scrollDown = function () {
|
Build.prototype.scrollDown = function () {
|
||||||
document.body.scrollTop = document.body.scrollHeight;
|
$(document).scrollTop($(document).height());
|
||||||
};
|
};
|
||||||
|
|
||||||
Build.prototype.scrollToBottom = function () {
|
Build.prototype.scrollToBottom = function () {
|
||||||
|
@ -147,7 +148,7 @@ window.Build = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Build.prototype.scrollToTop = function () {
|
Build.prototype.scrollToTop = function () {
|
||||||
document.body.scrollTop = 0;
|
$(document).scrollTop(0);
|
||||||
this.hasBeenScrolled = true;
|
this.hasBeenScrolled = true;
|
||||||
this.toggleScroll();
|
this.toggleScroll();
|
||||||
};
|
};
|
||||||
|
@ -178,7 +179,7 @@ window.Build = (function () {
|
||||||
this.state = log.state;
|
this.state = log.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.windowSize = this.$buildTraceOutput.prop('scrollHeight');
|
this.windowSize = this.$buildTraceOutput.height();
|
||||||
|
|
||||||
if (log.append) {
|
if (log.append) {
|
||||||
this.$buildTraceOutput.append(log.html);
|
this.$buildTraceOutput.append(log.html);
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
/* global LabelsSelect */
|
/* global LabelsSelect */
|
||||||
/* global MilestoneSelect */
|
/* global MilestoneSelect */
|
||||||
/* global Commit */
|
/* global Commit */
|
||||||
|
/* global CommitsList */
|
||||||
|
/* global NewBranchForm */
|
||||||
/* global NotificationsForm */
|
/* global NotificationsForm */
|
||||||
/* global NotificationsDropdown */
|
/* global NotificationsDropdown */
|
||||||
/* global GroupAvatar */
|
/* global GroupAvatar */
|
||||||
|
@ -18,15 +20,20 @@
|
||||||
/* global Search */
|
/* global Search */
|
||||||
/* global Admin */
|
/* global Admin */
|
||||||
/* global NamespaceSelects */
|
/* global NamespaceSelects */
|
||||||
|
/* global NewCommitForm */
|
||||||
|
/* global NewBranchForm */
|
||||||
/* global Project */
|
/* global Project */
|
||||||
/* global ProjectAvatar */
|
/* global ProjectAvatar */
|
||||||
/* global MergeRequest */
|
/* global MergeRequest */
|
||||||
/* global Compare */
|
/* global Compare */
|
||||||
/* global CompareAutocomplete */
|
/* global CompareAutocomplete */
|
||||||
|
/* global ProjectFindFile */
|
||||||
/* global ProjectNew */
|
/* global ProjectNew */
|
||||||
/* global ProjectShow */
|
/* global ProjectShow */
|
||||||
|
/* global ProjectImport */
|
||||||
/* global Labels */
|
/* global Labels */
|
||||||
/* global Shortcuts */
|
/* global Shortcuts */
|
||||||
|
/* global ShortcutsFindFile */
|
||||||
/* global Sidebar */
|
/* global Sidebar */
|
||||||
/* global ShortcutsWiki */
|
/* global ShortcutsWiki */
|
||||||
|
|
||||||
|
@ -194,7 +201,6 @@ import GpgBadges from './gpg_badges';
|
||||||
break;
|
break;
|
||||||
case 'explore:groups:index':
|
case 'explore:groups:index':
|
||||||
new GroupsList();
|
new GroupsList();
|
||||||
|
|
||||||
const landingElement = document.querySelector('.js-explore-groups-landing');
|
const landingElement = document.querySelector('.js-explore-groups-landing');
|
||||||
if (!landingElement) break;
|
if (!landingElement) break;
|
||||||
const exploreGroupsLanding = new Landing(
|
const exploreGroupsLanding = new Landing(
|
||||||
|
@ -217,6 +223,10 @@ import GpgBadges from './gpg_badges';
|
||||||
case 'projects:compare:show':
|
case 'projects:compare:show':
|
||||||
new gl.Diff();
|
new gl.Diff();
|
||||||
break;
|
break;
|
||||||
|
case 'projects:branches:new':
|
||||||
|
case 'projects:branches:create':
|
||||||
|
new NewBranchForm($('.js-create-branch-form'), JSON.parse(document.getElementById('availableRefs').innerHTML));
|
||||||
|
break;
|
||||||
case 'projects:branches:index':
|
case 'projects:branches:index':
|
||||||
gl.AjaxLoadingSpinner.init();
|
gl.AjaxLoadingSpinner.init();
|
||||||
new DeleteModal();
|
new DeleteModal();
|
||||||
|
@ -258,7 +268,7 @@ import GpgBadges from './gpg_badges';
|
||||||
case 'projects:tags:new':
|
case 'projects:tags:new':
|
||||||
new ZenMode();
|
new ZenMode();
|
||||||
new gl.GLForm($('.tag-form'), true);
|
new gl.GLForm($('.tag-form'), true);
|
||||||
new RefSelectDropdown($('.js-branch-select'), window.gl.availableRefs);
|
new RefSelectDropdown($('.js-branch-select'));
|
||||||
break;
|
break;
|
||||||
case 'projects:snippets:show':
|
case 'projects:snippets:show':
|
||||||
initNotes();
|
initNotes();
|
||||||
|
@ -304,19 +314,24 @@ import GpgBadges from './gpg_badges';
|
||||||
container: '.js-commit-pipeline-graph',
|
container: '.js-commit-pipeline-graph',
|
||||||
}).bindEvents();
|
}).bindEvents();
|
||||||
initNotes();
|
initNotes();
|
||||||
|
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
|
||||||
break;
|
break;
|
||||||
case 'projects:commit:pipelines':
|
case 'projects:commit:pipelines':
|
||||||
new MiniPipelineGraph({
|
new MiniPipelineGraph({
|
||||||
container: '.js-commit-pipeline-graph',
|
container: '.js-commit-pipeline-graph',
|
||||||
}).bindEvents();
|
}).bindEvents();
|
||||||
break;
|
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
|
||||||
case 'projects:commits:show':
|
|
||||||
shortcut_handler = new ShortcutsNavigation();
|
|
||||||
GpgBadges.fetch();
|
|
||||||
break;
|
break;
|
||||||
case 'projects:activity':
|
case 'projects:activity':
|
||||||
|
new gl.Activities();
|
||||||
shortcut_handler = new ShortcutsNavigation();
|
shortcut_handler = new ShortcutsNavigation();
|
||||||
break;
|
break;
|
||||||
|
case 'projects:commits:show':
|
||||||
|
CommitsList.init(document.querySelector('.js-project-commits-show').dataset.commitsLimit);
|
||||||
|
new gl.Activities();
|
||||||
|
shortcut_handler = new ShortcutsNavigation();
|
||||||
|
GpgBadges.fetch();
|
||||||
|
break;
|
||||||
case 'projects:show':
|
case 'projects:show':
|
||||||
shortcut_handler = new ShortcutsNavigation();
|
shortcut_handler = new ShortcutsNavigation();
|
||||||
new NotificationsForm();
|
new NotificationsForm();
|
||||||
|
@ -330,6 +345,12 @@ import GpgBadges from './gpg_badges';
|
||||||
case 'projects:edit':
|
case 'projects:edit':
|
||||||
setupProjectEdit();
|
setupProjectEdit();
|
||||||
break;
|
break;
|
||||||
|
case 'projects:imports:show':
|
||||||
|
new ProjectImport();
|
||||||
|
break;
|
||||||
|
case 'projects:pipelines:new':
|
||||||
|
new NewBranchForm($('.js-new-pipeline-form'));
|
||||||
|
break;
|
||||||
case 'projects:pipelines:builds':
|
case 'projects:pipelines:builds':
|
||||||
case 'projects:pipelines:failures':
|
case 'projects:pipelines:failures':
|
||||||
case 'projects:pipelines:show':
|
case 'projects:pipelines:show':
|
||||||
|
@ -383,8 +404,19 @@ import GpgBadges from './gpg_badges';
|
||||||
shortcut_handler = new ShortcutsNavigation();
|
shortcut_handler = new ShortcutsNavigation();
|
||||||
new TreeView();
|
new TreeView();
|
||||||
new BlobViewer();
|
new BlobViewer();
|
||||||
|
new NewCommitForm($('.js-create-dir-form'));
|
||||||
|
$('#tree-slider').waitForImages(function() {
|
||||||
|
gl.utils.ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case 'projects:find_file:show':
|
case 'projects:find_file:show':
|
||||||
|
const findElement = document.querySelector('.js-file-finder');
|
||||||
|
const projectFindFile = new ProjectFindFile($(".file-finder-holder"), {
|
||||||
|
url: findElement.dataset.fileFindUrl,
|
||||||
|
treeUrl: findElement.dataset.findTreeUrl,
|
||||||
|
blobUrlTemplate: findElement.dataset.blobUrlTemplate,
|
||||||
|
});
|
||||||
|
new ShortcutsFindFile(projectFindFile);
|
||||||
shortcut_handler = true;
|
shortcut_handler = true;
|
||||||
break;
|
break;
|
||||||
case 'projects:blob:show':
|
case 'projects:blob:show':
|
||||||
|
@ -540,6 +572,7 @@ import GpgBadges from './gpg_badges';
|
||||||
shortcut_handler = new ShortcutsWiki();
|
shortcut_handler = new ShortcutsWiki();
|
||||||
new ZenMode();
|
new ZenMode();
|
||||||
new gl.GLForm($('.wiki-form'), true);
|
new gl.GLForm($('.wiki-form'), true);
|
||||||
|
new Sidebar();
|
||||||
break;
|
break;
|
||||||
case 'snippets':
|
case 'snippets':
|
||||||
shortcut_handler = new ShortcutsNavigation();
|
shortcut_handler = new ShortcutsNavigation();
|
||||||
|
|
|
@ -730,10 +730,10 @@ GitLabDropdown = (function() {
|
||||||
|
|
||||||
GitLabDropdown.prototype.focusTextInput = function(triggerFocus = false) {
|
GitLabDropdown.prototype.focusTextInput = function(triggerFocus = false) {
|
||||||
if (this.options.filterable) {
|
if (this.options.filterable) {
|
||||||
$(':focus').blur();
|
|
||||||
|
|
||||||
this.dropdown.one('transitionend', () => {
|
this.dropdown.one('transitionend', () => {
|
||||||
|
if (this.dropdown.is('.open')) {
|
||||||
this.filterInput.focus();
|
this.filterInput.focus();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (triggerFocus) {
|
if (triggerFocus) {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import Chart from 'vendor/Chart';
|
import Chart from 'vendor/Chart';
|
||||||
import ContributorsStatGraph from './stat_graph_contributors';
|
|
||||||
|
|
||||||
// export to global scope
|
// export to global scope
|
||||||
window.Chart = Chart;
|
window.Chart = Chart;
|
||||||
window.ContributorsStatGraph = ContributorsStatGraph;
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import Chart from 'vendor/Chart';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const projectChartData = JSON.parse(document.getElementById('projectChartData').innerHTML);
|
||||||
|
|
||||||
|
const responsiveChart = (selector, data) => {
|
||||||
|
const options = {
|
||||||
|
scaleOverlay: true,
|
||||||
|
responsive: true,
|
||||||
|
pointHitDetectionRadius: 2,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
};
|
||||||
|
// get selector by context
|
||||||
|
const ctx = selector.get(0).getContext('2d');
|
||||||
|
// pointing parent container to make chart.js inherit its width
|
||||||
|
const container = $(selector).parent();
|
||||||
|
const generateChart = () => {
|
||||||
|
selector.attr('width', $(container).width());
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
// Scale fonts if window width lower than 768px (iPad portrait)
|
||||||
|
options.scaleFontSize = 8;
|
||||||
|
}
|
||||||
|
return new Chart(ctx).Bar(data, options);
|
||||||
|
};
|
||||||
|
// enabling auto-resizing
|
||||||
|
$(window).resize(generateChart);
|
||||||
|
return generateChart();
|
||||||
|
};
|
||||||
|
|
||||||
|
const chartData = (keys, values) => {
|
||||||
|
const data = {
|
||||||
|
labels: keys,
|
||||||
|
datasets: [{
|
||||||
|
fillColor: 'rgba(220,220,220,0.5)',
|
||||||
|
strokeColor: 'rgba(220,220,220,1)',
|
||||||
|
barStrokeWidth: 1,
|
||||||
|
barValueSpacing: 1,
|
||||||
|
barDatasetSpacing: 1,
|
||||||
|
data: values,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const hourData = chartData(projectChartData.hour.keys, projectChartData.hour.values);
|
||||||
|
responsiveChart($('#hour-chart'), hourData);
|
||||||
|
|
||||||
|
const dayData = chartData(projectChartData.weekDays.keys, projectChartData.weekDays.values);
|
||||||
|
responsiveChart($('#weekday-chart'), dayData);
|
||||||
|
|
||||||
|
const monthData = chartData(projectChartData.month.keys, projectChartData.month.values);
|
||||||
|
responsiveChart($('#month-chart'), monthData);
|
||||||
|
|
||||||
|
const data = projectChartData.languages;
|
||||||
|
const ctx = $('#languages-chart').get(0).getContext('2d');
|
||||||
|
const options = {
|
||||||
|
scaleOverlay: true,
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
new Chart(ctx).Pie(data, options);
|
||||||
|
});
|
|
@ -0,0 +1,21 @@
|
||||||
|
import ContributorsStatGraph from './stat_graph_contributors';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: document.querySelector('.js-graphs-show').dataset.projectGraphPath,
|
||||||
|
dataType: 'json',
|
||||||
|
success(data) {
|
||||||
|
const graph = new ContributorsStatGraph();
|
||||||
|
graph.init(data);
|
||||||
|
|
||||||
|
$('#brush_change').change(() => {
|
||||||
|
graph.change_date_header();
|
||||||
|
graph.redraw_authors();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.stat-graph').fadeIn();
|
||||||
|
$('.loading-graph').hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,38 @@
|
||||||
|
import Chart from 'vendor/Chart';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const chartData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML);
|
||||||
|
const buildChart = (chartScope) => {
|
||||||
|
const data = {
|
||||||
|
labels: chartScope.labels,
|
||||||
|
datasets: [{
|
||||||
|
fillColor: '#7f8fa4',
|
||||||
|
strokeColor: '#7f8fa4',
|
||||||
|
pointColor: '#7f8fa4',
|
||||||
|
pointStrokeColor: '#EEE',
|
||||||
|
data: chartScope.totalValues,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fillColor: '#44aa22',
|
||||||
|
strokeColor: '#44aa22',
|
||||||
|
pointColor: '#44aa22',
|
||||||
|
pointStrokeColor: '#fff',
|
||||||
|
data: chartScope.successValues,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const ctx = $(`#${chartScope.scope}Chart`).get(0).getContext('2d');
|
||||||
|
const options = {
|
||||||
|
scaleOverlay: true,
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
};
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
// Scale fonts if window width lower than 768px (iPad portrait)
|
||||||
|
options.scaleFontSize = 8;
|
||||||
|
}
|
||||||
|
new Chart(ctx).Line(data, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
chartData.forEach(scope => buildChart(scope));
|
||||||
|
});
|
|
@ -0,0 +1,27 @@
|
||||||
|
import Chart from 'vendor/Chart';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const chartData = JSON.parse(document.getElementById('pipelinesTimesChartsData').innerHTML);
|
||||||
|
const data = {
|
||||||
|
labels: chartData.labels,
|
||||||
|
datasets: [{
|
||||||
|
fillColor: 'rgba(220,220,220,0.5)',
|
||||||
|
strokeColor: 'rgba(220,220,220,1)',
|
||||||
|
barStrokeWidth: 1,
|
||||||
|
barValueSpacing: 1,
|
||||||
|
barDatasetSpacing: 1,
|
||||||
|
data: chartData.values,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
const ctx = $('#build_timesChart').get(0).getContext('2d');
|
||||||
|
const options = {
|
||||||
|
scaleOverlay: true,
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
};
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
// Scale fonts if window width lower than 768px (iPad portrait)
|
||||||
|
options.scaleFontSize = 8;
|
||||||
|
}
|
||||||
|
new Chart(ctx).Bar(data, options);
|
||||||
|
});
|
|
@ -0,0 +1,85 @@
|
||||||
|
let hasUserDefinedProjectPath = false;
|
||||||
|
|
||||||
|
const deriveProjectPathFromUrl = ($projectImportUrl, $projectPath) => {
|
||||||
|
if ($projectImportUrl.attr('disabled') || hasUserDefinedProjectPath) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let importUrl = $projectImportUrl.val().trim();
|
||||||
|
if (importUrl.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
\/?: remove trailing slash
|
||||||
|
(\.git\/?)?: remove trailing .git (with optional trailing slash)
|
||||||
|
(\?.*)?: remove query string
|
||||||
|
(#.*)?: remove fragment identifier
|
||||||
|
*/
|
||||||
|
importUrl = importUrl.replace(/\/?(\.git\/?)?(\?.*)?(#.*)?$/, '');
|
||||||
|
|
||||||
|
// extract everything after the last slash
|
||||||
|
const pathMatch = /\/([^/]+)$/.exec(importUrl);
|
||||||
|
if (pathMatch) {
|
||||||
|
$projectPath.val(pathMatch[1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const bindEvents = () => {
|
||||||
|
const $newProjectForm = $('#new_project');
|
||||||
|
const importBtnTooltip = 'Please enter a valid project name.';
|
||||||
|
const $importBtnWrapper = $('.import_gitlab_project');
|
||||||
|
const $projectImportUrl = $('#project_import_url');
|
||||||
|
const $projectPath = $('#project_path');
|
||||||
|
|
||||||
|
if ($newProjectForm.length !== 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.how_to_import_link').on('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
$('.how_to_import_link').next('.modal').show();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.modal-header .close').on('click', () => {
|
||||||
|
$('.modal').hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn_import_gitlab_project').on('click', () => {
|
||||||
|
const importHref = $('a.btn_import_gitlab_project').attr('href');
|
||||||
|
$('.btn_import_gitlab_project').attr('href', `${importHref}?namespace_id=${$('#project_namespace_id').val()}&path=${$projectPath.val()}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn_import_gitlab_project').attr('disabled', !$projectPath.val().trim().length);
|
||||||
|
$importBtnWrapper.attr('title', importBtnTooltip);
|
||||||
|
|
||||||
|
$newProjectForm.on('submit', () => {
|
||||||
|
$projectPath.val($projectPath.val().trim());
|
||||||
|
});
|
||||||
|
|
||||||
|
$projectPath.on('keyup', () => {
|
||||||
|
hasUserDefinedProjectPath = $projectPath.val().trim().length > 0;
|
||||||
|
if (hasUserDefinedProjectPath) {
|
||||||
|
$('.btn_import_gitlab_project').attr('disabled', false);
|
||||||
|
$importBtnWrapper.attr('title', '');
|
||||||
|
$importBtnWrapper.removeClass('has-tooltip');
|
||||||
|
} else {
|
||||||
|
$('.btn_import_gitlab_project').attr('disabled', true);
|
||||||
|
$importBtnWrapper.addClass('has-tooltip');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$projectImportUrl.disable();
|
||||||
|
$projectImportUrl.keyup(() => deriveProjectPathFromUrl($projectImportUrl, $projectPath));
|
||||||
|
|
||||||
|
$('.import_git').on('click', () => {
|
||||||
|
$projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', bindEvents);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
bindEvents,
|
||||||
|
deriveProjectPathFromUrl,
|
||||||
|
};
|
|
@ -1,7 +1,8 @@
|
||||||
class RefSelectDropdown {
|
class RefSelectDropdown {
|
||||||
constructor($dropdownButton, availableRefs) {
|
constructor($dropdownButton, availableRefs) {
|
||||||
|
const availableRefsValue = availableRefs || JSON.parse(document.getElementById('availableRefs').innerHTML);
|
||||||
$dropdownButton.glDropdown({
|
$dropdownButton.glDropdown({
|
||||||
data: availableRefs,
|
data: availableRefsValue,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
filterByText: true,
|
filterByText: true,
|
||||||
remote: false,
|
remote: false,
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* global U2FRegister */
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const twoFactorNode = document.querySelector('.js-two-factor-auth');
|
||||||
|
const skippable = twoFactorNode.dataset.twoFactorSkippable === 'true';
|
||||||
|
if (skippable) {
|
||||||
|
const button = `<a class="btn btn-xs btn-warning pull-right" data-method="patch" href="${twoFactorNode.dataset.two_factor_skip_url}">Configure it later</a>`;
|
||||||
|
const flashAlert = document.querySelector('.flash-alert .container-fluid');
|
||||||
|
if (flashAlert) flashAlert.insertAdjacentHTML('beforeend', button);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u2fRegister = new U2FRegister($('#js-register-u2f'), gon.u2f);
|
||||||
|
u2fRegister.start();
|
||||||
|
});
|
|
@ -0,0 +1,22 @@
|
||||||
|
import Api from './api';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
$('#js-project-dropdown').glDropdown({
|
||||||
|
data: (term, callback) => {
|
||||||
|
Api.projects(term, {
|
||||||
|
order_by: 'last_activity_at',
|
||||||
|
}, (data) => {
|
||||||
|
callback(data);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
text: project => (project.name_with_namespace || project.name),
|
||||||
|
selectable: true,
|
||||||
|
fieldName: 'author_id',
|
||||||
|
filterable: true,
|
||||||
|
search: {
|
||||||
|
fields: ['name_with_namespace'],
|
||||||
|
},
|
||||||
|
id: data => data.id,
|
||||||
|
isSelected: data => (data.id === 2),
|
||||||
|
});
|
||||||
|
});
|
|
@ -88,6 +88,10 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -414,13 +414,16 @@
|
||||||
background-color: $dropdown-hover-color;
|
background-color: $dropdown-hover-color;
|
||||||
color: $white-light;
|
color: $white-light;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
outline: 0;
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
border-color: $white-light;
|
border-color: $white-light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-dropdown-item {
|
.droplab-dropdown .dropdown-menu .filter-dropdown-item {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -455,14 +458,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-user {
|
.dropdown-user {
|
||||||
display: -webkit-flex;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-user-details {
|
.dropdown-user-details {
|
||||||
display: -webkit-flex;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
-webkit-flex-direction: column;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
|
|
|
@ -313,6 +313,29 @@ header {
|
||||||
.impersonation i {
|
.impersonation i {
|
||||||
color: $red-500;
|
color: $red-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fallback to global style
|
||||||
|
.dropdown-menu,
|
||||||
|
.dropdown-menu-nav {
|
||||||
|
li {
|
||||||
|
padding: 0 1px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 8px 16px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: $gray-darker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.with-performance-bar header.navbar-gitlab {
|
||||||
|
top: $performance-bar-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-nav {
|
.navbar-nav {
|
||||||
|
|
|
@ -120,3 +120,7 @@ of the body element here, we negate cascading side effects but allow momentum sc
|
||||||
.page-with-sidebar {
|
.page-with-sidebar {
|
||||||
-webkit-overflow-scrolling: auto;
|
-webkit-overflow-scrolling: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .page-with-sidebar {
|
||||||
|
margin-top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
|
|
@ -347,6 +347,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .layout-nav {
|
||||||
|
margin-top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
|
||||||
.scrolling-tabs-container {
|
.scrolling-tabs-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -441,6 +445,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .page-with-layout-nav {
|
||||||
|
.right-sidebar {
|
||||||
|
top: ($header-height + 1) * 2 + $performance-bar-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.page-with-sub-nav {
|
||||||
|
.right-sidebar {
|
||||||
|
top: ($header-height + 1) * 3 + $performance-bar-height;
|
||||||
|
|
||||||
|
&.affix {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.nav-block {
|
.nav-block {
|
||||||
&.activities {
|
&.activities {
|
||||||
border-bottom: 1px solid $border-color;
|
border-bottom: 1px solid $border-color;
|
||||||
|
|
|
@ -89,6 +89,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .right-sidebar.affix {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin maintain-sidebar-dimensions {
|
@mixin maintain-sidebar-dimensions {
|
||||||
display: block;
|
display: block;
|
||||||
width: $gutter-width;
|
width: $gutter-width;
|
||||||
|
|
|
@ -204,6 +204,7 @@ $divergence-graph-separator-bg: #ccc;
|
||||||
$general-hover-transition-duration: 100ms;
|
$general-hover-transition-duration: 100ms;
|
||||||
$general-hover-transition-curve: linear;
|
$general-hover-transition-curve: linear;
|
||||||
$highlight-changes-color: rgb(235, 255, 232);
|
$highlight-changes-color: rgb(235, 255, 232);
|
||||||
|
$performance-bar-height: 35px;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -309,6 +309,25 @@ header.navbar-gitlab-new {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fallback to global style
|
||||||
|
.dropdown-menu {
|
||||||
|
li {
|
||||||
|
padding: 0 1px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 8px 16px;
|
||||||
|
|
||||||
|
&.is-focused,
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: $gray-darker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumbs-container {
|
.breadcrumbs-container {
|
||||||
|
@ -325,6 +344,7 @@ header.navbar-gitlab-new {
|
||||||
|
|
||||||
.breadcrumbs-links {
|
.breadcrumbs-links {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
color: $gl-text-color-quaternary;
|
color: $gl-text-color-quaternary;
|
||||||
|
|
||||||
|
@ -343,7 +363,7 @@ header.navbar-gitlab-new {
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
white-space: nowrap;
|
display: inline-block;
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
&:last-of-type:not(:first-child) {
|
&:last-of-type:not(:first-child) {
|
||||||
|
|
|
@ -118,7 +118,7 @@ $new-sidebar-width: 220px;
|
||||||
z-index: 400;
|
z-index: 400;
|
||||||
width: $new-sidebar-width;
|
width: $new-sidebar-width;
|
||||||
transition: left $sidebar-transition-duration;
|
transition: left $sidebar-transition-duration;
|
||||||
top: 50px;
|
top: $header-height;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@ -163,6 +163,10 @@ $new-sidebar-width: 220px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .nav-sidebar {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-sub-level-items {
|
.sidebar-sub-level-items {
|
||||||
display: none;
|
display: none;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
@ -260,7 +264,7 @@ $new-sidebar-width: 220px;
|
||||||
// Make issue boards full-height now that sub-nav is gone
|
// Make issue boards full-height now that sub-nav is gone
|
||||||
|
|
||||||
.boards-list {
|
.boards-list {
|
||||||
height: calc(100vh - 50px);
|
height: calc(100vh - #{$header-height});
|
||||||
|
|
||||||
@media (min-width: $screen-sm-min) {
|
@media (min-width: $screen-sm-min) {
|
||||||
height: 475px; // Needed for PhantomJS
|
height: 475px; // Needed for PhantomJS
|
||||||
|
@ -270,6 +274,10 @@ $new-sidebar-width: 220px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .boards-list {
|
||||||
|
height: calc(100vh - #{$header-height} - #{$performance-bar-height});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Change color of all horizontal tabs to match the new indigo color
|
// Change color of all horizontal tabs to match the new indigo color
|
||||||
.nav-links li.active a {
|
.nav-links li.active a {
|
||||||
|
|
|
@ -64,10 +64,10 @@
|
||||||
color: $gl-text-color;
|
color: $gl-text-color;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
position: -webkit-sticky;
|
position: -webkit-sticky;
|
||||||
top: 50px;
|
top: $header-height;
|
||||||
|
|
||||||
&.affix {
|
&.affix {
|
||||||
top: 50px;
|
top: $header-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// with sidebar
|
// with sidebar
|
||||||
|
@ -86,6 +86,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.truncated-info {
|
.truncated-info {
|
||||||
|
@ -171,6 +172,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .build-page {
|
||||||
|
.top-bar {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
|
||||||
|
&.affix {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.build-header {
|
.build-header {
|
||||||
.ci-header-container,
|
.ci-header-container,
|
||||||
.header-action-buttons {
|
.header-action-buttons {
|
||||||
|
@ -300,9 +311,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
right: $gl-padding;
|
margin-top: -$gl-padding;
|
||||||
left: $gl-padding;
|
|
||||||
width: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
|
|
|
@ -110,6 +110,10 @@
|
||||||
|
|
||||||
.js-ca-dropdown {
|
.js-ca-dropdown {
|
||||||
top: $gl-padding-top;
|
top: $gl-padding-top;
|
||||||
|
|
||||||
|
.dropdown-menu-align-right {
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-list {
|
.content-list {
|
||||||
|
@ -442,6 +446,24 @@
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fallback to global style
|
||||||
|
.dropdown-menu {
|
||||||
|
li {
|
||||||
|
padding: 0 1px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 8px 16px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: $gray-darker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cycle-analytics-overview {
|
.cycle-analytics-overview {
|
||||||
|
|
|
@ -445,6 +445,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .right-sidebar {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
|
||||||
|
.issuable-sidebar {
|
||||||
|
height: calc(100% - #{$header-height} - #{$performance-bar-height});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.detail-page-description {
|
.detail-page-description {
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
|
|
||||||
|
|
|
@ -759,6 +759,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-performance-bar .merge-request-tabs-holder {
|
||||||
|
top: $header-height + $performance-bar-height;
|
||||||
|
}
|
||||||
|
|
||||||
.merge-request-tabs {
|
.merge-request-tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
|
@ -202,6 +202,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: fallback to global style
|
||||||
|
.dropdown-menu:not(.dropdown-menu-selectable) {
|
||||||
|
li {
|
||||||
|
padding: 0 1px;
|
||||||
|
|
||||||
|
&.dropdown-header {
|
||||||
|
padding: 8px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 8px 16px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:active,
|
||||||
|
&:focus {
|
||||||
|
background-color: $gray-darker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.blob-commit-info {
|
.blob-commit-info {
|
||||||
|
|
|
@ -3,9 +3,16 @@
|
||||||
@import "peek/views/rblineprof";
|
@import "peek/views/rblineprof";
|
||||||
|
|
||||||
#peek {
|
#peek {
|
||||||
height: 35px;
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 2000;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
height: $performance-bar-height;
|
||||||
background: $black;
|
background: $black;
|
||||||
line-height: 35px;
|
line-height: $performance-bar-height;
|
||||||
color: $perf-bar-text;
|
color: $perf-bar-text;
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
|
@ -25,7 +32,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
width: 1000px;
|
width: 80%;
|
||||||
|
height: $performance-bar-height;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,23 +43,7 @@ class Projects::GraphsController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_languages
|
def get_languages
|
||||||
@languages = Linguist::Repository.new(@repository.rugged, @repository.rugged.head.target_id).languages
|
@languages = @project.repository.languages
|
||||||
total = @languages.map(&:last).sum
|
|
||||||
|
|
||||||
@languages = @languages.map do |language|
|
|
||||||
name, share = language
|
|
||||||
color = Linguist::Language[name].color || "##{Digest::SHA256.hexdigest(name)[0...6]}"
|
|
||||||
{
|
|
||||||
value: (share.to_f * 100 / total).round(2),
|
|
||||||
label: name,
|
|
||||||
color: color,
|
|
||||||
highlight: color
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
@languages.sort! do |x, y|
|
|
||||||
y[:value] <=> x[:value]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_graph
|
def fetch_graph
|
||||||
|
|
|
@ -264,7 +264,11 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def page_class
|
def page_class
|
||||||
"issue-boards-page" if current_controller?(:boards)
|
class_names = []
|
||||||
|
class_names << 'issue-boards-page' if current_controller?(:boards)
|
||||||
|
class_names << 'with-performance-bar' if performance_bar_enabled?
|
||||||
|
|
||||||
|
class_names
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns active css class when condition returns true
|
# Returns active css class when condition returns true
|
||||||
|
|
|
@ -48,8 +48,12 @@ module GitlabRoutingHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def milestone_path(entity, *args)
|
def milestone_path(entity, *args)
|
||||||
|
if entity.is_group_milestone?
|
||||||
|
group_milestone_path(entity.group, entity, *args)
|
||||||
|
elsif entity.is_project_milestone?
|
||||||
project_milestone_path(entity.project, entity, *args)
|
project_milestone_path(entity.project, entity, *args)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def issue_url(entity, *args)
|
def issue_url(entity, *args)
|
||||||
project_issue_url(entity.project, entity, *args)
|
project_issue_url(entity.project, entity, *args)
|
||||||
|
@ -63,6 +67,14 @@ module GitlabRoutingHelper
|
||||||
project_pipeline_url(pipeline.project, pipeline.id, *args)
|
project_pipeline_url(pipeline.project, pipeline.id, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def milestone_url(entity, *args)
|
||||||
|
if entity.is_group_milestone?
|
||||||
|
group_milestone_url(entity.group, entity, *args)
|
||||||
|
elsif entity.is_project_milestone?
|
||||||
|
project_milestone_url(entity.project, entity, *args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def pipeline_job_url(pipeline, build, *args)
|
def pipeline_job_url(pipeline, build, *args)
|
||||||
project_job_url(pipeline.project, build.id, *args)
|
project_job_url(pipeline.project, build.id, *args)
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,7 +40,7 @@ module MergeRequestsHelper
|
||||||
|
|
||||||
def merge_path_description(merge_request, separator)
|
def merge_path_description(merge_request, separator)
|
||||||
if merge_request.for_fork?
|
if merge_request.for_fork?
|
||||||
"Project:Branches: #{@merge_request.source_project_path}:#{@merge_request.source_branch} #{separator} #{@merge_request.target_project.path_with_namespace}:#{@merge_request.target_branch}"
|
"Project:Branches: #{@merge_request.source_project_path}:#{@merge_request.source_branch} #{separator} #{@merge_request.target_project.full_path}:#{@merge_request.target_branch}"
|
||||||
else
|
else
|
||||||
"Branches: #{@merge_request.source_branch} #{separator} #{@merge_request.target_branch}"
|
"Branches: #{@merge_request.source_branch} #{separator} #{@merge_request.target_branch}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,38 +1,49 @@
|
||||||
module NavHelper
|
module NavHelper
|
||||||
|
def page_with_sidebar_class
|
||||||
|
class_name = page_gutter_class
|
||||||
|
class_name << 'page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar
|
||||||
|
|
||||||
|
class_name
|
||||||
|
end
|
||||||
|
|
||||||
def page_gutter_class
|
def page_gutter_class
|
||||||
if current_path?('merge_requests#show') ||
|
if current_path?('merge_requests#show') ||
|
||||||
current_path?('projects/merge_requests/conflicts#show') ||
|
current_path?('projects/merge_requests/conflicts#show') ||
|
||||||
current_path?('issues#show') ||
|
current_path?('issues#show') ||
|
||||||
current_path?('milestones#show')
|
current_path?('milestones#show')
|
||||||
if cookies[:collapsed_gutter] == 'true'
|
if cookies[:collapsed_gutter] == 'true'
|
||||||
"page-gutter right-sidebar-collapsed"
|
%w[page-gutter right-sidebar-collapsed]
|
||||||
else
|
else
|
||||||
"page-gutter right-sidebar-expanded"
|
%w[page-gutter right-sidebar-expanded]
|
||||||
end
|
end
|
||||||
elsif current_path?('jobs#show')
|
elsif current_path?('jobs#show')
|
||||||
"page-gutter build-sidebar right-sidebar-expanded"
|
%w[page-gutter build-sidebar right-sidebar-expanded]
|
||||||
elsif current_path?('wikis#show') ||
|
elsif current_path?('wikis#show') ||
|
||||||
current_path?('wikis#edit') ||
|
current_path?('wikis#edit') ||
|
||||||
current_path?('wikis#update') ||
|
current_path?('wikis#update') ||
|
||||||
current_path?('wikis#history') ||
|
current_path?('wikis#history') ||
|
||||||
current_path?('wikis#git_access')
|
current_path?('wikis#git_access')
|
||||||
"page-gutter wiki-sidebar right-sidebar-expanded"
|
%w[page-gutter wiki-sidebar right-sidebar-expanded]
|
||||||
|
else
|
||||||
|
[]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def nav_header_class
|
def nav_header_class
|
||||||
class_name = ''
|
class_names = []
|
||||||
class_name << " with-horizontal-nav" if defined?(nav) && nav
|
class_names << 'with-horizontal-nav' if defined?(nav) && nav
|
||||||
|
|
||||||
class_name
|
class_names
|
||||||
end
|
end
|
||||||
|
|
||||||
def layout_nav_class
|
def layout_nav_class
|
||||||
class_name = ''
|
return [] if show_new_nav?
|
||||||
class_name << " page-with-layout-nav" if defined?(nav) && nav
|
|
||||||
class_name << " page-with-sub-nav" if content_for?(:sub_nav)
|
|
||||||
|
|
||||||
class_name
|
class_names = []
|
||||||
|
class_names << 'page-with-layout-nav' if defined?(nav) && nav
|
||||||
|
class_names << 'page-with-sub-nav' if content_for?(:sub_nav)
|
||||||
|
|
||||||
|
class_names
|
||||||
end
|
end
|
||||||
|
|
||||||
def nav_control_class
|
def nav_control_class
|
||||||
|
|
|
@ -398,7 +398,7 @@ module ProjectsHelper
|
||||||
if project
|
if project
|
||||||
import_path = "/Home/Stacks/import"
|
import_path = "/Home/Stacks/import"
|
||||||
|
|
||||||
repo = project.path_with_namespace
|
repo = project.full_path
|
||||||
branch ||= project.default_branch
|
branch ||= project.default_branch
|
||||||
sha ||= project.commit.short_id
|
sha ||= project.commit.short_id
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ module ProjectsHelper
|
||||||
|
|
||||||
def readme_cache_key
|
def readme_cache_key
|
||||||
sha = @project.commit.try(:sha) || 'nil'
|
sha = @project.commit.try(:sha) || 'nil'
|
||||||
[@project.path_with_namespace, sha, "readme"].join('-')
|
[@project.full_path, sha, "readme"].join('-')
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_ref
|
def current_ref
|
||||||
|
|
|
@ -34,6 +34,8 @@ module WebpackHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def webpack_public_path
|
def webpack_public_path
|
||||||
"#{webpack_public_host}/#{Rails.application.config.webpack.public_path}/"
|
relative_path = Rails.application.config.relative_url_root
|
||||||
|
webpack_path = Rails.application.config.webpack.public_path
|
||||||
|
File.join(webpack_public_host.to_s, relative_path.to_s, webpack_path.to_s, '')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -165,7 +165,7 @@ class Notify < BaseMailer
|
||||||
|
|
||||||
headers['X-GitLab-Project'] = @project.name
|
headers['X-GitLab-Project'] = @project.name
|
||||||
headers['X-GitLab-Project-Id'] = @project.id
|
headers['X-GitLab-Project-Id'] = @project.id
|
||||||
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
|
headers['X-GitLab-Project-Path'] = @project.full_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_unsubscription_headers_and_links
|
def add_unsubscription_headers_and_links
|
||||||
|
|
|
@ -317,7 +317,7 @@ module Ci
|
||||||
return @config_processor if defined?(@config_processor)
|
return @config_processor if defined?(@config_processor)
|
||||||
|
|
||||||
@config_processor ||= begin
|
@config_processor ||= begin
|
||||||
Ci::GitlabCiYamlProcessor.new(ci_yaml_file, project.path_with_namespace)
|
Ci::GitlabCiYamlProcessor.new(ci_yaml_file, project.full_path)
|
||||||
rescue Ci::GitlabCiYamlProcessor::ValidationError, Psych::SyntaxError => e
|
rescue Ci::GitlabCiYamlProcessor::ValidationError, Psych::SyntaxError => e
|
||||||
self.yaml_errors = e.message
|
self.yaml_errors = e.message
|
||||||
nil
|
nil
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
module Storage
|
||||||
|
module LegacyNamespace
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def move_dir
|
||||||
|
if any_project_has_container_registry_tags?
|
||||||
|
raise Gitlab::UpdatePathError.new('Namespace cannot be moved, because at least one project has tags in container registry')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Move the namespace directory in all storage paths used by member projects
|
||||||
|
repository_storage_paths.each do |repository_storage_path|
|
||||||
|
# Ensure old directory exists before moving it
|
||||||
|
gitlab_shell.add_namespace(repository_storage_path, full_path_was)
|
||||||
|
|
||||||
|
unless gitlab_shell.mv_namespace(repository_storage_path, full_path_was, full_path)
|
||||||
|
Rails.logger.error "Exception moving path #{repository_storage_path} from #{full_path_was} to #{full_path}"
|
||||||
|
|
||||||
|
# if we cannot move namespace directory we should rollback
|
||||||
|
# db changes in order to prevent out of sync between db and fs
|
||||||
|
raise Gitlab::UpdatePathError.new('namespace directory cannot be moved')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Gitlab::UploadsTransfer.new.rename_namespace(full_path_was, full_path)
|
||||||
|
Gitlab::PagesTransfer.new.rename_namespace(full_path_was, full_path)
|
||||||
|
|
||||||
|
remove_exports!
|
||||||
|
|
||||||
|
# If repositories moved successfully we need to
|
||||||
|
# send update instructions to users.
|
||||||
|
# However we cannot allow rollback since we moved namespace dir
|
||||||
|
# So we basically we mute exceptions in next actions
|
||||||
|
begin
|
||||||
|
send_update_instructions
|
||||||
|
true
|
||||||
|
rescue
|
||||||
|
# Returning false does not rollback after_* transaction but gives
|
||||||
|
# us information about failing some of tasks
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Hooks
|
||||||
|
|
||||||
|
# Save the storage paths before the projects are destroyed to use them on after destroy
|
||||||
|
def prepare_for_destroy
|
||||||
|
old_repository_storage_paths
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def old_repository_storage_paths
|
||||||
|
@old_repository_storage_paths ||= repository_storage_paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def repository_storage_paths
|
||||||
|
# We need to get the storage paths for all the projects, even the ones that are
|
||||||
|
# pending delete. Unscoping also get rids of the default order, which causes
|
||||||
|
# problems with SELECT DISTINCT.
|
||||||
|
Project.unscoped do
|
||||||
|
all_projects.select('distinct(repository_storage)').to_a.map(&:repository_storage_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def rm_dir
|
||||||
|
# Remove the namespace directory in all storages paths used by member projects
|
||||||
|
old_repository_storage_paths.each do |repository_storage_path|
|
||||||
|
# Move namespace directory into trash.
|
||||||
|
# We will remove it later async
|
||||||
|
new_path = "#{full_path}+#{id}+deleted"
|
||||||
|
|
||||||
|
if gitlab_shell.mv_namespace(repository_storage_path, full_path, new_path)
|
||||||
|
Gitlab::AppLogger.info %Q(Namespace directory "#{full_path}" moved to "#{new_path}")
|
||||||
|
|
||||||
|
# Remove namespace directroy async with delay so
|
||||||
|
# GitLab has time to remove all projects first
|
||||||
|
run_after_commit do
|
||||||
|
GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_exports!
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_exports!
|
||||||
|
Gitlab::Popen.popen(%W(find #{export_path} -not -path #{export_path} -delete))
|
||||||
|
end
|
||||||
|
|
||||||
|
def export_path
|
||||||
|
File.join(Gitlab::ImportExport.storage_path, full_path_was)
|
||||||
|
end
|
||||||
|
|
||||||
|
def full_path_was
|
||||||
|
if parent
|
||||||
|
parent.full_path + '/' + path_was
|
||||||
|
else
|
||||||
|
path_was
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,76 @@
|
||||||
|
module Storage
|
||||||
|
module LegacyProject
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def disk_path
|
||||||
|
full_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_storage_path_exist
|
||||||
|
gitlab_shell.add_namespace(repository_storage_path, namespace.full_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def rename_repo
|
||||||
|
path_was = previous_changes['path'].first
|
||||||
|
old_path_with_namespace = File.join(namespace.full_path, path_was)
|
||||||
|
new_path_with_namespace = File.join(namespace.full_path, path)
|
||||||
|
|
||||||
|
Rails.logger.error "Attempting to rename #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
||||||
|
|
||||||
|
if has_container_registry_tags?
|
||||||
|
Rails.logger.error "Project #{old_path_with_namespace} cannot be renamed because container registry tags are present!"
|
||||||
|
|
||||||
|
# we currently doesn't support renaming repository if it contains images in container registry
|
||||||
|
raise StandardError.new('Project cannot be renamed, because images are present in its container registry')
|
||||||
|
end
|
||||||
|
|
||||||
|
expire_caches_before_rename(old_path_with_namespace)
|
||||||
|
|
||||||
|
if gitlab_shell.mv_repository(repository_storage_path, old_path_with_namespace, new_path_with_namespace)
|
||||||
|
# If repository moved successfully we need to send update instructions to users.
|
||||||
|
# However we cannot allow rollback since we moved repository
|
||||||
|
# So we basically we mute exceptions in next actions
|
||||||
|
begin
|
||||||
|
gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
|
||||||
|
send_move_instructions(old_path_with_namespace)
|
||||||
|
expires_full_path_cache
|
||||||
|
|
||||||
|
@old_path_with_namespace = old_path_with_namespace
|
||||||
|
|
||||||
|
SystemHooksService.new.execute_hooks_for(self, :rename)
|
||||||
|
|
||||||
|
@repository = nil
|
||||||
|
rescue => e
|
||||||
|
Rails.logger.error "Exception renaming #{old_path_with_namespace} -> #{new_path_with_namespace}: #{e}"
|
||||||
|
# Returning false does not rollback after_* transaction but gives
|
||||||
|
# us information about failing some of tasks
|
||||||
|
false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Rails.logger.error "Repository could not be renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
||||||
|
|
||||||
|
# if we cannot move namespace directory we should rollback
|
||||||
|
# db changes in order to prevent out of sync between db and fs
|
||||||
|
raise StandardError.new('repository cannot be renamed')
|
||||||
|
end
|
||||||
|
|
||||||
|
Gitlab::AppLogger.info "Project was renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
||||||
|
|
||||||
|
Gitlab::UploadsTransfer.new.rename_project(path_was, path, namespace.full_path)
|
||||||
|
Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.full_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_repository(force: false)
|
||||||
|
# Forked import is handled asynchronously
|
||||||
|
return if forked? && !force
|
||||||
|
|
||||||
|
if gitlab_shell.add_repository(repository_storage_path, path_with_namespace)
|
||||||
|
repository.after_create
|
||||||
|
true
|
||||||
|
else
|
||||||
|
errors.add(:base, 'Failed to create repository via gitlab-shell')
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
module Storage
|
||||||
|
module LegacyProjectWiki
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def disk_path
|
||||||
|
project.disk_path + '.wiki'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
module Storage
|
||||||
|
module LegacyRepository
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
delegate :disk_path, to: :project
|
||||||
|
end
|
||||||
|
end
|
|
@ -630,7 +630,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
|
|
||||||
def target_project_path
|
def target_project_path
|
||||||
if target_project
|
if target_project
|
||||||
target_project.path_with_namespace
|
target_project.full_path
|
||||||
else
|
else
|
||||||
"(removed)"
|
"(removed)"
|
||||||
end
|
end
|
||||||
|
@ -638,7 +638,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
|
|
||||||
def source_project_path
|
def source_project_path
|
||||||
if source_project
|
if source_project
|
||||||
source_project.path_with_namespace
|
source_project.full_path
|
||||||
else
|
else
|
||||||
"(removed)"
|
"(removed)"
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Namespace < ActiveRecord::Base
|
||||||
include Gitlab::VisibilityLevel
|
include Gitlab::VisibilityLevel
|
||||||
include Routable
|
include Routable
|
||||||
include AfterCommitQueue
|
include AfterCommitQueue
|
||||||
|
include Storage::LegacyNamespace
|
||||||
|
|
||||||
# Prevent users from creating unreasonably deep level of nesting.
|
# Prevent users from creating unreasonably deep level of nesting.
|
||||||
# The number 20 was taken based on maximum nesting level of
|
# The number 20 was taken based on maximum nesting level of
|
||||||
|
@ -41,10 +42,11 @@ class Namespace < ActiveRecord::Base
|
||||||
|
|
||||||
delegate :name, to: :owner, allow_nil: true, prefix: true
|
delegate :name, to: :owner, allow_nil: true, prefix: true
|
||||||
|
|
||||||
after_update :move_dir, if: :path_changed?
|
|
||||||
after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
|
after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
|
||||||
|
|
||||||
# Save the storage paths before the projects are destroyed to use them on after destroy
|
# Legacy Storage specific hooks
|
||||||
|
|
||||||
|
after_update :move_dir, if: :path_changed?
|
||||||
before_destroy(prepend: true) { prepare_for_destroy }
|
before_destroy(prepend: true) { prepare_for_destroy }
|
||||||
after_destroy :rm_dir
|
after_destroy :rm_dir
|
||||||
|
|
||||||
|
@ -118,43 +120,6 @@ class Namespace < ActiveRecord::Base
|
||||||
owner_name
|
owner_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def move_dir
|
|
||||||
if any_project_has_container_registry_tags?
|
|
||||||
raise Gitlab::UpdatePathError.new('Namespace cannot be moved, because at least one project has tags in container registry')
|
|
||||||
end
|
|
||||||
|
|
||||||
# Move the namespace directory in all storages paths used by member projects
|
|
||||||
repository_storage_paths.each do |repository_storage_path|
|
|
||||||
# Ensure old directory exists before moving it
|
|
||||||
gitlab_shell.add_namespace(repository_storage_path, full_path_was)
|
|
||||||
|
|
||||||
unless gitlab_shell.mv_namespace(repository_storage_path, full_path_was, full_path)
|
|
||||||
Rails.logger.error "Exception moving path #{repository_storage_path} from #{full_path_was} to #{full_path}"
|
|
||||||
|
|
||||||
# if we cannot move namespace directory we should rollback
|
|
||||||
# db changes in order to prevent out of sync between db and fs
|
|
||||||
raise Gitlab::UpdatePathError.new('namespace directory cannot be moved')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Gitlab::UploadsTransfer.new.rename_namespace(full_path_was, full_path)
|
|
||||||
Gitlab::PagesTransfer.new.rename_namespace(full_path_was, full_path)
|
|
||||||
|
|
||||||
remove_exports!
|
|
||||||
|
|
||||||
# If repositories moved successfully we need to
|
|
||||||
# send update instructions to users.
|
|
||||||
# However we cannot allow rollback since we moved namespace dir
|
|
||||||
# So we basically we mute exceptions in next actions
|
|
||||||
begin
|
|
||||||
send_update_instructions
|
|
||||||
rescue
|
|
||||||
# Returning false does not rollback after_* transaction but gives
|
|
||||||
# us information about failing some of tasks
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def any_project_has_container_registry_tags?
|
def any_project_has_container_registry_tags?
|
||||||
all_projects.any?(&:has_container_registry_tags?)
|
all_projects.any?(&:has_container_registry_tags?)
|
||||||
end
|
end
|
||||||
|
@ -206,14 +171,6 @@ class Namespace < ActiveRecord::Base
|
||||||
parent_id_changed?
|
parent_id_changed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_for_destroy
|
|
||||||
old_repository_storage_paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def old_repository_storage_paths
|
|
||||||
@old_repository_storage_paths ||= repository_storage_paths
|
|
||||||
end
|
|
||||||
|
|
||||||
# Includes projects from this namespace and projects from all subgroups
|
# Includes projects from this namespace and projects from all subgroups
|
||||||
# that belongs to this namespace
|
# that belongs to this namespace
|
||||||
def all_projects
|
def all_projects
|
||||||
|
@ -232,37 +189,6 @@ class Namespace < ActiveRecord::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def repository_storage_paths
|
|
||||||
# We need to get the storage paths for all the projects, even the ones that are
|
|
||||||
# pending delete. Unscoping also get rids of the default order, which causes
|
|
||||||
# problems with SELECT DISTINCT.
|
|
||||||
Project.unscoped do
|
|
||||||
all_projects.select('distinct(repository_storage)').to_a.map(&:repository_storage_path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def rm_dir
|
|
||||||
# Remove the namespace directory in all storages paths used by member projects
|
|
||||||
old_repository_storage_paths.each do |repository_storage_path|
|
|
||||||
# Move namespace directory into trash.
|
|
||||||
# We will remove it later async
|
|
||||||
new_path = "#{full_path}+#{id}+deleted"
|
|
||||||
|
|
||||||
if gitlab_shell.mv_namespace(repository_storage_path, full_path, new_path)
|
|
||||||
message = "Namespace directory \"#{full_path}\" moved to \"#{new_path}\""
|
|
||||||
Gitlab::AppLogger.info message
|
|
||||||
|
|
||||||
# Remove namespace directroy async with delay so
|
|
||||||
# GitLab has time to remove all projects first
|
|
||||||
run_after_commit do
|
|
||||||
GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
remove_exports!
|
|
||||||
end
|
|
||||||
|
|
||||||
def refresh_access_of_projects_invited_groups
|
def refresh_access_of_projects_invited_groups
|
||||||
Group
|
Group
|
||||||
.joins(project_group_links: :project)
|
.joins(project_group_links: :project)
|
||||||
|
@ -270,22 +196,6 @@ class Namespace < ActiveRecord::Base
|
||||||
.find_each(&:refresh_members_authorized_projects)
|
.find_each(&:refresh_members_authorized_projects)
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_exports!
|
|
||||||
Gitlab::Popen.popen(%W(find #{export_path} -not -path #{export_path} -delete))
|
|
||||||
end
|
|
||||||
|
|
||||||
def export_path
|
|
||||||
File.join(Gitlab::ImportExport.storage_path, full_path_was)
|
|
||||||
end
|
|
||||||
|
|
||||||
def full_path_was
|
|
||||||
if parent
|
|
||||||
parent.full_path + '/' + path_was
|
|
||||||
else
|
|
||||||
path_was
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def nesting_level_allowed
|
def nesting_level_allowed
|
||||||
if ancestors.count > Group::NUMBER_OF_ANCESTORS_ALLOWED
|
if ancestors.count > Group::NUMBER_OF_ANCESTORS_ALLOWED
|
||||||
errors.add(:parent_id, "has too deep level of nesting")
|
errors.add(:parent_id, "has too deep level of nesting")
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
class NotificationSetting < ActiveRecord::Base
|
class NotificationSetting < ActiveRecord::Base
|
||||||
|
include IgnorableColumn
|
||||||
|
|
||||||
|
ignore_column :events
|
||||||
|
|
||||||
enum level: { global: 3, watch: 2, mention: 4, participating: 1, disabled: 0, custom: 5 }
|
enum level: { global: 3, watch: 2, mention: 4, participating: 1, disabled: 0, custom: 5 }
|
||||||
|
|
||||||
default_value_for :level, NotificationSetting.levels[:global]
|
default_value_for :level, NotificationSetting.levels[:global]
|
||||||
|
@ -41,9 +45,6 @@ class NotificationSetting < ActiveRecord::Base
|
||||||
:success_pipeline
|
:success_pipeline
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
store :events, coder: JSON
|
|
||||||
before_save :convert_events
|
|
||||||
|
|
||||||
def self.find_or_create_for(source)
|
def self.find_or_create_for(source)
|
||||||
setting = find_or_initialize_by(source: source)
|
setting = find_or_initialize_by(source: source)
|
||||||
|
|
||||||
|
@ -54,42 +55,17 @@ class NotificationSetting < ActiveRecord::Base
|
||||||
setting
|
setting
|
||||||
end
|
end
|
||||||
|
|
||||||
# 1. Check if this event has a value stored in its database column.
|
|
||||||
# 2. If it does, return that value.
|
|
||||||
# 3. If it doesn't (the value is nil), return the value from the serialized
|
|
||||||
# JSON hash in `events`.
|
|
||||||
(EMAIL_EVENTS - [:failed_pipeline]).each do |event|
|
|
||||||
define_method(event) do
|
|
||||||
bool = super()
|
|
||||||
|
|
||||||
bool.nil? ? !!events[event] : bool
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :"#{event}?", event
|
|
||||||
end
|
|
||||||
|
|
||||||
# Allow people to receive failed pipeline notifications if they already have
|
# Allow people to receive failed pipeline notifications if they already have
|
||||||
# custom notifications enabled, as these are more like mentions than the other
|
# custom notifications enabled, as these are more like mentions than the other
|
||||||
# custom settings.
|
# custom settings.
|
||||||
def failed_pipeline
|
def failed_pipeline
|
||||||
bool = super
|
bool = super
|
||||||
bool = events[:failed_pipeline] if bool.nil?
|
|
||||||
|
|
||||||
bool.nil? || bool
|
bool.nil? || bool
|
||||||
end
|
end
|
||||||
alias_method :failed_pipeline?, :failed_pipeline
|
alias_method :failed_pipeline?, :failed_pipeline
|
||||||
|
|
||||||
def event_enabled?(event)
|
def event_enabled?(event)
|
||||||
respond_to?(event) && public_send(event)
|
respond_to?(event) && !!public_send(event)
|
||||||
end
|
|
||||||
|
|
||||||
def convert_events
|
|
||||||
return if events_before_type_cast.nil?
|
|
||||||
|
|
||||||
EMAIL_EVENTS.each do |event|
|
|
||||||
write_attribute(event, public_send(event))
|
|
||||||
end
|
|
||||||
|
|
||||||
write_attribute(:events, nil)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,7 @@ class Project < ActiveRecord::Base
|
||||||
include ProjectFeaturesCompatibility
|
include ProjectFeaturesCompatibility
|
||||||
include SelectForProjectAuthorization
|
include SelectForProjectAuthorization
|
||||||
include Routable
|
include Routable
|
||||||
|
include Storage::LegacyProject
|
||||||
|
|
||||||
extend Gitlab::ConfigHelper
|
extend Gitlab::ConfigHelper
|
||||||
|
|
||||||
|
@ -43,9 +44,8 @@ class Project < ActiveRecord::Base
|
||||||
default_value_for :snippets_enabled, gitlab_config_features.snippets
|
default_value_for :snippets_enabled, gitlab_config_features.snippets
|
||||||
default_value_for :only_allow_merge_if_all_discussions_are_resolved, false
|
default_value_for :only_allow_merge_if_all_discussions_are_resolved, false
|
||||||
|
|
||||||
after_create :ensure_dir_exist
|
after_create :ensure_storage_path_exist
|
||||||
after_create :create_project_feature, unless: :project_feature
|
after_create :create_project_feature, unless: :project_feature
|
||||||
after_save :ensure_dir_exist, if: :namespace_id_changed?
|
|
||||||
after_save :update_project_statistics, if: :namespace_id_changed?
|
after_save :update_project_statistics, if: :namespace_id_changed?
|
||||||
|
|
||||||
# set last_activity_at to the same as created_at
|
# set last_activity_at to the same as created_at
|
||||||
|
@ -67,6 +67,10 @@ class Project < ActiveRecord::Base
|
||||||
|
|
||||||
after_validation :check_pending_delete
|
after_validation :check_pending_delete
|
||||||
|
|
||||||
|
# Legacy Storage specific hooks
|
||||||
|
|
||||||
|
after_save :ensure_storage_path_exist, if: :namespace_id_changed?
|
||||||
|
|
||||||
acts_as_taggable
|
acts_as_taggable
|
||||||
|
|
||||||
attr_accessor :new_default_branch
|
attr_accessor :new_default_branch
|
||||||
|
@ -375,7 +379,7 @@ class Project < ActiveRecord::Base
|
||||||
begin
|
begin
|
||||||
Projects::HousekeepingService.new(project).execute
|
Projects::HousekeepingService.new(project).execute
|
||||||
rescue Projects::HousekeepingService::LeaseTaken => e
|
rescue Projects::HousekeepingService::LeaseTaken => e
|
||||||
Rails.logger.info("Could not perform housekeeping for project #{project.path_with_namespace} (#{project.id}): #{e}")
|
Rails.logger.info("Could not perform housekeeping for project #{project.full_path} (#{project.id}): #{e}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -476,12 +480,12 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository
|
def repository
|
||||||
@repository ||= Repository.new(path_with_namespace, self)
|
@repository ||= Repository.new(full_path, self, disk_path: disk_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def container_registry_url
|
def container_registry_url
|
||||||
if Gitlab.config.registry.enabled
|
if Gitlab.config.registry.enabled
|
||||||
"#{Gitlab.config.registry.host_port}/#{path_with_namespace.downcase}"
|
"#{Gitlab.config.registry.host_port}/#{full_path.downcase}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -520,16 +524,16 @@ class Project < ActiveRecord::Base
|
||||||
job_id =
|
job_id =
|
||||||
if forked?
|
if forked?
|
||||||
RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path,
|
RepositoryForkWorker.perform_async(id, forked_from_project.repository_storage_path,
|
||||||
forked_from_project.path_with_namespace,
|
forked_from_project.full_path,
|
||||||
self.namespace.full_path)
|
self.namespace.full_path)
|
||||||
else
|
else
|
||||||
RepositoryImportWorker.perform_async(self.id)
|
RepositoryImportWorker.perform_async(self.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
if job_id
|
if job_id
|
||||||
Rails.logger.info "Import job started for #{path_with_namespace} with job ID #{job_id}"
|
Rails.logger.info "Import job started for #{full_path} with job ID #{job_id}"
|
||||||
else
|
else
|
||||||
Rails.logger.error "Import job failed to start for #{path_with_namespace}"
|
Rails.logger.error "Import job failed to start for #{full_path}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -690,7 +694,7 @@ class Project < ActiveRecord::Base
|
||||||
# `from` argument can be a Namespace or Project.
|
# `from` argument can be a Namespace or Project.
|
||||||
def to_reference(from = nil, full: false)
|
def to_reference(from = nil, full: false)
|
||||||
if full || cross_namespace_reference?(from)
|
if full || cross_namespace_reference?(from)
|
||||||
path_with_namespace
|
full_path
|
||||||
elsif cross_project_reference?(from)
|
elsif cross_project_reference?(from)
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
|
@ -714,7 +718,7 @@ class Project < ActiveRecord::Base
|
||||||
author.ensure_incoming_email_token!
|
author.ensure_incoming_email_token!
|
||||||
|
|
||||||
Gitlab::IncomingEmail.reply_address(
|
Gitlab::IncomingEmail.reply_address(
|
||||||
"#{path_with_namespace}+#{author.incoming_email_token}")
|
"#{full_path}+#{author.incoming_email_token}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_commit_note(commit)
|
def build_commit_note(commit)
|
||||||
|
@ -941,7 +945,7 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_to_repo
|
def url_to_repo
|
||||||
gitlab_shell.url_to_repo(path_with_namespace)
|
gitlab_shell.url_to_repo(full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def repo_exists?
|
def repo_exists?
|
||||||
|
@ -974,56 +978,6 @@ class Project < ActiveRecord::Base
|
||||||
!group
|
!group
|
||||||
end
|
end
|
||||||
|
|
||||||
def rename_repo
|
|
||||||
path_was = previous_changes['path'].first
|
|
||||||
old_path_with_namespace = File.join(namespace.full_path, path_was)
|
|
||||||
new_path_with_namespace = File.join(namespace.full_path, path)
|
|
||||||
|
|
||||||
Rails.logger.error "Attempting to rename #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
|
||||||
|
|
||||||
if has_container_registry_tags?
|
|
||||||
Rails.logger.error "Project #{old_path_with_namespace} cannot be renamed because container registry tags are present!"
|
|
||||||
|
|
||||||
# we currently doesn't support renaming repository if it contains images in container registry
|
|
||||||
raise StandardError.new('Project cannot be renamed, because images are present in its container registry')
|
|
||||||
end
|
|
||||||
|
|
||||||
expire_caches_before_rename(old_path_with_namespace)
|
|
||||||
|
|
||||||
if gitlab_shell.mv_repository(repository_storage_path, old_path_with_namespace, new_path_with_namespace)
|
|
||||||
# If repository moved successfully we need to send update instructions to users.
|
|
||||||
# However we cannot allow rollback since we moved repository
|
|
||||||
# So we basically we mute exceptions in next actions
|
|
||||||
begin
|
|
||||||
gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
|
|
||||||
send_move_instructions(old_path_with_namespace)
|
|
||||||
expires_full_path_cache
|
|
||||||
|
|
||||||
@old_path_with_namespace = old_path_with_namespace
|
|
||||||
|
|
||||||
SystemHooksService.new.execute_hooks_for(self, :rename)
|
|
||||||
|
|
||||||
@repository = nil
|
|
||||||
rescue => e
|
|
||||||
Rails.logger.error "Exception renaming #{old_path_with_namespace} -> #{new_path_with_namespace}: #{e}"
|
|
||||||
# Returning false does not rollback after_* transaction but gives
|
|
||||||
# us information about failing some of tasks
|
|
||||||
false
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Rails.logger.error "Repository could not be renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
|
||||||
|
|
||||||
# if we cannot move namespace directory we should rollback
|
|
||||||
# db changes in order to prevent out of sync between db and fs
|
|
||||||
raise StandardError.new('repository cannot be renamed')
|
|
||||||
end
|
|
||||||
|
|
||||||
Gitlab::AppLogger.info "Project was renamed: #{old_path_with_namespace} -> #{new_path_with_namespace}"
|
|
||||||
|
|
||||||
Gitlab::UploadsTransfer.new.rename_project(path_was, path, namespace.full_path)
|
|
||||||
Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.full_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Expires various caches before a project is renamed.
|
# Expires various caches before a project is renamed.
|
||||||
def expire_caches_before_rename(old_path)
|
def expire_caches_before_rename(old_path)
|
||||||
repo = Repository.new(old_path, self)
|
repo = Repository.new(old_path, self)
|
||||||
|
@ -1048,7 +1002,7 @@ class Project < ActiveRecord::Base
|
||||||
git_http_url: http_url_to_repo,
|
git_http_url: http_url_to_repo,
|
||||||
namespace: namespace.name,
|
namespace: namespace.name,
|
||||||
visibility_level: visibility_level,
|
visibility_level: visibility_level,
|
||||||
path_with_namespace: path_with_namespace,
|
path_with_namespace: full_path,
|
||||||
default_branch: default_branch,
|
default_branch: default_branch,
|
||||||
ci_config_path: ci_config_path
|
ci_config_path: ci_config_path
|
||||||
}
|
}
|
||||||
|
@ -1109,19 +1063,6 @@ class Project < ActiveRecord::Base
|
||||||
merge_requests.where(source_project_id: self.id)
|
merge_requests.where(source_project_id: self.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_repository(force: false)
|
|
||||||
# Forked import is handled asynchronously
|
|
||||||
return if forked? && !force
|
|
||||||
|
|
||||||
if gitlab_shell.add_repository(repository_storage_path, path_with_namespace)
|
|
||||||
repository.after_create
|
|
||||||
true
|
|
||||||
else
|
|
||||||
errors.add(:base, 'Failed to create repository via gitlab-shell')
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def ensure_repository
|
def ensure_repository
|
||||||
create_repository(force: true) unless repository_exists?
|
create_repository(force: true) unless repository_exists?
|
||||||
end
|
end
|
||||||
|
@ -1257,7 +1198,7 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def pages_path
|
def pages_path
|
||||||
File.join(Settings.pages.path, path_with_namespace)
|
File.join(Settings.pages.path, disk_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_pages_path
|
def public_pages_path
|
||||||
|
@ -1265,9 +1206,21 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_private_deploy_keys
|
def remove_private_deploy_keys
|
||||||
deploy_keys.where(public: false).delete_all
|
exclude_keys_linked_to_other_projects = <<-SQL
|
||||||
|
NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM deploy_keys_projects dkp2
|
||||||
|
WHERE dkp2.deploy_key_id = deploy_keys_projects.deploy_key_id
|
||||||
|
AND dkp2.project_id != deploy_keys_projects.project_id
|
||||||
|
)
|
||||||
|
SQL
|
||||||
|
|
||||||
|
deploy_keys.where(public: false)
|
||||||
|
.where(exclude_keys_linked_to_other_projects)
|
||||||
|
.delete_all
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: what to do here when not using Legacy Storage? Do we still need to rename and delay removal?
|
||||||
def remove_pages
|
def remove_pages
|
||||||
::Projects::UpdatePagesConfigurationService.new(self).execute
|
::Projects::UpdatePagesConfigurationService.new(self).execute
|
||||||
|
|
||||||
|
@ -1315,7 +1268,7 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def export_path
|
def export_path
|
||||||
File.join(Gitlab::ImportExport.storage_path, path_with_namespace)
|
File.join(Gitlab::ImportExport.storage_path, disk_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def export_project_path
|
def export_project_path
|
||||||
|
@ -1327,16 +1280,12 @@ class Project < ActiveRecord::Base
|
||||||
status.zero?
|
status.zero?
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_dir_exist
|
|
||||||
gitlab_shell.add_namespace(repository_storage_path, namespace.full_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def predefined_variables
|
def predefined_variables
|
||||||
[
|
[
|
||||||
{ key: 'CI_PROJECT_ID', value: id.to_s, public: true },
|
{ key: 'CI_PROJECT_ID', value: id.to_s, public: true },
|
||||||
{ key: 'CI_PROJECT_NAME', value: path, public: true },
|
{ key: 'CI_PROJECT_NAME', value: path, public: true },
|
||||||
{ key: 'CI_PROJECT_PATH', value: path_with_namespace, public: true },
|
{ key: 'CI_PROJECT_PATH', value: full_path, public: true },
|
||||||
{ key: 'CI_PROJECT_PATH_SLUG', value: path_with_namespace.parameterize, public: true },
|
{ key: 'CI_PROJECT_PATH_SLUG', value: full_path.parameterize, public: true },
|
||||||
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true },
|
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true },
|
||||||
{ key: 'CI_PROJECT_URL', value: web_url, public: true }
|
{ key: 'CI_PROJECT_URL', value: web_url, public: true }
|
||||||
]
|
]
|
||||||
|
@ -1441,6 +1390,7 @@ class Project < ActiveRecord::Base
|
||||||
|
|
||||||
alias_method :name_with_namespace, :full_name
|
alias_method :name_with_namespace, :full_name
|
||||||
alias_method :human_name, :full_name
|
alias_method :human_name, :full_name
|
||||||
|
# @deprecated cannot remove yet because it has an index with its name in elasticsearch
|
||||||
alias_method :path_with_namespace, :full_path
|
alias_method :path_with_namespace, :full_path
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -1495,7 +1445,7 @@ class Project < ActiveRecord::Base
|
||||||
def pending_delete_twin
|
def pending_delete_twin
|
||||||
return false unless path
|
return false unless path
|
||||||
|
|
||||||
Project.pending_delete.find_by_full_path(path_with_namespace)
|
Project.pending_delete.find_by_full_path(full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -35,9 +35,9 @@ class FlowdockService < Service
|
||||||
data[:after],
|
data[:after],
|
||||||
token: token,
|
token: token,
|
||||||
repo: project.repository.path_to_repo,
|
repo: project.repository.path_to_repo,
|
||||||
repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}",
|
repo_url: "#{Gitlab.config.gitlab.url}/#{project.full_path}",
|
||||||
commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s",
|
commit_url: "#{Gitlab.config.gitlab.url}/#{project.full_path}/commit/%s",
|
||||||
diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s"
|
diff_url: "#{Gitlab.config.gitlab.url}/#{project.full_path}/compare/%s...%s"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -140,7 +140,7 @@ class JiraService < IssueTrackerService
|
||||||
url: resource_url(user_path(author))
|
url: resource_url(user_path(author))
|
||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
name: project.path_with_namespace,
|
name: project.full_path,
|
||||||
url: resource_url(namespace_project_path(project.namespace, project)) # rubocop:disable Cop/ProjectPathHelper
|
url: resource_url(namespace_project_path(project.namespace, project)) # rubocop:disable Cop/ProjectPathHelper
|
||||||
},
|
},
|
||||||
entity: {
|
entity: {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class ProjectWiki
|
class ProjectWiki
|
||||||
include Gitlab::ShellAdapter
|
include Gitlab::ShellAdapter
|
||||||
|
include Storage::LegacyProjectWiki
|
||||||
|
|
||||||
MARKUPS = {
|
MARKUPS = {
|
||||||
'Markdown' => :markdown,
|
'Markdown' => :markdown,
|
||||||
|
@ -26,16 +27,19 @@ class ProjectWiki
|
||||||
@project.path + '.wiki'
|
@project.path + '.wiki'
|
||||||
end
|
end
|
||||||
|
|
||||||
def path_with_namespace
|
def full_path
|
||||||
@project.path_with_namespace + ".wiki"
|
@project.full_path + '.wiki'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @deprecated use full_path when you need it for an URL route or disk_path when you want to point to the filesystem
|
||||||
|
alias_method :path_with_namespace, :full_path
|
||||||
|
|
||||||
def web_url
|
def web_url
|
||||||
Gitlab::Routing.url_helpers.project_wiki_url(@project, :home)
|
Gitlab::Routing.url_helpers.project_wiki_url(@project, :home)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_to_repo
|
def url_to_repo
|
||||||
gitlab_shell.url_to_repo(path_with_namespace)
|
gitlab_shell.url_to_repo(full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ssh_url_to_repo
|
def ssh_url_to_repo
|
||||||
|
@ -43,11 +47,11 @@ class ProjectWiki
|
||||||
end
|
end
|
||||||
|
|
||||||
def http_url_to_repo
|
def http_url_to_repo
|
||||||
"#{Gitlab.config.gitlab.url}/#{path_with_namespace}.git"
|
"#{Gitlab.config.gitlab.url}/#{full_path}.git"
|
||||||
end
|
end
|
||||||
|
|
||||||
def wiki_base_path
|
def wiki_base_path
|
||||||
[Gitlab.config.gitlab.relative_url_root, "/", @project.path_with_namespace, "/wikis"].join('')
|
[Gitlab.config.gitlab.relative_url_root, '/', @project.full_path, '/wikis'].join('')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the Gollum::Wiki object.
|
# Returns the Gollum::Wiki object.
|
||||||
|
@ -134,7 +138,7 @@ class ProjectWiki
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository
|
def repository
|
||||||
@repository ||= Repository.new(path_with_namespace, @project)
|
@repository ||= Repository.new(full_path, @project, disk_path: disk_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_branch
|
def default_branch
|
||||||
|
@ -142,7 +146,7 @@ class ProjectWiki
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_repo!
|
def create_repo!
|
||||||
if init_repo(path_with_namespace)
|
if init_repo(disk_path)
|
||||||
wiki = Gollum::Wiki.new(path_to_repo)
|
wiki = Gollum::Wiki.new(path_to_repo)
|
||||||
else
|
else
|
||||||
raise CouldNotCreateWikiError
|
raise CouldNotCreateWikiError
|
||||||
|
@ -162,15 +166,15 @@ class ProjectWiki
|
||||||
web_url: web_url,
|
web_url: web_url,
|
||||||
git_ssh_url: ssh_url_to_repo,
|
git_ssh_url: ssh_url_to_repo,
|
||||||
git_http_url: http_url_to_repo,
|
git_http_url: http_url_to_repo,
|
||||||
path_with_namespace: path_with_namespace,
|
path_with_namespace: full_path,
|
||||||
default_branch: default_branch
|
default_branch: default_branch
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def init_repo(path_with_namespace)
|
def init_repo(disk_path)
|
||||||
gitlab_shell.add_repository(project.repository_storage_path, path_with_namespace)
|
gitlab_shell.add_repository(project.repository_storage_path, disk_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit_details(action, message = nil, title = nil)
|
def commit_details(action, message = nil, title = nil)
|
||||||
|
@ -184,7 +188,7 @@ class ProjectWiki
|
||||||
end
|
end
|
||||||
|
|
||||||
def path_to_repo
|
def path_to_repo
|
||||||
@path_to_repo ||= File.join(project.repository_storage_path, "#{path_with_namespace}.git")
|
@path_to_repo ||= File.join(project.repository_storage_path, "#{disk_path}.git")
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_project_activity
|
def update_project_activity
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Repository
|
||||||
include Gitlab::ShellAdapter
|
include Gitlab::ShellAdapter
|
||||||
include RepositoryMirroring
|
include RepositoryMirroring
|
||||||
|
|
||||||
attr_accessor :path_with_namespace, :project
|
attr_accessor :full_path, :disk_path, :project
|
||||||
|
|
||||||
delegate :ref_name_for_sha, to: :raw_repository
|
delegate :ref_name_for_sha, to: :raw_repository
|
||||||
|
|
||||||
|
@ -52,13 +52,14 @@ class Repository
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(path_with_namespace, project)
|
def initialize(full_path, project, disk_path: nil)
|
||||||
@path_with_namespace = path_with_namespace
|
@full_path = full_path
|
||||||
|
@disk_path = disk_path || full_path
|
||||||
@project = project
|
@project = project
|
||||||
end
|
end
|
||||||
|
|
||||||
def raw_repository
|
def raw_repository
|
||||||
return nil unless path_with_namespace
|
return nil unless full_path
|
||||||
|
|
||||||
@raw_repository ||= initialize_raw_repository
|
@raw_repository ||= initialize_raw_repository
|
||||||
end
|
end
|
||||||
|
@ -66,7 +67,7 @@ class Repository
|
||||||
# Return absolute path to repository
|
# Return absolute path to repository
|
||||||
def path_to_repo
|
def path_to_repo
|
||||||
@path_to_repo ||= File.expand_path(
|
@path_to_repo ||= File.expand_path(
|
||||||
File.join(repository_storage_path, path_with_namespace + ".git")
|
File.join(repository_storage_path, disk_path + '.git')
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -469,7 +470,7 @@ class Repository
|
||||||
|
|
||||||
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/314
|
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/314
|
||||||
def exists?
|
def exists?
|
||||||
return false unless path_with_namespace
|
return false unless full_path
|
||||||
|
|
||||||
Gitlab::GitalyClient.migrate(:repository_exists) do |enabled|
|
Gitlab::GitalyClient.migrate(:repository_exists) do |enabled|
|
||||||
if enabled
|
if enabled
|
||||||
|
@ -1005,7 +1006,7 @@ class Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_remote(remote, forced: false, no_tags: false)
|
def fetch_remote(remote, forced: false, no_tags: false)
|
||||||
gitlab_shell.fetch_remote(repository_storage_path, path_with_namespace, remote, forced: forced, no_tags: no_tags)
|
gitlab_shell.fetch_remote(repository_storage_path, disk_path, remote, forced: forced, no_tags: no_tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_ref(source_path, source_ref, target_ref)
|
def fetch_ref(source_path, source_ref, target_ref)
|
||||||
|
@ -1104,7 +1105,8 @@ class Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def cache
|
def cache
|
||||||
@cache ||= RepositoryCache.new(path_with_namespace, @project.id)
|
# TODO: should we use UUIDs here? We could move repositories without clearing this cache
|
||||||
|
@cache ||= RepositoryCache.new(full_path, @project.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tags_sorted_by_committed_date
|
def tags_sorted_by_committed_date
|
||||||
|
@ -1127,7 +1129,7 @@ class Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository_event(event, tags = {})
|
def repository_event(event, tags = {})
|
||||||
Gitlab::Metrics.add_event(event, { path: path_with_namespace }.merge(tags))
|
Gitlab::Metrics.add_event(event, { path: full_path }.merge(tags))
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_commit(params = {})
|
def create_commit(params = {})
|
||||||
|
@ -1141,6 +1143,6 @@ class Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize_raw_repository
|
def initialize_raw_repository
|
||||||
Gitlab::Git::Repository.new(project.repository_storage, path_with_namespace + '.git')
|
Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -44,7 +44,7 @@ class GlobalPolicy < BasePolicy
|
||||||
prevent :log_in
|
prevent :log_in
|
||||||
end
|
end
|
||||||
|
|
||||||
rule { admin | ~restricted_public_level }.policy do
|
rule { ~(anonymous & restricted_public_level) }.policy do
|
||||||
enable :read_users_list
|
enable :read_users_list
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,7 +60,7 @@ class GitOperationService
|
||||||
start_branch_name = nil if start_repository.empty_repo?
|
start_branch_name = nil if start_repository.empty_repo?
|
||||||
|
|
||||||
if start_branch_name && !start_repository.branch_exists?(start_branch_name)
|
if start_branch_name && !start_repository.branch_exists?(start_branch_name)
|
||||||
raise ArgumentError, "Cannot find branch #{start_branch_name} in #{start_repository.path_with_namespace}"
|
raise ArgumentError, "Cannot find branch #{start_branch_name} in #{start_repository.full_path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
update_branch_with_hooks(branch_name) do
|
update_branch_with_hooks(branch_name) do
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Projects
|
||||||
def async_execute
|
def async_execute
|
||||||
project.update_attribute(:pending_delete, true)
|
project.update_attribute(:pending_delete, true)
|
||||||
job_id = ProjectDestroyWorker.perform_async(project.id, current_user.id, params)
|
job_id = ProjectDestroyWorker.perform_async(project.id, current_user.id, params)
|
||||||
Rails.logger.info("User #{current_user.id} scheduled destruction of project #{project.path_with_namespace} with job ID #{job_id}")
|
Rails.logger.info("User #{current_user.id} scheduled destruction of project #{project.full_path} with job ID #{job_id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
|
@ -40,7 +40,7 @@ module Projects
|
||||||
private
|
private
|
||||||
|
|
||||||
def repo_path
|
def repo_path
|
||||||
project.path_with_namespace
|
project.disk_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def wiki_path
|
def wiki_path
|
||||||
|
@ -127,7 +127,7 @@ module Projects
|
||||||
def flush_caches(project)
|
def flush_caches(project)
|
||||||
project.repository.before_delete
|
project.repository.before_delete
|
||||||
|
|
||||||
Repository.new(wiki_path, project).before_delete
|
Repository.new(wiki_path, project, disk_path: repo_path).before_delete
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Projects
|
||||||
module ImportExport
|
module ImportExport
|
||||||
class ExportService < BaseService
|
class ExportService < BaseService
|
||||||
def execute(_options = {})
|
def execute(_options = {})
|
||||||
@shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work'))
|
@shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.disk_path, 'work'))
|
||||||
save_all
|
save_all
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ module Projects
|
||||||
|
|
||||||
success
|
success
|
||||||
rescue => e
|
rescue => e
|
||||||
error("Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}")
|
error("Error importing repository #{project.import_url} into #{project.full_path} - #{e.message}")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -51,7 +51,7 @@ module Projects
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone_repository
|
def clone_repository
|
||||||
gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
|
gitlab_shell.import_repository(project.repository_storage_path, project.disk_path, project.import_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_repository
|
def fetch_repository
|
||||||
|
|
|
@ -34,7 +34,7 @@ module Projects
|
||||||
private
|
private
|
||||||
|
|
||||||
def transfer(project)
|
def transfer(project)
|
||||||
@old_path = project.path_with_namespace
|
@old_path = project.full_path
|
||||||
@old_group = project.group
|
@old_group = project.group
|
||||||
@new_path = File.join(@new_namespace.try(:full_path) || '', project.path)
|
@new_path = File.join(@new_namespace.try(:full_path) || '', project.path)
|
||||||
@old_namespace = project.namespace
|
@old_namespace = project.namespace
|
||||||
|
@ -61,11 +61,13 @@ module Projects
|
||||||
project.send_move_instructions(@old_path)
|
project.send_move_instructions(@old_path)
|
||||||
|
|
||||||
# Move main repository
|
# Move main repository
|
||||||
|
# TODO: check storage type and NOOP when not using Legacy
|
||||||
unless move_repo_folder(@old_path, @new_path)
|
unless move_repo_folder(@old_path, @new_path)
|
||||||
raise TransferError.new('Cannot move project')
|
raise TransferError.new('Cannot move project')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Move wiki repo also if present
|
# Move wiki repo also if present
|
||||||
|
# TODO: check storage type and NOOP when not using Legacy
|
||||||
move_repo_folder("#{@old_path}.wiki", "#{@new_path}.wiki")
|
move_repo_folder("#{@old_path}.wiki", "#{@new_path}.wiki")
|
||||||
|
|
||||||
# Move missing group labels to project
|
# Move missing group labels to project
|
||||||
|
|
|
@ -4,6 +4,9 @@ module QuickActions
|
||||||
|
|
||||||
attr_reader :issuable
|
attr_reader :issuable
|
||||||
|
|
||||||
|
SHRUG = '¯\\_(ツ)_/¯'.freeze
|
||||||
|
TABLEFLIP = '(╯°□°)╯︵ ┻━┻'.freeze
|
||||||
|
|
||||||
# Takes a text and interprets the commands that are extracted from it.
|
# Takes a text and interprets the commands that are extracted from it.
|
||||||
# Returns the content without commands, and hash of changes to be applied to a record.
|
# Returns the content without commands, and hash of changes to be applied to a record.
|
||||||
def execute(content, issuable)
|
def execute(content, issuable)
|
||||||
|
@ -14,6 +17,7 @@ module QuickActions
|
||||||
|
|
||||||
content, commands = extractor.extract_commands(content, context)
|
content, commands = extractor.extract_commands(content, context)
|
||||||
extract_updates(commands, context)
|
extract_updates(commands, context)
|
||||||
|
|
||||||
[content, @updates]
|
[content, @updates]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -423,6 +427,18 @@ module QuickActions
|
||||||
@updates[:spend_time] = { duration: :reset, user: current_user }
|
@updates[:spend_time] = { duration: :reset, user: current_user }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc "Append the comment with #{SHRUG}"
|
||||||
|
params '<Comment>'
|
||||||
|
substitution :shrug do |comment|
|
||||||
|
"#{comment} #{SHRUG}"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Append the comment with #{TABLEFLIP}"
|
||||||
|
params '<Comment>'
|
||||||
|
substitution :tableflip do |comment|
|
||||||
|
"#{comment} #{TABLEFLIP}"
|
||||||
|
end
|
||||||
|
|
||||||
# This is a dummy command, so that it appears in the autocomplete commands
|
# This is a dummy command, so that it appears in the autocomplete commands
|
||||||
desc 'CC'
|
desc 'CC'
|
||||||
params '@user'
|
params '@user'
|
||||||
|
|
|
@ -79,7 +79,7 @@ class SystemHooksService
|
||||||
{
|
{
|
||||||
name: model.name,
|
name: model.name,
|
||||||
path: model.path,
|
path: model.path,
|
||||||
path_with_namespace: model.path_with_namespace,
|
path_with_namespace: model.full_path,
|
||||||
project_id: model.id,
|
project_id: model.id,
|
||||||
owner_name: owner.name,
|
owner_name: owner.name,
|
||||||
owner_email: owner.respond_to?(:email) ? owner.email : "",
|
owner_email: owner.respond_to?(:email) ? owner.email : "",
|
||||||
|
@ -93,7 +93,7 @@ class SystemHooksService
|
||||||
{
|
{
|
||||||
project_name: project.name,
|
project_name: project.name,
|
||||||
project_path: project.path,
|
project_path: project.path,
|
||||||
project_path_with_namespace: project.path_with_namespace,
|
project_path_with_namespace: project.full_path,
|
||||||
project_id: project.id,
|
project_id: project.id,
|
||||||
user_username: model.user.username,
|
user_username: model.user.username,
|
||||||
user_name: model.user.name,
|
user_name: model.user.name,
|
||||||
|
|
|
@ -30,7 +30,7 @@ class FileUploader < GitlabUploader
|
||||||
#
|
#
|
||||||
# Returns a String without a trailing slash
|
# Returns a String without a trailing slash
|
||||||
def self.dynamic_path_segment(model)
|
def self.dynamic_path_segment(model)
|
||||||
File.join(CarrierWave.root, base_dir, model.path_with_namespace)
|
File.join(CarrierWave.root, base_dir, model.full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :model
|
attr_accessor :model
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
%span.badge
|
%span.badge
|
||||||
= storage_counter(project.statistics.storage_size)
|
= storage_counter(project.statistics.storage_size)
|
||||||
%span.pull-right.light
|
%span.pull-right.light
|
||||||
%span.monospace= project.path_with_namespace + ".git"
|
%span.monospace= project.full_path + '.git'
|
||||||
.panel-footer
|
.panel-footer
|
||||||
= paginate @projects, param_name: 'projects_page', theme: 'gitlab'
|
= paginate @projects, param_name: 'projects_page', theme: 'gitlab'
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
%span.badge
|
%span.badge
|
||||||
= storage_counter(project.statistics.storage_size)
|
= storage_counter(project.statistics.storage_size)
|
||||||
%span.pull-right.light
|
%span.pull-right.light
|
||||||
%span.monospace= project.path_with_namespace + ".git"
|
%span.monospace= project.full_path + '.git'
|
||||||
|
|
||||||
.col-md-6
|
.col-md-6
|
||||||
- if can?(current_user, :admin_group_member, @group)
|
- if can?(current_user, :admin_group_member, @group)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
- page_title "UI Development Kit", "Help"
|
- page_title "UI Development Kit", "Help"
|
||||||
- lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fermentum nisi sapien, non consequat lectus aliquam ultrices. Suspendisse sodales est euismod nunc condimentum, a consectetur diam ornare."
|
- lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fermentum nisi sapien, non consequat lectus aliquam ultrices. Suspendisse sodales est euismod nunc condimentum, a consectetur diam ornare."
|
||||||
|
- content_for :page_specific_javascripts do
|
||||||
|
= webpack_bundle_tag('ui_development_kit')
|
||||||
|
|
||||||
.gitlab-ui-dev-kit
|
.gitlab-ui-dev-kit
|
||||||
%h1 GitLab UI development kit
|
%h1 GitLab UI development kit
|
||||||
|
@ -407,29 +409,6 @@
|
||||||
.dropdown-content
|
.dropdown-content
|
||||||
.dropdown-loading
|
.dropdown-loading
|
||||||
= icon('spinner spin')
|
= icon('spinner spin')
|
||||||
:javascript
|
|
||||||
$('#js-project-dropdown').glDropdown({
|
|
||||||
data: function (term, callback) {
|
|
||||||
Api.projects(term, { order_by: 'last_activity_at' }, function (data) {
|
|
||||||
callback(data);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
text: function (project) {
|
|
||||||
return project.name_with_namespace || project.name;
|
|
||||||
},
|
|
||||||
selectable: true,
|
|
||||||
fieldName: "author_id",
|
|
||||||
filterable: true,
|
|
||||||
search: {
|
|
||||||
fields: ['name_with_namespace']
|
|
||||||
},
|
|
||||||
id: function (data) {
|
|
||||||
return data.id;
|
|
||||||
},
|
|
||||||
isSelected: function (data) {
|
|
||||||
return data.id === 2;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
.example
|
.example
|
||||||
%div
|
%div
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
%td
|
%td
|
||||||
= provider_project_link(provider, project.import_source)
|
= provider_project_link(provider, project.import_source)
|
||||||
%td
|
%td
|
||||||
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
|
= link_to project.full_path, [project.namespace.becomes(Namespace), project]
|
||||||
%td.job-status
|
%td.job-status
|
||||||
- if project.import_status == 'finished'
|
- if project.import_status == 'finished'
|
||||||
%span
|
%span
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
job.attr("id", "project_#{@project.id}")
|
job.attr("id", "project_#{@project.id}")
|
||||||
target_field = job.find(".import-target")
|
target_field = job.find(".import-target")
|
||||||
target_field.empty()
|
target_field.empty()
|
||||||
target_field.append('#{link_to @project.path_with_namespace, project_path(@project)}')
|
target_field.append('#{link_to @project.full_path, project_path(@project)}')
|
||||||
$("table.import-jobs tbody").prepend(job)
|
$("table.import-jobs tbody").prepend(job)
|
||||||
job.addClass("active").find(".import-actions").html("<i class='fa fa-spinner fa-spin'></i> started")
|
job.addClass("active").find(".import-actions").html("<i class='fa fa-spinner fa-spin'></i> started")
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
%td
|
%td
|
||||||
= link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: '_blank', rel: 'noopener noreferrer'
|
= link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: '_blank', rel: 'noopener noreferrer'
|
||||||
%td
|
%td
|
||||||
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
|
= link_to project.full_path, [project.namespace.becomes(Namespace), project]
|
||||||
%td.job-status
|
%td.job-status
|
||||||
- if project.import_status == 'finished'
|
- if project.import_status == 'finished'
|
||||||
%span
|
%span
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
%td
|
%td
|
||||||
= project.import_source
|
= project.import_source
|
||||||
%td
|
%td
|
||||||
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
|
= link_to project.full_path, [project.namespace.becomes(Namespace), project]
|
||||||
%td.job-status
|
%td.job-status
|
||||||
- if project.import_status == 'finished'
|
- if project.import_status == 'finished'
|
||||||
%span
|
%span
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
%td
|
%td
|
||||||
= link_to project.import_source, "https://gitlab.com/#{project.import_source}", target: "_blank"
|
= link_to project.import_source, "https://gitlab.com/#{project.import_source}", target: "_blank"
|
||||||
%td
|
%td
|
||||||
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
|
= link_to project.full_path, [project.namespace.becomes(Namespace), project]
|
||||||
%td.job-status
|
%td.job-status
|
||||||
- if project.import_status == 'finished'
|
- if project.import_status == 'finished'
|
||||||
%span
|
%span
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
%td
|
%td
|
||||||
= link_to project.import_source, "https://code.google.com/p/#{project.import_source}", target: "_blank", rel: 'noopener noreferrer'
|
= link_to project.import_source, "https://code.google.com/p/#{project.import_source}", target: "_blank", rel: 'noopener noreferrer'
|
||||||
%td
|
%td
|
||||||
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
|
= link_to project.full_path, [project.namespace.becomes(Namespace), project]
|
||||||
%td.job-status
|
%td.job-status
|
||||||
- if project.import_status == 'finished'
|
- if project.import_status == 'finished'
|
||||||
%span
|
%span
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
-# haml-lint:disable InlineJavaScript
|
||||||
:javascript
|
:javascript
|
||||||
var _gaq = _gaq || [];
|
var _gaq = _gaq || [];
|
||||||
_gaq.push(['_setAccount', '#{extra_config.google_analytics_id}']);
|
_gaq.push(['_setAccount', '#{extra_config.google_analytics_id}']);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
- noteable_type = @noteable.class if @noteable.present?
|
- noteable_type = @noteable.class if @noteable.present?
|
||||||
|
|
||||||
- if project
|
- if project
|
||||||
|
-# haml-lint:disable InlineJavaScript
|
||||||
:javascript
|
:javascript
|
||||||
gl.GfmAutoComplete = gl.GfmAutoComplete || {};
|
gl.GfmAutoComplete = gl.GfmAutoComplete || {};
|
||||||
gl.GfmAutoComplete.dataSources = {
|
gl.GfmAutoComplete.dataSources = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.page-with-sidebar{ class: "#{('page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar)} #{page_gutter_class}" }
|
.page-with-sidebar{ class: page_with_sidebar_class }
|
||||||
- if show_new_nav?
|
- if show_new_nav?
|
||||||
- if defined?(nav) && nav
|
- if defined?(nav) && nav
|
||||||
= render "layouts/nav/#{nav}"
|
= render "layouts/nav/#{nav}"
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
= render "layouts/nav/#{nav}"
|
= render "layouts/nav/#{nav}"
|
||||||
- if content_for?(:sub_nav)
|
- if content_for?(:sub_nav)
|
||||||
= yield :sub_nav
|
= yield :sub_nav
|
||||||
.content-wrapper{ class: "#{(layout_nav_class unless show_new_nav?)}" }
|
.content-wrapper{ class: layout_nav_class }
|
||||||
- if show_new_nav?
|
- if show_new_nav?
|
||||||
.mobile-overlay
|
.mobile-overlay
|
||||||
.alert-wrapper
|
.alert-wrapper
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<!-- Piwik -->
|
<!-- Piwik -->
|
||||||
|
-# haml-lint:disable InlineJavaScript
|
||||||
:javascript
|
:javascript
|
||||||
var _paq = _paq || [];
|
var _paq = _paq || [];
|
||||||
_paq.push(['trackPageView']);
|
_paq.push(['trackPageView']);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
!!! 5
|
!!! 5
|
||||||
%html{ lang: I18n.locale, class: "#{page_class}" }
|
%html{ lang: I18n.locale, class: page_class }
|
||||||
= render "layouts/head"
|
= render "layouts/head"
|
||||||
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } }
|
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } }
|
||||||
= render "layouts/init_auto_complete" if @gfm_form
|
= render "layouts/init_auto_complete" if @gfm_form
|
||||||
|
= render 'peek/bar'
|
||||||
- if show_new_nav?
|
- if show_new_nav?
|
||||||
= render "layouts/header/new"
|
= render "layouts/header/new"
|
||||||
- else
|
- else
|
||||||
|
@ -10,5 +11,3 @@
|
||||||
= render 'layouts/page', sidebar: sidebar, nav: nav
|
= render 'layouts/page', sidebar: sidebar, nav: nav
|
||||||
|
|
||||||
= yield :scripts_body
|
= yield :scripts_body
|
||||||
|
|
||||||
= render 'peek/bar'
|
|
||||||
|
|
|
@ -91,8 +91,8 @@
|
||||||
= nav_link(controller: :abuse_reports) do
|
= nav_link(controller: :abuse_reports) do
|
||||||
= link_to admin_abuse_reports_path, title: "Abuse Reports" do
|
= link_to admin_abuse_reports_path, title: "Abuse Reports" do
|
||||||
%span
|
%span
|
||||||
Abuse Reports
|
|
||||||
%span.badge.count= number_with_delimiter(AbuseReport.count(:all))
|
%span.badge.count= number_with_delimiter(AbuseReport.count(:all))
|
||||||
|
Abuse Reports
|
||||||
|
|
||||||
- if akismet_enabled?
|
- if akismet_enabled?
|
||||||
= nav_link(controller: :spam_logs) do
|
= nav_link(controller: :spam_logs) do
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
= nav_link(path: ['groups#issues', 'labels#index', 'milestones#index']) do
|
= nav_link(path: ['groups#issues', 'labels#index', 'milestones#index']) do
|
||||||
= link_to issues_group_path(@group), title: 'Issues' do
|
= link_to issues_group_path(@group), title: 'Issues' do
|
||||||
%span
|
%span
|
||||||
Issues
|
|
||||||
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
|
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
|
||||||
%span.badge.count= number_with_delimiter(issues.count)
|
%span.badge.count= number_with_delimiter(issues.count)
|
||||||
|
Issues
|
||||||
|
|
||||||
%ul.sidebar-sub-level-items
|
%ul.sidebar-sub-level-items
|
||||||
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
|
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
= nav_link(path: 'groups#merge_requests') do
|
= nav_link(path: 'groups#merge_requests') do
|
||||||
= link_to merge_requests_group_path(@group), title: 'Merge Requests' do
|
= link_to merge_requests_group_path(@group), title: 'Merge Requests' do
|
||||||
%span
|
%span
|
||||||
Merge Requests
|
|
||||||
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute
|
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute
|
||||||
%span.badge.count= number_with_delimiter(merge_requests.count)
|
%span.badge.count= number_with_delimiter(merge_requests.count)
|
||||||
|
Merge Requests
|
||||||
= nav_link(path: 'group_members#index') do
|
= nav_link(path: 'group_members#index') do
|
||||||
= link_to group_group_members_path(@group), title: 'Members' do
|
= link_to group_group_members_path(@group), title: 'Members' do
|
||||||
%span
|
%span
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
- content_for :project_javascripts do
|
- content_for :project_javascripts do
|
||||||
- project = @target_project || @project
|
- project = @target_project || @project
|
||||||
- if current_user
|
- if current_user
|
||||||
|
-# haml-lint:disable InlineJavaScript
|
||||||
:javascript
|
:javascript
|
||||||
window.uploads_path = "#{project_uploads_path(project)}";
|
window.uploads_path = "#{project_uploads_path(project)}";
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
- content_for :page_specific_javascripts do
|
- content_for :page_specific_javascripts do
|
||||||
- if @snippet && current_user
|
- if @snippet && current_user
|
||||||
|
-# haml-lint:disable InlineJavaScript
|
||||||
:javascript
|
:javascript
|
||||||
window.uploads_path = "#{upload_path('personal_snippet', id: @snippet.id)}";
|
window.uploads_path = "#{upload_path('personal_snippet', id: @snippet.id)}";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
%span.current-host
|
||||||
|
= truncate(view.hostname)
|
|
@ -1,5 +1,6 @@
|
||||||
- page_title "Personal Access Tokens"
|
- page_title "Personal Access Tokens"
|
||||||
- @content_class = "limit-container-width" unless fluid_layout
|
- @content_class = "limit-container-width" unless fluid_layout
|
||||||
|
|
||||||
= render 'profiles/head'
|
= render 'profiles/head'
|
||||||
|
|
||||||
.row.prepend-top-default
|
.row.prepend-top-default
|
||||||
|
@ -19,7 +20,7 @@
|
||||||
%h5.prepend-top-0
|
%h5.prepend-top-0
|
||||||
Your New Personal Access Token
|
Your New Personal Access Token
|
||||||
.form-group
|
.form-group
|
||||||
= text_field_tag 'created-personal-access-token', flash[:personal_access_token], readonly: true, class: "form-control", 'aria-describedby' => "created-personal-access-token-help-block"
|
= text_field_tag 'created-personal-access-token', flash[:personal_access_token], readonly: true, class: "form-control js-select-on-focus", 'aria-describedby' => "created-personal-access-token-help-block"
|
||||||
= clipboard_button(text: flash[:personal_access_token], title: "Copy personal access token to clipboard", placement: "left")
|
= clipboard_button(text: flash[:personal_access_token], title: "Copy personal access token to clipboard", placement: "left")
|
||||||
%span#created-personal-access-token-help-block.help-block.text-danger Make sure you save it - you won't be able to access it again.
|
%span#created-personal-access-token-help-block.help-block.text-danger Make sure you save it - you won't be able to access it again.
|
||||||
|
|
||||||
|
@ -28,8 +29,3 @@
|
||||||
= render "shared/personal_access_tokens_form", path: profile_personal_access_tokens_path, impersonation: false, token: @personal_access_token, scopes: @scopes
|
= render "shared/personal_access_tokens_form", path: profile_personal_access_tokens_path, impersonation: false, token: @personal_access_token, scopes: @scopes
|
||||||
|
|
||||||
= render "shared/personal_access_tokens_table", impersonation: false, active_tokens: @active_personal_access_tokens, inactive_tokens: @inactive_personal_access_tokens
|
= render "shared/personal_access_tokens_table", impersonation: false, active_tokens: @active_personal_access_tokens, inactive_tokens: @inactive_personal_access_tokens
|
||||||
|
|
||||||
:javascript
|
|
||||||
$("#created-personal-access-token").click(function() {
|
|
||||||
this.select();
|
|
||||||
});
|
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
|
|
||||||
= render 'profiles/head'
|
= render 'profiles/head'
|
||||||
|
|
||||||
- if inject_u2f_api?
|
- content_for :page_specific_javascripts do
|
||||||
- content_for :page_specific_javascripts do
|
- if inject_u2f_api?
|
||||||
= page_specific_javascript_bundle_tag('u2f')
|
= page_specific_javascript_bundle_tag('u2f')
|
||||||
|
= page_specific_javascript_bundle_tag('two_factor_auth')
|
||||||
|
|
||||||
.row.prepend-top-default
|
.js-two-factor-auth{ 'data-two-factor-skippable' => "#{two_factor_skippable?}", 'data-two_factor_skip_url' => skip_profile_two_factor_auth_path }
|
||||||
|
.row.prepend-top-default
|
||||||
.col-lg-4
|
.col-lg-4
|
||||||
%h4.prepend-top-0
|
%h4.prepend-top-0
|
||||||
Register Two-Factor Authentication App
|
Register Two-Factor Authentication App
|
||||||
|
@ -51,10 +53,9 @@
|
||||||
.prepend-top-default
|
.prepend-top-default
|
||||||
= submit_tag 'Register with two-factor app', class: 'btn btn-success'
|
= submit_tag 'Register with two-factor app', class: 'btn btn-success'
|
||||||
|
|
||||||
%hr
|
%hr
|
||||||
|
|
||||||
.row.prepend-top-default
|
|
||||||
|
|
||||||
|
.row.prepend-top-default
|
||||||
.col-lg-4
|
.col-lg-4
|
||||||
%h4.prepend-top-0
|
%h4.prepend-top-0
|
||||||
Register Universal Two-Factor (U2F) Device
|
Register Universal Two-Factor (U2F) Device
|
||||||
|
@ -95,9 +96,3 @@
|
||||||
- else
|
- else
|
||||||
.settings-message.text-center
|
.settings-message.text-center
|
||||||
You don't have any U2F devices registered yet.
|
You don't have any U2F devices registered yet.
|
||||||
|
|
||||||
|
|
||||||
- if two_factor_skippable?
|
|
||||||
:javascript
|
|
||||||
var button = "<a class='btn btn-xs btn-warning pull-right' data-method='patch' href='#{skip_profile_two_factor_auth_path}'>Configure it later</a>";
|
|
||||||
$(".flash-alert").append(button);
|
|
||||||
|
|
|
@ -8,9 +8,3 @@
|
||||||
|
|
||||||
.content_list.project-activity{ :"data-href" => activity_project_path(@project) }
|
.content_list.project-activity{ :"data-href" => activity_project_path(@project) }
|
||||||
= spinner
|
= spinner
|
||||||
|
|
||||||
:javascript
|
|
||||||
var activity = new gl.Activities();
|
|
||||||
$(document).on('page:restore', function (event) {
|
|
||||||
activity.reloadActivities()
|
|
||||||
})
|
|
||||||
|
|
|
@ -20,6 +20,3 @@
|
||||||
- unless can?(current_user, :push_code, @project)
|
- unless can?(current_user, :push_code, @project)
|
||||||
.inline.prepend-left-10
|
.inline.prepend-left-10
|
||||||
= commit_in_fork_help
|
= commit_in_fork_help
|
||||||
|
|
||||||
:javascript
|
|
||||||
new NewCommitForm($('.js-create-dir-form'))
|
|
||||||
|
|
|
@ -13,6 +13,3 @@
|
||||||
.col-sm-offset-2.col-sm-10
|
.col-sm-offset-2.col-sm-10
|
||||||
= button_tag 'Delete file', class: 'btn btn-remove btn-remove-file'
|
= button_tag 'Delete file', class: 'btn btn-remove btn-remove-file'
|
||||||
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
|
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
|
||||||
|
|
||||||
:javascript
|
|
||||||
new NewCommitForm($('.js-delete-blob-form'))
|
|
||||||
|
|
|
@ -28,8 +28,4 @@
|
||||||
.form-actions
|
.form-actions
|
||||||
= button_tag 'Create branch', class: 'btn btn-create', tabindex: 3
|
= button_tag 'Create branch', class: 'btn btn-create', tabindex: 3
|
||||||
= link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
|
= link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
|
||||||
|
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
|
||||||
:javascript
|
|
||||||
var availableRefs = #{@project.repository.ref_names.to_json};
|
|
||||||
|
|
||||||
new NewBranchForm($('.js-create-branch-form'), availableRefs)
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.page-content-header
|
.page-content-header.js-commit-box{ 'data-commit-path' => branches_project_commit_path(@project, @commit.id) }
|
||||||
.header-main-content
|
.header-main-content
|
||||||
= render partial: 'signature', object: @commit.signature
|
= render partial: 'signature', object: @commit.signature
|
||||||
%strong
|
%strong
|
||||||
|
@ -79,6 +79,3 @@
|
||||||
= render 'shared/mini_pipeline_graph', pipeline: last_pipeline, klass: 'js-commit-pipeline-graph'
|
= render 'shared/mini_pipeline_graph', pipeline: last_pipeline, klass: 'js-commit-pipeline-graph'
|
||||||
in
|
in
|
||||||
= time_interval_in_words last_pipeline.duration
|
= time_interval_in_words last_pipeline.duration
|
||||||
|
|
||||||
:javascript
|
|
||||||
$(".commit-info.branches").load("#{branches_project_commit_path(@project, @commit.id)}");
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- notes = commit.notes
|
- notes = commit.notes
|
||||||
- note_count = notes.user.count
|
- note_count = notes.user.count
|
||||||
|
|
||||||
- cache_key = [project.path_with_namespace, commit.id, current_application_settings, note_count, @path.presence, current_controller?(:commits)]
|
- cache_key = [project.full_path, commit.id, current_application_settings, note_count, @path.presence, current_controller?(:commits)]
|
||||||
- cache_key.push(commit.status(ref)) if commit.status(ref)
|
- cache_key.push(commit.status(ref)) if commit.status(ref)
|
||||||
|
|
||||||
= cache(cache_key, expires_in: 1.day) do
|
= cache(cache_key, expires_in: 1.day) do
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
= content_for :sub_nav do
|
= content_for :sub_nav do
|
||||||
= render "head"
|
= render "head"
|
||||||
|
|
||||||
%div{ class: container_class }
|
.js-project-commits-show{ 'data-commits-limit' => @limit }
|
||||||
|
%div{ class: container_class }
|
||||||
.tree-holder
|
.tree-holder
|
||||||
.nav-block
|
.nav-block
|
||||||
.tree-ref-container
|
.tree-ref-container
|
||||||
|
@ -39,6 +40,3 @@
|
||||||
%ol#commits-list.list-unstyled.content_list
|
%ol#commits-list.list-unstyled.content_list
|
||||||
= render 'commits', project: @project, ref: @ref
|
= render 'commits', project: @project, ref: @ref
|
||||||
= spinner
|
= spinner
|
||||||
|
|
||||||
:javascript
|
|
||||||
CommitsList.init(#{@limit});
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
- page_title "Find File", @ref
|
- page_title "Find File", @ref
|
||||||
= render "projects/commits/head"
|
= render "projects/commits/head"
|
||||||
|
|
||||||
.file-finder-holder.tree-holder.clearfix
|
.file-finder-holder.tree-holder.clearfix.js-file-finder{ 'data-file-find-url': "#{escape_javascript(project_files_path(@project, @ref, @options.merge(format: :json)))}", 'data-find-tree-url': escape_javascript(project_tree_path(@project, @ref)), 'data-blob-url-template': escape_javascript(project_blob_path(@project, @id || @commit.id)) }
|
||||||
.nav-block
|
.nav-block
|
||||||
.tree-ref-holder
|
.tree-ref-holder
|
||||||
= render 'shared/ref_switcher', destination: 'find_file', path: @path
|
= render 'shared/ref_switcher', destination: 'find_file', path: @path
|
||||||
|
@ -17,11 +17,3 @@
|
||||||
%table.table.files-slider{ class: "table_#{@hex_path} tree-table table-striped" }
|
%table.table.files-slider{ class: "table_#{@hex_path} tree-table table-striped" }
|
||||||
%tbody
|
%tbody
|
||||||
= spinner nil, true
|
= spinner nil, true
|
||||||
|
|
||||||
:javascript
|
|
||||||
var projectFindFile = new ProjectFindFile($(".file-finder-holder"), {
|
|
||||||
url: "#{escape_javascript(project_files_path(@project, @ref, @options.merge(format: :json)))}",
|
|
||||||
treeUrl: "#{escape_javascript(project_tree_path(@project, @ref))}",
|
|
||||||
blobUrlTemplate: "#{escape_javascript(project_blob_path(@project, @id || @commit.id))}"
|
|
||||||
});
|
|
||||||
new ShortcutsFindFile(projectFindFile);
|
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
- if show_new_nav?
|
- if show_new_nav?
|
||||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||||
- content_for :page_specific_javascripts do
|
- content_for :page_specific_javascripts do
|
||||||
= page_specific_javascript_bundle_tag('common_d3')
|
= webpack_bundle_tag('common_d3')
|
||||||
= page_specific_javascript_bundle_tag('graphs')
|
= webpack_bundle_tag('graphs')
|
||||||
|
= webpack_bundle_tag('graphs_charts')
|
||||||
= render "projects/commits/head"
|
= render "projects/commits/head"
|
||||||
|
|
||||||
.repo-charts{ class: container_class }
|
.repo-charts{ class: container_class }
|
||||||
|
@ -75,55 +76,10 @@
|
||||||
Commits per day hour (UTC)
|
Commits per day hour (UTC)
|
||||||
%canvas#hour-chart
|
%canvas#hour-chart
|
||||||
|
|
||||||
:javascript
|
%script#projectChartData{ type: "application/json" }
|
||||||
var responsiveChart = function (selector, data) {
|
- projectChartData = {};
|
||||||
var options = { "scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2, maintainAspectRatio: false };
|
- projectChartData['hour'] = { 'keys' => @commits_per_time.keys, 'values' => @commits_per_time.values }
|
||||||
// get selector by context
|
- projectChartData['weekDays'] = { 'keys' => @commits_per_week_days.keys, 'values' => @commits_per_week_days.values }
|
||||||
var ctx = selector.get(0).getContext("2d");
|
- projectChartData['month'] = { 'keys' => @commits_per_month.keys, 'values' => @commits_per_month.values }
|
||||||
// pointing parent container to make chart.js inherit its width
|
- projectChartData['languages'] = @languages
|
||||||
var container = $(selector).parent();
|
= projectChartData.to_json.html_safe
|
||||||
var generateChart = function() {
|
|
||||||
selector.attr('width', $(container).width());
|
|
||||||
if (window.innerWidth < 768) {
|
|
||||||
// Scale fonts if window width lower than 768px (iPad portrait)
|
|
||||||
options.scaleFontSize = 8
|
|
||||||
}
|
|
||||||
return new Chart(ctx).Bar(data, options);
|
|
||||||
};
|
|
||||||
// enabling auto-resizing
|
|
||||||
$(window).resize(generateChart);
|
|
||||||
return generateChart();
|
|
||||||
};
|
|
||||||
|
|
||||||
var chartData = function (keys, values) {
|
|
||||||
var data = {
|
|
||||||
labels : keys,
|
|
||||||
datasets : [{
|
|
||||||
fillColor : "rgba(220,220,220,0.5)",
|
|
||||||
strokeColor : "rgba(220,220,220,1)",
|
|
||||||
barStrokeWidth: 1,
|
|
||||||
barValueSpacing: 1,
|
|
||||||
barDatasetSpacing: 1,
|
|
||||||
data : values
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
var hourData = chartData(#{@commits_per_time.keys.to_json}, #{@commits_per_time.values.to_json});
|
|
||||||
responsiveChart($('#hour-chart'), hourData);
|
|
||||||
|
|
||||||
var dayData = chartData(#{@commits_per_week_days.keys.to_json}, #{@commits_per_week_days.values.to_json});
|
|
||||||
responsiveChart($('#weekday-chart'), dayData);
|
|
||||||
|
|
||||||
var monthData = chartData(#{@commits_per_month.keys.to_json}, #{@commits_per_month.values.to_json});
|
|
||||||
responsiveChart($('#month-chart'), monthData);
|
|
||||||
|
|
||||||
var data = #{@languages.to_json};
|
|
||||||
var ctx = $("#languages-chart").get(0).getContext("2d");
|
|
||||||
var options = {
|
|
||||||
scaleOverlay: true,
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false
|
|
||||||
}
|
|
||||||
var myPieChart = new Chart(ctx).Pie(data, options);
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- page_title "Contributors"
|
- page_title "Contributors"
|
||||||
- content_for :page_specific_javascripts do
|
- content_for :page_specific_javascripts do
|
||||||
= page_specific_javascript_bundle_tag('common_d3')
|
= webpack_bundle_tag('common_d3')
|
||||||
= page_specific_javascript_bundle_tag('graphs')
|
= webpack_bundle_tag('graphs')
|
||||||
|
= webpack_bundle_tag('graphs_show')
|
||||||
|
|
||||||
- if show_new_nav?
|
- if show_new_nav?
|
||||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||||
|
|
||||||
= render 'projects/commits/head'
|
= render 'projects/commits/head'
|
||||||
|
|
||||||
%div{ class: container_class }
|
.js-graphs-show{ class: container_class, 'data-project-graph-path': project_graph_path(@project, current_ref, format: :json) }
|
||||||
.sub-header-block
|
.sub-header-block
|
||||||
.tree-ref-holder
|
.tree-ref-holder
|
||||||
= render 'shared/ref_switcher', destination: 'graphs'
|
= render 'shared/ref_switcher', destination: 'graphs'
|
||||||
|
@ -33,24 +34,3 @@
|
||||||
#contributors-master
|
#contributors-master
|
||||||
#contributors.clearfix
|
#contributors.clearfix
|
||||||
%ol.contributors-list.clearfix
|
%ol.contributors-list.clearfix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:javascript
|
|
||||||
$.ajax({
|
|
||||||
type: "GET",
|
|
||||||
url: "#{project_graph_path(@project, current_ref, format: :json)}",
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data) {
|
|
||||||
var graph = new ContributorsStatGraph();
|
|
||||||
graph.init(data);
|
|
||||||
|
|
||||||
$("#brush_change").change(function(){
|
|
||||||
graph.change_date_header();
|
|
||||||
graph.redraw_authors();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".stat-graph").fadeIn();
|
|
||||||
$(".loading-graph").hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -10,5 +10,3 @@
|
||||||
- if @project.external_import?
|
- if @project.external_import?
|
||||||
%p.monospace git clone --bare #{@project.safe_import_url}
|
%p.monospace git clone --bare #{@project.safe_import_url}
|
||||||
%p Please wait while we import the repository for you. Refresh at will.
|
%p Please wait while we import the repository for you. Refresh at will.
|
||||||
:javascript
|
|
||||||
new ProjectImport();
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
Suggestions:
|
Suggestions:
|
||||||
%code= 'gitlab'
|
%code= 'gitlab'
|
||||||
%code= @project.path # Path contains no spaces, but dashes
|
%code= @project.path # Path contains no spaces, but dashes
|
||||||
%code= @project.path_with_namespace
|
%code= @project.full_path
|
||||||
%p
|
%p
|
||||||
Reserved:
|
Reserved:
|
||||||
= link_to 'https://docs.mattermost.com/help/messaging/executing-commands.html#built-in-commands', target: '__blank' do
|
= link_to 'https://docs.mattermost.com/help/messaging/executing-commands.html#built-in-commands', target: '__blank' do
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
- projects = target_projects(@project)
|
- projects = target_projects(@project)
|
||||||
.merge-request-select.dropdown
|
.merge-request-select.dropdown
|
||||||
= f.hidden_field :target_project_id
|
= f.hidden_field :target_project_id
|
||||||
= dropdown_toggle f.object.target_project.path_with_namespace, { toggle: "dropdown", field_name: "#{f.object_name}[target_project_id]", disabled: @merge_request.persisted? }, { toggle_class: "js-compare-dropdown js-target-project" }
|
= dropdown_toggle f.object.target_project.full_path, { toggle: "dropdown", field_name: "#{f.object_name}[target_project_id]", disabled: @merge_request.persisted? }, { toggle_class: "js-compare-dropdown js-target-project" }
|
||||||
.dropdown-menu.dropdown-menu-selectable.dropdown-target-project
|
.dropdown-menu.dropdown-menu-selectable.dropdown-target-project
|
||||||
= dropdown_title("Select target project")
|
= dropdown_title("Select target project")
|
||||||
= dropdown_filter("Search projects")
|
= dropdown_filter("Search projects")
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
- projects.each do |project|
|
- projects.each do |project|
|
||||||
%li
|
%li
|
||||||
%a{ href: "#", class: "#{('is-active' if selected == project.id)}", data: { id: project.id } }
|
%a{ href: "#", class: "#{('is-active' if selected == project.id)}", data: { id: project.id } }
|
||||||
= project.path_with_namespace
|
= project.full_path
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue