Guest User

Untitled

a guest
Mar 2nd, 2018
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.92 KB | None | 0 0
  1. require "yaml"
  2. require "irb"
  3. require Pathname("irb/completion")
  4.  
  5. # TODO: error handling for:
  6. # missing adapter, host or database
  7. module DataMapper
  8.  
  9. class CLI
  10.  
  11. class << self
  12.  
  13. def usage
  14. <<-USAGE
  15.  
  16. dm - Data Mapper CLI
  17.  
  18. Usage Examples\n#{'='*80}
  19.  
  20. * If one argument is given the CLI assumes it is a connection string:
  21. $ dm mysql://root@localhost/test_development
  22.  
  23. The connection string has the format:
  24. adapter://user:password@host:port/database
  25. Where adapter is in: {mysql, pgsql, sqlite...} and the user/password is optional
  26.  
  27. Note that if there are any non-optional arguments specified, the first is
  28. assumed to be a database connection string which will be used instead of any
  29. database specified by options.
  30.  
  31. * Load the database by specifying cli options
  32. $ dm -a mysql -u root -h localhost -d test_development
  33.  
  34. * Load the database using a yaml config file and specifying the environment to use
  35. $ dm --yaml config/database.yml -e development
  36.  
  37. * Load everything from a config file, this example is equivalent to the above
  38. $ dm --config config/development.yml
  39.  
  40. * Load the database and some model files from a directory, specifying the environment
  41. $ dm --yaml config/database.yml -e development --models app/models
  42.  
  43. * Load an assumed structure of a typical merb application
  44. $ dm --merb -e development
  45.  
  46. This is similar to merb -i without the merb framework being loaded.
  47.  
  48. * Load the dm-validations and dm-timestamps plugins before connecting to the db
  49. $ dm -P validations,dm-timestamps mysql://root@localhost/test_development
  50.  
  51. If dm- isn't at the start of the file, it will be prepended.
  52.  
  53.  
  54. USAGE
  55. end
  56.  
  57. attr_accessor :options, :config
  58.  
  59. def parse_args(argv = ARGV)
  60. @config ||= {}
  61.  
  62. # Build a parser for the command line arguments
  63. OptionParser.new do |opt|
  64. opt.define_head "DataMapper CLI"
  65. opt.banner = usage
  66.  
  67. opt.on("-m", "--models MODELS", "The directory to load models from.") do |models|
  68. @config[:models] = Pathname(models)
  69. end
  70.  
  71. opt.on("-c", "--config FILE", "Entire configuration structure, useful for testing scenarios.") do |config_file|
  72. @config = YAML::load_file Pathname(config_file)
  73. end
  74.  
  75. opt.on("--merb", "--rails", "Loads application settings: config/database.yml, app/models.") do
  76. @config[:models] = Pathname("app/models")
  77. @config[:yaml] = Pathname("config/database.yml")
  78. end
  79.  
  80. opt.on("-y", "--yaml YAML", "The database connection configuration yaml file.") do |yaml_file|
  81. if (yaml = Pathname(yaml_file)).file?
  82. @config[:yaml] = yaml
  83. elsif (yaml = Pathname("#{Dir.getwd}/#{yaml_file}")).file?
  84. @config[:yaml] = yaml
  85. else
  86. raise "yaml file was specifed as #{yaml_file} but does not exist."
  87. end
  88. end
  89.  
  90. opt.on("-l", "--log LOGFILE", "A string representing the logfile to use. Also accepts STDERR and STDOUT") do |log_file|
  91. @config[:log_file] = log_file
  92. end
  93.  
  94. opt.on("-e", "--environment STRING", "Run merb in the correct mode(development, production, testing)") do |environment|
  95. @config[:environment] = environment
  96. end
  97.  
  98. opt.on("-a", "--adapter ADAPTER", "Number of merb daemons to run.") do |adapter|
  99. @config[:adapter] = adapter
  100. end
  101.  
  102. opt.on("-u", "--username USERNAME", "The user to connect to the database as.") do |username|
  103. @config[:username] = username
  104. end
  105.  
  106. opt.on("-p", "--password PASSWORD", "The password to connect to the database with") do |password|
  107. @config[:password] = password
  108. end
  109.  
  110. opt.on("-h", "--host HOSTNAME", "Host to connect to.") do |host|
  111. @config[:host] = host
  112. end
  113.  
  114. opt.on("-s", "--socket SOCKET", "The socket to connect to.") do |socket|
  115. @config[:socket] = socket
  116. end
  117.  
  118. opt.on("-o", "--port PORT", "The port to connect to.") do |port|
  119. @config[:port] = port
  120. end
  121.  
  122. opt.on("-d", "--database DATABASENAME", "Name of the database to connect to.") do |database_name|
  123. @config[:database] = database_name
  124. end
  125.  
  126. opt.on("-P", "--plugins PLUGIN,PLUGIN...", "A list of dm-plugins to require", Array) do |plugins|
  127. @config[:plugins] = plugins
  128. end
  129.  
  130. opt.on("-?", "-H", "--help", "Show this help message") do
  131. puts opt
  132. exit
  133. end
  134.  
  135. end.parse!(argv)
  136.  
  137. end
  138.  
  139. def configure(args)
  140.  
  141. parse_args(args)
  142.  
  143. @config[:environment] ||= "development"
  144. if @config[:config]
  145. @config.merge!(YAML::load_file(@config[:config]))
  146. @options = @config[:options]
  147. elsif @config[:yaml]
  148. @config.merge!(YAML::load_file(@config[:yaml]))
  149. @options = @config[@config[:environment]] || @config[@config[:environment].to_sym]
  150. raise "Options for environment '#{@config[:environment]}' are missing." if @options.nil?
  151. else
  152. @options = {
  153. :adapter => @config[:adapter],
  154. :username => @config[:username],
  155. :password => @config[:password],
  156. :host => @config[:host],
  157. :database => @config[:database]
  158. }
  159. end
  160. if !ARGV.empty?
  161. @config[:connection_string] = ARGV.shift
  162. end
  163.  
  164. end
  165.  
  166. def load_models
  167. Pathname.glob("#{config[:models]}/**/*.rb") { |file| load file }
  168. end
  169.  
  170. def require_plugins
  171. # make sure we're loading dm plugins!
  172. plugins = config[:plugins].map {|p| (p =~ /^dm/) ? p : "dm-" + p }
  173. plugins.each do |plugin|
  174. begin
  175. require plugin
  176. puts "required #{plugin}."
  177. rescue LoadError => e
  178. puts "couldn't load #{plugin}."
  179. end
  180. end
  181. end
  182.  
  183. def setup_logger
  184. if config[:log_file] =~ /^std(?:out|err)$/i
  185. log = Object.full_const_get(config[:log_file].upcase)
  186. else
  187. log = Pathname(config[:log_file])
  188. end
  189.  
  190. DataMapper::Logger.new(log, :debug)
  191. end
  192.  
  193. def start(argv = ARGV)
  194. if (ARGV.nil? || ARGV.empty?)
  195. puts DataMapper::CLI.usage
  196. exit 1
  197. end
  198.  
  199. begin
  200. configure(argv)
  201.  
  202. require_plugins if config[:plugins]
  203.  
  204. setup_logger if config[:log_file]
  205.  
  206. if config[:connection_string]
  207. DataMapper.setup(:default, config[:connection_string])
  208. puts "DataMapper has been loaded using '#{config[:connection_string]}'"
  209. else
  210. DataMapper.setup(:default, options.dup)
  211. puts "DataMapper has been loaded using the '#{options[:adapter] || options["adapter"]}' database '#{options[:database] || options["database"]}' on '#{options[:host] || options["host"]}' as '#{options[:username] || options["username"]}'"
  212.  
  213. if options[:repositories]
  214. repositories = options[:repositories].dup
  215. repositories.each do |name, opts|
  216. ::DataMapper.setup(name, opts)
  217. puts "DataMapper connected to repository #{name} using the '#{opts[:adapter] || opts['adapter']}' database '#{opts[:database] || opts["database"]}' on '#{opts[:host] || opts["host"]}' as '#{opts[:username] || opts["username"]}'"
  218. end
  219. end
  220.  
  221. end
  222. load_models if config[:models]
  223. ENV["IRBRC"] ||= DataMapper::CLI::BinDir + "/.irbrc" # Do not change this please. This should NOT be DataMapper.root
  224. IRB.start
  225. rescue => error
  226. puts error.message
  227. exit
  228. end
  229.  
  230. end
  231. end
  232. end # module CLI
  233. end # module DataMapper
Add Comment
Please, Sign In to add comment