3scale/porta

View on GitHub
app/models/service_discovery/cluster_client.rb

Summary

Maintainability
A
2 hrs
Test Coverage

Class ClusterClient has 22 methods (exceeds 20 allowed). Consider refactoring.
Open

  class ClusterClient
    class ClusterClientError < StandardError; end

    class ResourceNotFound < ClusterClientError
      def initialize(resource_type, name, namespace, labels = {})
Severity: Minor
Found in app/models/service_discovery/cluster_client.rb - About 2 hrs to fix

    ServiceDiscovery::ClusterClient#raise_not_found has 4 parameters
    Open

        def raise_not_found(resource_type, resource_name, namespace = nil, fields = {})

    A Long Parameter List occurs when a method has a lot of parameters.

    Example

    Given

    class Dummy
      def long_list(foo,bar,baz,fling,flung)
        puts foo,bar,baz,fling,flung
      end
    end

    Reek would report the following warning:

    test.rb -- 1 warning:
      [2]:Dummy#long_list has 5 parameters (LongParameterList)

    A common solution to this problem would be the introduction of parameter objects.

    ServiceDiscovery::ClusterClient#respond_to_missing? has boolean parameter 'include_private'
    Open

        def respond_to_missing?(method_sym, include_private = false)

    Boolean Parameter is a special case of Control Couple, where a method parameter is defaulted to true or false. A Boolean Parameter effectively permits a method's caller to decide which execution path to take. This is a case of bad cohesion. You're creating a dependency between methods that is not really necessary, thus increasing coupling.

    Example

    Given

    class Dummy
      def hit_the_switch(switch = true)
        if switch
          puts 'Hitting the switch'
          # do other things...
        else
          puts 'Not hitting the switch'
          # do other things...
        end
      end
    end

    Reek would emit the following warning:

    test.rb -- 3 warnings:
      [1]:Dummy#hit_the_switch has boolean parameter 'switch' (BooleanParameter)
      [2]:Dummy#hit_the_switch is controlled by argument switch (ControlParameter)

    Note that both smells are reported, Boolean Parameter and Control Parameter.

    Getting rid of the smell

    This is highly dependent on your exact architecture, but looking at the example above what you could do is:

    • Move everything in the if branch into a separate method
    • Move everything in the else branch into a separate method
    • Get rid of the hit_the_switch method alltogether
    • Make the decision what method to call in the initial caller of hit_the_switch

    ServiceDiscovery::ClusterClient#services contains iterators nested 2 deep
    Open

            get_services(search_criteria).map { |resource| ClusterService.new(resource, self) }

    A Nested Iterator occurs when a block contains another block.

    Example

    Given

    class Duck
      class << self
        def duck_names
          %i!tick trick track!.each do |surname|
            %i!duck!.each do |last_name|
              puts "full name is #{surname} #{last_name}"
            end
          end
        end
      end
    end

    Reek would report the following warning:

    test.rb -- 1 warning:
      [5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)

    ServiceDiscovery::ClusterClient has at least 18 methods
    Open

      class ClusterClient

    Too Many Methods is a special case of LargeClass.

    Example

    Given this configuration

    TooManyMethods:
      max_methods: 3

    and this code:

    class TooManyMethods
      def one; end
      def two; end
      def three; end
      def four; end
    end

    Reek would emit the following warning:

    test.rb -- 1 warning:
      [1]:TooManyMethods has at least 4 methods (TooManyMethods)

    ServiceDiscovery::ClusterClient#find_resource calls 'type.to_s' 2 times
    Open

            resource_data = public_send("get_#{type.to_s.downcase}", *args)
            raise_not_found(type, name, namespace) unless resource_data
          rescue KubeException => exception
            handle_kube_exception(exception, type, name, namespace)
          end

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    ServiceDiscovery::ClusterClient#initialize calls 'self.class' 2 times
    Open

            self.class.build_client(options),
            self.class.build_client_for_projects(options)

    Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.

    Reek implements a check for Duplicate Method Call.

    Example

    Here's a very much simplified and contrived example. The following method will report a warning:

    def double_thing()
      @other.thing + @other.thing
    end

    One quick approach to silence Reek would be to refactor the code thus:

    def double_thing()
      thing = @other.thing
      thing + thing
    end

    A slightly different approach would be to replace all calls of double_thing by calls to @other.double_thing:

    class Other
      def double_thing()
        thing + thing
      end
    end

    The approach you take will depend on balancing other factors in your code.

    ServiceDiscovery::ClusterClient#client_that_responds_to manually dispatches method call
    Open

            client_responds_to_method = client.respond_to?(method_sym)

    Reek reports a Manual Dispatch smell if it finds source code that manually checks whether an object responds to a method before that method is called. Manual dispatch is a type of Simulated Polymorphism which leads to code that is harder to reason about, debug, and refactor.

    Example

    class MyManualDispatcher
      attr_reader :foo
    
      def initialize(foo)
        @foo = foo
      end
    
      def call
        foo.bar if foo.respond_to?(:bar)
      end
    end

    Reek would emit the following warning:

    test.rb -- 1 warning:
      [9]: MyManualDispatcher manually dispatches method call (ManualDispatch)

    There are no issues that match your filters.

    Category
    Status