diff --git a/.csscomb.json b/.csscomb.json new file mode 100644 index 0000000000..741cc1488b --- /dev/null +++ b/.csscomb.json @@ -0,0 +1,20 @@ +{ + "exclude": [ + "app/assets/stylesheets/framework/tw_bootstrap_variables.scss", + "app/assets/stylesheets/framework/fonts.scss" + ], + "always-semicolon": true, + "color-case": "lower", + "block-indent": " ", + "color-shorthand": true, + "element-case": "lower", + "space-before-colon": "", + "space-after-colon": " ", + "space-before-combinator": " ", + "space-after-combinator": " ", + "space-between-declarations": "\n", + "space-before-opening-brace": " ", + "space-after-opening-brace": "\n", + "space-before-closing-brace": "\n", + "unitless-zero": true +} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bd013d50fa..1dc49ca336 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,6 @@ image: "ruby:2.1" services: - mysql:latest - - postgres:latest - redis:latest cache: @@ -35,126 +34,86 @@ spec:feature: script: - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:feature - tags: - - ruby - - mysql spec:api: stage: test script: - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:api - tags: - - ruby - - mysql spec:models: stage: test script: - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:models - tags: - - ruby - - mysql spec:lib: stage: test script: - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:lib - tags: - - ruby - - mysql spec:services: stage: test script: - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:services - tags: - - ruby - - mysql spec:other: stage: test script: - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:other - tags: - - ruby - - mysql spinach:project:half: stage: test script: - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:half - tags: - - ruby - - mysql spinach:project:rest: stage: test script: - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:rest - tags: - - ruby - - mysql spinach:other: stage: test script: - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:other - tags: - - ruby - - mysql teaspoon: stage: test script: - RAILS_ENV=test bundle exec teaspoon - tags: - - ruby - - mysql rubocop: stage: test script: - bundle exec rubocop - tags: - - ruby - - mysql + +scss-lint: + stage: test + script: + - bundle exec rake scss_lint brakeman: stage: test script: - bundle exec rake brakeman - tags: - - ruby - - mysql flog: stage: test script: - bundle exec rake flog - tags: - - ruby - - mysql flay: stage: test script: - bundle exec rake flay - tags: - - ruby - - mysql bundler:audit: stage: test + only: + - master script: - - "bundle exec bundle-audit update" - - "bundle exec bundle-audit check" - tags: - - ruby - - mysql - allow_failure: true + - "bundle exec bundle-audit check --update --ignore OSVDB-115941" # Ruby 2.2 jobs @@ -162,7 +121,7 @@ spec:feature:ruby22: stage: test image: ruby:2.2 only: - - master + - master script: - RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null - RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:feature @@ -170,9 +129,6 @@ spec:feature:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spec:api:ruby22: stage: test @@ -185,9 +141,6 @@ spec:api:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spec:models:ruby22: stage: test @@ -200,9 +153,6 @@ spec:models:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spec:lib:ruby22: stage: test @@ -215,9 +165,6 @@ spec:lib:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spec:services:ruby22: stage: test @@ -230,9 +177,6 @@ spec:services:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spec:other:ruby22: stage: test @@ -245,9 +189,6 @@ spec:other:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spinach:project:half:ruby22: stage: test @@ -261,9 +202,6 @@ spinach:project:half:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spinach:project:rest:ruby22: stage: test @@ -277,9 +215,6 @@ spinach:project:rest:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql spinach:other:ruby22: stage: test @@ -293,10 +228,6 @@ spinach:other:ruby22: key: "ruby22" paths: - vendor - tags: - - ruby - - mysql - notify:slack: stage: notifications diff --git a/.rubocop.yml b/.rubocop.yml index 89aa0591c3..71273ce609 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,1032 +1,14 @@ -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/BlockDelimiters: - 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/ExtraSpacing: - Description: 'Do not use unnecessary spacing.' - Enabled: false - -Style/FileName: - Description: 'Use snake_case for source file names.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files' - 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: true - -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: true - -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: true - -Style/NonNilCheck: - Description: 'Checks for redundant nil checks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks' - Enabled: true - -Style/Not: - Description: 'Use ! instead of not.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bang-not-not' - Enabled: true - -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: true - -Style/OpMethod: - Description: 'When defining binary operators, name the argument other.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg' - Enabled: false - -Style/ParallelAssignment: - Description: >- - Check for simple usages of parallel assignment. - It will only warn when the number of variables - matches on both sides of the assignment. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parallel-assignment' - Enabled: false - -Style/ParenthesesAroundCondition: - Description: >- - Don't use parentheses around the condition of an - if/unless/while. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-parens-if' - Enabled: true - -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: true - -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: true - -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/TrailingUnderscoreVariable: - Description: >- - Checks for the usage of unneeded trailing underscores at the - end of parallel variable assignment. - AllowNamedUnderscoreVariables: true - Enabled: false - -Style/TrivialAccessors: - Description: 'Prefer attr_* methods to trivial readers/writers.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr_family' - 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/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: true - Max: 70 - -Metrics/CyclomaticComplexity: - Description: >- - A complexity metric that is strongly correlated to the number - of test cases needed to validate a method. - Enabled: true - Max: 17 - -Metrics/PerceivedComplexity: - Description: >- - A complexity metric geared towards measuring complexity for a - human reader. - Enabled: true - Max: 17 - -Metrics/ParameterLists: - Description: 'Avoid parameter lists longer than three or four parameters.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#too-many-params' - Enabled: true - Max: 8 - -Metrics/BlockNesting: - Description: 'Avoid excessive block nesting' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count' - Enabled: true - Max: 4 - -Metrics/ClassLength: - Description: 'Avoid classes longer than 100 lines of code.' - 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/ModuleLength: - Description: 'Avoid modules longer than 100 lines of code.' - 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: true - -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: true - -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: true - -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: true - -Rails/Date: - Description: >- - Checks the correct usage of date aware methods, - such as Date.today, Date.current etc. - Enabled: false - -Rails/DefaultScope: - Description: 'Checks if the argument passed to default_scope is a block.' - Enabled: false - -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/TimeZone: - Description: 'Checks the correct usage of time zone aware methods.' - StyleGuide: 'https://github.com/bbatsov/rails-style-guide#time' - Reference: 'http://danilenko.org/2012/7/6/rails_timezones' - Enabled: false - -Rails/Validation: - Description: 'Use validates :attribute, hash of validations.' - Enabled: false - - -# Exclude some of GitLab files -# -# AllCops: - RunRailsCops: true + TargetRubyVersion: 2.1 + # Cop names are not displayed in offense messages by default. Change behavior + # by overriding DisplayCopNames, or by giving the -D/--display-cop-names + # option. + DisplayCopNames: true + # Style guide URLs are not displayed in offense messages by default. Change + # behavior by overriding DisplayStyleGuide, or by giving the + # -S/--display-style-guide option. + DisplayStyleGuide: false + # Exclude some GitLab files Exclude: - 'vendor/**/*' - 'db/**/*' @@ -1039,3 +21,1041 @@ AllCops: - 'lib/email_validator.rb' - 'lib/gitlab/upgrader.rb' - 'lib/gitlab/seeder.rb' + + +##################### Style ################################## + +# Check indentation of private/protected visibility modifiers. +Style/AccessModifierIndentation: + Enabled: true + +# Check the naming of accessor methods for get_/set_. +Style/AccessorMethodName: + Enabled: false + +# Use alias_method instead of alias. +Style/Alias: + EnforcedStyle: prefer_alias_method + Enabled: true + +# Align the elements of an array literal if they span more than one line. +Style/AlignArray: + Enabled: true + +# Align the elements of a hash literal if they span more than one line. +Style/AlignHash: + Enabled: true + +# Align the parameters of a method call if they span more than one line. +Style/AlignParameters: + Enabled: false + +# Use &&/|| instead of and/or. +Style/AndOr: + Enabled: false + +# Use `Array#join` instead of `Array#*`. +Style/ArrayJoin: + Enabled: false + +# Use only ascii symbols in comments. +Style/AsciiComments: + Enabled: true + +# Use only ascii symbols in identifiers. +Style/AsciiIdentifiers: + Enabled: true + +# Checks for uses of Module#attr. +Style/Attr: + Enabled: false + +# Avoid the use of BEGIN blocks. +Style/BeginBlock: + Enabled: true + +# Checks if usage of %() or %Q() matches configuration. +Style/BarePercentLiterals: + Enabled: false + +# Do not use block comments. +Style/BlockComments: + Enabled: false + +# Put end statement of multiline block on its own line. +Style/BlockEndNewline: + Enabled: true + +# Avoid using {...} for multi-line blocks (multiline chaining is # always +# ugly). Prefer {...} over do...end for single-line blocks. +Style/BlockDelimiters: + Enabled: true + +# Enforce braces style around hash parameters. +Style/BracesAroundHashParameters: + Enabled: false + +# Avoid explicit use of the case equality operator(===). +Style/CaseEquality: + Enabled: false + +# Indentation of when in a case/when/[else/]end. +Style/CaseIndentation: + Enabled: true + +# Checks for uses of character literals. +Style/CharacterLiteral: + Enabled: true + +# Use CamelCase for classes and modules.' +Style/ClassAndModuleCamelCase: + Enabled: true + +# Checks style of children classes and modules. +Style/ClassAndModuleChildren: + Enabled: false + +# Enforces consistent use of `Object#is_a?` or `Object#kind_of?`. +Style/ClassCheck: + Enabled: false + +# Use self when defining module/class methods. +Style/ClassMethods: + Enabled: false + +# Avoid the use of class variables. +Style/ClassVars: + Enabled: true + +# Do not use :: for method call. +Style/ColonMethodCall: + Enabled: false + +# Checks formatting of special comments (TODO, FIXME, OPTIMIZE, HACK, REVIEW). +Style/CommentAnnotation: + Enabled: false + +# Indentation of comments. +Style/CommentIndentation: + Enabled: true + +# Use the return value of `if` and `case` statements for assignment to a +# variable and variable comparison instead of assigning that variable +# inside of each branch. +Style/ConditionalAssignment: + Enabled: false + +# Constants should use SCREAMING_SNAKE_CASE. +Style/ConstantName: + Enabled: true + +# Use def with parentheses when there are arguments. +Style/DefWithParentheses: + Enabled: false + +# Checks for use of deprecated Hash methods. +Style/DeprecatedHashMethods: + Enabled: false + +# Document classes and non-namespace modules. +Style/Documentation: + Enabled: false + +# Checks the position of the dot in multi-line method calls. +Style/DotPosition: + Enabled: false + +# Checks for uses of double negation (!!). +Style/DoubleNegation: + Enabled: false + +# Prefer `each_with_object` over `inject` or `reduce`. +Style/EachWithObject: + Enabled: false + +# Align elses and elsifs correctly. +Style/ElseAlignment: + Enabled: true + +# Avoid empty else-clauses. +Style/EmptyElse: + Enabled: false + +# Use empty lines between defs. +Style/EmptyLineBetweenDefs: + Enabled: false + +# Don't use several empty lines in a row. +Style/EmptyLines: + Enabled: false + +# Keep blank lines around access modifiers. +Style/EmptyLinesAroundAccessModifier: + Enabled: false + +# Keeps track of empty lines around block bodies. +Style/EmptyLinesAroundBlockBody: + Enabled: false + +# Keeps track of empty lines around class bodies. +Style/EmptyLinesAroundClassBody: + Enabled: false + +# Keeps track of empty lines around module bodies. +Style/EmptyLinesAroundModuleBody: + Enabled: false + +# Keeps track of empty lines around method bodies. +Style/EmptyLinesAroundMethodBody: + Enabled: false + +# Prefer literals to Array.new/Hash.new/String.new. +Style/EmptyLiteral: + Enabled: false + +# Avoid the use of END blocks. +Style/EndBlock: + Enabled: false + +# Use Unix-style line endings. +Style/EndOfLine: + Enabled: false + +# Favor the use of Fixnum#even? && Fixnum#odd? +Style/EvenOdd: + Enabled: false + +# Do not use unnecessary spacing. +Style/ExtraSpacing: + Enabled: false + +# Use snake_case for source file names. +Style/FileName: + Enabled: false + +# Checks for flip flops. +Style/FlipFlop: + Enabled: false + +# Checks use of for or each in multiline loops. +Style/For: + Enabled: false + +# Enforce the use of Kernel#sprintf, Kernel#format or String#%. +Style/FormatString: + Enabled: false + +# Do not introduce global variables. +Style/GlobalVars: + Enabled: false + +# Check for conditionals that can be replaced with guard clauses. +Style/GuardClause: + Enabled: false + +# Prefer Ruby 1.9 hash syntax `{ a: 1, b: 2 }` +# over 1.8 syntax `{ :a => 1, :b => 2 }`. +Style/HashSyntax: + Enabled: true + +# Finds if nodes inside else, which can be converted to elsif. +Style/IfInsideElse: + Enabled: false + +# Favor modifier if/unless usage when you have a single-line body. +Style/IfUnlessModifier: + Enabled: false + +# Do not use if x; .... Use the ternary operator instead. +Style/IfWithSemicolon: + Enabled: false + +# Checks that conditional statements do not have an identical line at the +# end of each branch, which can validly be moved out of the conditional. +Style/IdenticalConditionalBranches: + Enabled: false + +# Checks the indentation of the first line of the right-hand-side of a +# multi-line assignment. +Style/IndentAssignment: + Enabled: false + +# Keep indentation straight. +Style/IndentationConsistency: + Enabled: true + +# Use 2 spaces for indentation. +Style/IndentationWidth: + Enabled: true + +# Checks the indentation of the first element in an array literal. +Style/IndentArray: + Enabled: false + +# Checks the indentation of the first key in a hash literal. +Style/IndentHash: + Enabled: false + +# Use Kernel#loop for infinite loops. +Style/InfiniteLoop: + Enabled: false + +# Use the new lambda literal syntax for single-line blocks. +Style/Lambda: + Enabled: false + +# Use lambda.call(...) instead of lambda.(...). +Style/LambdaCall: + Enabled: false + +# Comments should start with a space. +Style/LeadingCommentSpace: + Enabled: false + +# Use \ instead of + or << to concatenate two string literals at line end. +Style/LineEndConcatenation: + Enabled: false + +# Do not use parentheses for method calls with no arguments. +Style/MethodCallParentheses: + Enabled: false + +# Checks if the method definitions have or don't have parentheses. +Style/MethodDefParentheses: + Enabled: false + +# Use the configured style when naming methods. +Style/MethodName: + Enabled: false + +# Checks for usage of `extend self` in modules. +Style/ModuleFunction: + Enabled: false + +# Avoid multi-line chains of blocks. +Style/MultilineBlockChain: + Enabled: false + +# Ensures newlines after multiline block do statements. +Style/MultilineBlockLayout: + Enabled: true + +# Do not use then for multi-line if/unless. +Style/MultilineIfThen: + Enabled: false + +# Checks indentation of method calls with the dot operator that span more than +# one line. +Style/MultilineMethodCallIndentation: + Enabled: false + +# Checks indentation of binary operations that span more than one line. +Style/MultilineOperationIndentation: + Enabled: false + +# Avoid multi-line `? :` (the ternary operator), use if/unless instead. +Style/MultilineTernaryOperator: + Enabled: false + +# Do not assign mutable objects to constants. +Style/MutableConstant: + Enabled: false + +# Favor unless over if for negative conditions (or control flow or). +Style/NegatedIf: + Enabled: false + +# Favor until over while for negative conditions. +Style/NegatedWhile: + Enabled: false + +# Avoid using nested modifiers. +Style/NestedModifier: + Enabled: false + +# Parenthesize method calls which are nested inside the argument list of +# another parenthesized method call. +Style/NestedParenthesizedCalls: + Enabled: false + +# Use one expression per branch in a ternary operator. +Style/NestedTernaryOperator: + Enabled: true + +# Use `next` to skip iteration instead of a condition at the end. +Style/Next: + Enabled: false + +# Prefer x.nil? to x == nil. +Style/NilComparison: + Enabled: true + +# Checks for redundant nil checks. +Style/NonNilCheck: + Enabled: true + +# Use ! instead of not. +Style/Not: + Enabled: true + +# Add underscores to large numeric literals to improve their readability. +Style/NumericLiterals: + Enabled: false + +# Favor the ternary operator(?:) over if/then/else/end constructs. +Style/OneLineConditional: + Enabled: true + +# When defining binary operators, name the argument other. +Style/OpMethod: + Enabled: false + +# Check for simple usages of parallel assignment. It will only warn when +# the number of variables matches on both sides of the assignment. +Style/ParallelAssignment: + Enabled: false + +# Don't use parentheses around the condition of an if/unless/while. +Style/ParenthesesAroundCondition: + Enabled: true + +# Use `%`-literal delimiters consistently. +Style/PercentLiteralDelimiters: + Enabled: false + +# Checks if uses of %Q/%q match the configured preference. +Style/PercentQLiterals: + Enabled: false + +# Avoid Perl-style regex back references. +Style/PerlBackrefs: + Enabled: false + +# Check the names of predicate methods. +Style/PredicateName: + Enabled: false + +# Use proc instead of Proc.new. +Style/Proc: + Enabled: false + +# Checks the arguments passed to raise/fail. +Style/RaiseArgs: + Enabled: false + +# Don't use begin blocks when they are not needed. +Style/RedundantBegin: + Enabled: false + +# Checks for an obsolete RuntimeException argument in raise/fail. +Style/RedundantException: + Enabled: false + +# Checks usages of Object#freeze on immutable objects. +Style/RedundantFreeze: + Enabled: false + +# TODO: Enable RedundantParentheses Cop. +# Checks for parentheses that seem not to serve any purpose. +Style/RedundantParentheses: + Enabled: false + +# Don't use return where it's not required. +Style/RedundantReturn: + Enabled: true + +# Don't use self where it's not needed. +Style/RedundantSelf: + Enabled: false + +# Use %r for regular expressions matching more than `MaxSlashes` '/' +# characters. Use %r only for regular expressions matching more +# than `MaxSlashes` '/' character. +Style/RegexpLiteral: + Enabled: false + +# Avoid using rescue in its modifier form. +Style/RescueModifier: + Enabled: false + +# Checks for places where self-assignment shorthand should have been used. +Style/SelfAssignment: + Enabled: false + +# Don't use semicolons to terminate expressions. +Style/Semicolon: + Enabled: false + +# Checks for proper usage of fail and raise. +Style/SignalException: + Enabled: false + +# Enforces the names of some block params. +Style/SingleLineBlockParams: + Enabled: false + +# Avoid single-line methods. +Style/SingleLineMethods: + Enabled: false + +# Use spaces after colons. +Style/SpaceAfterColon: + Enabled: false + +# Use spaces after commas. +Style/SpaceAfterComma: + Enabled: false + +# Do not put a space between a method name and the opening parenthesis in a +# method definition. +Style/SpaceAfterMethodName: + Enabled: false + +# Tracks redundant space after the ! operator. +Style/SpaceAfterNot: + Enabled: false + +# Use spaces after semicolons. +Style/SpaceAfterSemicolon: + Enabled: false + +# Checks that the equals signs in parameter default assignments have or don't +# have surrounding space depending on configuration. +Style/SpaceAroundEqualsInParameterDefault: + Enabled: false + +# TODO: Enable SpaceAroundKeyword Cop. +# Use a space around keywords if appropriate. +Style/SpaceAroundKeyword: + Enabled: false + +# Use a single space around operators. +Style/SpaceAroundOperators: + Enabled: false + +# Checks that the left block brace has or doesn't have space before it. +Style/SpaceBeforeBlockBraces: + Enabled: false + +# No spaces before commas. +Style/SpaceBeforeComma: + Enabled: false + +# Checks for missing space between code and a comment on the same line. +Style/SpaceBeforeComment: + Enabled: false + +# Checks that exactly one space is used between a method name and the first +# argument for method calls without parentheses. +Style/SpaceBeforeFirstArg: + Enabled: false + +# No spaces before semicolons. +Style/SpaceBeforeSemicolon: + Enabled: false + +# Checks that block braces have or don't have surrounding space. +# For blocks taking parameters, checks that the left brace has or doesn't +# have trailing space. +Style/SpaceInsideBlockBraces: + Enabled: false + +# No spaces after [ or before ]. +Style/SpaceInsideBrackets: + Enabled: false + +# Use spaces inside hash literal braces - or don't. +Style/SpaceInsideHashLiteralBraces: + Enabled: true + +# No spaces after ( or before ). +Style/SpaceInsideParens: + Enabled: false + +# No spaces inside range literals. +Style/SpaceInsideRangeLiteral: + Enabled: false + +# Checks for padding/surrounding spaces inside string interpolation. +Style/SpaceInsideStringInterpolation: + Enabled: false + +# Avoid Perl-style global variables. +Style/SpecialGlobalVars: + Enabled: false + +# Check for the usage of parentheses around stabby lambda arguments. +Style/StabbyLambdaParentheses: + Enabled: false + +# Checks if uses of quotes match the configured preference. +Style/StringLiterals: + Enabled: false + +# Checks if uses of quotes inside expressions in interpolated strings match the +# configured preference. +Style/StringLiteralsInInterpolation: + Enabled: false + +# Checks if configured preferred methods are used over non-preferred. +Style/StringMethods: + Enabled: false + +# Use %i or %I for arrays of symbols. +Style/SymbolArray: + Enabled: false + +# Use symbols as procs instead of blocks when possible. +Style/SymbolProc: + Enabled: false + +# No hard tabs. +Style/Tab: + Enabled: true + +# Checks trailing blank lines and final newline. +Style/TrailingBlankLines: + Enabled: true + +# Checks for trailing comma in array and hash literals. +Style/TrailingCommaInLiteral: + Enabled: false + +# Checks for trailing comma in argument lists. +Style/TrailingCommaInArguments: + Enabled: false + +# Avoid trailing whitespace. +Style/TrailingWhitespace: + Enabled: false + +# Checks for the usage of unneeded trailing underscores at the end of +# parallel variable assignment. +Style/TrailingUnderscoreVariable: + Enabled: false + +# Prefer attr_* methods to trivial readers/writers. +Style/TrivialAccessors: + Enabled: false + +# Do not use unless with else. Rewrite these with the positive case first. +Style/UnlessElse: + Enabled: false + +# Checks for %W when interpolation is not needed. +Style/UnneededCapitalW: + Enabled: false + +# TODO: Enable UnneededInterpolation Cop. +# Checks for strings that are just an interpolated expression. +Style/UnneededInterpolation: + Enabled: false + +# Checks for %q/%Q when single quotes or double quotes would do. +Style/UnneededPercentQ: + Enabled: false + +# Don't interpolate global, instance and class variables directly in strings. +Style/VariableInterpolation: + Enabled: false + +# Use the configured style when naming variables. +Style/VariableName: + Enabled: false + +# Use when x then ... for one-line cases. +Style/WhenThen: + Enabled: false + +# Checks for redundant do after while or until. +Style/WhileUntilDo: + Enabled: false + +# Favor modifier while/until usage when you have a single-line body. +Style/WhileUntilModifier: + Enabled: false + +# Use %w or %W for arrays of words. +Style/WordArray: + Enabled: false + +# TODO: Enable ZeroLengthPredicate Cop. +# Use #empty? when testing for objects of length 0. +Style/ZeroLengthPredicate: + Enabled: false + + +#################### Metrics ################################ + +# A calculated magnitude based on number of assignments, +# branches, and conditions. +Metrics/AbcSize: + Enabled: true + Max: 70 + +# Avoid excessive block nesting. +Metrics/BlockNesting: + Enabled: true + Max: 4 + +# Avoid classes longer than 100 lines of code. +Metrics/ClassLength: + Enabled: false + +# A complexity metric that is strongly correlated to the number +# of test cases needed to validate a method. +Metrics/CyclomaticComplexity: + Enabled: true + Max: 17 + +# Limit lines to 80 characters. +Metrics/LineLength: + Enabled: false + +# Avoid methods longer than 10 lines of code. +Metrics/MethodLength: + Enabled: false + +# Avoid modules longer than 100 lines of code. +Metrics/ModuleLength: + Enabled: false + +# Avoid parameter lists longer than three or four parameters. +Metrics/ParameterLists: + Enabled: true + Max: 8 + +# A complexity metric geared towards measuring complexity for a human reader. +Metrics/PerceivedComplexity: + Enabled: true + Max: 17 + + +#################### Lint ################################ + +# Checks for ambiguous operators in the first argument of a method invocation +# without parentheses. +Lint/AmbiguousOperator: + Enabled: false + +# Checks for ambiguous regexp literals in the first argument of a method +# invocation without parentheses. +Lint/AmbiguousRegexpLiteral: + Enabled: false + +# Don't use assignment in conditions. +Lint/AssignmentInCondition: + Enabled: false + +# Align block ends correctly. +Lint/BlockAlignment: + Enabled: false + +# Default values in optional keyword arguments and optional ordinal arguments +# should not refer back to the name of the argument. +Lint/CircularArgumentReference: + Enabled: false + +# Checks for condition placed in a confusing position relative to the keyword. +Lint/ConditionPosition: + Enabled: false + +# Check for debugger calls. +Lint/Debugger: + Enabled: false + +# Align ends corresponding to defs correctly. +Lint/DefEndAlignment: + Enabled: false + +# Check for deprecated class method calls. +Lint/DeprecatedClassMethods: + Enabled: false + +# Check for duplicate method definitions. +Lint/DuplicateMethods: + Enabled: false + +# Check for duplicate keys in hash literals. +Lint/DuplicatedKey: + Enabled: false + +# Check for immutable argument given to each_with_object. +Lint/EachWithObjectArgument: + Enabled: false + +# Check for odd code arrangement in an else block. +Lint/ElseLayout: + Enabled: false + +# Checks for empty ensure block. +Lint/EmptyEnsure: + Enabled: false + +# Checks for empty string interpolation. +Lint/EmptyInterpolation: + Enabled: false + +# Align ends correctly. +Lint/EndAlignment: + Enabled: false + +# END blocks should not be placed inside method definitions. +Lint/EndInMethod: + Enabled: false + +# Do not use return in an ensure block. +Lint/EnsureReturn: + Enabled: false + +# The use of eval represents a serious security risk. +Lint/Eval: + Enabled: false + +# Catches floating-point literals too large or small for Ruby to represent. +Lint/FloatOutOfRange: + Enabled: false + +# The number of parameters to format/sprint must match the fields. +Lint/FormatParameterMismatch: + Enabled: false + +# Don't suppress exception. +Lint/HandleExceptions: + Enabled: false + +# TODO: Enable ImplicitStringConcatenation Cop. +# Checks for adjacent string literals on the same line, which could better be +# represented as a single string literal. +Lint/ImplicitStringConcatenation: + Enabled: false + +# TODO: Enable IneffectiveAccessModifier Cop. +# Checks for attempts to use `private` or `protected` to set the visibility +# of a class method, which does not work. +Lint/IneffectiveAccessModifier: + Enabled: false + +# Checks for invalid character literals with a non-escaped whitespace +# character. +Lint/InvalidCharacterLiteral: + Enabled: false + +# Checks of literals used in conditions. +Lint/LiteralInCondition: + Enabled: false + +# Checks for literals used in interpolation. +Lint/LiteralInInterpolation: + Enabled: false + +# Use Kernel#loop with break rather than begin/end/until or begin/end/while +# for post-loop tests. +Lint/Loop: + Enabled: false + +# Do not use nested method definitions. +Lint/NestedMethodDefinition: + Enabled: false + +# Do not omit the accumulator when calling `next` in a `reduce`/`inject` block. +Lint/NextWithoutAccumulator: + Enabled: false + +# Checks for method calls with a space before the opening parenthesis. +Lint/ParenthesesAsGroupedExpression: + Enabled: true + +# Checks for `rand(1)` calls. Such calls always return `0` and most likely +# a mistake. +Lint/RandOne: + Enabled: false + +# Use parentheses in the method call to avoid confusion about precedence. +Lint/RequireParentheses: + Enabled: false + +# Avoid rescuing the Exception class. +Lint/RescueException: + Enabled: true + +# Do not use the same name as outer local variable for block arguments +# or block local variables. +Lint/ShadowingOuterLocalVariable: + Enabled: false + +# 'Checks for Object#to_s usage in string interpolation. +Lint/StringConversionInInterpolation: + Enabled: false + +# Do not use prefix `_` for a variable that is used. +Lint/UnderscorePrefixedVariableName: + Enabled: true + +# Checks for rubocop:disable comments that can be removed. +# Note: this cop is not disabled when disabling all cops. +# It must be explicitly disabled. +Lint/UnneededDisable: + Enabled: false + +# Checks for unused block arguments. +Lint/UnusedBlockArgument: + Enabled: false + +# Checks for unused method arguments. +Lint/UnusedMethodArgument: + Enabled: false + +# Unreachable code. +Lint/UnreachableCode: + Enabled: false + +# Checks for useless access modifiers. +Lint/UselessAccessModifier: + Enabled: false + +# Checks for useless assignment to a local variable. +Lint/UselessAssignment: + Enabled: true + +# Checks for comparison of something with itself. +Lint/UselessComparison: + Enabled: false + +# Checks for useless `else` in `begin..end` without `rescue`. +Lint/UselessElseWithoutRescue: + Enabled: false + +# Checks for useless setter call to a local variable. +Lint/UselessSetterCall: + Enabled: false + +# Possible use of operator/literal/variable in void context. +Lint/Void: + Enabled: false + + +##################### Performance ############################ + +# TODO: Enable Casecmp Cop. +# Use `casecmp` rather than `downcase ==`. +Performance/Casecmp: + Enabled: false + +# TODO: Enable DoubleStartEndWith Cop. +# Use `str.{start,end}_with?(x, ..., y, ...)` instead of +# `str.{start,end}_with?(x, ...) || str.{start,end}_with?(y, ...)`. +Performance/DoubleStartEndWith: + Enabled: false + +# TODO: Enable EndWith Cop. +# Use `end_with?` instead of a regex match anchored to the end of a string. +Performance/EndWith: + Enabled: false + +# TODO: Enable LstripRstrip Cop. +# Use `strip` instead of `lstrip.rstrip`. +Performance/LstripRstrip: + Enabled: false + +# TODO: Enable RangeInclude Cop. +# Use `Range#cover?` instead of `Range#include?`. +Performance/RangeInclude: + Enabled: false + +# TODO: Enable RedundantBlockCall Cop. +# Use `yield` instead of `block.call`. +Performance/RedundantBlockCall: + Enabled: false + +# TODO: Enable RedundantMatch Cop. +# Use `=~` instead of `String#match` or `Regexp#match` in a context where the +# returned `MatchData` is not needed. +Performance/RedundantMatch: + Enabled: false + +# TODO: Enable RedundantMerge Cop. +# Use `Hash#[]=`, rather than `Hash#merge!` with a single key-value pair. +Performance/RedundantMerge: + # Max number of key-value pairs to consider an offense + MaxKeyValuePairs: 2 + Enabled: false + +# TODO: Enable RedundantSortBy Cop. +# Use `sort` instead of `sort_by { |x| x }`. +Performance/RedundantSortBy: + Enabled: false + +# TODO: Enable StartWith Cop. +# Use `start_with?` instead of a regex match anchored to the beginning of a +# string. +Performance/StartWith: + Enabled: false +# Use `tr` instead of `gsub` when you are replacing the same number of +# characters. Use `delete` instead of `gsub` when you are deleting +# characters. +Performance/StringReplacement: + Enabled: false + +# TODO: Enable TimesMap Cop. +# Checks for `.times.map` calls. +Performance/TimesMap: + Enabled: false + + +##################### Rails ################################## + +# Enables Rails cops. +Rails: + Enabled: true + +# Enforces consistent use of action filter methods. +Rails/ActionFilter: + Enabled: true + EnforcedStyle: action + +# Checks the correct usage of date aware methods, such as `Date.today`, +# `Date.current`, etc. +Rails/Date: + Enabled: false + +# Prefer delegate method for delegations. +Rails/Delegate: + Enabled: false + +# Prefer `find_by` over `where.first`. +Rails/FindBy: + Enabled: false + +# Prefer `all.find_each` over `all.find`. +Rails/FindEach: + Enabled: false + +# Prefer has_many :through to has_and_belongs_to_many. +Rails/HasAndBelongsToMany: + Enabled: true + +# Checks for calls to puts, print, etc. +Rails/Output: + Enabled: true + +# Checks for incorrect grammar when using methods like `3.day.ago`. +Rails/PluralizationGrammar: + Enabled: false + +# Checks for `read_attribute(:attr)` and `write_attribute(:attr, val)`. +Rails/ReadWriteAttribute: + Enabled: false + +# Checks the arguments of ActiveRecord scopes. +Rails/ScopeArgs: + Enabled: false + +# Checks the correct usage of time zone aware methods. +# http://danilenko.org/2012/7/6/rails_timezones +Rails/TimeZone: + Enabled: false + +# Use validates :attribute, hash of validations. +Rails/Validation: + Enabled: false diff --git a/.scss-lint.yml b/.scss-lint.yml new file mode 100644 index 0000000000..835a4a88c4 --- /dev/null +++ b/.scss-lint.yml @@ -0,0 +1,264 @@ +# Linter Documentation: +# https://github.com/brigade/scss-lint/blob/master/lib/scss_lint/linter/README.md + +scss_files: 'app/assets/stylesheets/**/*.scss' + +exclude: + - 'app/assets/stylesheets/pages/emojis.scss' + +linters: + # Reports when you use improper spacing around ! (the "bang") in !default, + # !global, !important, and !optional flags. + BangFormat: + enabled: false + + # Whether or not to prefer `border: 0` over `border: none`. + BorderZero: + enabled: false + + # Reports when you define a rule set using a selector with chained classes + # (a.k.a. adjoining classes). + ChainedClasses: + enabled: false + + # Prefer hexadecimal color codes over color keywords. + # (e.g. `color: green` is a color keyword) + ColorKeyword: + enabled: false + + # Prefer color literals (keywords or hexadecimal codes) to be used only in + # variable declarations. They should be referred to via variables everywhere + # else. + ColorVariable: + enabled: false + + # Which form of comments to prefer in CSS. + Comment: + enabled: false + + # Reports @debug statements (which you probably left behind accidentally). + DebugStatement: + enabled: false + + # Rule sets should be ordered as follows: + # - @extend declarations + # - @include declarations without inner @content + # - properties, @include declarations with inner @content + # - nested rule sets. + DeclarationOrder: + enabled: false + + # `scss-lint:disable` control comments should be preceded by a comment + # explaining why these linters are being disabled for this file. + # See https://github.com/brigade/scss-lint#disabling-linters-via-source for + # more information. + DisableLinterReason: + enabled: true + + # Reports when you define the same property twice in a single rule set. + DuplicateProperty: + enabled: false + + # Separate rule, function, and mixin declarations with empty lines. + EmptyLineBetweenBlocks: + enabled: false + + # Reports when you have an empty rule set. + EmptyRule: + enabled: false + + # Reports when you have an @extend directive. + ExtendDirective: + enabled: false + + # Files should always have a final newline. This results in better diffs + # when adding lines to the file, since SCM systems such as git won't + # think that you touched the last line. + FinalNewline: + enabled: false + + # HEX colors should use three-character values where possible. + HexLength: + enabled: true + + # HEX color values should use lower-case colors to differentiate between + # letters and numbers, e.g. `#E3E3E3` vs. `#e3e3e3`. + HexNotation: + enabled: true + + # Avoid using ID selectors. + IdSelector: + enabled: false + + # The basenames of @imported SCSS partials should not begin with an + # underscore and should not include the filename extension. + ImportPath: + enabled: false + + # Avoid using !important in properties. It is usually indicative of a + # misunderstanding of CSS specificity and can lead to brittle code. + ImportantRule: + enabled: false + + # Indentation should always be done in increments of 2 spaces. + Indentation: + enabled: true + width: 2 + + # Don't write leading zeros for numeric values with a decimal point. + LeadingZero: + enabled: false + + # Reports when you define the same selector twice in a single sheet. + MergeableSelector: + enabled: false + + # Functions, mixins, variables, and placeholders should be declared + # with all lowercase letters and hyphens instead of underscores. + NameFormat: + enabled: false + + # Avoid nesting selectors too deeply. + NestingDepth: + enabled: false + + # Always use placeholder selectors in @extend. + PlaceholderInExtend: + enabled: false + + # Sort properties in a strict order. + PropertySortOrder: + enabled: false + + # Reports when you use an unknown or disabled CSS property + # (ignoring vendor-prefixed properties). + PropertySpelling: + enabled: false + + # Configure which units are allowed for property values. + PropertyUnits: + enabled: false + + # Pseudo-elements, like ::before, and ::first-letter, should be declared + # with two colons. Pseudo-classes, like :hover and :first-child, should + # be declared with one colon. + PseudoElement: + enabled: false + + # Avoid qualifying elements in selectors (also known as "tag-qualifying"). + QualifyingElement: + enabled: false + + # Don't write selectors with a depth of applicability greater than 3. + SelectorDepth: + enabled: false + + # Selectors should always use hyphenated-lowercase, rather than camelCase or + # snake_case. + SelectorFormat: + enabled: false + convention: hyphenated_lowercase + + # Prefer the shortest shorthand form possible for properties that support it. + Shorthand: + enabled: true + + # Each property should have its own line, except in the special case of + # single line rulesets. + SingleLinePerProperty: + enabled: true + allow_single_line_rule_sets: true + + # Split selectors onto separate lines after each comma, and have each + # individual selector occupy a single line. + SingleLinePerSelector: + enabled: false + + # Commas in lists should be followed by a space. + SpaceAfterComma: + enabled: false + + # Properties should be formatted with a single space separating the colon + # from the property's value. + SpaceAfterPropertyColon: + enabled: true + + # Properties should be formatted with no space between the name and the + # colon. + SpaceAfterPropertyName: + enabled: true + + # Variables should be formatted with a single space separating the colon + # from the variable's value. + SpaceAfterVariableColon: + enabled: false + + # Variables should be formatted with no space between the name and the + # colon. + SpaceAfterVariableName: + enabled: false + + # Operators should be formatted with a single space on both sides of an + # infix operator. + SpaceAroundOperator: + enabled: false + + # Opening braces should be preceded by a single space. + SpaceBeforeBrace: + enabled: true + + # Parentheses should not be padded with spaces. + SpaceBetweenParens: + enabled: false + + # Enforces that string literals should be written with a consistent form + # of quotes (single or double). + StringQuotes: + enabled: false + + # Property values, @extend, @include, and @import directives, and variable + # declarations should always end with a semicolon. + TrailingSemicolon: + enabled: false + + # Reports lines containing trailing whitespace. + TrailingWhitespace: + enabled: false + + # Don't write trailing zeros for numeric values with a decimal point. + TrailingZero: + enabled: false + + # Don't use the `all` keyword to specify transition properties. + TransitionAll: + enabled: false + + # Numeric values should not contain unnecessary fractional portions. + UnnecessaryMantissa: + enabled: false + + # Do not use parent selector references (&) when they would otherwise + # be unnecessary. + UnnecessaryParentReference: + enabled: false + + # URLs should be valid and not contain protocols or domain names. + UrlFormat: + enabled: false + + # URLs should always be enclosed within quotes. + UrlQuotes: + enabled: false + + # Properties, like color and font, are easier to read and maintain + # when defined using variables rather than literals. + VariableForProperty: + enabled: false + + # Avoid vendor prefixes. Or rather: don't write them yourself. + VendorPrefix: + enabled: false + + # Omit length units on zero values, e.g. `0px` vs. `0`. + ZeroUnit: + enabled: true diff --git a/CHANGELOG b/CHANGELOG index d11f02e6e2..a23c8a54af 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,42 +1,169 @@ Please view this file on the master branch, on stable branches it's out of date. -v 8.6.0 (unreleased) +v 8.7.0 (unreleased) + - All images in discussions and wikis now link to their source files !3464 (Connor Shea). + - Improved Markdown rendering performance !3389 (Yorick Peterse) + - Don't attempt to look up an avatar in repo if repo directory does not exist (Stan Hu) + - Preserve time notes/comments have been updated at when moving issue + - Make HTTP(s) label consistent on clone bar (Stan Hu) + - Expose label description in API (Mariusz Jachimowicz) + - Allow back dating on issues when created through the API + - Fix Error 500 after renaming a project path (Stan Hu) + - Fix avatar stretching by providing a cropping feature + - Add endpoints to archive or unarchive a project !3372 + - Add links to CI setup documentation from project settings and builds pages + - Handle nil descriptions in Slack issue messages (Stan Hu) + - Add default scope to projects to exclude projects pending deletion + - Ensure empty recipients are rejected in BuildsEmailService + - Implement 'Groups View' as an option for dashboard preferences !3379 (Elias W.) + - Implement 'TODOs View' as an option for dashboard preferences !3379 (Elias W.) + - Gracefully handle notes on deleted commits in merge requests (Stan Hu) + - Fix creation of merge requests for orphaned branches (Stan Hu) + - Fall back to `In-Reply-To` and `References` headers when sub-addressing is not available (David Padilla) + - Remove "Congratulations!" tweet button on newly-created project. (Connor Shea) + - Improved UX of the navigation sidebar + - Build status notifications + - API: Ability to retrieve a specific tag (Robert Schilling) + - API: Expose user location (Robert Schilling) + +v 8.6.5 (unreleased) + - Check permissions when user attempts to import members from another project + +v 8.6.4 + - Don't attempt to fetch any tags from a forked repo (Stan Hu) + +v 8.6.3 + - Mentions on confidential issues doesn't create todos for non-members. !3374 + - Destroy related todos when an Issue/MR is deleted. !3376 + - Fix error 500 when target is nil on todo list. !3376 + - Fix copying uploads when moving issue to another project. !3382 + - Ensuring Merge Request API returns boolean values for work_in_progress (Abhi Rao). !3432 + - Fix raw/rendered diff producing different results on merge requests. !3450 + - Fix commit comment alignment (Stan Hu). !3466 + - Fix Error 500 when searching for a comment in a project snippet. !3468 + - Allow temporary email as notification email. !3477 + - Fix issue with dropdowns not selecting values. !3478 + - Update gitlab-shell version and doc to 2.6.12. gitlab-org/gitlab-ee!280 + +v 8.6.2 + - Fix dropdown alignment. !3298 + - Fix issuable sidebar overlaps on tablet. !3299 + - Make dropdowns pixel perfect. !3337 + - Fix order of steps to prevent PostgreSQL errors when running migration. !3355 + - Fix bold text in issuable sidebar. !3358 + - Fix error with anonymous token in applications settings. !3362 + - Fix the milestone 'upcoming' filter. !3364 + !3368 + - Fix comments on confidential issues showing up in activity feed to non-members. !3375 + - Fix `NoMethodError` when visiting CI root path at `/ci`. !3377 + - Add a tooltip to new branch button in issue page. !3380 + - Fix an issue hiding the password form when signed-in with a linked account. !3381 + - Add links to CI setup documentation from project settings and builds pages. !3384 + - Fix an issue with width of project select dropdown. !3386 + - Remove redundant `require`s from Banzai files. !3391 + - Fix error 500 with cancel button on issuable edit form. !3392 + !3417 + - Fix background when editing a highlighted note. !3423 + - Remove tabstop from the WIP toggle links. !3426 + - Ensure private project snippets are not viewable by unauthorized people. + - Gracefully handle notes on deleted commits in merge requests (Stan Hu). !3402 + - Fixed issue with notification settings not saving. !3452 + +v 8.6.1 + - Add option to reload the schema before restoring a database backup. !2807 + - Display navigation controls on mobile. !3214 + - Fixed bug where participants would not work correctly on merge requests. !3329 + - Fix sorting issues by votes on the groups issues page results in SQL errors. !3333 + - Restrict notifications for confidential issues. !3334 + - Do not allow to move issue if it has not been persisted. !3340 + - Add a confirmation step before deleting an issuable. !3341 + - Fixes issue with signin button overflowing on mobile. !3342 + - Auto collapses the navigation sidebar when resizing. !3343 + - Fix build dependencies, when the dependency is a string. !3344 + - Shows error messages when trying to create label in dropdown menu. !3345 + - Fixes issue with assign milestone not loading milestone list. !3346 + - Fix an issue causing the Dashboard/Milestones page to be blank. !3348 + +v 8.6.0 + - Add ability to move issue to another project + - Prevent tokens in the import URL to be showed by the UI + - Fix bug where wrong commit ID was being used in a merge request diff to show old image (Stan Hu) + - Add confidential issues + - Bump gitlab_git to 9.0.3 (Stan Hu) + - Fix diff image view modes (2-up, swipe, onion skin) not working (Stan Hu) - Support Golang subpackage fetching (Stan Hu) + - Bump Capybara gem to 2.6.2 (Stan Hu) + - New branch button appears on issues where applicable - Contributions to forked projects are included in calendar - Improve the formatting for the user page bio (Connor Shea) + - Easily (un)mark merge request as WIP using link + - Use specialized system notes when MR is (un)marked as WIP - Removed the default password from the initial admin account created during setup. A password can be provided during setup (see installation docs), or GitLab will ask the user to create a new one upon first visit. - Fix issue when pushing to projects ending in .wiki - - Fix avatar stretching by providing a cropping feature (Johann Pardanaud) + - Properly display YAML front matter in Markdown + - Add support for wiki with UTF-8 page names (Hiroyuki Sato) + - Fix wiki search results point to raw source (Hiroyuki Sato) - Don't load all of GitLab in mail_room + - Add information about `image` and `services` field at `job` level in the `.gitlab-ci.yml` documentation (Pat Turner) + - HTTP error pages work independently from location and config (Artem Sidorenko) - Update `omniauth-saml` to 1.5.0 to allow for custom response attributes to be set - Memoize @group in Admin::GroupsController (Yatish Mehta) - Indicate how much an MR diverged from the target branch (Pierre de La Morinerie) + - Added omniauth-auth0 Gem (Daniel Carraro) + - Add label description in tooltip to labels in issue index and sidebar - Strip leading and trailing spaces in URL validator (evuez) - Add "last_sign_in_at" and "confirmed_at" to GET /users/* API endpoints for admins (evuez) - Return empty array instead of 404 when commit has no statuses in commit status API - Decrease the font size and the padding of the `.anchor` icons used in the README (Roberto Dip) - Rewrite logo to simplify SVG code (Sean Lang) + - Allow to use YAML anchors when parsing the `.gitlab-ci.yml` (Pascal Bach) + - Ignore jobs that start with `.` (hidden jobs) + - Hide builds from project's settings when the feature is disabled + - Allow to pass name of created artifacts archive in `.gitlab-ci.yml` - Refactor and greatly improve search performance - Add support for cross-project label references + - Ensure "new SSH key" email do not ends up as dead Sidekiq jobs - Update documentation to reflect Guest role not being enforced on internal projects - Allow search for logged out users + - Allow to define on which builds the current one depends on + - Allow user subscription to a label: get notified for issues/merge requests related to that label (Timothy Andrew) - Fix bug where Bitbucket `closed` issues were imported as `opened` (Iuri de Silvio) - Don't show Issues/MRs from archived projects in Groups view + - Fix wrong "iid of max iid" in Issuable sidebar for some merged MRs + - Fix empty source_sha on Merge Request when there is no diff (Pierre de La Morinerie) - Increase the notes polling timeout over time (Roberto Dip) - Add shortcut to toggle markdown preview (Florent Baldino) - Show labels in dashboard and group milestone views + - Fix an issue when the target branch of a MR had been deleted - Add main language of a project in the list of projects (Tiago Botelho) + - Add #upcoming filter to Milestone filter (Tiago Botelho) - Add ability to show archived projects on dashboard, explore and group pages + - Remove fork link closes all merge requests opened on source project (Florent Baldino) - Move group activity to separate page + - Create external users which are excluded of internal and private projects unless access was explicitly granted + - Continue parameters are checked to ensure redirection goes to the same instance + - User deletion is now done in the background so the request can not time out + - Canceled builds are now ignored in compound build status if marked as `allowed to fail` + - Trigger a todo for mentions on commits page + - Let project owners and admins soft delete issues and merge requests + +v 8.5.9 + - Don't attempt to fetch any tags from a forked repo (Stan Hu). + +v 8.5.8 + - Bump Git version requirement to 2.7.4 + +v 8.5.7 + - Bump Git version requirement to 2.7.3 + +v 8.5.6 + - Obtain a lease before querying LDAP v 8.5.5 - Ensure removing a project removes associated Todo entries - Prevent a 500 error in Todos when author was removed - Fix pagination for filtered dashboard and explore pages - Fix "Show all" link behavior - - Add #upcoming filter to Milestone filter (Tiago Botelho) v 8.5.4 - Do not cache requests for badges (including builds badge) @@ -164,6 +291,12 @@ v 8.5.0 - Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul) - Add Todos +v 8.4.7 + - Don't attempt to fetch any tags from a forked repo (Stan Hu). + +v 8.4.6 + - Bump Git version requirement to 2.7.4 + v 8.4.5 - No CE-specific changes @@ -277,6 +410,12 @@ v 8.4.0 - Add IP check against DNSBLs at account sign-up - Added cache:key to .gitlab-ci.yml allowing to fine tune the caching +v 8.3.6 + - Don't attempt to fetch any tags from a forked repo (Stan Hu). + +v 8.3.5 + - Bump Git version requirement to 2.7.4 + v 8.3.4 - Use gitlab-workhorse 0.5.4 (fixes API routing bug) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30c9742904..511336f384 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,6 +16,7 @@ - [Issue tracker guidelines](#issue-tracker-guidelines) - [Issue weight](#issue-weight) - [Regression issues](#regression-issues) + - [Technical debt](#technical-debt) - [Merge requests](#merge-requests) - [Merge request guidelines](#merge-request-guidelines) - [Merge request description format](#merge-request-description-format) @@ -242,6 +243,28 @@ addressed. [8.3 Regressions]: https://gitlab.com/gitlab-org/gitlab-ce/issues/4127 [update the notes]: https://gitlab.com/gitlab-org/release-tools/blob/master/doc/pro-tips.md#update-the-regression-issue +### Technical debt + +In order to track things that can be improved in GitLab's codebase, we created +the ~"technical debt" label in [GitLab's issue tracker][ce-tracker]. + +This label should be added to issues that describe things that can be improved, +shortcuts that have been taken, code that needs refactoring, features that need +additional attention, and all other things that have been left behind due to +high velocity of development. + +Everyone can create an issue, though you may need to ask for adding a specific +label, if you do not have permissions to do it by yourself. Additional labels +can be combined with the `technical debt` label, to make it easier to schedule +the improvements for a release. + +Issues tagged with the `technical debt` label have the same priority like issues +that describe a new feature to be introduced in GitLab, and should be scheduled +for a release by the appropriate person. + +Make sure to mention the merge request that the `technical debt` issue is +associated with in the description of the issue. + ## Merge requests We welcome merge requests with fixes and improvements to GitLab code, tests, @@ -427,6 +450,7 @@ merge request: 1. [Rails](https://github.com/bbatsov/rails-style-guide) 1. [Testing](https://github.com/thoughtbot/guides/tree/master/style/testing) 1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style/coffeescript) +1. [SCSS styleguide][scss-styleguide] 1. [Shell commands](doc/development/shell_commands.md) created by GitLab contributors to enhance security 1. [Database Migrations](doc/development/migration_style_guide.md) @@ -494,6 +518,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor [rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout [rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming [doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide" +[scss-styleguide]: doc/development/scss_styleguide.md "SCSS styleguide" [gitlab-design]: https://gitlab.com/gitlab-org/gitlab-design [free Antetype viewer (Mac OSX only)]: https://itunes.apple.com/us/app/antetype-viewer/id824152298?mt=12 [`gitlab1.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/gitlab1.atype/ diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index a04abec914..24ba9a38de 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -2.6.10 +2.7.0 diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION index ef5e445445..39e898a4f9 100644 --- a/GITLAB_WORKHORSE_VERSION +++ b/GITLAB_WORKHORSE_VERSION @@ -1 +1 @@ -0.6.5 +0.7.1 diff --git a/Gemfile b/Gemfile index 1550afb1b5..6327227282 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,7 @@ gem 'devise', '~> 3.5.4' gem 'devise-async', '~> 0.9.0' gem 'doorkeeper', '~> 2.2.0' gem 'omniauth', '~> 1.3.1' +gem 'omniauth-auth0', '~> 1.4.1' gem 'omniauth-azure-oauth2', '~> 0.0.6' gem 'omniauth-bitbucket', '~> 0.0.2' gem 'omniauth-cas3', '~> 1.1.2' @@ -50,7 +51,7 @@ gem "browser", '~> 1.0.0' # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '~> 9.0' +gem "gitlab_git", '~> 10.0' # LDAP Auth # GitLab fork with several improvements to original library. For full list of changes @@ -58,7 +59,9 @@ gem "gitlab_git", '~> 9.0' gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: "omniauth-ldap" # Git Wiki -gem 'gollum-lib', '~> 4.1.0' +# Required manually in config/initializers/gollum.rb to control load order +gem 'gollum-lib', '~> 4.1.0', require: false +gem 'gollum-rugged_adapter', '~> 0.4.2', require: false # Language detection gem "github-linguist", "~> 4.7.0", require: "linguist" @@ -77,9 +80,6 @@ gem "haml-rails", '~> 0.9.0' # Files attachments gem "carrierwave", '~> 0.10.0' -# Image editing -gem "mini_magick", '~> 4.4.0' - # Drag and Drop UI gem 'dropzonejs-rails', '~> 0.7.1' @@ -214,7 +214,7 @@ gem 'jquery-rails', '~> 4.0.0' gem 'jquery-scrollto-rails', '~> 1.4.3' gem 'jquery-ui-rails', '~> 5.0.0' gem 'raphael-rails', '~> 2.1.2' -gem 'request_store', '~> 1.2.0' +gem 'request_store', '~> 1.3.0' gem 'select2-rails', '~> 3.5.9' gem 'virtus', '~> 1.0.1' gem 'net-ssh', '~> 3.0.1' @@ -222,6 +222,8 @@ gem 'net-ssh', '~> 3.0.1' # Sentry integration gem 'sentry-raven', '~> 0.15' +gem 'premailer-rails', '~> 1.9.0' + # Metrics group :metrics do gem 'allocations', '~> 1.0', require: false, platform: :mri @@ -232,7 +234,7 @@ end group :development do gem "foreman" - gem 'brakeman', '~> 3.1.0', require: false + gem 'brakeman', '~> 3.2.0', require: false gem "annotate", "~> 2.6.0" gem "letter_opener", '~> 1.1.2' @@ -273,11 +275,11 @@ group :development, :test do # Generate Fake data gem 'ffaker', '~> 2.0.0' - gem 'capybara', '~> 2.4.0' + gem 'capybara', '~> 2.6.2' gem 'capybara-screenshot', '~> 1.0.0' gem 'poltergeist', '~> 1.9.0' - gem 'teaspoon', '~> 1.0.0' + gem 'teaspoon', '~> 1.1.0' gem 'teaspoon-jasmine', '~> 2.2.0' gem 'spring', '~> 1.6.4' @@ -285,7 +287,8 @@ group :development, :test do gem 'spring-commands-spinach', '~> 1.0.0' gem 'spring-commands-teaspoon', '~> 0.0.2' - gem 'rubocop', '~> 0.35.0', require: false + gem 'rubocop', '~> 0.38.0', require: false + gem 'scss_lint', '~> 0.47.0', require: false gem 'coveralls', '~> 0.8.2', require: false gem 'simplecov', '~> 0.10.0', require: false gem 'flog', require: false diff --git a/Gemfile.lock b/Gemfile.lock index d4e28db00d..0981c3195a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,9 +61,7 @@ GEM faraday_middleware-multi_json (~> 0.0) oauth2 (~> 1.0) asciidoctor (1.5.3) - ast (2.1.0) - astrolabe (1.3.1) - parser (~> 2.2) + ast (2.2.0) attr_encrypted (1.3.4) encryptor (>= 1.3.0) attr_required (1.0.0) @@ -86,29 +84,28 @@ GEM bootstrap-sass (3.3.6) autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) - brakeman (3.1.4) + brakeman (3.2.1) erubis (~> 2.6) - fastercsv (~> 1.5) haml (>= 3.0, < 5.0) highline (>= 1.6.20, < 2.0) - multi_json (~> 1.2) - ruby2ruby (>= 2.1.1, < 2.3.0) - ruby_parser (~> 3.7.0) + ruby2ruby (~> 2.3.0) + ruby_parser (~> 3.8.1) safe_yaml (>= 1.0) sass (~> 3.0) slim (>= 1.3.6, < 4.0) terminal-table (~> 1.4) browser (1.0.1) builder (3.2.2) - bullet (4.14.10) + bullet (5.0.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.9.0) - bundler-audit (0.4.0) + bundler-audit (0.5.0) bundler (~> 1.2) thor (~> 0.18) byebug (8.2.1) cal-heatmap-rails (3.5.1) - capybara (2.4.4) + capybara (2.6.2) + addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) @@ -129,9 +126,9 @@ GEM coderay (1.1.0) coercible (1.0.0) descendants_tracker (~> 0.0.1) - coffee-rails (4.1.0) + coffee-rails (4.1.1) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.0) + railties (>= 4.0.0, < 5.1.x) coffee-script (2.4.1) coffee-script-source execjs @@ -149,6 +146,8 @@ GEM crack (0.4.3) safe_yaml (~> 1.0.0) creole (0.5.0) + css_parser (1.3.7) + addressable d3_rails (3.5.11) railties (>= 3.1.0) daemons (1.2.3) @@ -207,7 +206,6 @@ GEM faraday_middleware-multi_json (0.0.6) faraday_middleware multi_json - fastercsv (1.5.5) ffaker (2.0.0) ffi (1.9.10) fission (0.5.0) @@ -327,8 +325,8 @@ GEM fog-xml (0.1.2) fog-core nokogiri (~> 1.5, >= 1.5.11) - font-awesome-rails (4.5.0.0) - railties (>= 3.2, < 5.0) + font-awesome-rails (4.5.0.1) + railties (>= 3.2, < 5.1) foreman (0.78.0) thor (~> 0.19.1) formatador (0.2.5) @@ -358,11 +356,11 @@ GEM posix-spawn (~> 0.3) gitlab_emoji (0.3.1) gemojione (~> 2.2, >= 2.2.1) - gitlab_git (9.0.1) + gitlab_git (10.0.0) activesupport (~> 4.0) charlock_holmes (~> 0.7.3) github-linguist (~> 4.7.0) - rugged (~> 0.24.0b13) + rugged (~> 0.24.0) gitlab_meta (7.0) gitlab_omniauth-ldap (1.2.1) net-ldap (~> 0.9) @@ -380,6 +378,9 @@ GEM rouge (~> 1.9) sanitize (~> 2.1.0) stringex (~> 2.5.1) + gollum-rugged_adapter (0.4.2) + mime-types (>= 1.15) + rugged (~> 0.24.0, >= 0.21.3) gon (6.0.1) actionpack (>= 3.0) json @@ -419,6 +420,7 @@ GEM haml (~> 4.0.0) nokogiri (~> 1.6.0) ruby_parser (~> 3.5) + htmlentities (4.3.4) http-cookie (1.0.2) domain_name (~> 0.5) http_parser.rb (0.5.3) @@ -468,7 +470,6 @@ GEM method_source (0.8.2) mime-types (1.25.1) mimemagic (0.3.0) - mini_magick (4.4.0) mini_portile2 (2.0.0) minitest (5.7.0) mousetrap-rails (1.4.6) @@ -495,6 +496,8 @@ GEM omniauth (1.3.1) hashie (>= 1.2, < 4) rack (>= 1.0, < 3) + omniauth-auth0 (1.4.1) + omniauth-oauth2 (~> 1.1) omniauth-azure-oauth2 (0.0.6) jwt (~> 1.0) omniauth (~> 1.0) @@ -549,8 +552,8 @@ GEM orm_adapter (0.5.0) paranoia (2.1.4) activerecord (~> 4.0) - parser (2.2.3.0) - ast (>= 1.1, < 3.0) + parser (2.3.0.6) + ast (~> 2.2) pg (0.18.4) poltergeist (1.9.0) capybara (~> 2.1) @@ -559,6 +562,12 @@ GEM websocket-driver (>= 0.2.0) posix-spawn (0.3.11) powerpack (0.1.1) + premailer (1.8.6) + css_parser (>= 1.3.6) + htmlentities (>= 4.0.0) + premailer-rails (1.9.0) + actionmailer (>= 3, < 5) + premailer (~> 1.7, >= 1.7.9) pry (0.10.3) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -610,7 +619,7 @@ GEM activesupport (= 4.2.5.2) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.0.0) + rainbow (2.1.0) raindrops (0.15.0) rake (10.5.0) raphael-rails (2.1.2) @@ -643,7 +652,7 @@ GEM redis-store (~> 1.1.0) redis-store (1.1.7) redis (>= 2.2) - request_store (1.2.1) + request_store (1.3.0) rerun (0.11.0) listen (~> 3.0) responders (2.1.1) @@ -682,32 +691,31 @@ GEM rspec-retry (0.4.5) rspec-core rspec-support (3.3.0) - rubocop (0.35.1) - astrolabe (~> 1.3) - parser (>= 2.2.3.0, < 3.0) + rubocop (0.38.0) + parser (>= 2.3.0.6, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) - tins (<= 1.6.0) + unicode-display_width (~> 1.0, >= 1.0.1) ruby-fogbugz (0.2.1) crack (~> 0.4) ruby-progressbar (1.7.5) ruby-saml (1.1.2) nokogiri (>= 1.5.10) uuid (~> 2.3) - ruby2ruby (2.2.0) + ruby2ruby (2.3.0) ruby_parser (~> 3.1) sexp_processor (~> 4.0) - ruby_parser (3.7.2) + ruby_parser (3.8.1) sexp_processor (~> 4.1) rubyntlm (0.5.2) rubypants (0.2.0) rufus-scheduler (3.1.10) - rugged (0.24.0b13) + rugged (0.24.0) safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) - sass (3.4.20) + sass (3.4.21) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) sass (~> 3.1) @@ -717,6 +725,9 @@ GEM sawyer (0.6.0) addressable (~> 2.3.5) faraday (~> 0.8, < 0.10) + scss_lint (0.47.1) + rake (>= 0.9, < 11) + sass (~> 3.4.15) sdoc (0.3.20) json (>= 1.1.3) rdoc (~> 3.10) @@ -728,7 +739,7 @@ GEM sentry-raven (0.15.6) faraday (>= 0.7.6) settingslogic (2.0.9) - sexp_processor (4.6.0) + sexp_processor (4.7.0) sham_rack (1.3.6) rack shoulda-matchers (2.8.0) @@ -792,8 +803,8 @@ GEM systemu (2.6.5) task_list (1.0.2) html-pipeline - teaspoon (1.0.2) - railties (>= 3.2.5, < 5) + teaspoon (1.1.5) + railties (>= 3.2.5, < 6) teaspoon-jasmine (2.2.0) teaspoon (>= 1.0.0) temple (0.7.6) @@ -835,6 +846,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.1) + unicode-display_width (1.0.2) unicorn (4.9.0) kgio (~> 2.6) rack @@ -853,7 +865,7 @@ GEM equalizer (~> 0.0, >= 0.0.9) warden (1.2.4) rack (>= 1.0) - web-console (2.2.1) + web-console (2.3.0) activemodel (>= 4.0) binding_of_caller (>= 0.7.2) railties (>= 4.0) @@ -895,13 +907,13 @@ DEPENDENCIES better_errors (~> 1.0.1) binding_of_caller (~> 0.7.2) bootstrap-sass (~> 3.3.0) - brakeman (~> 3.1.0) + brakeman (~> 3.2.0) browser (~> 1.0.0) bullet bundler-audit byebug cal-heatmap-rails (~> 3.5.0) - capybara (~> 2.4.0) + capybara (~> 2.6.2) capybara-screenshot (~> 1.0.0) carrierwave (~> 0.10.0) charlock_holmes (~> 0.7.3) @@ -934,10 +946,11 @@ DEPENDENCIES github-markup (~> 1.3.1) gitlab-flowdock-git-hook (~> 1.0.1) gitlab_emoji (~> 0.3.0) - gitlab_git (~> 9.0) + gitlab_git (~> 10.0) gitlab_meta (= 7.0) gitlab_omniauth-ldap (~> 1.2.1) gollum-lib (~> 4.1.0) + gollum-rugged_adapter (~> 0.4.2) gon (~> 6.0.1) grape (~> 0.13.0) grape-entity (~> 0.4.2) @@ -956,7 +969,6 @@ DEPENDENCIES loofah (~> 2.0.3) mail_room (~> 0.6.1) method_source (~> 0.8) - mini_magick (~> 4.4.0) minitest (~> 5.7.0) mousetrap-rails (~> 1.4.6) mysql2 (~> 0.3.16) @@ -967,6 +979,7 @@ DEPENDENCIES oauth2 (~> 1.0.0) octokit (~> 3.8.0) omniauth (~> 1.3.1) + omniauth-auth0 (~> 1.4.1) omniauth-azure-oauth2 (~> 0.0.6) omniauth-bitbucket (~> 0.0.2) omniauth-cas3 (~> 1.1.2) @@ -983,6 +996,7 @@ DEPENDENCIES paranoia (~> 2.0) pg (~> 0.18.2) poltergeist (~> 1.9.0) + premailer-rails (~> 1.9.0) pry-rails quiet_assets (~> 1.0.2) rack-attack (~> 4.3.1) @@ -997,17 +1011,18 @@ DEPENDENCIES redcarpet (~> 3.3.3) redis-namespace redis-rails (~> 4.0.0) - request_store (~> 1.2.0) + request_store (~> 1.3.0) rerun (~> 0.11.0) responders (~> 2.0) rouge (~> 1.10.1) rqrcode-rails3 (~> 0.1.7) rspec-rails (~> 3.3.0) rspec-retry - rubocop (~> 0.35.0) + rubocop (~> 0.38.0) ruby-fogbugz (~> 0.2.1) sanitize (~> 2.0) sass-rails (~> 5.0.0) + scss_lint (~> 0.47.0) sdoc (~> 0.3.20) seed-fu (~> 2.3.5) select2-rails (~> 3.5.9) @@ -1030,7 +1045,7 @@ DEPENDENCIES sprockets (~> 3.3.5) state_machines-activerecord (~> 0.3.0) task_list (~> 1.0.2) - teaspoon (~> 1.0.0) + teaspoon (~> 1.1.0) teaspoon-jasmine (~> 2.2.0) test_after_commit (~> 0.4.2) thin (~> 1.6.1) diff --git a/README.md b/README.md index 3ec1d4a776..afa60116eb 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ GitLab is a Ruby on Rails application that runs on the following software: - Ubuntu/Debian/CentOS/RHEL - Ruby (MRI) 2.1 -- Git 1.7.10+ +- Git 2.7.4+ - Redis 2.8+ - MySQL or PostgreSQL diff --git a/VERSION b/VERSION index cac7d91add..91ab1f99da 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.6.0-pre +8.7.0-pre diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index 2ddf8612db..f3ed9a6671 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -74,6 +74,8 @@ dataType: "json" ).done (label) -> callback(label) + .error (message) -> + callback(message.responseJSON) # Return group projects list. Filtered by query groupProjects: (group_id, query, callback) -> diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 1212e89975..f01c67e947 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -7,6 +7,7 @@ #= require jquery #= require jquery-ui/autocomplete #= require jquery-ui/datepicker +#= require jquery-ui/draggable #= require jquery-ui/effect-highlight #= require jquery-ui/sortable #= require jquery_ujs @@ -42,7 +43,7 @@ #= require jquery.nicescroll #= require_tree . #= require fuzzaldrin-plus -#= require cropper.js +#= require cropper window.slugify = (text) -> text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() @@ -108,6 +109,8 @@ window.onload = -> setTimeout shiftWindow, 100 $ -> + bootstrapBreakpoint = bp.getBreakpointSize() + $(".nicescroll").niceScroll(cursoropacitymax: '0.4', cursorcolor: '#FFF', cursorborder: "1px solid #FFF") # Click a .js-select-on-focus field, select the contents @@ -137,7 +140,7 @@ $ -> # Initialize tooltips $('body').tooltip( - selector: '.has_tooltip, [data-toggle="tooltip"]' + selector: '.has-tooltip, [data-toggle="tooltip"]' placement: (_, el) -> $el = $(el) $el.data('placement') || 'bottom' @@ -216,13 +219,20 @@ $ -> $this = $(this) $this.attr 'value', $this.val() + $sidebarGutterToggle = $('.js-sidebar-toggle') + $navIconToggle = $('.toggle-nav-collapse') + $(document) .off 'breakpoint:change' .on 'breakpoint:change', (e, breakpoint) -> if breakpoint is 'sm' or breakpoint is 'xs' - $gutterIcon = $('.js-sidebar-toggle').find('i') + $gutterIcon = $sidebarGutterToggle.find('i') if $gutterIcon.hasClass('fa-angle-double-right') - $gutterIcon.closest('a').trigger('click') + $sidebarGutterToggle.trigger('click') + + $navIcon = $navIconToggle.find('.fa') + if $navIcon.hasClass('fa-angle-left') + $navIconToggle.trigger('click') $(document) .off 'click', '.js-sidebar-toggle' @@ -256,35 +266,14 @@ $ -> $('.right-sidebar') .hasClass('right-sidebar-collapsed'), { path: '/' }) - bootstrapBreakpoint = undefined; - checkBootstrapBreakpoints = -> - if $('.device-xs').is(':visible') - bootstrapBreakpoint = "xs" - else if $('.device-sm').is(':visible') - bootstrapBreakpoint = "sm" - else if $('.device-md').is(':visible') - bootstrapBreakpoint = "md" - else if $('.device-lg').is(':visible') - bootstrapBreakpoint = "lg" - - setBootstrapBreakpoints = -> - if $('.device-xs').length - return - - $("body") - .append('
'+ - '
'+ - '
'+ - '
') - checkBootstrapBreakpoints() - fitSidebarForSize = -> oldBootstrapBreakpoint = bootstrapBreakpoint - checkBootstrapBreakpoints() + bootstrapBreakpoint = bp.getBreakpointSize() if bootstrapBreakpoint != oldBootstrapBreakpoint $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) checkInitialSidebarSize = -> + bootstrapBreakpoint = bp.getBreakpointSize() if bootstrapBreakpoint is "xs" or "sm" $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) @@ -293,6 +282,5 @@ $ -> .on "resize", (e) -> fitSidebarForSize() - setBootstrapBreakpoints() checkInitialSidebarSize() new Aside() diff --git a/app/assets/javascripts/aside.js.coffee b/app/assets/javascripts/aside.js.coffee index 8547310194..66ab505432 100644 --- a/app/assets/javascripts/aside.js.coffee +++ b/app/assets/javascripts/aside.js.coffee @@ -5,7 +5,6 @@ class @Aside e.preventDefault() btn = $(e.currentTarget) icon = btn.find('i') - console.log('1') if icon.hasClass('fa-angle-left') btn.parent().find('section').hide() diff --git a/app/assets/javascripts/awards_handler.coffee b/app/assets/javascripts/awards_handler.coffee index 03a4487416..6a670d5e88 100644 --- a/app/assets/javascripts/awards_handler.coffee +++ b/app/assets/javascripts/awards_handler.coffee @@ -1,5 +1,5 @@ class @AwardsHandler - constructor: (@post_emoji_url, @noteable_type, @noteable_id, @aliases) -> + constructor: (@get_emojis_url, @post_emoji_url, @noteable_type, @noteable_id, @aliases) -> $(".js-add-award").on "click", (event) => event.stopPropagation() event.preventDefault() @@ -34,7 +34,7 @@ class @AwardsHandler $("#emoji_search").focus() else $('.js-add-award').addClass "is-loading" - $.get "/emojis", (response) => + $.get @get_emojis_url, (response) => $('.js-add-award').removeClass "is-loading" $(".js-award-holder").append response setTimeout => @@ -122,7 +122,7 @@ class @AwardsHandler nodes = [] nodes.push( - "" diff --git a/app/assets/javascripts/breakpoints.coffee b/app/assets/javascripts/breakpoints.coffee new file mode 100644 index 0000000000..5457430f92 --- /dev/null +++ b/app/assets/javascripts/breakpoints.coffee @@ -0,0 +1,37 @@ +class @Breakpoints + instance = null; + + class BreakpointInstance + BREAKPOINTS = ["xs", "sm", "md", "lg"] + + constructor: -> + @setup() + + setup: -> + allDeviceSelector = BREAKPOINTS.map (breakpoint) -> + ".device-#{breakpoint}" + return if $(allDeviceSelector.join(",")).length + + # Create all the elements + els = $.map BREAKPOINTS, (breakpoint) -> + "
" + $("body").append els.join('') + + visibleDevice: -> + allDeviceSelector = BREAKPOINTS.map (breakpoint) -> + ".device-#{breakpoint}" + $(allDeviceSelector.join(",")).filter(":visible") + + getBreakpointSize: -> + $visibleDevice = @visibleDevice + # the page refreshed via turbolinks + if not $visibleDevice().length + @setup() + $visibleDevice = @visibleDevice() + return $visibleDevice.attr("class").split("visible-")[1] + + @get: -> + return instance ?= new BreakpointInstance + +$ => + @bp = Breakpoints.get() diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index ee81fee586..70fd6f50e9 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -14,7 +14,6 @@ class Dispatcher path = page.split(':') shortcut_handler = null - switch page when 'projects:issues:index' Issues.init() @@ -25,6 +24,8 @@ class Dispatcher new ZenMode() when 'projects:milestones:show', 'groups:milestones:show', 'dashboard:milestones:show' new Milestone() + when 'dashboard:todos:index' + new Todos() when 'projects:milestones:new', 'projects:milestones:edit' new ZenMode() new DropzoneInput($('.milestone-form')) @@ -104,6 +105,8 @@ class Dispatcher new ProjectFork() when 'projects:artifacts:browse' new BuildArtifacts() + when 'projects:group_links:index' + new GroupsSelect() switch path.first() when 'admin' @@ -143,15 +146,11 @@ class Dispatcher when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches' shortcut_handler = new ShortcutsNavigation() - # If we haven't installed a custom shortcut handler, install the default one if not shortcut_handler new Shortcuts() initSearch: -> - opts = $('.search-autocomplete-opts') - path = opts.data('autocomplete-path') - project_id = opts.data('autocomplete-project-id') - project_ref = opts.data('autocomplete-project-ref') - new SearchAutocomplete(path, project_id, project_ref) + # Only when search form is present + new SearchAutocomplete() if $('.search').length diff --git a/app/assets/javascripts/gl_crop.js.coffee b/app/assets/javascripts/gl_crop.js.coffee new file mode 100644 index 0000000000..df9bfdfa6c --- /dev/null +++ b/app/assets/javascripts/gl_crop.js.coffee @@ -0,0 +1,152 @@ +class GitLabCrop + # Matches everything but the file name + FILENAMEREGEX = /^.*[\\\/]/ + + constructor: (input, opts = {}) -> + @fileInput = $(input) + + # We should rename to avoid spec to fail + # Form will submit the proper input filed with a file using FormData + @fileInput + .attr('name', "#{@fileInput.attr('name')}-trigger") + .attr('id', "#{@fileInput.attr('id')}-trigger") + + # Set defaults + { + @exportWidth = 200 + @exportHeight = 200 + @cropBoxWidth = 200 + @cropBoxHeight = 200 + @form = @fileInput.parents('form') + + # Required params + @filename + @previewImage + @modalCrop + @pickImageEl + @uploadImageBtn + @modalCropImg + } = opts + + # Ensure needed elements are jquery objects + # If selector is provided we will convert them to a jQuery Object + @filename = @getElement(@filename) + @previewImage = @getElement(@previewImage) + @pickImageEl = @getElement(@pickImageEl) + + # Modal elements usually are outside the @form element + @modalCrop = if _.isString(@modalCrop) then $(@modalCrop) else @modalCrop + @uploadImageBtn = if _.isString(@uploadImageBtn) then $(@uploadImageBtn) else @uploadImageBtn + @modalCropImg = if _.isString(@modalCropImg) then $(@modalCropImg) else @modalCropImg + + @cropActionsBtn = @modalCrop.find('[data-method]') + + @bindEvents() + + getElement: (selector) -> + $(selector, @form) + + bindEvents: -> + _this = @ + @fileInput.on 'change', (e) -> + _this.onFileInputChange(e, @) + + @pickImageEl.on 'click', @onPickImageClick + @modalCrop.on 'shown.bs.modal', @onModalShow + @modalCrop.on 'hidden.bs.modal', @onModalHide + @uploadImageBtn.on 'click', @onUploadImageBtnClick + @cropActionsBtn.on 'click', (e) -> + btn = @ + _this.onActionBtnClick(btn) + @croppedImageBlob = null + + onPickImageClick: => + @fileInput.trigger('click') + + onModalShow: => + _this = @ + @modalCropImg.cropper( + viewMode: 1 + center: false + aspectRatio: 1 + modal: true + scalable: false + rotatable: false + zoomable: true + dragMode: 'move' + guides: false + zoomOnTouch: false + zoomOnWheel: false + cropBoxMovable: false + cropBoxResizable: false + toggleDragModeOnDblclick: false + built: -> + $image = $(@) + container = $image.cropper 'getContainerData' + cropBoxWidth = _this.cropBoxWidth; + cropBoxHeight = _this.cropBoxHeight; + + $image.cropper('setCropBoxData', + width: cropBoxWidth, + height: cropBoxHeight, + left: (container.width - cropBoxWidth) / 2, + top: (container.height - cropBoxHeight) / 2 + ) + ) + + + onModalHide: => + @modalCropImg + .attr('src', '') # Remove attached image + .cropper('destroy') # Destroy cropper instance + + onUploadImageBtnClick: (e) => + e.preventDefault() + @setBlob() + @setPreview() + @modalCrop.modal('hide') + @fileInput.val('') + + onActionBtnClick: (btn) -> + data = $(btn).data() + + if @modalCropImg.data('cropper') && data.method + result = @modalCropImg.cropper data.method, data.option + + onFileInputChange: (e, input) -> + @readFile(input) + + readFile: (input) -> + _this = @ + reader = new FileReader + reader.onload = -> + _this.modalCropImg.attr('src', reader.result) + _this.modalCrop.modal('show') + + reader.readAsDataURL(input.files[0]) + + dataURLtoBlob: (dataURL) -> + binary = atob(dataURL.split(',')[1]) + array = [] + for v, k in binary + array.push(binary.charCodeAt(k)) + new Blob([new Uint8Array(array)], type: 'image/png') + + setPreview: -> + @previewImage.attr('src', @dataURL) + filename = @fileInput.val().replace(FILENAMEREGEX, '') + @filename.text(filename) + + setBlob: -> + @dataURL = @modalCropImg.cropper('getCroppedCanvas', + width: 200 + height: 200 + ).toDataURL('image/png') + @croppedImageBlob = @dataURLtoBlob(@dataURL) + + getBlob: -> + @croppedImageBlob + +$.fn.glCrop = (opts) -> + return @.each -> + $(@).data('glcrop', new GitLabCrop(@, opts)) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 8e1449bc59..2a4811b876 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -1,23 +1,48 @@ class GitLabDropdownFilter BLUR_KEYCODES = [27, 40] + ARROW_KEY_CODES = [38, 40] + HAS_VALUE_CLASS = "has-value" - constructor: (@dropdown, @options) -> - @input = @dropdown.find(".dropdown-input .dropdown-input-field") + constructor: (@input, @options) -> + { + @filterInputBlur = true + } = @options + + $inputContainer = @input.parent() + $clearButton = $inputContainer.find('.js-dropdown-input-clear') + + # Clear click + $clearButton.on 'click', (e) => + e.preventDefault() + e.stopPropagation() + @input + .val('') + .trigger('keyup') + .focus() # Key events timeout = "" @input.on "keyup", (e) => - if e.keyCode is 13 && @input.val() isnt "" + keyCode = e.which + + return if ARROW_KEY_CODES.indexOf(keyCode) >= 0 + + if @input.val() isnt "" and !$inputContainer.hasClass HAS_VALUE_CLASS + $inputContainer.addClass HAS_VALUE_CLASS + else if @input.val() is "" and $inputContainer.hasClass HAS_VALUE_CLASS + $inputContainer.removeClass HAS_VALUE_CLASS + + if keyCode is 13 and @input.val() isnt "" if @options.enterCallback @options.enterCallback() return clearTimeout timeout timeout = setTimeout => - blur_field = @shouldBlur e.keyCode + blur_field = @shouldBlur keyCode search_text = @input.val() - if blur_field + if blur_field and @filterInputBlur @input.blur() if @options.remote @@ -76,39 +101,67 @@ class GitLabDropdown LOADING_CLASS = "is-loading" PAGE_TWO_CLASS = "is-page-two" ACTIVE_CLASS = "is-active" + currentIndex = -1 + + FILTER_INPUT = '.dropdown-input .dropdown-input-field' constructor: (@el, @options) -> - self = @ @dropdown = $(@el).parent() + + # Set Defaults + { + # If no input is passed create a default one + @filterInput = @getElement(FILTER_INPUT) + @highlight = false + @filterInputBlur = true + @enterCallback = true + } = @options + + self = @ + + # If selector was passed + if _.isString(@filterInput) + @filterInput = @getElement(@filterInput) + search_fields = if @options.search then @options.search.fields else []; if @options.data - # Remote data - @remote = new GitLabDropdownRemote @options.data, { - dataType: @options.dataType, - beforeSend: @toggleLoading.bind(@) - success: (data) => - @fullData = data + # If data is an array + if _.isArray @options.data + @fullData = @options.data + @parseData @options.data + else + # Remote data + @remote = new GitLabDropdownRemote @options.data, { + dataType: @options.dataType, + beforeSend: @toggleLoading.bind(@) + success: (data) => + @fullData = data - @parseData @fullData - } + @parseData @fullData + } - # Init filiterable + # Init filterable if @options.filterable - @filter = new GitLabDropdownFilter @dropdown, + @filter = new GitLabDropdownFilter @filterInput, + filterInputBlur: @filterInputBlur remote: @options.filterRemote query: @options.data keys: @options.search.fields data: => return @fullData callback: (data) => + currentIndex = -1 @parseData data enterCallback: => - @selectFirstRow() + if @enterCallback + @selectRowAtIndex 0 # Event listeners + @dropdown.on "shown.bs.dropdown", @opened @dropdown.on "hidden.bs.dropdown", @hidden + @dropdown.on "click", ".dropdown-menu, .dropdown-menu-close", @shouldPropagate if @dropdown.find(".dropdown-toggle-page").length @dropdown.find(".dropdown-toggle-page, .dropdown-menu-back").on "click", (e) => @@ -124,10 +177,14 @@ class GitLabDropdown selector = ".dropdown-page-one .dropdown-content a" @dropdown.on "click", selector, (e) -> - self.rowClicked $(@) + selected = self.rowClicked $(@) if self.options.clicked - self.options.clicked() + self.options.clicked(selected) + + # Finds an element inside wrapper element + getElement: (selector) -> + @dropdown.find selector toggleLoading: -> $('.dropdown-menu', @dropdown).toggleClass LOADING_CLASS @@ -157,21 +214,44 @@ class GitLabDropdown @appendMenu(full_html) + shouldPropagate: (e) => + if @options.multiSelect + $target = $(e.target) + if not $target.hasClass('dropdown-menu-close') and not $target.hasClass('dropdown-menu-close-icon') + e.stopPropagation() + return false + else + return true + opened: => + @addArrowKeyEvent() + contentHtml = $('.dropdown-content', @dropdown).html() if @remote && contentHtml is "" @remote.execute() if @options.filterable - @dropdown.find(".dropdown-input-field").focus() + @filterInput.focus() - hidden: => + @dropdown.trigger('shown.gl.dropdown') + + hidden: (e) => + @removeArrayKeyEvent() if @options.filterable - @dropdown.find(".dropdown-input-field").blur().val("") + @dropdown + .find(".dropdown-input-field") + .blur() + .val("") + .trigger("keyup") if @dropdown.find(".dropdown-toggle-page").length $('.dropdown-menu', @dropdown).removeClass PAGE_TWO_CLASS + if @options.hidden + @options.hidden.call(@,e) + + @dropdown.trigger('hidden.gl.dropdown') + # Render the full menu renderMenu: (html) -> @@ -196,75 +276,192 @@ class GitLabDropdown renderItem: (data) -> html = "" + # Divider return "
  • " if data is "divider" + # Separator is a full-width divider + return "
  • " if data is "separator" + + # Header + return "" if data.header? + if @options.renderRow # Call the render function html = @options.renderRow(data) else - selected = if @options.isSelected then @options.isSelected(data) else false - url = if @options.url then @options.url(data) else "#" - text = if @options.text then @options.text(data) else "" + if not selected + value = if @options.id then @options.id(data) else data.id + fieldName = @options.fieldName + field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") + if field.length + selected = true + + # Set URL + if @options.url? + url = @options.url(data) + else + url = if data.url? then data.url else '#' + + # Set Text + if @options.text? + text = @options.text(data) + else + text = if data.text? then data.text else '' + cssClass = ""; if selected cssClass = "is-active" - html = "
  • " - html += "" - html += text - html += "" - html += "
  • " + if @highlight + text = @highlightTextMatches(text, @filterInput.val()) + + html = "
  • + + #{text} + +
  • " return html + highlightTextMatches: (text, term) -> + occurrences = fuzzaldrinPlus.match(text, term) + text.split('').map((character, i) -> + if i in occurrences then "#{character}" else character + ).join('') + noResults: -> - html = "
  • " - html += "" - html += "No matching results." - html += "" - html += "
  • " + html = "" + + highlightRow: (index) -> + if @filterInput.val() isnt "" + selector = '.dropdown-content li:first-child a' + if @dropdown.find(".dropdown-toggle-page").length + selector = ".dropdown-page-one .dropdown-content li:first-child a" + + @getElement(selector).addClass 'is-focused' rowClicked: (el) -> fieldName = @options.fieldName - field = @dropdown.parent().find("input[name='#{fieldName}']") + selectedIndex = el.parent().index() + if @renderedData + selectedObject = @renderedData[selectedIndex] + value = if @options.id then @options.id(selectedObject, el) else selectedObject.id + field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") if el.hasClass(ACTIVE_CLASS) + el.removeClass(ACTIVE_CLASS) field.remove() - else - fieldName = @options.fieldName - selectedIndex = el.parent().index() - if @renderedData - selectedObject = @renderedData[selectedIndex] - value = if @options.id then @options.id(selectedObject, el) else selectedObject.id - if @options.multiSelect - oldValue = field.val() - if oldValue - value = "#{oldValue},#{value}" - else - @dropdown.find(ACTIVE_CLASS).removeClass ACTIVE_CLASS + # Toggle the dropdown label + if @options.toggleLabel + $(@el).find(".dropdown-toggle-text").text @options.toggleLabel + else + if !value? field.remove() - # Toggle active class for the tick mark - el.toggleClass "is-active" + if not @options.multiSelect + @dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS + @dropdown.parent().find("input[name='#{fieldName}']").remove() - if value + # Toggle active class for the tick mark + el.addClass ACTIVE_CLASS + + # Toggle the dropdown label + if @options.toggleLabel + $(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selectedObject) + if value? if !field.length # Create hidden input for form - input = "" + input = "" + if @options.inputId? + input = $(input) + .attr('id', @options.inputId) @dropdown.before input + else + field.val value - @dropdown.parent().find("input[name='#{fieldName}']").val value + return selectedObject + + selectRowAtIndex: (index) -> + selector = ".dropdown-content li:not(.divider):eq(#{index}) a" - selectFirstRow: -> - selector = '.dropdown-content li:first-child a' if @dropdown.find(".dropdown-toggle-page").length - selector = ".dropdown-page-one .dropdown-content li:first-child a" + selector = ".dropdown-page-one #{selector}" - # similute a click on the first link + # simulate a click on the first link $(selector).trigger "click" + addArrowKeyEvent: -> + ARROW_KEY_CODES = [38, 40] + $input = @dropdown.find(".dropdown-input-field") + + selector = '.dropdown-content li:not(.divider)' + if @dropdown.find(".dropdown-toggle-page").length + selector = ".dropdown-page-one #{selector}" + + $('body').on 'keydown', (e) => + currentKeyCode = e.which + + if ARROW_KEY_CODES.indexOf(currentKeyCode) >= 0 + e.preventDefault() + e.stopImmediatePropagation() + + PREV_INDEX = currentIndex + $listItems = $(selector, @dropdown) + + # if @options.filterable + # $input.blur() + + if currentKeyCode is 40 + # Move down + currentIndex += 1 if currentIndex < ($listItems.length - 1) + else if currentKeyCode is 38 + # Move up + currentIndex -= 1 if currentIndex > 0 + + @highlightRowAtIndex($listItems, currentIndex) if currentIndex isnt PREV_INDEX + + return false + + if currentKeyCode is 13 + @selectRowAtIndex currentIndex + + removeArrayKeyEvent: -> + $('body').off 'keydown' + + highlightRowAtIndex: ($listItems, index) -> + # Remove the class for the previously focused row + $('.is-focused', @dropdown).removeClass 'is-focused' + + # Update the class for the row at the specific index + $listItem = $listItems.eq(index) + $listItem.find('a:first-child').addClass "is-focused" + + # Dropdown content scroll area + $dropdownContent = $listItem.closest('.dropdown-content') + dropdownScrollTop = $dropdownContent.scrollTop() + dropdownContentHeight = $dropdownContent.outerHeight() + dropdownContentTop = $dropdownContent.prop('offsetTop') + dropdownContentBottom = dropdownContentTop + dropdownContentHeight + + # Get the offset bottom of the list item + listItemHeight = $listItem.outerHeight() + listItemTop = $listItem.prop('offsetTop') + listItemBottom = listItemTop + listItemHeight + + if listItemBottom > dropdownContentBottom + dropdownScrollTop + # Scroll the dropdown content down + $dropdownContent.scrollTop(listItemBottom - dropdownContentBottom) + else if listItemTop < dropdownContentTop + dropdownScrollTop + # Scroll the dropdown content up + $dropdownContent.scrollTop(listItemTop - dropdownContentTop) + $.fn.glDropdown = (opts) -> return @.each -> - new GitLabDropdown @, opts + if (!$.data @, 'glDropdown') + $.data(@, 'glDropdown', new GitLabDropdown @, opts) diff --git a/app/assets/javascripts/issuable_context.js.coffee b/app/assets/javascripts/issuable_context.js.coffee index e52b73f94f..2f19513a83 100644 --- a/app/assets/javascripts/issuable_context.js.coffee +++ b/app/assets/javascripts/issuable_context.js.coffee @@ -1,8 +1,7 @@ -#= require jquery.waitforimages - class @IssuableContext - constructor: -> - new UsersSelect() + constructor: (currentUser) -> + @initParticipants() + new UsersSelect(currentUser) $('select.select2').select2({width: 'resolve', dropdownAutoWidth: true}) $(".issuable-sidebar .inline-update").on "change", "select", -> @@ -10,10 +9,44 @@ class @IssuableContext $(".issuable-sidebar .inline-update").on "change", ".js-assignee", -> $(this).submit() - $(document).on "click",".edit-link", (e) -> - block = $(@).parents('.block') - block.find('.selectbox').show() - block.find('.value').hide() - block.find('.js-select2').select2("open") + $(document).off("click", ".edit-link").on "click",".edit-link", (e) -> + $block = $(@).parents('.block') + $selectbox = $block.find('.selectbox') + if $selectbox.is(':visible') + $selectbox.hide() + $block.find('.value').show() + else + $selectbox.show() + $block.find('.value').hide() + + if $selectbox.is(':visible') + setTimeout (-> + $block.find('.dropdown-menu-toggle').trigger 'click' + ), 0 + $(".right-sidebar").niceScroll() + + initParticipants: -> + _this = @ + $(document).on "click", ".js-participants-more", @toggleHiddenParticipants + + $(".js-participants-author").each (i) -> + if i >= _this.PARTICIPANTS_ROW_COUNT + $(@) + .addClass "js-participants-hidden" + .hide() + + toggleHiddenParticipants: (e) -> + e.preventDefault() + + currentText = $(this).text().trim() + lessText = $(this).data("less-text") + originalText = $(this).data("original-text") + + if currentText is originalText + $(this).text(lessText) + else + $(this).text(originalText) + + $(".js-participants-hidden").toggle() diff --git a/app/assets/javascripts/issuable_form.js.coffee b/app/assets/javascripts/issuable_form.js.coffee index 48c249943f..7a788f761b 100644 --- a/app/assets/javascripts/issuable_form.js.coffee +++ b/app/assets/javascripts/issuable_form.js.coffee @@ -1,4 +1,7 @@ class @IssuableForm + issueMoveConfirmMsg: 'Are you sure you want to move this issue to another project?' + wipRegex: /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i + constructor: (@form) -> GitLab.GfmAutoComplete.setup() new UsersSelect() @@ -6,14 +9,17 @@ class @IssuableForm @titleField = @form.find("input[name*='[title]']") @descriptionField = @form.find("textarea[name*='[description]']") + @issueMoveField = @form.find("#move_to_project_id") return unless @titleField.length && @descriptionField.length @initAutosave() - @form.on "submit", @resetAutosave + @form.on "submit", @handleSubmit @form.on "click", ".btn-cancel", @resetAutosave + @initWip() + initAutosave: -> new Autosave @titleField, [ document.location.pathname, @@ -27,6 +33,50 @@ class @IssuableForm "description" ] + handleSubmit: => + if (parseInt(@issueMoveField?.val()) ? 0) > 0 + return false unless confirm(@issueMoveConfirmMsg) + + @resetAutosave() + resetAutosave: => @titleField.data("autosave").reset() @descriptionField.data("autosave").reset() + + initWip: -> + @$wipExplanation = @form.find(".js-wip-explanation") + @$noWipExplanation = @form.find(".js-no-wip-explanation") + return unless @$wipExplanation.length and @$noWipExplanation.length + + @form.on "click", ".js-toggle-wip", @toggleWip + + @titleField.on "keyup blur", @renderWipExplanation + + @renderWipExplanation() + + workInProgress: -> + @wipRegex.test @titleField.val() + + renderWipExplanation: => + if @workInProgress() + @$wipExplanation.show() + @$noWipExplanation.hide() + else + @$wipExplanation.hide() + @$noWipExplanation.show() + + toggleWip: (event) => + event.preventDefault() + + if @workInProgress() + @removeWip() + else + @addWip() + + @renderWipExplanation() + + removeWip: -> + @titleField.val @titleField.val().replace(@wipRegex, "") + + addWip: -> + @titleField.val "WIP: #{@titleField.val()}" diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee index d663e34871..946d83b7bd 100644 --- a/app/assets/javascripts/issue.js.coffee +++ b/app/assets/javascripts/issue.js.coffee @@ -6,25 +6,10 @@ class @Issue constructor: -> # Prevent duplicate event bindings @disableTaskList() - @fixAffixScroll() if $('a.btn-close').length @initTaskList() @initIssueBtnEventListeners() - fixAffixScroll: -> - fixAffix = -> - $discussion = $('.issuable-discussion') - $sidebar = $('.issuable-sidebar') - if $sidebar.hasClass('no-affix') - $sidebar.removeClass(['affix-top','affix']) - discussionHeight = $discussion.height() - sidebarHeight = $sidebar.height() - if sidebarHeight > discussionHeight - $discussion.height(sidebarHeight + 50) - $sidebar.addClass('no-affix') - $(window).on('resize', fixAffix) - fixAffix() - initTaskList: -> $('.detail-page-description .js-task-list-container').taskList('enable') $(document).on 'tasklist:changed', '.detail-page-description .js-task-list-container', @updateTaskList @@ -49,7 +34,7 @@ class @Issue issueStatus = if isClose then 'close' else 'open' new Flash(issueFailMessage, 'alert') success: (data, textStatus, jqXHR) -> - if data.saved + if 'id' of data $(document).trigger('issuable:change'); if isClose $('a.btn-close').addClass('hidden') diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index a0acf3028b..b1479bfb44 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -1,7 +1,6 @@ @Issues = init: -> Issues.initSearch() - Issues.initSelects() Issues.initChecks() $("body").on "ajax:success", ".close_issue, .reopen_issue", -> @@ -17,18 +16,9 @@ $(this).html totalIssues - 1 reload: -> - Issues.initSelects() Issues.initChecks() $('#filter_issue_search').val($('#issue_search').val()) - initSelects: -> - $("select#update_state_event").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#update_assignee_id").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#update_milestone_id").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#label_name").select2(width: 'resolve', dropdownAutoWidth: true) - $("#milestone_id, #assignee_id, #label_name").on "change", -> - $(this).closest("form").submit() - initChecks: -> $(".check_all_issues").click -> $(".selected_issue").prop("checked", @checked) @@ -41,24 +31,28 @@ @timer = null $("#issue_search").keyup -> clearTimeout(@timer) - @timer = setTimeout(Issues.filterResults, 500) + @timer = setTimeout( -> + Issues.filterResults $("#issue_search_form") + , 500) - filterResults: => - form = $("#issue_search_form") - search = $("#issue_search").val() - $('.issues-holder').css("opacity", '0.5') - issues_url = form.attr('action') + '?' + form.serialize() + filterResults: (form) => + $('.issues-holder, .merge-requests-holder').css("opacity", '0.5') + formAction = form.attr('action') + formData = form.serialize() + issuesUrl = formAction + issuesUrl += ("#{if formAction.indexOf("?") < 0 then '?' else '&'}") + issuesUrl += formData $.ajax type: "GET" - url: form.attr('action') - data: form.serialize() + url: formAction + data: formData complete: -> - $('.issues-holder').css("opacity", '1.0') + $('.issues-holder, .merge-requests-holder').css("opacity", '1.0') success: (data) -> - $('.issues-holder').html(data.html) + $('.issues-holder, .merge-requests-holder').html(data.html) # Change url so if user reload a page - search results are saved - history.replaceState {page: issues_url}, document.title, issues_url + history.replaceState {page: issuesUrl}, document.title, issuesUrl Issues.reload() dataType: "json" diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index 5ade2cb66c..d1fe116397 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -1,30 +1,86 @@ class @LabelsSelect constructor: -> $('.js-label-select').each (i, dropdown) -> - projectId = $(dropdown).data('project-id') - labelUrl = $(dropdown).data("labels") - selectedLabel = $(dropdown).data('selected') - if selectedLabel - selectedLabel = selectedLabel.split(",") + $dropdown = $(dropdown) + projectId = $dropdown.data('project-id') + labelUrl = $dropdown.data('labels') + issueUpdateURL = $dropdown.data('issueUpdate') + selectedLabel = $dropdown.data('selected') + if selectedLabel? + selectedLabel = selectedLabel.split(',') newLabelField = $('#new_label_name') newColorField = $('#new_label_color') - showNo = $(dropdown).data('show-no') - showAny = $(dropdown).data('show-any') + showNo = $dropdown.data('show-no') + showAny = $dropdown.data('show-any') + defaultLabel = $dropdown.data('default-label') + abilityName = $dropdown.data('ability-name') + $selectbox = $dropdown.closest('.selectbox') + $block = $selectbox.closest('.block') + $sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span') + $value = $block.find('.value') + $loading = $block.find('.block-loading').fadeOut() if newLabelField.length + $newLabelCreateButton = $('.js-new-label-btn') + $colorPreview = $('.js-dropdown-label-color-preview') + $newLabelError = $dropdown.parent().find('.js-label-error') + $newLabelError.hide() + + # Suggested colors in the dropdown to chose from pre-chosen colors + $('.suggest-colors-dropdown a').on 'click', (e) -> + + issueURLSplit = issueUpdateURL.split('/') if issueUpdateURL? + if issueUpdateURL + labelHTMLTemplate = _.template( + '<% _.each(labels, function(label){ %> + issues?label_name=<%= label.title %>"> + + <%= label.title %> + + + <% }); %>' + ); + labelNoneHTMLTemplate = _.template('
    None
    ') + + if newLabelField.length and $dropdown.hasClass 'js-extra-options' $('.suggest-colors-dropdown a').on "click", (e) -> e.preventDefault() e.stopPropagation() - newColorField.val $(this).data("color") - $('.js-dropdown-label-color-preview') - .css 'background-color', $(this).data("color") + newColorField + .val($(this).data('color')) + .trigger('change') + $colorPreview + .css 'background-color', $(this).data('color') + .parent() .addClass 'is-active' - $('.js-new-label-btn').on "click", (e) -> + # Cancel button takes back to first page + resetForm = -> + newLabelField + .val '' + .trigger 'change' + newColorField + .val '' + .trigger 'change' + $colorPreview + .css 'background-color', '' + .parent() + .removeClass 'is-active' + + $('.dropdown-menu-back').on 'click', -> + resetForm() + + $('.js-cancel-label-btn').on 'click', (e) -> e.preventDefault() e.stopPropagation() + resetForm() + $('.dropdown-menu-back', $dropdown.parent()).trigger 'click' - if newLabelField.val() isnt "" && newColorField.val() isnt "" + # Listen for change and keyup events on label and color field + # This allows us to enable the button when ready + enableLabelCreateButton = -> + if newLabelField.val() isnt '' and newColorField.val() isnt '' + $newLabelError.hide() $('.js-new-label-btn').disable() # Create new label with API @@ -33,49 +89,126 @@ class @LabelsSelect color: newColorField.val() }, (label) -> $('.js-new-label-btn').enable() - $('.dropdown-menu-back', $(dropdown).parent()).trigger "click" - $(dropdown).glDropdown( + if label.message? + $newLabelError + .text label.message + .show() + else + $('.dropdown-menu-back', $dropdown.parent()).trigger 'click' + + $newLabelCreateButton.enable() + else + $newLabelCreateButton.disable() + + newLabelField.on 'keyup change', enableLabelCreateButton + + newColorField.on 'keyup change', enableLabelCreateButton + + # Send the API call to create the label + $newLabelCreateButton + .disable() + .on 'click', (e) -> + e.preventDefault() + e.stopPropagation() + + if newLabelField.val() isnt '' and newColorField.val() isnt '' + $newLabelError.hide() + $('.js-new-label-btn').disable() + + # Create new label with API + Api.newLabel projectId, { + name: newLabelField.val() + color: newColorField.val() + }, (label) -> + $('.js-new-label-btn').enable() + + if label.message? + $newLabelError + .text label.message + .show() + else + $('.dropdown-menu-back', $dropdown.parent()).trigger 'click' + + saveLabelData = -> + selected = $dropdown + .closest('.selectbox') + .find("input[name='#{$dropdown.data('field-name')}']") + .map(-> + @value + ).get() + data = {} + data[abilityName] = {} + data[abilityName].label_ids = selected + if not selected.length + data[abilityName].label_ids = [''] + $loading.fadeIn() + $dropdown.trigger('loading.gl.dropdown') + $.ajax( + type: 'PUT' + url: issueUpdateURL + dataType: 'JSON' + data: data + ).done (data) -> + $loading.fadeOut() + $dropdown.trigger('loaded.gl.dropdown') + $selectbox.hide() + data.issueURLSplit = issueURLSplit + labelCount = 0 + if data.labels.length + template = labelHTMLTemplate(data) + labelCount = data.labels.length + else + template = labelNoneHTMLTemplate() + $value + .removeAttr('style') + .html(template) + $sidebarCollapsedValue.text(labelCount) + + $value + .find('a') + .each((i) -> + setTimeout(=> + glAnimate($(@), 'pulse') + ,200 * i + ) + ) + + + $dropdown.glDropdown( data: (term, callback) -> - # We have to fetch the JS version of the labels list because there is no - # public facing JSON url for labels $.ajax( url: labelUrl ).done (data) -> - html = $(data) - data = [] - html.find('.label-row a').each -> - data.push( - title: $(@).text().trim() - ) + if $dropdown.hasClass 'js-extra-options' + if showNo + data.unshift( + id: 0 + title: 'No Label' + ) - if showNo - data.unshift( - id: "0" - title: 'No label' - ) - - if showAny - data.unshift( - title: 'Any label' - ) - - if data.length > 2 - data.splice 2, 0, "divider" + if showAny + data.unshift( + isAny: true + title: 'Any Label' + ) + if data.length > 2 + data.splice 2, 0, 'divider' callback data + renderRow: (label) -> - if $.isArray(selectedLabel) - selected = "" - $.each selectedLabel, (i, selectedLbl) -> - selectedLbl = selectedLbl.trim() - if selected is "" && label.title is selectedLbl - selected = "is-active" - else - selected = if label.title is selectedLabel then "is-active" else "" + selectedClass = '' + if $selectbox.find("input[type='hidden']\ + [name='#{$dropdown.data('field-name')}']\ + [value='#{label.id}']").length + selectedClass = 'is-active' + + color = if label.color? then "" else "" "
  • - + + #{color} #{label.title}
  • " @@ -83,10 +216,43 @@ class @LabelsSelect search: fields: ['title'] selectable: true - fieldName: $(dropdown).data('field-name') + + toggleLabel: (selected) -> + if selected and selected.title isnt 'Any Label' + selected.title + else + defaultLabel + fieldName: $dropdown.data('field-name') id: (label) -> - label.title - clicked: -> - if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents('form').submit() + if label.isAny? + '' + else if $dropdown.hasClass "js-filter-submit" + label.title + else + label.id + + hidden: -> + $selectbox.hide() + # display:block overrides the hide-collapse rule + $value.removeAttr('style') + if $dropdown.hasClass 'js-multiselect' + saveLabelData() + + multiSelect: $dropdown.hasClass 'js-multiselect' + clicked: (label) -> + page = $('body').data 'page' + isIssueIndex = page is 'projects:issues:index' + isMRIndex = page is page is 'projects:merge_requests:index' + + if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex) + selectedLabel = label.title + + Issues.filterResults $dropdown.closest('form') + else if $dropdown.hasClass 'js-filter-submit' + $dropdown.closest('form').submit() + else + if $dropdown.hasClass 'js-multiselect' + return + else + saveLabelData() ) diff --git a/app/assets/javascripts/lib/animate.js.coffee b/app/assets/javascripts/lib/animate.js.coffee new file mode 100644 index 0000000000..8f892b5a2b --- /dev/null +++ b/app/assets/javascripts/lib/animate.js.coffee @@ -0,0 +1,13 @@ +((w) -> + + w.glAnimate = ($el, animation, done) -> + $el + .removeClass() + .addClass(animation + ' animated') + .one 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', -> + $(this).removeClass() + return + return + return + +) window \ No newline at end of file diff --git a/app/assets/javascripts/lib/notify.js.coffee b/app/assets/javascripts/lib/notify.js.coffee new file mode 100644 index 0000000000..3f9ca39912 --- /dev/null +++ b/app/assets/javascripts/lib/notify.js.coffee @@ -0,0 +1,30 @@ +((w) -> + notificationGranted = (message, opts, onclick) -> + notification = new Notification(message, opts) + + if onclick + notification.onclick = onclick + + notifyPermissions = -> + if 'Notification' of window + Notification.requestPermission() + + notifyMe = (message, body, icon, onclick) -> + opts = + body: body + icon: icon + # Let's check if the browser supports notifications + if !('Notification' of window) + # do nothing + else if Notification.permission == 'granted' + # If it's okay let's create a notification + notificationGranted message, opts, onclick + else if Notification.permission != 'denied' + Notification.requestPermission (permission) -> + # If the user accepts, let's create a notification + if permission == 'granted' + notificationGranted message, opts, onclick + + w.notify = notifyMe + w.notifyPermissions = notifyPermissions +) window diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee index 6af5a48a0b..1f46e33142 100644 --- a/app/assets/javascripts/merge_request.js.coffee +++ b/app/assets/javascripts/merge_request.js.coffee @@ -15,8 +15,6 @@ class @MergeRequest this.$('.show-all-commits').on 'click', => this.showAllCommits() - @fixAffixScroll(); - @initTabs() # Prevent duplicate event bindings @@ -30,20 +28,6 @@ class @MergeRequest $: (selector) -> this.$el.find(selector) - fixAffixScroll: -> - fixAffix = -> - $discussion = $('.issuable-discussion') - $sidebar = $('.issuable-sidebar') - if $sidebar.hasClass('no-affix') - $sidebar.removeClass(['affix-top','affix']) - discussionHeight = $discussion.height() - sidebarHeight = $sidebar.height() - if sidebarHeight > discussionHeight - $discussion.height(sidebarHeight + 50) - $sidebar.addClass('no-affix') - $(window).on('resize', fixAffix) - fixAffix() - initTabs: -> if @opts.action != 'new' # `MergeRequests#new` has no tab-persisting or lazy-loading behavior diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee index 8322b4c46a..839e6ec2c0 100644 --- a/app/assets/javascripts/merge_request_tabs.js.coffee +++ b/app/assets/javascripts/merge_request_tabs.js.coffee @@ -3,6 +3,8 @@ # Handles persisting and restoring the current tab selection and lazily-loading # content on the MergeRequests#show page. # +#= require jquery.cookie +# # ### Example Markup # #