ClusterLabs/hawk

View on GitHub
hawk/app/controllers/application_controller.rb

Summary

Maintainability
B
4 hrs
Test Coverage

Assignment Branch Condition size for set_shadow_cib is too high. [56.54/15]
Open

  def set_shadow_cib
    if !current_cib || current_cib.live?
      ENV.delete("CIB_shadow")
      return
    end

This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

Class ApplicationController has 25 methods (exceeds 20 allowed). Consider refactoring.
Open

class ApplicationController < ActionController::Base
  include FastGettext::Translation

  protect_from_forgery with: :exception
  helper :all
Severity: Minor
Found in hawk/app/controllers/application_controller.rb - About 2 hrs to fix

    Assignment Branch Condition size for cors_preflight_check is too high. [21.79/15]
    Open

      def cors_preflight_check
        if request.method == 'OPTIONS' && request.headers['Origin']
          response.headers['Access-Control-Allow-Origin'] = ENV["HAWK_ACCESS_CONTROL_ALLOW_ORIGIN"] || request.headers["Origin"]
          response.headers['Access-Control-Allow-Credentials'] = 'true'
          response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'

    This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

    Assignment Branch Condition size for cors_set_access_control_headers is too high. [20.02/15]
    Open

      def cors_set_access_control_headers
        response.headers['Content-Security-Policy'] = "frame-ancestors 'self'"
        if request.headers['Origin']
          response.headers['Access-Control-Allow-Origin'] = ENV["HAWK_ACCESS_CONTROL_ALLOW_ORIGIN"] || request.headers["Origin"]
          response.headers['Access-Control-Allow-Credentials'] = 'true'

    This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

    Assignment Branch Condition size for current_cib is too high. [16.4/15]
    Open

      def current_cib
        if current_user
          @current_cib ||= begin
            Cib.new(params[:cib_id] || production_cib, current_user, current_pass, params[:debug] == "file", cookies[:stonithwarning].nil? || cookies[:stonithwarning] == true)
          end

    This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric

    Cyclomatic complexity for set_shadow_cib is too high. [7/6]
    Open

      def set_shadow_cib
        if !current_cib || current_cib.live?
          ENV.delete("CIB_shadow")
          return
        end

    This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of linearly independent paths through a method. The algorithm counts decision points and adds one.

    An if statement (or unless or ?:) increases the complexity by one. An else branch does not, since it doesn't add a decision point. The && operator (or keyword and) can be converted to a nested if statement, and ||/or is shorthand for a sequence of ifs, so they also add one. Loops can be said to have an exit condition, so they add one.

    Perceived complexity for set_shadow_cib is too high. [8/7]
    Open

      def set_shadow_cib
        if !current_cib || current_cib.live?
          ENV.delete("CIB_shadow")
          return
        end

    This cop tries to produce a complexity score that's a measure of the complexity the reader experiences when looking at a method. For that reason it considers when nodes as something that doesn't add as much complexity as an if or a &&. Except if it's one of those special case/when constructs where there's no expression after case. Then the cop treats it as an if/elsif/elsif... and lets all the when nodes count. In contrast to the CyclomaticComplexity cop, this cop considers else nodes as adding complexity.

    Example:

    def my_method                   # 1
      if cond                       # 1
        case var                    # 2 (0.8 + 4 * 0.2, rounded)
        when 1 then func_one
        when 2 then func_two
        when 3 then func_three
        when 4..10 then func_other
        end
      else                          # 1
        do_something until a && b   # 2
      end                           # ===
    end                             # 7 complexity points

    Method set_shadow_cib has 30 lines of code (exceeds 25 allowed). Consider refactoring.
    Open

      def set_shadow_cib
        if !current_cib || current_cib.live?
          ENV.delete("CIB_shadow")
          return
        end
    Severity: Minor
    Found in hawk/app/controllers/application_controller.rb - About 1 hr to fix

      Method set_shadow_cib has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
      Open

        def set_shadow_cib
          if !current_cib || current_cib.live?
            ENV.delete("CIB_shadow")
            return
          end
      Severity: Minor
      Found in hawk/app/controllers/application_controller.rb - About 35 mins to fix

      Cognitive Complexity

      Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

      A method's cognitive complexity is based on a few simple rules:

      • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
      • Code is considered more complex for each "break in the linear flow of the code"
      • Code is considered more complex when "flow breaking structures are nested"

      Further reading

      Use casecmp instead of downcase ==.
      Open

          init_cib = params[:init_cib].to_s.downcase == "true"

      This cop identifies places where a case-insensitive string comparison can better be implemented using casecmp.

      Example:

      # bad
      str.downcase == 'abc'
      str.upcase.eql? 'ABC'
      'abc' == str.downcase
      'ABC'.eql? str.upcase
      str.downcase == str.downcase
      
      # good
      str.casecmp('ABC').zero?
      'abc'.casecmp(str).zero?

      Provide an exception class and message as arguments to raise.
      Open

          raise Cib::PermissionDenied.new _("Error: Permission denied for user (%s)") % [current_user]

      This cop checks the args passed to fail and raise. For exploded style (default), it recommends passing the exception class and message to raise, rather than construct an instance of the error. It will still allow passing just a message, or the construction of an error with more than one argument.

      The exploded style works identically, but with the addition that it will also suggest constructing error objects when the exception is passed multiple arguments.

      Example: EnforcedStyle: exploded (default)

      # bad
      raise StandardError.new("message")
      
      # good
      raise StandardError, "message"
      fail "message"
      raise MyCustomError.new(arg1, arg2, arg3)
      raise MyKwArgError.new(key1: val1, key2: val2)

      Example: EnforcedStyle: compact

      # bad
      raise StandardError, "message"
      raise RuntimeError, arg1, arg2, arg3
      
      # good
      raise StandardError.new("message")
      raise MyCustomError.new(arg1, arg2, arg3)
      fail "message"

      Unused block argument - e. You can omit the argument if you don't care about it.
      Open

        rescue_from Cib::NotAuthenticated do |e|

      This cop checks for unused block arguments.

      Example:

      # bad
      
      do_something do |used, unused|
        puts used
      end
      
      do_something do |bar|
        puts :foo
      end
      
      define_method(:foo) do |bar|
        puts :baz
      end

      Example:

      #good
      
      do_something do |used, _unused|
        puts used
      end
      
      do_something do
        puts :foo
      end
      
      define_method(:foo) do |_bar|
        puts :baz
      end

      Rename is_god? to god?.
      Open

        def is_god?

      This cop makes sure that predicates are named properly.

      Example:

      # bad
      def is_even?(value)
      end
      
      # good
      def even?(value)
      end
      
      # bad
      def has_value?
      end
      
      # good
      def value?
      end

      Use empty lines between method definitions.
      Open

        def login_from_cookie

      This cop checks whether method definitions are separated by one empty line.

      NumberOfEmptyLines can be and integer (e.g. 1 by default) or an array (e.g. [1, 2]) to specificy a minimum and a maximum of empty lines.

      AllowAdjacentOneLineDefs can be used to configure is adjacent one line methods definitions are an offense

      Example:

      # bad
      def a
      end
      def b
      end

      Example:

      # good
      def a
      end
      
      def b
      end

      Extra blank line detected.
      Open

      
        def login_from_cookie

      This cops checks for two or more consecutive blank lines.

      Example:

      # bad - It has two empty lines.
      some_method
      # one empty line
      # two empty lines
      some_method
      
      # good
      some_method
      # one empty line
      some_method

      Use a guard clause instead of wrapping the code inside a conditional expression.
      Open

          if current_user

      Use a guard clause instead of wrapping the code inside a conditional expression

      Example:

      # bad
      def test
        if something
          work
        end
      end
      
      # good
      def test
        return unless something
        work
      end
      
      # also good
      def test
        work if something
      end
      
      # bad
      if something
        raise 'exception'
      else
        ok
      end
      
      # good
      raise 'exception' if something
      ok

      Favor format over String#%.
      Open

          raise Cib::PermissionDenied.new _("Error: Permission denied for user (%s)") % [current_user]

      This cop enforces the use of a single string formatting utility. Valid options include Kernel#format, Kernel#sprintf and String#%.

      The detection of String#% cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal.

      Example: EnforcedStyle: format(default)

      # bad
      puts sprintf('%10s', 'hoge')
      puts '%10s' % 'hoge'
      
      # good
      puts format('%10s', 'hoge')

      Example: EnforcedStyle: sprintf

      # bad
      puts format('%10s', 'hoge')
      puts '%10s' % 'hoge'
      
      # good
      puts sprintf('%10s', 'hoge')

      Example: EnforcedStyle: percent

      # bad
      puts format('%10s', 'hoge')
      puts sprintf('%10s', 'hoge')
      
      # good
      puts '%10s' % 'hoge'

      Provide an exception class and message as arguments to raise.
      Open

          raise Cib::NotAuthenticated.new _("Error: Not authenticated")

      This cop checks the args passed to fail and raise. For exploded style (default), it recommends passing the exception class and message to raise, rather than construct an instance of the error. It will still allow passing just a message, or the construction of an error with more than one argument.

      The exploded style works identically, but with the addition that it will also suggest constructing error objects when the exception is passed multiple arguments.

      Example: EnforcedStyle: exploded (default)

      # bad
      raise StandardError.new("message")
      
      # good
      raise StandardError, "message"
      fail "message"
      raise MyCustomError.new(arg1, arg2, arg3)
      raise MyKwArgError.new(key1: val1, key2: val2)

      Example: EnforcedStyle: compact

      # bad
      raise StandardError, "message"
      raise RuntimeError, arg1, arg2, arg3
      
      # good
      raise StandardError.new("message")
      raise MyCustomError.new(arg1, arg2, arg3)
      fail "message"

      Use (result[2]).zero? instead of result[2] == 0.
      Open

            if result[2] == 0

      This cop checks for usage of comparison operators (==, >, <) to test numbers as zero, positive, or negative. These can be replaced by their respective predicate methods. The cop can also be configured to do the reverse.

      The cop disregards #nonzero? as it its value is truthy or falsey, but not true and false, and thus not always interchangeable with != 0.

      The cop ignores comparisons to global variables, since they are often populated with objects which can be compared with integers, but are not themselves Interger polymorphic.

      Example: EnforcedStyle: predicate (default)

      # bad
      
      foo == 0
      0 > foo
      bar.baz > 0
      
      # good
      
      foo.zero?
      foo.negative?
      bar.baz.positive?

      Example: EnforcedStyle: comparison

      # bad
      
      foo.zero?
      foo.negative?
      bar.baz.positive?
      
      # good
      
      foo == 0
      0 > foo
      bar.baz > 0

      Prefer annotated tokens (like %<foo>s</foo>) over unannotated tokens (like %s).
      Open

          raise Cib::PermissionDenied.new _("Error: Permission denied for user (%s)") % [current_user]

      Use a consistent style for named format string tokens.

      Note: unannotated style cop only works for strings which are passed as arguments to those methods: sprintf, format, %. The reason is that unannotated format is very similar to encoded URLs or Date/Time formatting strings.

      Example: EnforcedStyle: annotated (default)

      # bad
      format('%{greeting}', greeting: 'Hello')
      format('%s', 'Hello')
      
      # good
      format('%<greeting>s', greeting: 'Hello')</greeting>

      Example: EnforcedStyle: template

      # bad
      format('%<greeting>s', greeting: 'Hello')
      format('%s', 'Hello')
      
      # good
      format('%{greeting}', greeting: 'Hello')</greeting>

      Example: EnforcedStyle: unannotated

      # bad
      format('%<greeting>s', greeting: 'Hello')
      format('%{greeting}', 'Hello')
      
      # good
      format('%s', 'Hello')</greeting>

      Use a guard clause instead of wrapping the code inside a conditional expression.
      Open

          if request.method == 'OPTIONS' && request.headers['Origin']

      Use a guard clause instead of wrapping the code inside a conditional expression

      Example:

      # bad
      def test
        if something
          work
        end
      end
      
      # good
      def test
        return unless something
        work
      end
      
      # also good
      def test
        work if something
      end
      
      # bad
      if something
        raise 'exception'
      else
        ok
      end
      
      # good
      raise 'exception' if something
      ok

      Prefer to_s over string interpolation.
      Open

            result = Invoker.instance.run("crm_shadow", "-b", "-f", "-c", "#{current_cib.id}")

      This cop checks for strings that are just an interpolated expression.

      Example:

      # bad
      "#{@var}"
      
      # good
      @var.to_s
      
      # good if @var is already a String
      @var

      Use a guard clause instead of wrapping the code inside a conditional expression.
      Open

          if request.headers['Origin']

      Use a guard clause instead of wrapping the code inside a conditional expression

      Example:

      # bad
      def test
        if something
          work
        end
      end
      
      # good
      def test
        return unless something
        work
      end
      
      # also good
      def test
        work if something
      end
      
      # bad
      if something
        raise 'exception'
      else
        ok
      end
      
      # good
      raise 'exception' if something
      ok

      Favor modifier if usage when having a single-line body. Another good alternative is the usage of control flow &&/||.
      Open

          if init_cib || !File.exist?("/var/lib/pacemaker/cib/shadow.#{current_cib.id}")

      Checks for if and unless statements that would fit on one line if written as a modifier if/unless. The maximum line length is configured in the Metrics/LineLength cop.

      Example:

      # bad
      if condition
        do_stuff(bar)
      end
      
      unless qux.empty?
        Foo.do_something
      end
      
      # good
      do_stuff(bar) if condition
      Foo.do_something unless qux.empty?

      Provide an exception class and message as arguments to raise.
      Open

          raise ActionController::RoutingError.new _("Error: Record not found")

      This cop checks the args passed to fail and raise. For exploded style (default), it recommends passing the exception class and message to raise, rather than construct an instance of the error. It will still allow passing just a message, or the construction of an error with more than one argument.

      The exploded style works identically, but with the addition that it will also suggest constructing error objects when the exception is passed multiple arguments.

      Example: EnforcedStyle: exploded (default)

      # bad
      raise StandardError.new("message")
      
      # good
      raise StandardError, "message"
      fail "message"
      raise MyCustomError.new(arg1, arg2, arg3)
      raise MyKwArgError.new(key1: val1, key2: val2)

      Example: EnforcedStyle: compact

      # bad
      raise StandardError, "message"
      raise RuntimeError, arg1, arg2, arg3
      
      # good
      raise StandardError.new("message")
      raise MyCustomError.new(arg1, arg2, arg3)
      fail "message"

      There are no issues that match your filters.

      Category
      Status