From 59c34ed04917a87616dd1516cf53e9316e133f40 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Wed, 8 Jun 2016 13:33:46 +0200 Subject: [PATCH] Engage rubocop, make the code and also the police behave. --- .rubocop.yml | 69 ++++++++++++++++++++++++++++++++++++++++++++++ Gemfile | 12 +++++--- Makefile | 11 ++++++-- config.ru | 4 +-- lib/api.rb | 5 ++-- lib/nebula.rb | 88 +++++++++++++++++++++++++++++++++-------------------------- 6 files changed, 139 insertions(+), 50 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..9741b4f --- /dev/null +++ b/.rubocop.yml @@ -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 --- 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' diff --git a/Makefile b/Makefile index a5caece..b6d5d18 100644 --- 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 diff --git a/config.ru b/config.ru index 804c933..0531ef3 100644 --- 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' diff --git a/lib/api.rb b/lib/api.rb index 5999229..ead98eb 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -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 diff --git a/lib/nebula.rb b/lib/nebula.rb index fb4c0fe..2d6f2cf 100644 --- a/lib/nebula.rb +++ b/lib/nebula.rb @@ -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 -- 1.8.2.3