Commit 635ebac6 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' into mwessel/gitlab-ce-configure-protection

parents ac7af45d 704922c8
Style/AccessModifierIndentation:
Description: Check indentation of private/protected visibility modifiers.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected'
Enabled: true
Style/AccessorMethodName:
Description: Check the naming of accessor methods for get_/set_.
Enabled: false
Style/Alias:
Description: 'Use alias_method instead of alias.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#alias-method'
Enabled: true
Style/AlignArray:
Description: >-
Align the elements of an array literal if they span more than
one line.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays'
Enabled: true
Style/AlignHash:
Description: >-
Align the elements of a hash literal if they span more than
one line.
Enabled: true
Style/AlignParameters:
Description: >-
Align the parameters of a method call if they span more
than one line.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent'
Enabled: false
Style/AndOr:
Description: 'Use &&/|| instead of and/or.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-and-or-or'
Enabled: false
Style/ArrayJoin:
Description: 'Use Array#join instead of Array#*.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#array-join'
Enabled: false
Style/AsciiComments:
Description: 'Use only ascii symbols in comments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments'
Enabled: true
Style/AsciiIdentifiers:
Description: 'Use only ascii symbols in identifiers.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-identifiers'
Enabled: true
Style/Attr:
Description: 'Checks for uses of Module#attr.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr'
Enabled: false
Style/BeginBlock:
Description: 'Avoid the use of BEGIN blocks.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-BEGIN-blocks'
Enabled: true
Style/BarePercentLiterals:
Description: 'Checks if usage of %() or %Q() matches configuration.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q-shorthand'
Enabled: false
Style/BlockComments:
Description: 'Do not use block comments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-block-comments'
Enabled: false
Style/BlockEndNewline:
Description: 'Put end statement of multiline block on its own line.'
Enabled: true
Style/Blocks:
Description: >-
Avoid using {...} for multi-line blocks (multiline chaining is
always ugly).
Prefer {...} over do...end for single-line blocks.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks'
Enabled: true
Style/BracesAroundHashParameters:
Description: 'Enforce braces style around hash parameters.'
Enabled: false
Style/CaseEquality:
Description: 'Avoid explicit use of the case equality operator(===).'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-case-equality'
Enabled: false
Style/CaseIndentation:
Description: 'Indentation of when in a case/when/[else/]end.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-when-to-case'
Enabled: true
Style/CharacterLiteral:
Description: 'Checks for uses of character literals.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-character-literals'
Enabled: true
Style/ClassAndModuleCamelCase:
Description: 'Use CamelCase for classes and modules.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#camelcase-classes'
Enabled: true
Style/ClassAndModuleChildren:
Description: 'Checks style of children classes and modules.'
Enabled: false
Style/ClassCheck:
Description: 'Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.'
Enabled: false
Style/ClassMethods:
Description: 'Use self when defining module/class methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#def-self-singletons'
Enabled: false
Style/ClassVars:
Description: 'Avoid the use of class variables.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-class-vars'
Enabled: true
Style/ColonMethodCall:
Description: 'Do not use :: for method call.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#double-colons'
Enabled: false
Style/CommentAnnotation:
Description: >-
Checks formatting of special comments
(TODO, FIXME, OPTIMIZE, HACK, REVIEW).
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#annotate-keywords'
Enabled: false
Style/CommentIndentation:
Description: 'Indentation of comments.'
Enabled: true
Style/ConstantName:
Description: 'Constants should use SCREAMING_SNAKE_CASE.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#screaming-snake-case'
Enabled: true
Style/DefWithParentheses:
Description: 'Use def with parentheses when there are arguments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
Enabled: false
Style/DeprecatedHashMethods:
Description: 'Checks for use of deprecated Hash methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-key'
Enabled: false
Style/Documentation:
Description: 'Document classes and non-namespace modules.'
Enabled: false
Style/DotPosition:
Description: 'Checks the position of the dot in multi-line method calls.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains'
Enabled: false
Style/DoubleNegation:
Description: 'Checks for uses of double negation (!!).'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-bang-bang'
Enabled: false
Style/EachWithObject:
Description: 'Prefer `each_with_object` over `inject` or `reduce`.'
Enabled: false
Style/ElseAlignment:
Description: 'Align elses and elsifs correctly.'
Enabled: true
Style/EmptyElse:
Description: 'Avoid empty else-clauses.'
Enabled: false
Style/EmptyLineBetweenDefs:
Description: 'Use empty lines between defs.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods'
Enabled: false
Style/EmptyLines:
Description: "Don't use several empty lines in a row."
Enabled: false
Style/EmptyLinesAroundAccessModifier:
Description: "Keep blank lines around access modifiers."
Enabled: false
Style/EmptyLinesAroundBlockBody:
Description: "Keeps track of empty lines around block bodies."
Enabled: false
Style/EmptyLinesAroundClassBody:
Description: "Keeps track of empty lines around class bodies."
Enabled: false
Style/EmptyLinesAroundModuleBody:
Description: "Keeps track of empty lines around module bodies."
Enabled: false
Style/EmptyLinesAroundMethodBody:
Description: "Keeps track of empty lines around method bodies."
Enabled: false
Style/EmptyLiteral:
Description: 'Prefer literals to Array.new/Hash.new/String.new.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#literal-array-hash'
Enabled: false
Style/EndBlock:
Description: 'Avoid the use of END blocks.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-END-blocks'
Enabled: false
Style/EndOfLine:
Description: 'Use Unix-style line endings.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#crlf'
Enabled: false
Style/EvenOdd:
Description: 'Favor the use of Fixnum#even? && Fixnum#odd?'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods'
Enabled: false
Style/FileName:
Description: 'Use snake_case for source file names.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files'
Enabled: false
Style/FlipFlop:
Description: 'Checks for flip flops'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-flip-flops'
Enabled: false
Style/For:
Description: 'Checks use of for or each in multiline loops.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-for-loops'
Enabled: false
Style/FormatString:
Description: 'Enforce the use of Kernel#sprintf, Kernel#format or String#%.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#sprintf'
Enabled: false
Style/GlobalVars:
Description: 'Do not introduce global variables.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#instance-vars'
Enabled: false
Style/GuardClause:
Description: 'Check for conditionals that can be replaced with guard clauses'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals'
Enabled: false
Style/HashSyntax:
Description: >-
Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax
{ :a => 1, :b => 2 }.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-literals'
Enabled: true
Style/IfUnlessModifier:
Description: >-
Favor modifier if/unless usage when you have a
single-line body.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier'
Enabled: false
Style/IfWithSemicolon:
Description: 'Do not use if x; .... Use the ternary operator instead.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs'
Enabled: false
Style/IndentationConsistency:
Description: 'Keep indentation straight.'
Enabled: true
Style/IndentationWidth:
Description: 'Use 2 spaces for indentation.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation'
Enabled: true
Style/IndentArray:
Description: >-
Checks the indentation of the first element in an array
literal.
Enabled: false
Style/IndentHash:
Description: 'Checks the indentation of the first key in a hash literal.'
Enabled: false
Style/InfiniteLoop:
Description: 'Use Kernel#loop for infinite loops.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#infinite-loop'
Enabled: false
Style/Lambda:
Description: 'Use the new lambda literal syntax for single-line blocks.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#lambda-multi-line'
Enabled: false
Style/LambdaCall:
Description: 'Use lambda.call(...) instead of lambda.(...).'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc-call'
Enabled: false
Style/LeadingCommentSpace:
Description: 'Comments should start with a space.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-space'
Enabled: false
Style/LineEndConcatenation:
Description: >-
Use \ instead of + or << to concatenate two string literals at
line end.
Enabled: false
Style/MethodCallParentheses:
Description: 'Do not use parentheses for method calls with no arguments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
Enabled: false
Style/MethodDefParentheses:
Description: >-
Checks if the method definitions have or don't have
parentheses.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
Enabled: false
Style/MethodName:
Description: 'Use the configured style when naming methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars'
Enabled: false
Style/ModuleFunction:
Description: 'Checks for usage of `extend self` in modules.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#module-function'
Enabled: false
Style/MultilineBlockChain:
Description: 'Avoid multi-line chains of blocks.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks'
Enabled: false
Style/MultilineBlockLayout:
Description: 'Ensures newlines after multiline block do statements.'
Enabled: false
Style/MultilineIfThen:
Description: 'Do not use then for multi-line if/unless.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-then'
Enabled: false
Style/MultilineOperationIndentation:
Description: >-
Checks indentation of binary operations that span more than
one line.
Enabled: false
Style/MultilineTernaryOperator:
Description: >-
Avoid multi-line ?: (the ternary operator);
use if/unless instead.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-multiline-ternary'
Enabled: false
Style/NegatedIf:
Description: >-
Favor unless over if for negative conditions
(or control flow or).
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#unless-for-negatives'
Enabled: false
Style/NegatedWhile:
Description: 'Favor until over while for negative conditions.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#until-for-negatives'
Enabled: false
Style/NestedTernaryOperator:
Description: 'Use one expression per branch in a ternary operator.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-ternary'
Enabled: false
Style/Next:
Description: 'Use `next` to skip iteration instead of a condition at the end.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals'
Enabled: false
Style/NilComparison:
Description: 'Prefer x.nil? to x == nil.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods'
Enabled: false
Style/NonNilCheck:
Description: 'Checks for redundant nil checks.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks'
Enabled: false
Style/Not:
Description: 'Use ! instead of not.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bang-not-not'
Enabled: false
Style/NumericLiterals:
Description: >-
Add underscores to large numeric literals to improve their
readability.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics'
Enabled: false
Style/OneLineConditional:
Description: >-
Favor the ternary operator(?:) over
if/then/else/end constructs.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator'
Enabled: false
Style/OpMethod:
Description: 'When defining binary operators, name the argument other.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg'
Enabled: false
Style/ParenthesesAroundCondition:
Description: >-
Don't use parentheses around the condition of an
if/unless/while.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-parens-if'
Enabled: false
Style/PercentLiteralDelimiters:
Description: 'Use `%`-literal delimiters consistently'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-literal-braces'
Enabled: false
Style/PercentQLiterals:
Description: 'Checks if uses of %Q/%q match the configured preference.'
Enabled: false
Style/PerlBackrefs:
Description: 'Avoid Perl-style regex back references.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers'
Enabled: false
Style/PredicateName:
Description: 'Check the names of predicate methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark'
Enabled: false
Style/Proc:
Description: 'Use proc instead of Proc.new.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc'
Enabled: false
Style/RaiseArgs:
Description: 'Checks the arguments passed to raise/fail.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#exception-class-messages'
Enabled: false
Style/RedundantBegin:
Description: "Don't use begin blocks when they are not needed."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#begin-implicit'
Enabled: false
Style/RedundantException:
Description: "Checks for an obsolete RuntimeException argument in raise/fail."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror'
Enabled: false
Style/RedundantReturn:
Description: "Don't use return where it's not required."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-return'
Enabled: false
Style/RedundantSelf:
Description: "Don't use self where it's not needed."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-self-unless-required'
Enabled: false
Style/RegexpLiteral:
Description: >-
Use %r for regular expressions matching more than
`MaxSlashes` '/' characters.
Use %r only for regular expressions matching more than
`MaxSlashes` '/' character.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r'
Enabled: false
Style/RescueModifier:
Description: 'Avoid using rescue in its modifier form.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers'
Enabled: false
Style/SelfAssignment:
Description: >-
Checks for places where self-assignment shorthand should have
been used.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#self-assignment'
Enabled: false
Style/Semicolon:
Description: "Don't use semicolons to terminate expressions."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon'
Enabled: false
Style/SignalException:
Description: 'Checks for proper usage of fail and raise.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#fail-method'
Enabled: false
Style/SingleLineBlockParams:
Description: 'Enforces the names of some block params.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#reduce-blocks'
Enabled: false
Style/SingleLineMethods:
Description: 'Avoid single-line methods.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-single-line-methods'
Enabled: false
Style/SingleSpaceBeforeFirstArg:
Description: >-
Checks that exactly one space is used between a method name
and the first argument for method calls without parentheses.
Enabled: false
Style/SpaceAfterColon:
Description: 'Use spaces after colons.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceAfterComma:
Description: 'Use spaces after commas.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceAfterControlKeyword:
Description: 'Use spaces after if/elsif/unless/while/until/case/when.'
Enabled: false
Style/SpaceAfterMethodName:
Description: >-
Do not put a space between a method name and the opening
parenthesis in a method definition.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces'
Enabled: false
Style/SpaceAfterNot:
Description: Tracks redundant space after the ! operator.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-bang'
Enabled: false
Style/SpaceAfterSemicolon:
Description: 'Use spaces after semicolons.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceBeforeBlockBraces:
Description: >-
Checks that the left block brace has or doesn't have space
before it.
Enabled: false
Style/SpaceBeforeComma:
Description: 'No spaces before commas.'
Enabled: false
Style/SpaceBeforeComment:
Description: >-
Checks for missing space between code and a comment on the
same line.
Enabled: false
Style/SpaceBeforeSemicolon:
Description: 'No spaces before semicolons.'
Enabled: false
Style/SpaceInsideBlockBraces:
Description: >-
Checks that block braces have or don't have surrounding space.
For blocks taking parameters, checks that the left brace has
or doesn't have trailing space.
Enabled: false
Style/SpaceAroundEqualsInParameterDefault:
Description: >-
Checks that the equals signs in parameter default assignments
have or don't have surrounding space depending on
configuration.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-around-equals'
Enabled: false
Style/SpaceAroundOperators:
Description: 'Use spaces around operators.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: false
Style/SpaceBeforeModifierKeyword:
Description: 'Put a space before the modifier keyword.'
Enabled: false
Style/SpaceInsideBrackets:
Description: 'No spaces after [ or before ].'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
Enabled: false
Style/SpaceInsideHashLiteralBraces:
Description: "Use spaces inside hash literal braces - or don't."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators'
Enabled: true
Style/SpaceInsideParens:
Description: 'No spaces after ( or before ).'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces'
Enabled: false
Style/SpaceInsideRangeLiteral:
Description: 'No spaces inside range literals.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals'
Enabled: false
Style/SpecialGlobalVars:
Description: 'Avoid Perl-style global variables.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms'
Enabled: false
Style/StringLiterals:
Description: 'Checks if uses of quotes match the configured preference.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals'
Enabled: false
Style/StringLiteralsInInterpolation:
Description: >-
Checks if uses of quotes inside expressions in interpolated
strings match the configured preference.
Enabled: false
Style/SymbolProc:
Description: 'Use symbols as procs instead of blocks when possible.'
Enabled: false
Style/Tab:
Description: 'No hard tabs.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation'
Enabled: false
Style/TrailingBlankLines:
Description: 'Checks trailing blank lines and final newline.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#newline-eof'
Enabled: true
Style/TrailingComma:
Description: 'Checks for trailing comma in parameter lists and literals.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
Enabled: false
Style/TrailingWhitespace:
Description: 'Avoid trailing whitespace.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace'
Enabled: false
Style/TrivialAccessors:
Description: 'Prefer attr_* methods to trivial readers/writers.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr_family'
Enabled: false
Style/UnlessElse:
Description: >-
Do not use unless with else. Rewrite these with the positive
case first.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-else-with-unless'
Enabled: false
Style/UnneededCapitalW:
Description: 'Checks for %W when interpolation is not needed.'
Enabled: false
Style/UnneededPercentQ:
Description: 'Checks for %q/%Q when single quotes or double quotes would do.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q'
Enabled: false
Style/UnneededPercentX:
Description: 'Checks for %x when `` would do.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-x'
Enabled: false
Style/VariableInterpolation:
Description: >-
Don't interpolate global, instance and class variables
directly in strings.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#curlies-interpolate'
Enabled: false
Style/VariableName:
Description: 'Use the configured style when naming variables.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars'
Enabled: false
Style/WhenThen:
Description: 'Use when x then ... for one-line cases.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#one-line-cases'
Enabled: false
Style/WhileUntilDo:
Description: 'Checks for redundant do after while or until.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-multiline-while-do'
Enabled: false
Style/WhileUntilModifier:
Description: >-
Favor modifier while/until usage when you have a
single-line body.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier'
Enabled: false
Style/WordArray:
Description: 'Use %w or %W for arrays of words.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-w'
Enabled: false
#################### Metrics ################################
Metrics/AbcSize:
Description: >-
A calculated magnitude based on number of assignments,
branches, and conditions.
Enabled: false
Metrics/BlockNesting:
Description: 'Avoid excessive block nesting'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count'
Enabled: false
Metrics/ClassLength:
Description: 'Avoid classes longer than 100 lines of code.'
Enabled: false
Metrics/CyclomaticComplexity:
Description: >-
A complexity metric that is strongly correlated to the number
of test cases needed to validate a method.
Enabled: false
Metrics/LineLength:
Description: 'Limit lines to 80 characters.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits'
Enabled: false
Metrics/MethodLength:
Description: 'Avoid methods longer than 10 lines of code.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods'
Enabled: false
Metrics/ParameterLists:
Description: 'Avoid parameter lists longer than three or four parameters.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#too-many-params'
Enabled: false
Metrics/PerceivedComplexity:
Description: >-
A complexity metric geared towards measuring complexity for a
human reader.
Enabled: false
#################### Lint ################################
### Warnings
Lint/AmbiguousOperator:
Description: >-
Checks for ambiguous operators in the first argument of a
method invocation without parentheses.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-as-args'
Enabled: false
Lint/AmbiguousRegexpLiteral:
Description: >-
Checks for ambiguous regexp literals in the first argument of
a method invocation without parenthesis.
Enabled: false
Lint/AssignmentInCondition:
Description: "Don't use assignment in conditions."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition'
Enabled: false
Lint/BlockAlignment:
Description: 'Align block ends correctly.'
Enabled: false
Lint/ConditionPosition:
Description: >-
Checks for condition placed in a confusing position relative to
the keyword.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition'
Enabled: false
Lint/Debugger:
Description: 'Check for debugger calls.'
Enabled: false
Lint/DefEndAlignment:
Description: 'Align ends corresponding to defs correctly.'
Enabled: false
Lint/DeprecatedClassMethods:
Description: 'Check for deprecated class method calls.'
Enabled: false
Lint/ElseLayout:
Description: 'Check for odd code arrangement in an else block.'
Enabled: false
Lint/EmptyEnsure:
Description: 'Checks for empty ensure block.'
Enabled: false
Lint/EmptyInterpolation:
Description: 'Checks for empty string interpolation.'
Enabled: false
Lint/EndAlignment:
Description: 'Align ends correctly.'
Enabled: false
Lint/EndInMethod:
Description: 'END blocks should not be placed inside method definitions.'
Enabled: false
Lint/EnsureReturn:
Description: 'Do not use return in an ensure block.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-return-ensure'
Enabled: false
Lint/Eval:
Description: 'The use of eval represents a serious security risk.'
Enabled: false
Lint/HandleExceptions:
Description: "Don't suppress exception."
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions'
Enabled: false
Lint/InvalidCharacterLiteral:
Description: >-
Checks for invalid character literals with a non-escaped
whitespace character.
Enabled: false
Lint/LiteralInCondition:
Description: 'Checks of literals used in conditions.'
Enabled: false
Lint/LiteralInInterpolation:
Description: 'Checks for literals used in interpolation.'
Enabled: false
Lint/Loop:
Description: >-
Use Kernel#loop with break rather than begin/end/until or
begin/end/while for post-loop tests.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#loop-with-break'
Enabled: false
Lint/ParenthesesAsGroupedExpression:
Description: >-
Checks for method calls with a space before the opening
parenthesis.
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces'
Enabled: false
Lint/RequireParentheses:
Description: >-
Use parentheses in the method call to avoid confusion
about precedence.
Enabled: false
Lint/RescueException:
Description: 'Avoid rescuing the Exception class.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-blind-rescues'
Enabled: false
Lint/ShadowingOuterLocalVariable:
Description: >-
Do not use the same name as outer local variable
for block arguments or block local variables.
Enabled: false
Lint/SpaceBeforeFirstArg:
Description: >-
Put a space between a method name and the first argument
in a method call without parentheses.
Enabled: false
Lint/StringConversionInInterpolation:
Description: 'Checks for Object#to_s usage in string interpolation.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-to-s'
Enabled: false
Lint/UnderscorePrefixedVariableName:
Description: 'Do not use prefix `_` for a variable that is used.'
Enabled: true
Lint/UnusedBlockArgument:
Description: 'Checks for unused block arguments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars'
Enabled: false
Lint/UnusedMethodArgument:
Description: 'Checks for unused method arguments.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars'
Enabled: false
Lint/UnreachableCode:
Description: 'Unreachable code.'
Enabled: false
Lint/UselessAccessModifier:
Description: 'Checks for useless access modifiers.'
Enabled: false
Lint/UselessAssignment:
Description: 'Checks for useless assignment to a local variable.'
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars'
Enabled: false
Lint/UselessComparison:
Description: 'Checks for comparison of something with itself.'
Enabled: false
Lint/UselessElseWithoutRescue:
Description: 'Checks for useless `else` in `begin..end` without `rescue`.'
Enabled: false
Lint/UselessSetterCall:
Description: 'Checks for useless setter call to a local variable.'
Enabled: false
Lint/Void:
Description: 'Possible use of operator/literal/variable in void context.'
Enabled: false
##################### Rails ##################################
Rails/ActionFilter:
Description: 'Enforces consistent use of action filter methods.'
Enabled: false
Rails/DefaultScope:
Description: 'Checks if the argument passed to default_scope is a block.'
Enabled: false
Rails/Delegate:
Description: 'Prefer delegate method for delegations.'
Enabled: false
Rails/HasAndBelongsToMany:
Description: 'Prefer has_many :through to has_and_belongs_to_many.'
Enabled: true
Rails/Output:
Description: 'Checks for calls to puts, print, etc.'
Enabled: true
Rails/ReadWriteAttribute:
Description: >-
Checks for read_attribute(:attr) and
write_attribute(:attr, val).
Enabled: false
Rails/ScopeArgs:
Description: 'Checks the arguments of ActiveRecord scopes.'
Enabled: false
Rails/Validation:
Description: 'Use validates :attribute, hash of validations.'
Enabled: false
# Exclude some of GitLab files
#
#
AllCops:
RunRailsCops: true
Exclude:
- 'spec/**/*'
- 'features/**/*'
- 'vendor/**/*'
- 'db/**/*'
- 'tmp/**/*'
- 'bin/**/*'
- 'lib/backup/**/*'
- 'lib/tasks/**/*'
- 'lib/email_validator.rb'
- 'lib/gitlab/upgrader.rb'
- 'lib/gitlab/seeder.rb'
......@@ -25,10 +25,10 @@ v 7.8.0
- Upgrade Sidekiq gem to version 3.3.0
- Stop git zombie creation during force push check
- Show success/error messages for test setting button in services
-
- Added Rubocop for code style checks
- Fix commits pagination
-
-
- Async load a branch information at the commit page
-
- Allow configuring protection of the default branch upon first push (Marco Wessel)
-
......@@ -55,15 +55,20 @@ v 7.8.0
- Add a new API function that retrieves all issues assigned to a single milestone (Justin Whear and Hannes Rosenögger)
-
-
-
-
- API: Access groups with their path (Julien Bianchi)
- Added link to milestone and keeping resource context on smaller viewports for issues and merge requests (Jason Blanchard)
-
-
- API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger)
-
-
-
- When test web hook - show error message instead of 500 error page if connection to hook url was reset
- Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov)
- Added persistent collapse button for left side nav bar (Jason Blanchard)
v 7.7.2
- Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch
- Fix issue when LDAP user can't login with existing GitLab account
v 7.7.1
- Improve mention autocomplete performance
......
......@@ -206,8 +206,6 @@ group :development do
gem 'better_errors'
gem 'binding_of_caller'
gem 'rails_best_practices'
# Docs generator
gem "sdoc"
......@@ -217,11 +215,12 @@ end
group :development, :test do
gem 'coveralls', require: false
gem 'rubocop', '0.28.0', require: false
# gem 'rails-dev-tweaks'
gem 'spinach-rails'
gem "rspec-rails"
gem "capybara", '~> 2.2.1'
gem "pry"
gem "pry-rails"
gem "awesome_print"
gem "database_cleaner"
gem "launchy"
......@@ -254,7 +253,7 @@ end
group :test do
gem "simplecov", require: false
gem "shoulda-matchers", "~> 2.1.0"
gem "shoulda-matchers", "~> 2.7.0"
gem 'email_spec'
gem "webmock"
gem 'test_after_commit'
......
......@@ -37,6 +37,9 @@ GEM
rake (>= 0.8.7)
arel (5.0.1.20140414130214)
asciidoctor (0.1.4)
ast (2.0.0)
astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0)
attr_required (1.0.0)
awesome_print (1.2.0)
axiom-types (0.0.5)
......@@ -67,8 +70,6 @@ GEM
timers (~> 4.0.0)
charlock_holmes (0.6.9.4)
cliver (0.3.2)
code_analyzer (0.4.3)
sexp_processor
coderay (1.1.0)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
......@@ -260,7 +261,7 @@ GEM
multi_xml (>= 0.5.2)
httpauth (0.2.1)
httpclient (2.5.3.3)
i18n (0.6.11)
i18n (0.7.0)
ice_nine (0.10.0)
jasmine (2.0.2)
jasmine-core (~> 2.0.0)
......@@ -279,7 +280,7 @@ GEM
turbolinks
jquery-ui-rails (4.2.1)
railties (>= 3.2.16)
json (1.8.1)
json (1.8.2)
jwt (0.1.13)
multi_json (>= 1.5)
kaminari (0.15.1)
......@@ -353,6 +354,8 @@ GEM
org-ruby (0.9.12)
rubypants (~> 0.2)
orm_adapter (0.5.0)
parser (2.2.0.2)
ast (>= 1.1, < 3.0)
pg (0.15.1)
phantomjs (1.9.2.0)
poltergeist (1.5.1)
......@@ -362,10 +365,13 @@ GEM
websocket-driver (>= 0.2.0)
polyglot (0.3.4)
posix-spawn (0.3.9)
powerpack (0.0.9)
pry (0.9.12.4)
coderay (~> 1.0)
method_source (~> 0.8)
slop (~> 3.4)
pry-rails (0.3.2)
pry (>= 0.9.10)
pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.2)
railties (>= 3.1, < 5.0)
......@@ -402,20 +408,12 @@ GEM
sprockets-rails (~> 2.0)
rails_autolink (1.1.6)
rails (> 3.1)
rails_best_practices (1.14.4)
activesupport
awesome_print
code_analyzer (>= 0.4.3)
colored
erubis
i18n
require_all
ruby-progressbar
railties (4.1.1)
actionpack (= 4.1.1)
activesupport (= 4.1.1)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.0.0)
raindrops (0.13.0)
rake (10.3.2)
raphael-rails (2.1.2)
......@@ -446,7 +444,6 @@ GEM
redis (>= 2.2)
ref (1.0.5)
request_store (1.0.5)
require_all (1.3.2)
rest-client (1.6.7)
mime-types (>= 1.16)
rinku (1.7.3)
......@@ -466,7 +463,13 @@ GEM
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
ruby-progressbar (1.2.0)
rubocop (0.28.0)
astrolabe (~> 1.3)
parser (>= 2.2.0.pre.7, < 3.0)
powerpack (~> 0.0.6)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4)
ruby-progressbar (1.7.1)
rubyntlm (0.4.0)
rubypants (0.2.0)
rugged (0.21.2)
......@@ -494,8 +497,7 @@ GEM
semantic-ui-sass (1.8.0.0)
sass (~> 3.2)
settingslogic (2.0.9)
sexp_processor (4.4.0)
shoulda-matchers (2.1.0)
shoulda-matchers (2.7.0)
activesupport (>= 3.0.0)
sidekiq (3.3.0)
celluloid (>= 0.16.0)
......@@ -518,7 +520,7 @@ GEM
slim (2.0.2)
temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1)
slop (3.4.7)
slop (3.6.0)
spinach (0.8.7)
colorize (= 0.5.8)
gherkin-ruby (>= 0.3.1)
......@@ -694,7 +696,7 @@ DEPENDENCIES
org-ruby (= 0.9.12)
pg
poltergeist (~> 1.5.1)
pry
pry-rails
quiet_assets (~> 1.0.1)
rack-attack
rack-cors
......@@ -702,7 +704,6 @@ DEPENDENCIES
rack-oauth2 (~> 1.0.5)
rails (~> 4.1.0)
rails_autolink (~> 1.1)
rails_best_practices
raphael-rails (~> 2.1.2)
rb-fsevent
rb-inotify
......@@ -711,6 +712,7 @@ DEPENDENCIES
redis-rails
request_store
rspec-rails
rubocop (= 0.28.0)
rugments
sanitize (~> 2.0)
sass-rails (~> 4.0.2)
......@@ -719,7 +721,7 @@ DEPENDENCIES
select2-rails
semantic-ui-sass (~> 1.8.0)
settingslogic
shoulda-matchers (~> 2.1.0)
shoulda-matchers (~> 2.7.0)
sidekiq (~> 3.3)
simplecov
sinatra
......
......@@ -9,8 +9,6 @@ class @calendar
cal.init
itemName: ["commit"]
data: timestamps
domain: "year"
subDomain: "month"
start: new Date(starting_year, starting_month)
domainLabelFormat: "%b"
id: "cal-heatmap"
......
......@@ -24,3 +24,18 @@ $ ->
$(window).resize ->
responsive_resize()
return
$(document).on("click", '.toggle-nav-collapse', (e) ->
e.preventDefault()
collapsed = 'page-sidebar-collapsed'
expanded = 'page-sidebar-expanded'
if $('.page-with-sidebar').hasClass(collapsed)
$('.page-with-sidebar').removeClass(collapsed).addClass(expanded)
$('.toggle-nav-collapse i').removeClass('fa-angle-right').addClass('fa-angle-left')
$.cookie("collapsed_nav", "false", { path: '/' })
else
$('.page-with-sidebar').removeClass(expanded).addClass(collapsed)
$('.toggle-nav-collapse i').removeClass('fa-angle-left').addClass('fa-angle-right')
$.cookie("collapsed_nav", "true", { path: '/' })
)
......@@ -15,6 +15,10 @@
&.s24 { margin-right: 4px; }
}
&.avatar-tile {
@include border-radius(0px);
}
&.s16 { width: 16px; height: 16px; margin-right: 6px; }
&.s24 { width: 24px; height: 24px; margin-right: 8px; }
&.s26 { width: 26px; height: 26px; margin-right: 8px; }
......
......@@ -97,7 +97,17 @@
.dash-project-avatar {
float: left;
.avatar {
margin-top: -8px;
margin-left: -15px;
@include border-radius(0px);
}
.identicon {
line-height: 40px;
}
}
.dash-project-access-icon {
float: left;
margin-right: 5px;
......
......@@ -40,12 +40,12 @@
font-size: $code_font_size;
.old {
span.idiff {
background-color: #F99;
background-color: #f8cbcb;
}
}
.new {
span.idiff {
background-color: #8F8;
background-color: #a6f3a6;
}
}
.unfold {
......@@ -84,7 +84,7 @@
padding: 0px;
border: none;
background: #F5F5F5;
color: #666;
color: rgba(0,0,0,0.3);
padding: 0px 5px;
border-right: 1px solid #ccc;
text-align: right;
......@@ -96,7 +96,7 @@
float: left;
width: 35px;
font-weight: normal;
color: #666;
color: rgba(0,0,0,0.3);
&:hover {
text-decoration: underline;
}
......@@ -114,13 +114,13 @@
.line_holder {
&.old .old_line,
&.old .new_line {
background: #FCC;
border-color: #E7BABA;
background: #ffdddd;
border-color: #f1c0c0;
}
&.new .old_line,
&.new .new_line {
background: #CFC;
border-color: #B9ECB9;
background: #dbffdb;
border-color: #c1e9c1;
}
}
.line_content {
......@@ -129,10 +129,10 @@
padding: 0px 0.5em;
border: none;
&.new {
background: #CFD;
background: #eaffea;
}
&.old {
background: #FDD;
background: #ffecec;
}
&.matched {
color: #ccc;
......
.page-with-sidebar {
background: #F5F5F5;
......@@ -101,9 +99,7 @@
}
@mixin expanded-sidebar {
.page-with-sidebar {
padding-left: $sidebar_width;
}
padding-left: $sidebar_width;
.sidebar-wrapper {
width: $sidebar_width;
......@@ -122,9 +118,7 @@
}
@mixin folded-sidebar {
.page-with-sidebar {
padding-left: 50px;
}
padding-left: 50px;
.sidebar-wrapper {
width: 52px;
......@@ -150,10 +144,33 @@
}
}
.collapse-nav a {
position: fixed;
bottom: 15px;
padding: 10px;
background: #DDD;
}
@media (max-width: $screen-md-max) {
@include folded-sidebar;
.page-sidebar-collapsed {
@include folded-sidebar;
}
.page-sidebar-expanded {
@include folded-sidebar;
}
.collapse-nav {
display: none;
}
}
@media(min-width: $screen-md-max) {
@include expanded-sidebar;
.page-sidebar-collapsed {
@include folded-sidebar;
}
.page-sidebar-expanded {
@include expanded-sidebar;
}
}
......@@ -23,7 +23,7 @@ class GithubImportsController < ApplicationController
end
def jobs
jobs = current_user.created_projects.where(import_type: "github").to_json(:only => [:id, :import_status])
jobs = current_user.created_projects.where(import_type: "github").to_json(only: [:id, :import_status])
render json: jobs
end
......@@ -58,7 +58,7 @@ class GithubImportsController < ApplicationController
def octo_client
Octokit.auto_paginate = true
@octo_client ||= Octokit::Client.new(:access_token => current_user.github_access_token)
@octo_client ||= Octokit::Client.new(access_token: current_user.github_access_token)
end
def github_auth
......
......@@ -15,4 +15,3 @@ class NamespacesController < ApplicationController
end
end
end
......@@ -59,8 +59,7 @@ class Projects::BlobController < Projects::ApplicationController
def preview
@content = params[:content]
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
include_diff_info: true)
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/))
render layout: false
......
......@@ -11,8 +11,6 @@ class Projects::CommitController < Projects::ApplicationController
return git_not_found! unless @commit
@line_notes = @project.notes.for_commit_id(commit.id).inline
@branches = @project.repository.branch_names_contains(commit.id)
@tags = @project.repository.tag_names_contains(commit.id)
@diffs = @commit.diffs
@note = @project.build_commit_note(commit)
@notes_count = @project.notes.for_commit_id(commit.id).count
......@@ -31,6 +29,12 @@ class Projects::CommitController < Projects::ApplicationController
end
end
def branches
@branches = @project.repository.branch_names_contains(commit.id)
@tags = @project.repository.tag_names_contains(commit.id)
render layout: false
end
def commit
@commit ||= @project.repository.commit(params[:id])
end
......
......@@ -35,4 +35,3 @@ class Projects::RawController < Projects::ApplicationController
end
end
end
......@@ -31,10 +31,10 @@ class Projects::RefsController < Projects::ApplicationController
def logs_tree
@offset = if params[:offset].present?
params[:offset].to_i
else
0
end
params[:offset].to_i
else
0
end
@limit = 25
......
......@@ -16,16 +16,16 @@ class Projects::WikisController < Projects::ApplicationController
if @page
render 'show'
elsif file = @project_wiki.find_file(params[:id], params[:version_id])
if file.on_disk?
send_file file.on_disk_path, disposition: 'inline'
else
send_data(
file.raw_data,
type: file.mime_type,
disposition: 'inline',
filename: file.name
)
end
if file.on_disk?
send_file file.on_disk_path, disposition: 'inline'
else
send_data(
file.raw_data,
type: file.mime_type,
disposition: 'inline',
filename: file.name
)
end
else
return render('empty') unless can?(current_user, :write_wiki, @project)
@page = WikiPage.new(@project_wiki)
......
......@@ -27,7 +27,7 @@ class SnippetsController < ApplicationController
@snippets = SnippetsFinder.new.execute(current_user, {
filter: :by_user,
user: @user,
scope: params[:scope]}).
scope: params[:scope] }).
page(params[:page]).per(20)
if @user == current_user
......
......@@ -28,13 +28,10 @@ class UsersController < ApplicationController
def calendar
visible_projects = ProjectsFinder.new.execute(current_user)
# Get user repositories and collect timestamps for commits
user_repositories = visible_projects.map(&:repository)
calendar = Gitlab::CommitsCalendar.new(user_repositories, @user)
calendar = Gitlab::CommitsCalendar.new(visible_projects, @user)
@timestamps = calendar.timestamps
@starting_year = (Time.now - 1.year).strftime("%Y")
@starting_month = Date.today.strftime("%m").to_i
@starting_year = calendar.starting_year
@starting_month = calendar.starting_month
render 'calendar', layout: false
end
......
......@@ -7,18 +7,19 @@ class NotesFinder
# Default to 0 to remain compatible with old clients
last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i)
notes = case target_type
when "commit"
project.notes.for_commit_id(target_id).not_inline.fresh
when "issue"
project.issues.find(target_id).notes.inc_author.fresh
when "merge_request"
project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
when "snippet", "project_snippet"
project.snippets.find(target_id).notes.fresh
else
raise 'invalid target_type'
end
notes =
case target_type
when "commit"
project.notes.for_commit_id(target_id).not_inline.fresh
when "issue"
project.issues.find(target_id).notes.inc_author.fresh
when "merge_request"
project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
when "snippet", "project_snippet"
project.snippets.find(target_id).notes.fresh
else
raise 'invalid target_type'
end
# Use overlapping intervals to avoid worrying about race conditions
notes.where('updated_at > ?', last_fetched_at - FETCH_OVERLAP)
......
......@@ -40,7 +40,7 @@ class SnippetsFinder
when 'are_public' then
snippets.are_public
else
snippets
snippets
end
else
snippets.public_and_internal
......
......@@ -75,10 +75,10 @@ module ApplicationHelper
options[:class] ||= ''
options[:class] << ' identicon'
bg_key = project.id % 7
style = "background-color: ##{ allowed_colors.values[bg_key] }; color: #555"
content_tag(:div, class: options[:class],
style: "background-color: ##{ allowed_colors.values[bg_key] }; color: #555") do
project.name[0, 1].upcase
content_tag(:div, class: options[:class], style: style) do
project.name[0, 1].upcase
end
end
......@@ -247,15 +247,6 @@ module ApplicationHelper
Gitlab::MarkdownHelper.gitlab_markdown?(filename)
end
def spinner(text = nil, visible = false)
css_class = 'loading'
css_class << ' hide' unless visible
content_tag :div, class: css_class do
content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text
end
end
def link_to(name = nil, options = nil, html_options = nil, &block)
begin
uri = URI(options)
......@@ -324,4 +315,12 @@ module ApplicationHelper
profile_key_path(key)
end
end
def nav_sidebar_class
if nav_menu_collapsed?
"page-sidebar-collapsed"
else
"page-sidebar-expanded"
end
end
end
......@@ -65,8 +65,7 @@ module CommitsHelper
branches.sort.map do |branch|
link_to(project_tree_path(project, branch)) do
content_tag :span, class: 'label label-gray' do
content_tag(:i, nil, class: 'fa fa-code-fork') + ' ' +
branch
icon('code-fork') + ' ' + branch
end
end
end.join(" ").html_safe
......@@ -78,8 +77,7 @@ module CommitsHelper
sorted.map do |tag|
link_to(project_commits_path(project, project.repository.find_tag(tag).name)) do
content_tag :span, class: 'label label-gray' do
content_tag(:i, nil, class: 'fa fa-tag') + ' ' +
tag
icon('tag') + ' ' + tag
end
end
end.join(" ").html_safe
......@@ -114,12 +112,13 @@ module CommitsHelper
person_name = user.nil? ? source_name : user.name
person_email = user.nil? ? source_email : user.email
text = if options[:avatar]
avatar = image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>}
else
person_name
end
text =
if options[:avatar]
avatar = image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{person_name}</span>}
else
person_name
end
options = {
class: "commit-#{options[:source]}-link has_tooltip",
......
module CompareHelper
def compare_to_mr_button?
@project.merge_requests_enabled &&
params[:from].present? &&
params[:from].present? &&
params[:to].present? &&
@repository.branch_names.include?(params[:from]) &&
@repository.branch_names.include?(params[:to]) &&
......@@ -10,6 +10,6 @@ module CompareHelper
end
def compare_mr_path
new_project_merge_request_path(@project, merge_request: {source_branch: params[:to], target_branch: params[:from]})
new_project_merge_request_path(@project, merge_request: { source_branch: params[:to], target_branch: params[:from] })
end
end
......@@ -31,7 +31,7 @@ module EmailsHelper
end
def add_email_highlight_css
Rugments::Themes::Github.render(:scope => '.highlight')
Rugments::Themes::Github.render(scope: '.highlight')
end
def color_email_diff(diffcontent)
......
......@@ -27,18 +27,17 @@ module EventsHelper
content_tag :li, class: "filter_icon #{active}" do
link_to request.path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => tooltip do
content_tag(:i, nil, class: icon_for_event[key]) +
content_tag(:span, ' ' + tooltip)
icon(icon_for_event[key]) + content_tag(:span, ' ' + tooltip)
end
end
end
def icon_for_event
{
EventFilter.push => 'fa fa-upload',
EventFilter.merged => 'fa fa-check-square-o',
EventFilter.comments => 'fa fa-comments',
EventFilter.team => 'fa fa-user',
EventFilter.push => 'upload',
EventFilter.merged => 'check-square-o',
EventFilter.comments => 'comments',
EventFilter.team => 'user',
}
end
......
module IconsHelper
# Creates an icon tag given icon name(s) and possible icon modifiers.
#
# Right now this method simply delegates directly to `fa_icon` from the
# font-awesome-rails gem, but should we ever use a different icon pack in the
# future we won't have to change hundreds of method calls.
def icon(names, options = {})
fa_icon(names, options)
end
def spinner(text = nil, visible = false)
css_class = 'loading'
css_class << ' hide' unless visible
content_tag :div, class: css_class do
icon('spinner spin') + text
end
end
def boolean_to_icon(value)
if value.to_s == "true"
content_tag :i, nil, class: 'fa fa-circle cgreen'
icon('circle', class: 'cgreen')
else
content_tag :i, nil, class: 'fa fa-power-off clgray'
icon('power-off', class: 'clgray')
end
end
def public_icon
content_tag :i, nil, class: 'fa fa-globe'
icon('globe')
end
def internal_icon
content_tag :i, nil, class: 'fa fa-shield'
icon('shield')
end
def private_icon
content_tag :i, nil, class: 'fa fa-lock'
icon('lock')
end
end
......@@ -49,7 +49,7 @@ module IssuesHelper
ts << capture_haml do
haml_tag :span do
haml_concat '&middot;'
haml_concat '<i class="fa fa-edit" title="edited"></i> '
haml_concat icon('edit', title: 'edited')
haml_concat time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_edited_ago')
end
end
......
......@@ -15,11 +15,13 @@ module MergeRequestsHelper
end
def new_mr_from_push_event(event, target_project)
return :merge_request => {
source_project_id: event.project.id,
target_project_id: target_project.id,
source_branch: event.branch_name,
target_branch: target_project.repository.root_ref
return {
merge_request: {
source_project_id: event.project.id,
target_project_id: target_project.id,
source_branch: event.branch_name,
target_branch: target_project.repository.root_ref
}
}
end
......
module NavHelper
def nav_menu_collapsed?
cookies[:collapsed_nav] == 'true'
end
end
module NotesHelper
# Helps to distinguish e.g. commit notes in mr notes list
# Helps to distinguish e.g. commit notes in mr notes list
def note_for_main_target?(note)
(@noteable.class.name == note.noteable_type && !note.for_diff_line?)
end
......@@ -22,7 +22,7 @@ module NotesHelper
ts << capture_haml do
haml_tag :span do
haml_concat '&middot;'
haml_concat '<i class="fa fa-edit" title="edited"></i> '
haml_concat icon('edit', title: 'edited')
haml_concat time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago')
end
end
......@@ -57,7 +57,7 @@ module NotesHelper
button_tag(class: 'btn add-diff-note js-add-diff-note-button',
data: data,
title: 'Add a comment to this line') do
content_tag :i, nil, class: 'fa fa-comment-o'
icon('comment-o')
end
end
......@@ -74,7 +74,7 @@ module NotesHelper
button_tag class: 'btn reply-btn js-discussion-reply-button',
data: data, title: 'Add a reply' do
link_text = content_tag(:i, nil, class: 'fa fa-comment')
link_text = icon('comment')
link_text << ' Reply'
end
end
......
module NotificationsHelper
def notification_icon(notification)
if notification.disabled?
content_tag :i, nil, class: 'fa fa-volume-off ns-mute'
icon('volume-off', class: 'ns-mute')
elsif notification.participating?
content_tag :i, nil, class: 'fa fa-volume-down ns-part'
icon('volume-down', class: 'ns-part')
elsif notification.watch?
content_tag :i, nil, class: 'fa fa-volume-up ns-watch'
icon('volume-up', class: 'ns-watch')
else
content_tag :i, nil, class: 'fa fa-circle-o ns-default'
icon('circle-o', class: 'ns-default')
end
end
end
......@@ -83,7 +83,7 @@ module ProjectsHelper
' Star'
end
content_tag('i', ' ', class: 'fa fa-star') + toggle_text
icon('star') + toggle_text
end
count_html = content_tag('span', class: 'count') do
......@@ -95,7 +95,7 @@ module ProjectsHelper
class: cls,
method: :post,
remote: true,
data: {type: 'json'}
data: { type: 'json' }
}
......@@ -107,7 +107,7 @@ module ProjectsHelper
end
def link_to_toggle_fork
out = content_tag(:i, '', class: 'fa fa-code-fork')
out = icon('code-fork')
out << ' Fork'
out << content_tag(:span, class: 'count') do
@project.forks_count.to_s
......@@ -254,4 +254,3 @@ module ProjectsHelper
enabled_oauth_providers.include?(:github)
end
end
......@@ -90,7 +90,7 @@ module TabHelper
return "active" if current_page?(controller: "/projects", action: :edit, id: @project)
if ['services', 'hooks', 'deploy_keys', 'team_members', 'protected_branches'].include? controller.controller_name
"active"
"active"
end
end
......
......@@ -38,13 +38,8 @@ module TreeHelper
#
# type - String type of the tree item; either 'folder' or 'file'
def tree_icon(type)
icon_class = if type == 'folder'
'fa fa-folder'
else
'fa fa-file-o'
end
content_tag :i, nil, class: icon_class
icon_class = type == 'folder' ? 'folder' : 'file-o'
icon(icon_class)
end
def tree_hex_class(content)
......
......@@ -15,7 +15,8 @@
#
class ApplicationSetting < ActiveRecord::Base
validates :home_page_url, allow_blank: true,
validates :home_page_url,
allow_blank: true,
format: { with: URI::regexp(%w(http https)), message: "should be a valid url" },
if: :home_page_url_column_exist
......
......@@ -88,11 +88,12 @@ class Commit
# cut off, ellipses (`&hellp;`) are prepended to the commit message.
def description
title_end = safe_message.index("\n")
@description ||= if (!title_end && safe_message.length > 100) || (title_end && title_end > 100)
"&hellip;".html_safe << safe_message[80..-1]
else
safe_message.split("\n", 2)[1].try(:chomp)
end
@description ||=
if (!title_end && safe_message.length > 100) || (title_end && title_end > 100)
"&hellip;".html_safe << safe_message[80..-1]
else
safe_message.split("\n", 2)[1].try(:chomp)
end
end
def description?
......
......@@ -44,11 +44,11 @@ class WebHook < ActiveRecord::Base
}
WebHook.post(post_url,
body: data.to_json,
headers: {"Content-Type" => "application/json"},
headers: { "Content-Type" => "application/json" },
verify: false,
basic_auth: auth)
end
rescue SocketError, Errno::ECONNREFUSED, Net::OpenTimeout => e
rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
logger.error("WebHook Error => #{e}")
false
end
......
......@@ -11,5 +11,5 @@
class Identity < ActiveRecord::Base
belongs_to :user
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider }
end
......@@ -76,7 +76,7 @@ class MergeRequest < ActiveRecord::Base
merge_request.save
end
after_transition :locked => (any - :locked) do |merge_request, transition|
after_transition locked: (any - :locked) do |merge_request, transition|
merge_request.locked_at = nil
merge_request.save
end
......
......@@ -20,15 +20,20 @@ class Namespace < ActiveRecord::Base
belongs_to :owner, class_name: "User"
validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
validates :name, presence: true, uniqueness: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.name_regex,
message: Gitlab::Regex.name_regex_message }
validates :name,
presence: true, uniqueness: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.name_regex,
message: Gitlab::Regex.name_regex_message }
validates :description, length: { within: 0..255 }
validates :path, uniqueness: { case_sensitive: false }, presence: true, length: { within: 1..255 },
exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message }
validates :path,
uniqueness: { case_sensitive: false },
presence: true,
length: { within: 1..255 },
exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message }
delegate :name, to: :owner, allow_nil: true, prefix: true
......
......@@ -14,7 +14,7 @@
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
# issues_tracker :string(255) default('gitlab'), not null
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime
......@@ -108,13 +108,17 @@ class Project < ActiveRecord::Base
# Validations
validates :creator, presence: true, on: :create
validates :description, length: { maximum: 2000 }, allow_blank: true
validates :name, presence: true, length: { within: 0..255 },
format: { with: Gitlab::Regex.project_name_regex,
message: Gitlab::Regex.project_regex_message }
validates :path, presence: true, length: { within: 0..255 },
exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message }
validates :name,
presence: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.project_name_regex,
message: Gitlab::Regex.project_regex_message }
validates :path,
presence: true,
length: { within: 0..255 },
exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message }
validates :issues_enabled, :merge_requests_enabled,
:wiki_enabled, inclusion: { in: [true, false] }
validates :visibility_level,
......@@ -156,22 +160,22 @@ class Project < ActiveRecord::Base
end
event :import_finish do
transition :started => :finished
transition started: :finished
end
event :import_fail do
transition :started => :failed
transition started: :failed
end
event :import_retry do
transition :failed => :started
transition failed: :started
end
state :started
state :finished
state :failed
after_transition any => :started, :do => :add_import_job
after_transition any => :started, do: :add_import_job
end
class << self
......
class ProjectContributions
attr_reader :project, :user
def initialize(project, user)
@project, @user = project, user
end
def commits_log
repository = project.repository
if !repository.exists? || repository.empty?
return {}
end
Rails.cache.fetch(cache_key) do
repository.commits_per_day_for_user(user)
end
end
def cache_key
"#{Date.today.to_s}-commits-log-#{project.id}-#{user.email}"
end
end
......@@ -17,13 +17,19 @@ class BambooService < CiService
prop_accessor :bamboo_url, :build_key, :username, :password
validates :bamboo_url, presence: true,
format: { with: URI::regexp }, if: :activated?
validates :bamboo_url,
presence: true,
format: { with: URI::regexp },
if: :activated?
validates :build_key, presence: true, if: :activated?
validates :username, presence: true,
if: ->(service) { service.password? }, if: :activated?
validates :password, presence: true,
if: ->(service) { service.username? }, if: :activated?
validates :username,
presence: true,
if: ->(service) { service.password? },
if: :activated?
validates :password,
presence: true,
if: ->(service) { service.username? },
if: :activated?
attr_accessor :response
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class CustomIssueTrackerService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......@@ -27,8 +41,8 @@ class CustomIssueTrackerService < IssueTrackerService
{ type: 'text', name: 'title', placeholder: title },
{ type: 'text', name: 'description', placeholder: description },
{ type: 'text', name: 'project_url', placeholder: 'Project url' },
{ type: 'text', name: 'issues_url', placeholder: 'Issue url'},
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url'}
{ type: 'text', name: 'issues_url', placeholder: 'Issue url' },
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
]
end
......
......@@ -81,7 +81,7 @@ class GitlabCiService < CiService
def fields
[
{ type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3'}
{ type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' }
]
end
end
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class GitlabIssueTrackerService < IssueTrackerService
include Rails.application.routes.url_helpers
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class IssueTrackerService < Service
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
......@@ -30,8 +44,8 @@ class IssueTrackerService < Service
[
{ type: 'text', name: 'description', placeholder: description },
{ type: 'text', name: 'project_url', placeholder: 'Project url' },
{ type: 'text', name: 'issues_url', placeholder: 'Issue url'},
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url'}
{ type: 'text', name: 'issues_url', placeholder: 'Issue url' },
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
]
end
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class JiraService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class RedmineService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
......
......@@ -17,13 +17,16 @@ class TeamcityService < CiService
prop_accessor :teamcity_url, :build_type, :username, :password
validates :teamcity_url, presence: true,
format: { with: URI::regexp }, if: :activated?
validates :teamcity_url,
presence: true,
format: { with: URI::regexp }, if: :activated?
validates :build_type, presence: true, if: :activated?
validates :username, presence: true,
if: ->(service) { service.password? }, if: :activated?
validates :password, presence: true,
if: ->(service) { service.username? }, if: :activated?
validates :username,
presence: true,
if: ->(service) { service.password? }, if: :activated?
validates :password,
presence: true,
if: ->(service) { service.username? }, if: :activated?
attr_accessor :response
......
......@@ -136,7 +136,7 @@ class ProjectWiki
def commit_details(action, message = nil, title = nil)
commit_message = message || default_message(action, title)
{email: @user.email, name: @user.name, message: commit_message}
{ email: @user.email, name: @user.name, message: commit_message }
end
def default_message(action, title)
......
......@@ -30,7 +30,7 @@ class Repository
commit = Gitlab::Git::Commit.find(raw_repository, id)
commit = Commit.new(commit) if commit
commit
rescue Rugged::OdbError => ex
rescue Rugged::OdbError
nil
end
......@@ -61,25 +61,25 @@ class Repository
end
def add_branch(branch_name, ref)
Rails.cache.delete(cache_key(:branch_names))
cache.expire(:branch_names)
gitlab_shell.add_branch(path_with_namespace, branch_name, ref)
end
def add_tag(tag_name, ref, message = nil)
Rails.cache.delete(cache_key(:tag_names))
cache.expire(:tag_names)
gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message)
end
def rm_branch(branch_name)
Rails.cache.delete(cache_key(:branch_names))
cache.expire(:branch_names)
gitlab_shell.rm_branch(path_with_namespace, branch_name)
end
def rm_tag(tag_name)
Rails.cache.delete(cache_key(:tag_names))
cache.expire(:tag_names)
gitlab_shell.rm_tag(path_with_namespace, tag_name)
end
......@@ -97,19 +97,15 @@ class Repository
end
def branch_names
Rails.cache.fetch(cache_key(:branch_names)) do
raw_repository.branch_names
end
cache.fetch(:branch_names) { raw_repository.branch_names }
end
def tag_names
Rails.cache.fetch(cache_key(:tag_names)) do
raw_repository.tag_names
end
cache.fetch(:tag_names) { raw_repository.tag_names }
end
def commit_count
Rails.cache.fetch(cache_key(:commit_count)) do
cache.fetch(:commit_count) do
begin
raw_repository.commit_count(self.root_ref)
rescue
......@@ -121,26 +117,19 @@ class Repository
# Return repo size in megabytes
# Cached in redis
def size
Rails.cache.fetch(cache_key(:size)) do
raw_repository.size
end
cache.fetch(:size) { raw_repository.size }
end
def expire_cache
Rails.cache.delete(cache_key(:size))
Rails.cache.delete(cache_key(:branch_names))
Rails.cache.delete(cache_key(:tag_names))
Rails.cache.delete(cache_key(:commit_count))
Rails.cache.delete(cache_key(:graph_log))
Rails.cache.delete(cache_key(:readme))
Rails.cache.delete(cache_key(:version))
Rails.cache.delete(cache_key(:contribution_guide))
%i(size branch_names tag_names commit_count graph_log
readme version contribution_guide).each do |key|
cache.expire(key)
end
end
def graph_log
Rails.cache.fetch(cache_key(:graph_log)) do
commits = raw_repository.log(limit: 6000,
skip_merges: true,
cache.fetch(:graph_log) do
commits = raw_repository.log(limit: 6000, skip_merges: true,
ref: root_ref)
commits.map do |rugged_commit|
......@@ -176,10 +165,6 @@ class Repository
end
end
def cache_key(type)
"#{type}:#{path_with_namespace}"
end
def method_missing(m, *args, &block)
raw_repository.send(m, *args, &block)
end
......@@ -199,13 +184,11 @@ class Repository
end
def readme
Rails.cache.fetch(cache_key(:readme)) do
tree(:head).readme
end
cache.fetch(:readme) { tree(:head).readme }
end
def version
Rails.cache.fetch(cache_key(:version)) do
cache.fetch(:version) do
tree(:head).blobs.find do |file|
file.name.downcase == 'version'
end
......@@ -213,9 +196,7 @@ class Repository
end
def contribution_guide
Rails.cache.fetch(cache_key(:contribution_guide)) do
tree(:head).contribution_guide
end
cache.fetch(:contribution_guide) { tree(:head).contribution_guide }
end
def head_commit
......@@ -351,4 +332,10 @@ class Repository
[]
end
end
private
def cache
@cache ||= RepositoryCache.new(path_with_namespace)
end
end
......@@ -29,9 +29,11 @@ class Snippet < ActiveRecord::Base
validates :author, presence: true
validates :title, presence: true, length: { within: 0..255 }
validates :file_name, presence: true, length: { within: 0..255 },
format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message }
validates :file_name,
presence: true,
length: { within: 0..255 },
format: { with: Gitlab::Regex.path_regex,
message: Gitlab::Regex.path_regex_message }
validates :content, presence: true
validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values }
......
......@@ -113,13 +113,15 @@ class User < ActiveRecord::Base
# Validations
#
validates :name, presence: true
validates :email, presence: true, email: {strict_mode: true}, uniqueness: true
validates :email, presence: true, email: { strict_mode: true }, uniqueness: true
validates :bio, length: { maximum: 255 }, allow_blank: true
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
validates :username, presence: true, uniqueness: { case_sensitive: false },
exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.username_regex,
message: Gitlab::Regex.username_regex_message }
validates :projects_limit, presence: true, numericality: { greater_than_or_equal_to: 0 }
validates :username,
presence: true,
uniqueness: { case_sensitive: false },
exclusion: { in: Gitlab::Blacklist.path },
format: { with: Gitlab::Regex.username_regex,
message: Gitlab::Regex.username_regex_message }
validates :notification_level, inclusion: { in: Notification.notification_levels }, presence: true
validate :namespace_uniq, if: ->(user) { user.username_changed? }
......
......@@ -43,7 +43,7 @@ class WikiPage
@attributes[:slug]
end
alias :to_param :slug
alias_method :to_param, :slug
# The formatted title of this page.
def title
......
......@@ -38,4 +38,4 @@ module Oauth2::AccessTokenValidationService
end
end
end
end
\ No newline at end of file
end
......@@ -14,14 +14,14 @@ module Projects
uploader.store!(image)
link = {
'alt' => File.basename(alt, '.*'),
'url' => File.join(@root_url, uploader.url)
'url' => File.join(@root_url, uploader.url)
}
else
link = nil
end
end
protected
protected
def upload_path
base_dir = FileUploader.generate_dir
......
......@@ -5,11 +5,12 @@ module Projects
end
def execute(note_type, note_id)
participating = if note_type && note_id
participants_in(note_type, note_id)
else
[]
end
participating =
if note_type && note_id
participants_in(note_type, note_id)
else
[]
end
team_members = sorted(@project.team.members)
participants = all_members + team_members + participating
participants.uniq
......
......@@ -10,7 +10,8 @@
- groups.each do |group|
%li.group-row
= link_to group_path(id: group.path), class: dom_class(group) do
= image_tag group_icon(group.path), class: "avatar s24"
.dash-project-avatar
= image_tag group_icon(group.path), class: "avatar s40"
%span.group-name.filter-title
= truncate(group.name, length: 35)
%span.arrow
......
= link_to project_path(project), class: dom_class(project) do
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s40')
.dash-project-access-icon
= visibility_level_icon(project.visibility_level)
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
%span.str-truncated
%span.namespace-name
- if project.namespace
......
......@@ -12,10 +12,10 @@
- projects.each do |project|
%li.project-row
= link_to project_path(project), class: dom_class(project) do
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s40')
.dash-project-access-icon
= visibility_level_icon(project.visibility_level)
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
%span.str-truncated
%span.project-name
= project.name
......
.dashboard
%div
= image_tag group_icon(@group.path), class: "avatar s90"
= image_tag group_icon(@group.path), class: "avatar avatar-tile s90"
.clearfix
%h2
= @group.name
......
- if nav_menu_collapsed?
= link_to icon('angle-right'), '#', class: 'toggle-nav-collapse'
- else
= link_to icon('angle-left'), '#', class: 'toggle-nav-collapse'
- if defined?(sidebar)
.page-with-sidebar
.page-with-sidebar{ class: nav_sidebar_class }
= render "layouts/broadcast"
.sidebar-wrapper
= render(sidebar)
.collapse-nav
= render partial: 'layouts/collapse_button'
.content-wrapper
.container-fluid
.content
......
......@@ -37,23 +37,8 @@
- @commit.parents.each do |parent|
= link_to parent.short_id, project_commit_path(@project, parent)
.commit-info-row
- if @branches.any?
%span
- branch = commit_default_branch(@project, @branches)
= link_to(project_tree_path(@project, branch)) do
%span.label.label-gray
%i.fa.fa-code-fork
= branch
- if @branches.any? || @tags.any?
= link_to("#", class: "js-details-expand") do
%span.label.label-gray
\...
%span.js-details-content.hide
- if @branches.any?
= commit_branches_links(@project, @branches)
- if @tags.any?
= commit_tags_links(@project, @tags)
.commit-info-row.branches
%i.fa.fa-spinner.fa-spin
.commit-box
%h3.commit-title
......@@ -61,3 +46,7 @@
- if @commit.description.present?
%pre.commit-description
= preserve(gfm(escape_once(@commit.description)))
:coffeescript
$ ->
$(".commit-info-row.branches").load("#{branches_project_commit_path(@project, @commit.id)}")
\ No newline at end of file
- if @branches.any?
%span
- branch = commit_default_branch(@project, @branches)
= link_to(project_tree_path(@project, branch)) do
%span.label.label-gray
%i.fa.fa-code-fork
= branch
- if @branches.any? || @tags.any?
= link_to("#", class: "js-details-expand") do
%span.label.label-gray
\...
%span.js-details-content.hide
- if @branches.any?
= commit_branches_links(@project, @branches)
- if @tags.any?
= commit_tags_links(@project, @tags)
\ No newline at end of file
......@@ -10,7 +10,7 @@
You can
= link_to project_new_blob_path(@project, 'master'), class: 'btn btn-new btn-lg' do
add a file
&nbsp;or push it via command line.
&nbsp;or do a push via the command line.
%h4
%strong Command line instructions
......
......@@ -13,7 +13,7 @@
= link_to_member(@project, participant, name: false, size: 24)
.voting_notes#notes= render "projects/notes/notes_with_form"
.col-md-3.hidden-sm.hidden-xs
.col-md-3
%div
.clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
......
......@@ -2,23 +2,21 @@
%div.prepend-top-20
%p
Assignee:
- if issue.assignee
= link_to_member(@project, @issue.assignee)
- else
none
- if can?(current_user, :modify_issue, @issue)
= project_users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id)
- elsif issue.assignee
= link_to_member(@project, @issue.assignee)
- else
None
%div.prepend-top-20
%p
Milestone:
- if issue.milestone
#{link_to @issue.milestone.title, project_milestone_path(@project, @issue.milestone)}
- else
none
- if can?(current_user, :modify_issue, @issue)
= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issue_context
= f.submit class: 'btn'
- elsif issue.milestone
= link_to project_milestone_path(@project, @issue.milestone) do
= @issue.milestone.title
- else
None
......@@ -3,8 +3,15 @@
:plain
$("##{dom_id(@issue)}").fadeOut();
- elsif params[:issue_context]
$('.context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}");
$('.context').effect('highlight');
- if @issue.milestone
$('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, project_milestone_path(@issue.project, @issue.milestone))}</span>")
- else
$('.milestone-nav-link').html('')
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true})
$('.edit-issue.inline-update input[type="submit"]').hide();
new ProjectUsersSelect();
new Issue();
......@@ -9,7 +9,7 @@
.col-md-9
= render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form"
.col-md-3.hidden-sm.hidden-xs
.col-md-3
.clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
......@@ -18,7 +18,7 @@
%cite.cgray
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
%hr
.votes-holder.hidden-sm.hidden-xs
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @merge_request
......
......@@ -2,22 +2,22 @@
%div.prepend-top-20
%p
Assignee:
- if @merge_request.assignee
= link_to_member(@project, @merge_request.assignee)
- else
none
- if can?(current_user, :modify_merge_request, @merge_request)
= project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id)
- elsif merge_request.assignee
= link_to_member(@project, @merge_request.assignee)
- else
None
%div.prepend-top-20
%p
Milestone:
- if @merge_request.milestone
%span.back-to-milestone
#{link_to @merge_request.milestone.title, project_milestone_path(@project, @merge_request.milestone)}
- else
none
- if can?(current_user, :modify_merge_request, @merge_request)
= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :merge_request_context
= f.submit class: 'btn'
- elsif merge_request.milestone
= link_to merge_request.milestone.title, project_milestone_path
- else
None
- if params[:merge_request_context]
$('.context').html("#{escape_javascript(render partial: 'projects/merge_requests/show/context', locals: { issue: @issue })}");
$('.context').effect('highlight');
new ProjectUsersSelect();
$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true});
merge_request = new MergeRequest();
.clearfix
- groups.each do |group|
= link_to group, class: 'profile-groups-avatars', title: group.name do
= image_tag group_icon(group.path), class: 'avatar avatar-inline s40'
= link_to group, class: 'profile-groups-avatars inline', title: group.name do
= image_tag group_icon(group.path), class: 'avatar avatar-tile s40'
%h4 Calendar:
%h4 Calendar
#cal-heatmap.calendar
:javascript
new calendar(
......
.row
.col-md-8
%h3.page-title
= image_tag avatar_icon(@user.email, 90), class: "avatar s90", alt: ''
= image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: ''
= @user.name
- if @user == current_user
.pull-right
......@@ -15,7 +15,7 @@
.clearfix
- if @groups.any?
%h4 Groups:
%h4 Groups
= render 'groups', groups: @groups
%hr
......@@ -24,7 +24,7 @@
%i.fa.fa-spinner.fa-spin
%hr
%h4
User Activity:
User Activity
- if current_user
%span.rss-icon.pull-right
......
......@@ -70,7 +70,10 @@ module Gitlab
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/api/*', headers: :any, methods: [:get, :post, :options, :put, :delete]
resource '/api/*',
headers: :any,
methods: [:get, :post, :options, :put, :delete],
expose: ['Link']
end
end
......
......@@ -149,7 +149,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s
Settings['backup'] ||= Settingslogic.new({})
Settings.backup['keep_time'] ||= 0
Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root)
Settings.backup['upload'] ||= Settingslogic.new({'remote_directory' => nil, 'connection' => nil})
Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil })
# Convert upload connection settings to use symbol keys, to make Fog happy
if Settings.backup['upload']['connection']
Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }]
......
......@@ -9,4 +9,4 @@ if Gitlab::LDAP::Config.enabled?
server = Gitlab.config.ldap.servers.values.first
alias_method server['provider_name'], :ldap
end
end
\ No newline at end of file
end
......@@ -42,11 +42,12 @@ module ActsAsTaggableOn::Taggable
elsif options.delete(:any)
# get tags, drop out if nothing returned (we need at least one)
tags = if options.delete(:wild)
ActsAsTaggableOn::Tag.named_like_any(tag_list)
else
ActsAsTaggableOn::Tag.named_any(tag_list)
end
tags =
if options.delete(:wild)
ActsAsTaggableOn::Tag.named_like_any(tag_list)
else
ActsAsTaggableOn::Tag.named_any(tag_list)
end
return empty_result unless tags.length > 0
......@@ -68,12 +69,12 @@ module ActsAsTaggableOn::Taggable
select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
if owned_by
tagging_join << " AND " +
sanitize_sql([
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
owned_by.id,
owned_by.class.base_class.to_s
])
tagging_join << " AND " +
sanitize_sql([
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
owned_by.id,
owned_by.class.base_class.to_s
])
end
joins << tagging_join
......@@ -92,12 +93,12 @@ module ActsAsTaggableOn::Taggable
tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
if owned_by
tagging_join << " AND " +
sanitize_sql([
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
owned_by.id,
owned_by.class.base_class.to_s
])
tagging_join << " AND " +
sanitize_sql([
"#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
owned_by.id,
owned_by.class.base_class.to_s
])
end
joins << tagging_join
......
......@@ -12,22 +12,30 @@ if File.exists?(aws_file)
aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required
region: AWS_CONFIG['region'], # optional, defaults to 'us-east-1'
}
config.fog_directory = AWS_CONFIG['bucket'] # required
config.fog_public = false # optional, defaults to true
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
config.fog_authenticated_url_expiration = 1 << 29 # optional time (in seconds) that authenticated urls will be valid.
# when fog_public is false and provider is AWS or Google, defaults to 600
# required
config.fog_directory = AWS_CONFIG['bucket']
# optional, defaults to true
config.fog_public = false
# optional, defaults to {}
config.fog_attributes = { 'Cache-Control'=>'max-age=315576000' }
# optional time (in seconds) that authenticated urls will be valid.
# when fog_public is false and provider is AWS or Google, defaults to 600
config.fog_authenticated_url_expiration = 1 << 29
end
# Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders
if Rails.env.test?
Fog.mock!
connection = ::Fog::Storage.new(
:aws_access_key_id => AWS_CONFIG['access_key_id'],
:aws_secret_access_key => AWS_CONFIG['secret_access_key'],
:provider => 'AWS',
:region => AWS_CONFIG['region']
aws_access_key_id: AWS_CONFIG['access_key_id'],
aws_secret_access_key: AWS_CONFIG['secret_access_key'],
provider: 'AWS',
region: AWS_CONFIG['region']
)
connection.directories.create(:key => AWS_CONFIG['bucket'])
connection.directories.create(key: AWS_CONFIG['bucket'])
end
end
......@@ -43,10 +43,10 @@ Doorkeeper.configure do
force_ssl_in_redirect_uri false
# Provide support for an owner to be assigned to each registered application (disabled by default)
# Optional parameter :confirmation => true (default false) if you want to enforce ownership of
# Optional parameter confirmation: true (default false) if you want to enforce ownership of
# a registered application
# Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
enable_application_owner :confirmation => false
enable_application_owner confirmation: false
# Define access token scopes for your provider
# For more information go to
......
......@@ -16,4 +16,4 @@ end
if File.exist?(Gitlab.config.gitlab_shell.path) && !File.exist?(gitlab_shell_symlink)
FileUtils.symlink(secret_file, gitlab_shell_symlink)
end
\ No newline at end of file
end
......@@ -3,9 +3,9 @@ require 'api/api'
Gitlab::Application.routes.draw do
use_doorkeeper do
controllers :applications => 'oauth/applications',
:authorized_applications => 'oauth/authorized_applications',
:authorizations => 'oauth/authorizations'
controllers applications: 'oauth/applications',
authorized_applications: 'oauth/authorized_applications',
authorizations: 'oauth/authorizations'
end
#
# Search
......@@ -177,7 +177,7 @@ Gitlab::Application.routes.draw do
#
# Groups Area
#
resources :groups, constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} do
resources :groups, constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } do
member do
get :issues
get :merge_requests
......@@ -215,40 +215,44 @@ Gitlab::Application.routes.draw do
scope module: :projects do
# Blob routes:
get '/new/:id', to: 'blob#new', constraints: {id: /.+/}, as: 'new_blob'
post '/create/:id', to: 'blob#create', constraints: {id: /.+/}, as: 'create_blob'
get '/edit/:id', to: 'blob#edit', constraints: {id: /.+/}, as: 'edit_blob'
put '/update/:id', to: 'blob#update', constraints: {id: /.+/}, as: 'update_blob'
post '/preview/:id', to: 'blob#preview', constraints: {id: /.+/}, as: 'preview_blob'
get '/new/:id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob'
post '/create/:id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob'
get '/edit/:id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob'
put '/update/:id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob'
post '/preview/:id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
resources :blob, only: [:show, :destroy], constraints: { id: /.+/, format: false } do
get :diff, on: :member
end
resources :raw, only: [:show], constraints: {id: /.+/}
resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
resources :raw, only: [:show], constraints: { id: /.+/ }
resources :tree, only: [:show], constraints: { id: /.+/, format: /(html|js)/ }
resource :avatar, only: [:show, :destroy]
resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
resources :commit, only: [:show], constraints: { id: /[[:alnum:]]{6,40}/ } do
get :branches, on: :member
end
resources :commits, only: [:show], constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
resources :compare, only: [:index, :create]
resources :blame, only: [:show], constraints: {id: /.+/}
resources :network, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/}
resources :graphs, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/} do
resources :blame, only: [:show], constraints: { id: /.+/ }
resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }
resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do
member do
get :commits
end
end
get '/compare/:from...:to' => 'compare#show', :as => 'compare',
:constraints => {from: /.+/, to: /.+/}
:constraints => { from: /.+/, to: /.+/ }
resources :snippets, constraints: {id: /\d+/} do
resources :snippets, constraints: { id: /\d+/ } do
member do
get 'raw'
end
end
resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-\/]+/} do
resources :wikis, only: [:show, :edit, :destroy, :create], constraints: { id: /[a-zA-Z.0-9_\-\/]+/ } do
collection do
get :pages
put ':id' => 'wikis#update'
......@@ -275,7 +279,7 @@ Gitlab::Application.routes.draw do
end
end
resources :deploy_keys, constraints: {id: /\d+/} do
resources :deploy_keys, constraints: { id: /\d+/ } do
member do
put :enable
put :disable
......@@ -294,16 +298,14 @@ Gitlab::Application.routes.draw do
member do
# tree viewer logs
get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex }
get 'logs_tree/:path' => 'refs#logs_tree',
as: :logs_file,
constraints: {
id: Gitlab::Regex.git_reference_regex,
path: /.*/
}
get 'logs_tree/:path' => 'refs#logs_tree', as: :logs_file, constraints: {
id: Gitlab::Regex.git_reference_regex,
path: /.*/
}
end
end
resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do
resources :merge_requests, constraints: { id: /\d+/ }, except: [:destroy] do
member do
get :diffs
post :automerge
......@@ -318,27 +320,27 @@ Gitlab::Application.routes.draw do
end
end
resources :hooks, only: [:index, :create, :destroy], constraints: {id: /\d+/} do
resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ } do
member do
get :test
end
end
resources :team, controller: 'team_members', only: [:index]
resources :milestones, except: [:destroy], constraints: {id: /\d+/} do
resources :milestones, except: [:destroy], constraints: { id: /\d+/ } do
member do
put :sort_issues
put :sort_merge_requests
end
end
resources :labels, constraints: {id: /\d+/} do
resources :labels, constraints: { id: /\d+/ } do
collection do
post :generate
end
end
resources :issues, constraints: {id: /\d+/}, except: [:destroy] do
resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do
collection do
post :bulk_update
end
......@@ -355,7 +357,7 @@ Gitlab::Application.routes.draw do
end
end
resources :notes, only: [:index, :create, :destroy, :update], constraints: {id: /\d+/} do
resources :notes, only: [:index, :create, :destroy, :update], constraints: { id: /\d+/ } do
member do
delete :delete_attachment
end
......@@ -364,7 +366,7 @@ Gitlab::Application.routes.draw do
end
end
get ':id' => 'namespaces#show', constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
get ':id' => 'namespaces#show', constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
root to: 'dashboard#show'
end
......@@ -20,7 +20,7 @@ GET /groups
]
```
You can search for groups by name or path with: `/groups?search=Rails`
You can search for groups by name or path, see below.
## Details of a group
......@@ -32,7 +32,7 @@ GET /groups/:id
Parameters:
- `id` (required) - The ID of a group
- `id` (required) - The ID or path of a group
## New group
......@@ -58,7 +58,7 @@ POST /groups/:id/projects/:project_id
Parameters:
- `id` (required) - The ID of a group
- `id` (required) - The ID or path of a group
- `project_id` (required) - The ID of a project
## Remove group
......@@ -71,7 +71,27 @@ DELETE /groups/:id
Parameters:
- `id` (required) - The ID of a user group
- `id` (required) - The ID or path of a user group
## Search for group
Get all groups that match your string in their name or path.
```
GET /groups?search=foobar
```
```json
[
{
"id": 1,
"name": "Foobar Group",
"path": "foo-bar",
"owner_id": 18,
"description": "An interesting group"
}
]
```
## Group members
......@@ -128,7 +148,7 @@ POST /groups/:id/members
Parameters:
- `id` (required) - The ID of a group
- `id` (required) - The ID or path of a group
- `user_id` (required) - The ID of a user to add
- `access_level` (required) - Project access level
......@@ -142,5 +162,5 @@ DELETE /groups/:id/members/:user_id
Parameters:
- `id` (required) - The ID of a user group
- `id` (required) - The ID or path of a user group
- `user_id` (required) - The ID of a group member
......@@ -278,7 +278,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
GitLab Shell is an SSH access and repository management software developed specially for GitLab.
# Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.1] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production
sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.2] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production
# By default, the gitlab-shell config is generated from your main GitLab config.
# You can review (and modify) the gitlab-shell config as follows:
......
......@@ -19,19 +19,26 @@ your repositories are located by looking at `config/gitlab.yml` under the `gitla
New folder needs to have git user ownership and read/write/execute access for git user and its group:
```
$ mkdir new_group
$ chown git:git new_group
$ chmod 770 new_group
sudo -u git mkdir /var/opt/gitlab/git-data/repositories/new_group
```
If you are using an installation from source, replace `/var/opt/gitlab/git-data`
with `/home/git`.
### Copy your bare repositories inside this newly created folder:
```
$ cp -r /old/git/foo.git/ /home/git/repositories/new_group/
sudo cp -r /old/git/foo.git /var/opt/gitlab/git-data/repositories/new_group/
# Do this once when you are done copying git repositories
sudo chown -R git:git /var/opt/gitlab/git-data/repositories/new_group/
```
`foo.git` needs to be owned by the git user and git users group.
If you are using an installation from source, replace `/var/opt/gitlab/git-data`
with `/home/git`.
### Run the command below depending on your type of installation:
#### Omnibus Installation
......
......@@ -89,6 +89,9 @@ sudo apt-get install logrotate
# Install pkg-config and cmake, which is needed for the latest versions of rugged
sudo apt-get install pkg-config cmake
# Install Kerberos header files, which are needed for GitLab EE Kerberos support
sudo apt-get install libkrb5-dev
```
## 5. Configure Redis to use sockets
......
......@@ -37,7 +37,7 @@ sudo -u git -H git checkout 7-7-stable-ee
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch
sudo -u git -H git checkout v2.4.1
sudo -u git -H git checkout v2.4.2
```
### 4. Install libs, migrations, etc.
......
......@@ -10,3 +10,4 @@
- [Migrating from SVN to GitLab](migrating_from_svn.md)
- [Project importing from GitHub to GitLab](import_projects_from_github.md)
- [Protected branches](protected_branches.md)
- [Web Editor](web_editor.md)
# GitLab Web Editor
In GitLab you can create new files and edit existing files using our web editor.
This is especially useful if you don't have access to a command line or you just want to do a quick fix.
You can easily access the web editor, depending on the context.
Let's start from newly created project.
Click on `Add a file`
to create the first file and open it in the web editor.
![web editor 1](web_editor/empty_project.png)
Fill in a file name, some content, a commit message and press the commit button.
The file will be saved to the repository.
![web editor 2](web_editor/new_file.png)
You can edit any text file in a repository by pressing the edit button, when
viewing the file.
![web editor 3](web_editor/show_file.png)
Editing a file is almost the same as creating a new file,
with as addition the ability to preview your changes in a separate tab.
![web editor 3](web_editor/edit_file.png)
......@@ -11,7 +11,7 @@ RUN apt-get update -q \
# If the Omnibus package version below is outdated please contribute a merge request to update it.
# If you run GitLab Enterprise Edition point it to a location where you have downloaded it.
RUN TMP_FILE=$(mktemp); \
wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.7.1-omnibus.5.4.1.ci-1_amd64.deb \
wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.7.2-omnibus.5.4.2.ci-1_amd64.deb \
&& dpkg -i $TMP_FILE \
&& rm -f $TMP_FILE
......
......@@ -34,7 +34,7 @@ Feature: Project Source Browse Files
Then I am redirected to the new file
And I should see its new content
@javascript
@javascript @tricky
Scenario: I can create file in empty repo
Given I own an empty project
And I visit my empty project page
......
......@@ -6,7 +6,7 @@ module API
version 'v3', using: :path
rescue_from ActiveRecord::RecordNotFound do
rack_response({'message' => '404 Not found'}.to_json, 404)
rack_response({ 'message' => '404 Not found' }.to_json, 404)
end
rescue_from :all do |exception|
......@@ -19,7 +19,7 @@ module API
message << " " << trace.join("\n ")
API.logger.add Logger::FATAL, message
rack_response({'message' => '500 Internal Server Error'}, 500)
rack_response({ 'message' => '500 Internal Server Error' }, 500)
end
format :json
......
......@@ -47,16 +47,12 @@ module APIGuard
case validate_access_token(access_token, scopes)
when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE
raise InsufficientScopeError.new(scopes)
when Oauth2::AccessTokenValidationService::EXPIRED
raise ExpiredError
when Oauth2::AccessTokenValidationService::REVOKED
raise RevokedError
when Oauth2::AccessTokenValidationService::VALID
@current_user = User.find(access_token.resource_owner_id)
end
end
end
......@@ -120,8 +116,9 @@ module APIGuard
end
def oauth2_bearer_token_error_handler
Proc.new {|e|
response = case e
Proc.new do |e|
response =
case e
when MissingTokenError
Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new
......@@ -146,11 +143,11 @@ module APIGuard
Rack::OAuth2::Server::Resource::Bearer::Forbidden.new(
:insufficient_scope,
Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION[:insufficient_scope],
{ :scope => e.scopes})
{ scope: e.scopes })
end
response.finish
}
end
end
end
......@@ -172,4 +169,4 @@ module APIGuard
@scopes = scopes
end
end
end
\ No newline at end of file
end
......@@ -55,7 +55,7 @@ module API
expose :path, :path_with_namespace
expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at
expose :namespace
expose :forked_from_project, using: Entities::ForkedFromProject, :if => lambda{ | project, options | project.forked? }
expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ | project, options | project.forked? }
end
class ProjectMember < UserBasic
......
......@@ -3,22 +3,6 @@ module API
before { authenticate! }
resource :groups do
helpers do
def find_group(id)
group = Group.find(id)
if can?(current_user, :read_group, group)
group
else
render_api_error!("403 Forbidden - #{current_user.username} lacks sufficient access to #{group.name}", 403)
end
end
def validate_access_level?(level)
Gitlab::Access.options_with_owner.values.include? level.to_i
end
end
# Get a list of group members viewable by the authenticated user.
#
# Example Request:
......
......@@ -4,22 +4,6 @@ module API
before { authenticate! }
resource :groups do
helpers do
def find_group(id)
group = Group.find(id)
if can?(current_user, :read_group, group)
group
else
render_api_error!("403 Forbidden - #{current_user.username} lacks sufficient access to #{group.name}", 403)
end
end
def validate_access_level?(level)
Gitlab::Access.options_with_owner.values.include? level.to_i
end
end
# Get a groups list
#
# Example Request:
......
......@@ -55,6 +55,21 @@ module API
end
end
def find_group(id)
begin
group = Group.find(id)
rescue ActiveRecord::RecordNotFound
group = Group.find_by!(path: id)
end
if can?(current_user, :read_group, group)
group
else
forbidden!("#{current_user.username} lacks sufficient "\
"access to #{group.name}")
end
end
def paginate(relation)
per_page = params[:per_page].to_i
paginated = relation.page(params[:page]).per(per_page)
......@@ -135,10 +150,16 @@ module API
errors
end
def validate_access_level?(level)
Gitlab::Access.options_with_owner.values.include? level.to_i
end
# error helpers
def forbidden!
render_api_error!('403 Forbidden', 403)
def forbidden!(reason = nil)
message = ['403 Forbidden']
message << " - #{reason}" if reason
render_api_error!(message.join(' '), 403)
end
def bad_request!(attribute)
......@@ -173,7 +194,7 @@ module API
end
def render_api_error!(message, status)
error!({'message' => message}, status)
error!({ 'message' => message }, status)
end
private
......
module API
# Internal access API
class Internal < Grape::API
before {
authenticate_by_gitlab_shell_token!
}
before { authenticate_by_gitlab_shell_token! }
namespace 'internal' do
# Check if git command is allowed to project
......
module API
# namespaces API
class Namespaces < Grape::API
before {
before do
authenticate!
authenticated_as_admin!
}
end
resource :namespaces do
# Get a namespaces list
......
......@@ -106,7 +106,7 @@ module API
unless team_member.nil?
team_member.destroy
else
{message: "Access revoked", id: params[:user_id].to_i}
{ message: "Access revoked", id: params[:user_id].to_i }
end
end
end
......
module API
# Hooks API
class SystemHooks < Grape::API
before {
before do
authenticate!
authenticated_as_admin!
}
end
resource :hooks do
# Get the list of system hooks
......
# Based on https://github.com/balexand/email_validator
#
#
# Extended to use only strict mode with following allowed characters:
# ' - apostrophe
#
......
......@@ -34,7 +34,7 @@ module Grack
def auth!
if @auth.provided?
return bad_request unless @auth.basic?
# Authentication with username and password
login, password = @auth.credentials
......@@ -80,11 +80,11 @@ module Grack
def authenticate_user(login, password)
user = Gitlab::Auth.new.find(login, password)
unless user
user = oauth_access_token_check(login, password)
end
return user if user.present?
# At this point, we know the credentials were wrong. We let Rack::Attack
......@@ -154,7 +154,7 @@ module Grack
end
def render_not_found
[404, {"Content-Type" => "text/plain"}, ["Not Found"]]
[404, { "Content-Type" => "text/plain" }, ["Not Found"]]
end
end
end
......@@ -9,4 +9,3 @@ module Gitlab
end
end
end
......@@ -2,15 +2,15 @@ module Gitlab
class CommitsCalendar
attr_reader :timestamps
def initialize(repositories, user)
def initialize(projects, user)
@timestamps = {}
date_timestamps = []
repositories.select(&:exists?).reject(&:empty?).each do |raw_repository|
commits_log = raw_repository.commits_per_day_for_user(user)
date_timestamps << commits_log
projects.reject(&:forked?).each do |project|
date_timestamps << ProjectContributions.new(project, user).commits_log
end
# Sumarrize commits from all projects per days
date_timestamps = date_timestamps.inject do |collection, date|
collection.merge(date) { |k, old_v, new_v| old_v + new_v }
end
......@@ -21,5 +21,13 @@ module Gitlab
@timestamps[timestamp] = commits if timestamp
end
end
def starting_year
(Time.now - 1.year).strftime("%Y")
end
def starting_month
Date.today.strftime("%m").to_i
end
end
end
......@@ -4,7 +4,7 @@ module Gitlab
include Enumerable
def parse(lines)
@lines = lines,
@lines = lines
lines_obj = []
line_obj_index = 0
line_old = 1
......@@ -74,7 +74,7 @@ module Gitlab
def html_escape(str)
replacements = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
str.gsub(/[&"'><]/, replacements)
str.gsub(/[&"'><]/, replacements)
end
end
end
......
......@@ -12,4 +12,3 @@ module Gitlab
end
end
end
......@@ -112,14 +112,14 @@ module Gitlab
def protected_branch_action(project, oldrev, newrev, branch_name)
# we dont allow force push to protected branch
if forced_push?(project, oldrev, newrev)
:force_push_code_to_protected_branches
# and we dont allow remove of protected branch
:force_push_code_to_protected_branches
elsif newrev == Gitlab::Git::BLANK_SHA
:remove_protected_branches
# and we dont allow remove of protected branch
:remove_protected_branches
elsif project.developers_can_push_to_protected_branch?(branch_name)
:push_code
:push_code
else
:push_code_to_protected_branches
:push_code_to_protected_branches
end
end
......
......@@ -9,7 +9,7 @@ module Gitlab
end
def to_json
{status: @status, message: @message}.to_json
{ status: @status, message: @message }.to_json
end
end
end
\ No newline at end of file
end
......@@ -9,12 +9,12 @@ module Gitlab
def execute
client = octo_client(project.creator.github_access_token)
#Issues && Comments
client.list_issues(project.import_source, state: :all).each do |issue|
if issue.pull_request.nil?
body = "*Created by: #{issue.user.login}*\n\n#{issue.body}"
if issue.comments > 0
body += "\n\n\n**Imported comments:**\n"
client.issue_comments(project.import_source, issue.number).each do |c|
......@@ -23,7 +23,7 @@ module Gitlab
end
project.issues.create!(
description: body,
description: body,
title: issue.title,
state: issue.state == 'closed' ? 'closed' : 'opened',
author_id: gl_user_id(project, issue.user.id)
......@@ -36,7 +36,7 @@ module Gitlab
def octo_client(access_token)
::Octokit.auto_paginate = true
::Octokit::Client.new(:access_token => access_token)
::Octokit::Client.new(access_token: access_token)
end
def gl_user_id(project, github_id)
......
......@@ -63,8 +63,10 @@ module Gitlab
end
def dn_matches_filter?(dn, filter)
ldap_search(base: dn, filter: filter,
scope: Net::LDAP::SearchScope_BaseObject, attributes: %w{dn}).any?
ldap_search(base: dn,
filter: filter,
scope: Net::LDAP::SearchScope_BaseObject,
attributes: %w{dn}).any?
end
def ldap_search(*args)
......
......@@ -44,7 +44,7 @@ module Gitlab
end
def default_options(options = {})
{raise: true, timeout: true}.merge(options)
{ raise: true, timeout: true }.merge(options)
end
def handle_exception(exception)
......
......@@ -13,7 +13,7 @@ module Gitlab
prepare_satellite!(repo)
# create target branch in satellite at the corresponding commit from bare repo
repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
# update the file in the satellite's working dir
file_path_in_satellite = File.join(repo.working_dir, file_path)
......@@ -36,7 +36,7 @@ module Gitlab
# push commit back to bare repo
# will raise CommandFailed when push fails
repo.git.push({raise: true, timeout: true}, :origin, ref)
repo.git.push({ raise: true, timeout: true }, :origin, ref)
# everything worked
true
......
......@@ -15,7 +15,7 @@ module Gitlab
prepare_satellite!(repo)
# create target branch in satellite at the corresponding commit from bare repo
repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
# update the file in the satellite's working dir
file_path_in_satellite = File.join(repo.working_dir, file_path)
......@@ -36,7 +36,7 @@ module Gitlab
# push commit back to bare repo
# will raise CommandFailed when push fails
repo.git.push({raise: true, timeout: true}, :origin, ref)
repo.git.push({ raise: true, timeout: true }, :origin, ref)
# everything worked
true
......
......@@ -19,7 +19,7 @@ module Gitlab
# skip this step if we want to add first file to empty repo
Satellite::PARKING_BRANCH
else
repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
ref
end
......@@ -47,7 +47,7 @@ module Gitlab
# push commit back to bare repo
# will raise CommandFailed when push fails
repo.git.push({raise: true, timeout: true}, :origin, "#{current_ref}:#{ref}")
repo.git.push({ raise: true, timeout: true }, :origin, "#{current_ref}:#{ref}")
# everything worked
true
......
......@@ -86,7 +86,7 @@ module Gitlab
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
update_satellite_source_and_target!(merge_repo)
patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}")
patch = merge_repo.git.format_patch(default_options({ stdout: true }), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}")
end
rescue Grit::Git::CommandFailed => ex
handle_exception(ex)
......@@ -128,7 +128,7 @@ module Gitlab
# merge the source branch into the satellite
# will raise CommandFailed when merge fails
repo.git.merge(default_options({no_ff: true}), "-m#{message}", "source/#{merge_request.source_branch}")
repo.git.merge(default_options({ no_ff: true }), "-m#{message}", "source/#{merge_request.source_branch}")
rescue Grit::Git::CommandFailed => ex
handle_exception(ex)
end
......@@ -137,7 +137,7 @@ module Gitlab
def update_satellite_source_and_target!(repo)
repo.remote_add('source', merge_request.source_project.repository.path_to_repo)
repo.remote_fetch('source')
repo.git.checkout(default_options({b: true}), merge_request.target_branch, "origin/#{merge_request.target_branch}")
repo.git.checkout(default_options({ b: true }), merge_request.target_branch, "origin/#{merge_request.target_branch}")
rescue Grit::Git::CommandFailed => ex
handle_exception(ex)
end
......
......@@ -98,13 +98,13 @@ module Gitlab
if heads.include? PARKING_BRANCH
repo.git.checkout({}, PARKING_BRANCH)
else
repo.git.checkout(default_options({b: true}), PARKING_BRANCH)
repo.git.checkout(default_options({ b: true }), PARKING_BRANCH)
end
# remove the parking branch from the list of heads ...
heads.delete(PARKING_BRANCH)
# ... and delete all others
heads.each { |head| repo.git.branch(default_options({D: true}), head) }
heads.each { |head| repo.git.branch(default_options({ D: true }), head) }
end
# Deletes all remotes except origin
......@@ -126,7 +126,7 @@ module Gitlab
end
def default_options(options = {})
{raise: true, timeout: true}.merge(options)
{ raise: true, timeout: true }.merge(options)
end
# Create directory for storing
......
......@@ -62,7 +62,7 @@ module Gitlab
end
def env
{'RAILS_ENV' => 'production'}
{ 'RAILS_ENV' => 'production' }
end
def upgrade
......
# Interface to the Redis-backed cache store used by the Repository model
class RepositoryCache
attr_reader :namespace, :backend
def initialize(namespace, backend = Rails.cache)
@namespace = namespace
@backend = backend
end
def cache_key(type)
"#{type}:#{namespace}"
end
def expire(key)
backend.delete(cache_key(key))
end
def fetch(key, &block)
backend.fetch(cache_key(key), &block)
end
end
......@@ -2,6 +2,7 @@ namespace :gitlab do
desc "GITLAB | Run all tests"
task :test do
cmds = [
%W(rake rubocop),
%W(rake spinach),
%W(rake spec),
%W(rake jasmine:ci)
......
require 'rubocop/rake_task'
RuboCop::RakeTask.new
......@@ -2,9 +2,15 @@ Rake::Task["spinach"].clear if Rake::Task.task_defined?('spinach')
desc "GITLAB | Run spinach"
task :spinach do
tags = if ENV['SEMAPHORE']
'~@tricky'
else
'~@semaphore'
end
cmds = [
%W(rake gitlab:setup),
%W(spinach),
%W(spinach --tags #{tags}),
]
run_commands(cmds)
end
......
......@@ -9,5 +9,5 @@ unless Rails.env.production?
require 'coveralls/rake/task'
Coveralls::RakeTask.new
desc "GITLAB | Run all tests on CI with simplecov"
task :test_ci => [:spinach, :spec, 'coveralls:push']
task :test_ci => [:rubocop, :spinach, :spec, 'coveralls:push']
end
......@@ -70,4 +70,13 @@ describe Projects::CommitController do
end
end
end
describe "#branches" do
it "contains branch and tags information" do
get :branches, project_id: project.to_param, id: commit.id
expect(assigns(:branches)).to include("master", "feature_conflict")
expect(assigns(:tags)).to include("v1.1.0")
end
end
end
......@@ -26,6 +26,7 @@
# star_count :integer default(0), not null
# import_type :string(255)
# import_source :string(255)
# avatar :string(255)
#
FactoryGirl.define do
......
......@@ -65,7 +65,7 @@ describe "Issues", feature: true do
click_button "Save changes"
page.should have_content "Assignee: Select assignee"
page.should have_content 'Assignee: none'
issue.reload.assignee.should be_nil
end
end
......@@ -249,6 +249,7 @@ describe "Issues", feature: true do
click_button 'Update Issue'
page.should have_content "Milestone changed to #{milestone.title}"
page.should have_content "Milestone: #{milestone.title}"
has_select?('issue_assignee_id', :selected => milestone.title)
end
end
......@@ -287,7 +288,7 @@ describe "Issues", feature: true do
sleep 2 # wait for ajax stuff to complete
first('.user-result').click
page.should have_content "Assignee: Unassigned"
page.should have_content 'Assignee: none'
sleep 2 # wait for ajax stuff to complete
issue.reload.assignee.should be_nil
end
......
require 'spec_helper'
# Specs in this file have access to a helper object that includes
# the NavHelper. For example:
#
# describe NavHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
describe NavHelper do
describe '#nav_menu_collapsed?' do
it 'returns true when the nav is collapsed in the cookie' do
helper.request.cookies[:collapsed_nav] = 'true'
expect(helper.nav_menu_collapsed?).to eq true
end
it 'returns false when the nav is not collapsed in the cookie' do
helper.request.cookies[:collapsed_nav] = 'false'
expect(helper.nav_menu_collapsed?).to eq false
end
end
end
require 'spec_helper'
describe NotificationsHelper do
include FontAwesome::Rails::IconHelper
include IconsHelper
describe 'notification_icon' do
let(:notification) { double(disabled?: false, participating?: false, watch?: false) }
......
require 'rspec'
require_relative '../../lib/repository_cache'
describe RepositoryCache do
let(:backend) { double('backend').as_null_object }
let(:cache) { RepositoryCache.new('example', backend) }
describe '#cache_key' do
it 'includes the namespace' do
expect(cache.cache_key(:foo)).to eq 'foo:example'
end
end
describe '#expire' do
it 'expires the given key from the cache' do
cache.expire(:foo)
expect(backend).to have_received(:delete).with('foo:example')
end
end
describe '#fetch' do
it 'fetches the given key from the cache' do
cache.fetch(:bar)
expect(backend).to have_received(:fetch).with('bar:example')
end
it 'accepts a block' do
p = -> {}
cache.fetch(:baz, &p)
expect(backend).to have_received(:fetch).with('baz:example', &p)
end
end
end
......@@ -161,8 +161,8 @@ describe Issue, 'Votes' do
add_note '+1 I still like this'
add_note '+1 I really like this'
add_note '+1 Give me this now!!!!'
p issue.downvotes.should == 0
p issue.upvotes.should == 1
issue.downvotes.should == 0
issue.upvotes.should == 1
end
it 'should count a users vote only once without caring about comments' do
......@@ -171,8 +171,8 @@ describe Issue, 'Votes' do
add_note 'Another comment'
add_note '+1 vote'
add_note 'final comment'
p issue.downvotes.should == 0
p issue.upvotes.should == 1
issue.downvotes.should == 0
issue.upvotes.should == 1
end
end
......
......@@ -10,7 +10,7 @@ describe Member do
it { should validate_presence_of(:user) }
it { should validate_presence_of(:source) }
it { should ensure_inclusion_of(:access_level).in_array(Gitlab::Access.values) }
it { should validate_inclusion_of(:access_level).in_array(Gitlab::Access.values) }
end
describe "Delegate methods" do
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
require 'spec_helper'
describe JiraService do
......
......@@ -14,7 +14,7 @@
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
# issues_tracker :string(255) default('gitlab'), not null
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime
......
......@@ -73,6 +73,24 @@ describe API::API, api: true do
response.status.should == 404
end
end
context 'when using group path in URL' do
it 'should return any existing group' do
get api("/groups/#{group1.path}", admin)
response.status.should == 200
json_response['name'] == group2.name
end
it 'should not return a non existing group' do
get api('/groups/unknown', admin)
response.status.should == 404
end
it 'should not return a group not attached to user1' do
get api("/groups/#{group2.path}", user1)
response.status.should == 403
end
end
end
describe "POST /groups" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment