Engage rubocop, make the code and also the police behave.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Wed, 8 Jun 2016 11:33:46 +0000 (13:33 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Wed, 8 Jun 2016 11:35:59 +0000 (13:35 +0200)
.rubocop.yml [new file with mode: 0644]
Gemfile
Makefile
config.ru
lib/api.rb
lib/nebula.rb

diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644 (file)
index 0000000..9741b4f
--- /dev/null
@@ -0,0 +1,69 @@
+AllCops:
+  DisplayCopNames: true
+  DisplayStyleGuide: true
+  Exclude:
+   # exclude generated code (maybe we'll rewrite it anyway one day)
+   - models/*.rb
+
+# Assignment Branch Condition size for initialize is too high
+# Perceived complexity for deep_merge is too high
+# Cyclomatic complexity for ... is too high
+# Line is too long
+# Method has too many lines
+# ...
+# (wtf)
+Metrics:
+  Enabled: false
+
+# Do not introduce global variables
+# (do want)
+Style/GlobalVars:
+  Exclude:
+    - config.ru
+    - lib/api.rb
+    - lib/nebula.rb
+
+# Omit the parentheses in defs when the method doesn't accept any arguments
+# (easy to read)
+Style/DefWithParentheses:
+  Enabled: false
+
+# Extra empty line detected at class body end
+# (easy to read)
+Style/EmptyLinesAroundClassBody:
+  Enabled: false
+
+# Favor modifier if usage when having a single-line body
+# (easy to read)
+Style/IfUnlessModifier:
+  Enabled: false
+
+# Missing space after #
+# (debugging)
+Style/LeadingCommentSpace:
+  Enabled: false
+
+# Do not use parentheses for method calls with no arguments
+# (easy to read)
+Style/MethodCallParentheses:
+  Enabled: false
+
+# Freeze mutable objects assigned to constants
+# (easy to read)
+Style/MutableConstant:
+  Enabled: false
+
+# Favor unless over if for negative conditions
+# (easy to read)
+Style/NegatedIf:
+  Enabled: false
+
+# Provide an exception class and message as arguments to raise
+# (wtf)
+Style/RaiseArgs:
+  Enabled: false
+
+# Redundant return detected
+# (easy to read)
+Style/RedundantReturn:
+  Enabled: false
diff --git a/Gemfile b/Gemfile
index fb9d3a4..8b7c60e 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,8 +1,12 @@
 source 'https://rubygems.org'
 
-gem "opennebula"
-gem "sinatra"
-gem "sinatra-cross_origin"
+gem 'opennebula'
+
+gem 'sinatra'
+
+gem 'sinatra-cross_origin'
+
+gem 'rubocop', require: false
 
 # recommended for sinatra
-gem "thin"
+gem 'thin'
index a5caece..b6d5d18 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,15 +3,20 @@ all: run
 run: fetch
        bundle exec rackup
 
-check:
-       :
+check: lint test
 
 fetch: Gemfile.lock
 
+lint:
+       rubocop
+
+test:
+       :
+
 clean:
        rm -fv Gemfile.lock
 
 Gemfile.lock:
        bundle install
 
-.PHONY: all check clean fetch run
+.PHONY: all check clean fetch lint test run
index 804c933..0531ef3 100644 (file)
--- a/config.ru
+++ b/config.ru
@@ -1,8 +1,8 @@
 require 'logger'
 
-Dir["./models/*.rb"].each { |file|
+Dir['./models/*.rb'].each do |file|
   require file
-}
+end
 require './version.rb'
 require './lib/nebula.rb'
 require './lib/api.rb'
index 5999229..ead98eb 100644 (file)
@@ -1,10 +1,10 @@
 require 'json'
 require 'sinatra'
 require 'sinatra/cross_origin'
-require ::File.expand_path('../../version',  __FILE__)
+require ::File.expand_path('../../version', __FILE__)
 
 module Now
-
+  # HTTP REST API between NOW and rOCCI server
   class Application < Sinatra::Base
     attr_accessor :nebula
     register Sinatra::CrossOrigin
@@ -40,5 +40,4 @@ module Now
     end
 
   end
-
 end
index fb4c0fe..2d6f2cf 100644 (file)
@@ -3,24 +3,34 @@ require 'yaml'
 
 # http://stackoverflow.com/questions/9381553/ruby-merge-nested-hash
 public def deep_merge(second)
-   merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
-   self.merge(second.to_h, &merger)
+  merger = proc do |_key, v1, v2|
+    if [:undefined, nil, :nil].include?(v2)
+      v1
+    elsif [:undefined, nil, :nil].include?(v1)
+      v2
+    elsif v1.is_a?(Hash) && v2.is_a?(Hash)
+      v1.merge(v2, &merger)
+    elsif v1.is_a?(Array) && v2.is_a(Array)
+      v1 | v2
+    else
+      v2
+    end
+  end
+  merge(second.to_h, &merger)
 end
 
-
 module Now
+  # NOW core class for communication with OpenNebula
   class Nebula
     attr_accessor :config, :logger, :client
 
     def load_config(file)
-      begin
-        c = YAML.load_file(file)
-        @logger.debug "Config file '#{file}' loaded"
-        return c
-      rescue Errno::ENOENT
-        @logger.debug "Config file '#{file}' not found"
-        return {}
-      end
+      c = YAML.load_file(file)
+      @logger.debug "Config file '#{file}' loaded"
+      return c
+    rescue Errno::ENOENT
+      @logger.debug "Config file '#{file}' not found"
+      return {}
     end
 
     def one_connect(url, credentials)
@@ -41,8 +51,8 @@ module Now
       @config = @config.deep_merge(c)
       #@logger.debug "Configuration: #{@config}"
 
-      url = @config["opennebula"]["endpoint"]
-      credentials = "#{@config["opennebula"]["admin_user"]}:#{@config["opennebula"]["admin_password"]}"
+      url = @config['opennebula']['endpoint']
+      credentials = "#{@config['opennebula']['admin_user']}:#{@config['opennebula']['admin_password']}"
       one_connect(url, credentials)
     end
 
@@ -54,7 +64,7 @@ module Now
       vn_pool.each do |vn|
         id = vn.id
         title = vn.name
-        network = Network.new({id: id, title: title})
+        network = Network.new(id: id, title: title)
         networks << network.to_hash
       end
 
@@ -69,42 +79,44 @@ module Now
       id = vn.id
       title = vn.name
       @logger.debug "OpenNebula get(#{network_id}) ==> #{id}, #{title}"
-      network = Network.new({id: id, title: title})
+      network = Network.new(id: id, title: title)
 
       return network.to_hash
     end
 
     private
 
+    def error_one2http(errno)
+      case errno
+      when OpenNebula::Error::ESUCCESS
+        return 200
+      when OpenNebula::Error::EAUTHENTICATION
+        return 401
+      when OpenNebula::Error::EAUTHORIZATION
+        return 403
+      when OpenNebula::Error::ENO_EXISTS
+        return 404
+      when OpenNebula::Error::EXML_RPC_API
+        return 500
+      when OpenNebula::Error::EACTION
+        return 400
+      when OpenNebula::Error::EINTERNAL
+        return 500
+      when OpenNebula::Error::ENOTDEFINED
+        return 501
+      else
+        return 500
+      end
+    end
+
     def check(return_code)
       if !OpenNebula.is_error?(return_code)
         return true
       end
 
-      case return_code.errno
-        when OpenNebula::Error::ESUCCESS
-          code = 200
-        when OpenNebula::Error::EAUTHENTICATION
-          code = 401
-        when OpenNebula::Error::EAUTHORIZATION
-          code = 403
-        when OpenNebula::Error::ENO_EXISTS
-          code = 404
-        when OpenNebula::Error::EXML_RPC_API
-          code = 500
-        when OpenNebula::Error::EACTION
-          code = 400
-        when OpenNebula::Error::EINTERNAL
-          code = 500
-        when OpenNebula::Error::ENOTDEFINED
-          code = 501
-        else
-          code = 500
-      end
-
-      raise NowError.new({code: code, message: return_code.message})
+      code = error_one2http(return_code.errno)
+      raise NowError.new(code: code, message: return_code.message)
     end
 
   end
-
 end