lib/beerdb/cli/main.rb in beerdb-0.8.1 vs lib/beerdb/cli/main.rb in beerdb-0.8.2
- old
+ new
@@ -1,41 +1,49 @@
# encoding: utf-8
-require 'commander/import'
+require 'gli'
+
+include GLI::App
+
require 'logutils/db' # add support for logging to db
require 'beerdb/cli/opts'
-LogUtils::Logger.root.level = :info # set logging level to info
-program :name, 'beerdb'
-program :version, BeerDb::VERSION
-program :description, "beer.db command line tool, version #{BeerDb::VERSION}"
+program_desc 'beer.db command line tool'
+version BeerDb::VERSION
-# default_command :help
-default_command :load
+LogUtils::Logger.root.level = :info # set logging level to info
+logger = LogUtils::Logger.root
-program :help_formatter, Commander::HelpFormatter::TerminalCompact
+opts = BeerDb::Opts.new
-## todo: find a better name e.g. change to settings? config? safe_opts? why? why not?
-myopts = BeerDb::Opts.new
### global option (required)
## todo: add check that path is valid?? possible?
-global_option '-i', '--include PATH', String, "Data path (default is #{myopts.data_path})"
-global_option '-d', '--dbpath PATH', String, "Database path (default is #{myopts.db_path})"
-global_option '-n', '--dbname NAME', String, "Database name (datault is #{myopts.db_name})"
+desc 'Database path'
+arg_name 'PATH'
+default_value opts.db_path
+flag [:d, :dbpath]
-global_option '-q', '--quiet', "Only show warnings, errors and fatal messages"
-### todo/fix: just want --debug/--verbose flag (no single letter option wanted) - fix
-global_option '-w', '--verbose', "Show debug messages"
+desc 'Database name'
+arg_name 'NAME'
+default_value opts.db_name
+flag [:n, :dbname]
+desc '(Debug) Show debug messages'
+switch [:verbose], negatable: false ## todo: use -w for short form? check ruby interpreter if in use too?
+desc 'Only show warnings, errors and fatal messages'
+switch [:q, :quiet], negatable: false
+
+
+
def connect_to_db( options )
puts BeerDb.banner
puts "working directory: #{Dir.pwd}"
@@ -51,198 +59,189 @@
LogDb.setup # turn on logging to db
end
-command :create do |c|
- c.syntax = 'beerdb create [options]'
- c.description = 'Create DB schema'
+desc 'Create DB schema'
+command [:create] do |c|
- c.option '--extras', 'Extra tables (drinks,bookmarks,users)'
+ c.desc 'Extra tables (notes,drinks,marks,users)'
+ c.switch [:extras], negatable: false
- c.action do |args, options|
+ c.action do |g,o,args|
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
+ connect_to_db( opts )
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
-
- if options.extras.present?
+ if o[:extras].present?
# quick hack: only create extra tables
BeerDb::CreateDbExtrasUsers.new.up
BeerDb::CreateDbExtrasBookmarks.new.up
BeerDb::CreateDbExtrasNotes.new.up
BeerDb::CreateDbExtrasDrinks.new.up
else
LogDb.create
WorldDb.create
BeerDb.create
end
-
puts 'Done.'
end # action
end # command create
-command :setup do |c|
- c.syntax = 'beerdb setup [options]'
- c.description = "Create DB schema 'n' load all data"
- c.option '--world', 'Populate world tables'
- ## todo: use --world-include - how? find better name?
- c.option '--worldinclude PATH', String, 'World data path'
+desc "Create DB schema 'n' load all world and beer data"
+arg_name 'NAME' # optional setup profile name
+command [:setup,:s] do |c|
- c.option '--beer', 'Populate beer tables'
- c.option '--delete', 'Delete all records'
+ c.desc 'Beer data path'
+ c.arg_name 'PATH'
+ c.default_value opts.data_path
+ c.flag [:i,:include]
- c.action do |args, options|
+ c.desc 'World data path'
+ c.arg_name 'PATH'
+ c.flag [:worldinclude] ## todo: use --world-include - how? find better name? add :'world-include' ???
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
+ c.action do |g,o,args|
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
-
+ connect_to_db( opts )
+
## todo: document optional setup profile arg (defaults to all)
setup = args[0] || 'all'
- if options.world.present? || options.beer.present?
-
- ## todo: check order for reference integrity
- # not really possible to delete world data if sport data is present
- # delete sport first
-
- if options.delete.present?
- BeerDb.delete! if options.beer.present?
- WorldDb.delete! if options.world.present?
- end
-
- if options.world.present?
- WorldDb.read_all( myopts.world_data_path )
- end
-
- if options.beer.present?
- BeerDb.read_setup( "setups/#{setup}", myopts.data_path )
- end
-
- else # assume "plain" regular setup
- LogDb.create
- WorldDb.create
- BeerDb.create
+ LogDb.create
+ WorldDb.create
+ BeerDb.create
- WorldDb.read_all( myopts.world_data_path )
- BeerDb.read_setup( "setups/#{setup}", myopts.data_path )
- end
+ WorldDb.read_all( opts.world_data_path )
+ BeerDb.read_setup( "setups/#{setup}", opts.data_path )
+ puts 'Done.'
+ end # action
+end # command setup
+
+desc 'Update all beer data'
+arg_name 'NAME' # optional setup profile name
+command [:update,:up,:u] do |c|
+
+ c.desc 'Beer data path'
+ c.arg_name 'PATH'
+ c.default_value opts.data_path
+ c.flag [:i,:include]
+
+ c.desc 'Delete all beer data records'
+ c.switch [:delete], negatable: false
+
+ c.action do |g,o,args|
+
+ connect_to_db( opts )
+
+ ## todo: document optional setup profile arg (defaults to all)
+ setup = args[0] || 'all'
+
+ BeerDb.delete! if o[:delete].present?
+
+ BeerDb.read_setup( "setups/#{setup}", opts.data_path )
puts 'Done.'
end # action
end # command setup
-command :load do |c|
- ## todo: how to specify many fixutes <>... ??? in syntax
- c.syntax = 'beerdb load [options] <fixtures>'
- c.description = 'Load fixtures'
- c.option '--delete', 'Delete all records'
- c.action do |args, options|
+desc 'Load beer fixtures'
+arg_name 'NAME' # multiple fixture names - todo/fix: use multiple option
+command [:load, :l] do |c|
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
+ c.desc 'Delete all beer data records'
+ c.switch [:delete], negatable: false
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
+ c.action do |g,o,args|
+
+ connect_to_db( opts )
- if options.delete.present?
- LogDb.delete!
- BeerDb.delete!
- end
+ BeerDb.delete! if o[:delete].present?
- # read plain text country/region/city fixtures
- reader = BeerDb::Reader.new( myopts.data_path )
+ reader = BeerDb::Reader.new( opts.data_path )
+
args.each do |arg|
name = arg # File.basename( arg, '.*' )
reader.load( name )
end # each arg
-
+
puts 'Done.'
end
end # command load
+
## fix/todo: add server alias (serve/server)
-command :serve do |c|
- ## todo: how to specify many fixutes <>... ??? in syntax
- c.syntax = 'beerdb serve [options]'
- c.description = 'Start web service (HTTP JSON API)'
+desc 'Start web service (HTTP JSON API)'
+command [:serve,:server] do |c|
- c.action do |args, options|
+ c.action do |g,o,args|
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
+ connect_to_db( opts )
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
-
# NB: server (HTTP service) not included in standard default require
require 'beerdb/server'
- ### fix: add ActiveRecord rack Middleware to close connection!! how?
+# make sure connections get closed after every request e.g.
+#
+# after do
+# ActiveRecord::Base.connection.close
+# end
+#
+
+ puts 'before add middleware ConnectionManagement'
+ BeerDb::Server.use ActiveRecord::ConnectionAdapters::ConnectionManagement
+ puts 'after add middleware ConnectionManagement'
+ ## todo: check if we can check on/dump middleware stack
+
+ ## rack middleware might not work with multi-threaded thin web server; close it ourselfs
+ BeerDb::Server.after do
+ puts " #{Thread.current.object_id} -- make sure db connections gets closed after request"
+ # todo: check if connection is open - how?
+ ActiveRecord::Base.connection.close
+ end
+
BeerDb::Server.run!
-
+
puts 'Done.'
end
-end # command load
+end # command serve
+desc 'Show stats'
command :stats do |c|
- c.syntax = 'beerdb stats [options]'
- c.description = 'Show stats'
- c.action do |args, options|
+ c.action do |g,o,args|
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
-
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
+ connect_to_db( opts )
BeerDb.tables
puts 'Done.'
end
end
+desc 'Show props'
command :props do |c|
- c.syntax = 'beerdb props [options]'
- c.description = 'Show props'
- c.action do |args, options|
+ c.action do |g,o,args|
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
-
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
+ connect_to_db( opts )
BeerDb.props
puts 'Done.'
end
end
-
+desc 'Show logs'
command :logs do |c|
- c.syntax = 'beerdb logs [options]'
- c.description = 'Show logs'
- c.action do |args, options|
+ c.action do |g,o,args|
- LogUtils::Logger.root.level = :warn if options.quiet.present?
- LogUtils::Logger.root.level = :debug if options.verbose.present?
-
- myopts.merge_commander_options!( options.__hash__ )
- connect_to_db( myopts )
+ connect_to_db( opts )
LogDb::Models::Log.all.each do |log|
puts "[#{log.level}] -- #{log.msg}"
end
@@ -250,19 +249,60 @@
end
end
+desc '(Debug) Test command suite'
command :test do |c|
- c.syntax = 'beerdb test [options]'
- c.description = 'Debug/test command suite'
- c.action do |args, options|
+ c.action do |g,o,args|
+
puts "hello from test command"
puts "args (#{args.class.name}):"
pp args
- puts "options:"
- pp options
- puts "options.__hash__:"
- pp options.__hash__
+ puts "o (#{o.class.name}):"
+ pp o
+ puts "g (#{g.class.name}):"
+ pp g
+
+ LogUtils::Logger.root.debug 'test debug msg'
+ LogUtils::Logger.root.info 'test info msg'
+ LogUtils::Logger.root.warn 'test warn msg'
+
puts 'Done.'
end
end
+
+
+
+pre do |g,c,o,args|
+ opts.merge_gli_options!( g )
+ opts.merge_gli_options!( o )
+
+ puts BeerDb.banner
+
+ if opts.verbose?
+ LogUtils::Logger.root.level = :debug
+ end
+
+ logger.debug "Executing #{c.name}"
+ true
+end
+
+post do |global,c,o,args|
+ logger.debug "Executed #{c.name}"
+ true
+end
+
+
+on_error do |e|
+ puts
+ puts "*** error: #{e.message}"
+
+ if opts.verbose?
+ puts e.backtrace
+ end
+
+ false # skip default error handling
+end
+
+
+exit run(ARGV)
\ No newline at end of file