From 6812e52dee6fb52990eaf056e69978258b710090 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Mon, 23 Oct 2017 13:58:19 +0100 Subject: [PATCH] Replace CLI class with a more suitable Application class --- .rubocop.yml | 3 + bunnyrun.gemspec | 3 +- examples/application-example/bin/foobar | 17 +- .../lib/foobar/ping_consumer.rb | 3 + exe/bunnyrun | 4 +- lib/bunnyrun.rb | 4 +- lib/bunnyrun/application.rb | 173 ++++++++++++++++++ lib/bunnyrun/cli.rb | 119 ------------ 8 files changed, 199 insertions(+), 127 deletions(-) create mode 100644 lib/bunnyrun/application.rb delete mode 100644 lib/bunnyrun/cli.rb diff --git a/.rubocop.yml b/.rubocop.yml index 074bd4e..4dfb969 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,6 @@ +AllCops: + TargetRubyVersion: 2.3 + Documentation: Enabled: false diff --git a/bunnyrun.gemspec b/bunnyrun.gemspec index 53a337b..9f8545c 100644 --- a/bunnyrun.gemspec +++ b/bunnyrun.gemspec @@ -1,4 +1,5 @@ # coding: utf-8 + lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'bunnyrun/version' @@ -24,7 +25,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 1.14' spec.add_development_dependency 'rake', '~> 10.0' spec.add_development_dependency 'rspec', '~> 3.0' - spec.add_development_dependency 'rubocop', '~> 0.47' + spec.add_development_dependency 'rubocop', '~> 0.50' spec.add_development_dependency 'byebug' spec.add_runtime_dependency 'bunny', '~> 2.6' diff --git a/examples/application-example/bin/foobar b/examples/application-example/bin/foobar index a7fcb0e..96616dd 100755 --- a/examples/application-example/bin/foobar +++ b/examples/application-example/bin/foobar @@ -1,11 +1,18 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + $LOAD_PATH.unshift(File.expand_path('../../lib', File.realpath(__FILE__))) require 'bunnyrun' require 'foobar' -cli = BunnyRun::CLI.new( - name: File.basename(__FILE__), - version: Foobar::VERSION -) +module Foobar + class Application < BunnyRun::Application + name File.basename(__FILE__) + usage ' []' + version Foobar::VERSION -cli.run(ARGV) + option :log_message, 'Message to log after success', type: :string + end +end + +Foobar::Application.run(argv: ARGV) diff --git a/examples/application-example/lib/foobar/ping_consumer.rb b/examples/application-example/lib/foobar/ping_consumer.rb index 4273402..04f7e94 100644 --- a/examples/application-example/lib/foobar/ping_consumer.rb +++ b/examples/application-example/lib/foobar/ping_consumer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'bunnyrun' module Foobar @@ -15,6 +17,7 @@ module Foobar publish('ping-pong', 'PONG', routing_key: 'pong') message.ack + logger.info end end end diff --git a/exe/bunnyrun b/exe/bunnyrun index bc2d040..00b2df7 100755 --- a/exe/bunnyrun +++ b/exe/bunnyrun @@ -1,5 +1,7 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + $LOAD_PATH.unshift(File.expand_path('../../lib', File.realpath(__FILE__))) require 'bunnyrun' -BunnyRun::CLI.run(ARGV) +BunnyRun::Application.run(argv: ARGV) diff --git a/lib/bunnyrun.rb b/lib/bunnyrun.rb index bf87830..7bff22c 100644 --- a/lib/bunnyrun.rb +++ b/lib/bunnyrun.rb @@ -1,4 +1,6 @@ -require 'bunnyrun/cli' +# frozen_string_literal: true + +require 'bunnyrun/application' require 'bunnyrun/consumer' require 'bunnyrun/runner' require 'bunnyrun/version' diff --git a/lib/bunnyrun/application.rb b/lib/bunnyrun/application.rb new file mode 100644 index 0000000..800551b --- /dev/null +++ b/lib/bunnyrun/application.rb @@ -0,0 +1,173 @@ +# frozen_string_literal: true + +require 'trollop' + +require 'bunnyrun/consumer' +require 'bunnyrun/runner' +require 'bunnyrun/version' + +module BunnyRun + class Application + class << self + def run(*args) + new.run(*args) + end + + def name(input = nil) + @name = input unless input.nil? + @name + end + + def usage(input = nil) + @usage = input unless input.nil? + @usage + end + + def version(input = nil) + @version = input unless input.nil? + @version + end + + def option(name, description, opts) + options << [name, description, opts] + end + + def options + @options ||= [] + end + end + + def name + self.class.name + end + + def usage + self.class.usage + end + + def version + self.class.version + end + + def run(opts = {}) + argv = opts.delete(:argv) + options = parse_args(argv) + options.merge!(opts) + + require_files(options[:paths]) if options[:paths].any? + consumers = Consumer.children + + runner = Runner.new(options, consumers) + runner.run + end + + private + + def parse_args(args) + args = args.clone + + opts = Trollop.with_standard_exception_handling(parser) do + parser.parse(args) + end + opts[:paths] = args + + opts + end + + def parser + @parser ||= begin + parser = Trollop::Parser.new + define_version(parser) + define_usage(parser) + + define_connection_options(parser) + define_logging_options(parser) + define_application_options(parser) + + parser.banner "\nHelp/Version:" + parser + end + end + + def define_usage(parser) + parser.banner "Usage: #{name} #{usage}" + end + + def define_version(parser) + parser.version "#{name} #{version}" + end + + def define_connection_options(parser) + parser.banner "\nRabbitMQ Options:" + + parser.opt :url, 'Connection string ' \ + '(example: "amqp://guest:guest@127.0.0.1:5672/vhost")', + short: 'U', type: :string, + default: ENV['RABBITMQ_URL'] || nil + parser.opt :host, 'Host', + short: 'H', type: :string, + default: ENV['RABBITMQ_HOST'] || '127.0.0.1' + parser.opt :port, 'Port', + short: 'P', type: :int, + default: (ENV['RABBITMQ_PORT'] || 5672).to_i + parser.opt :ssl, 'Connect using SSL', + short: 's', type: :bool, + default: trufy?(ENV.fetch('RABBITMQ_SSL', false)) + parser.opt :vhost, 'Virtual host', + short: 'V', type: :string, + default: ENV['RABBITMQ_VHOST'] || '/' + parser.opt :user, 'Username', + short: 'u', type: :string, + default: ENV['RABBITMQ_USER'] || 'guest' + parser.opt :pass, 'Password', + short: 'p', type: :string, + default: ENV['RABBITMQ_PASS'] || 'guest' + parser.opt :prefetch, 'Default prefetch count', + short: :none, type: :int, + default: (ENV['RABBITMQ_PREFETCH'] || 1).to_i + + parser.conflicts :url, :host + parser.conflicts :url, :port + parser.conflicts :url, :ssl + parser.conflicts :url, :vhost + parser.conflicts :url, :user + parser.conflicts :url, :pass + end + + def define_logging_options(parser) + parser.banner "\nLogging Options:" + + parser.opt :log_target, 'Log target, file path or STDOUT', + short: 't', type: :string, + default: ENV['LOG_TARGET'] || 'STDOUT' + parser.opt :log_level, 'Log level (debug, info, warn, error, fatal)', + short: 'l', type: :string, + default: ENV['LOG_LEVEL'] || 'info' + parser.opt :bunny_log_target, 'Log target used by Bunny', + short: :none, type: :string, + default: ENV['BUNNY_LOG_TARGET'] || 'STDOUT' + parser.opt :bunny_log_level, 'Log level used by Bunny', + short: :none, type: :string, + default: ENV['BUNNY_LOG_LEVEL'] || 'warn' + end + + def define_application_options(parser) + return if self.class.options.empty? + + parser.banner "\nApplication Options:" + self.class.options.each do |opt_args| + parser.opt(*opt_args) + end + end + + def trufy?(input) + %w[true 1 y yes].include?(input) + end + + def require_files(paths) + paths.each do |path| + require File.expand_path(path) + end + end + end +end diff --git a/lib/bunnyrun/cli.rb b/lib/bunnyrun/cli.rb deleted file mode 100644 index ca23aea..0000000 --- a/lib/bunnyrun/cli.rb +++ /dev/null @@ -1,119 +0,0 @@ -require 'trollop' - -require 'bunnyrun/consumer' -require 'bunnyrun/runner' -require 'bunnyrun/version' - -module BunnyRun - class CLI - def self.run(argv = []) - new.run(argv) - end - - def initialize(name: nil, version: nil, usage: nil) - @name = name - @version = version - @usage = usage - end - - def name - @name ||= 'bunnyrun' - end - - def version - @version ||= BunnyRun::VERSION - end - - def usage - @usage ||= '[options] [path ...]' - end - - def run(args = []) - options = parse_args(args) - - require_files(options[:paths]) if options[:paths].any? - consumers = Consumer.children - - runner = Runner.new(options, consumers) - runner.run - end - - private - - def parse_args(args) - args = args.clone - - opts = Trollop.with_standard_exception_handling(parser) do - parser.parse(args) - end - opts[:paths] = args - - opts - end - - def parser - @parser ||= begin - parser = Trollop::Parser.new - define_version(parser) - define_usage(parser) - - parser.banner "\nOptions:" - define_connection_options(parser) - define_logging_options(parser) - parser - end - end - - def define_usage(parser) - parser.banner "Usage: #{name} #{usage}" - end - - def define_version(parser) - parser.version "#{name} #{version}" - end - - def define_connection_options(parser) - parser.opt :url, 'Connection string ' \ - '(example: "amqp://guest:guest@127.0.0.1:5672/vhost")', - short: 'U', type: :string - parser.opt :host, 'Host', - short: 'H', type: :string, default: '127.0.0.1' - parser.opt :port, 'Port', - short: 'P', type: :int, default: 5672 - parser.opt :ssl, 'Connect using SSL', - short: 's', type: :bool, default: false - parser.opt :vhost, 'Virtual host', - short: 'V', type: :string, default: '/' - parser.opt :user, 'Username', - short: 'u', type: :string, default: 'guest' - parser.opt :pass, 'Password', - short: 'p', type: :string, default: 'guest' - parser.opt :prefetch, 'Default prefetch count', - short: :none, type: :int, default: 1 - - parser.conflicts :url, :host - parser.conflicts :url, :port - parser.conflicts :url, :ssl - parser.conflicts :url, :vhost - parser.conflicts :url, :user - parser.conflicts :url, :pass - end - - def define_logging_options(parser) - parser.opt :log_target, 'Log target, file path or STDOUT', - short: 't', type: :string, default: 'STDOUT' - parser.opt :log_level, 'Log level (debug, info, warn, error, fatal)', - short: 'l', type: :string, default: 'info' - parser.opt :bunny_log_target, 'Log target used by Bunny', - short: :none, type: :string, default: 'STDOUT' - parser.opt :bunny_log_level, 'Log level used by Bunny', - short: :none, type: :string, default: 'warn' - end - - def require_files(paths) - paths.each do |path| - require File.expand_path(path) - end - end - end -end