#!/usr/bin/env ruby require 'rubygems' require 'yaml' require 'pp' begin require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /mswin/ rescue LoadError end require 'optparse' options = {} OptionParser.new do |opts| opts.banner = "Usage: example.rb [options]" opts.on("-g [NAME]", "--ginger [NAME]", "Ginger gem name") do |name| options[:ginger] = name end opts.on("-s [NAME]", "--sphinx [NAME]", "Sphinx daemon name") do |name| options[:sphinx] = name end end.parse! OPTIONS = options module ContributeHelper; end class Contribute include ContributeHelper def dependencies [ Dependencies::Sphinx, Dependencies::Mysql, Dependencies::AR, Dependencies::Rspec, Dependencies::Cucumber, Dependencies::Yard, Dependencies::Jeweler, Dependencies::Ginger, ] end def show show_welcome_screen ( check_for_dependencies && create_database_yaml && check_mysql_is_working && create_test_database ) || exit(1) show_done_screen end private WELCOME_SCREEN = <<-EO_WELCOME <banner>Thinking Sphinx Contribution</banner> Thanks for contributing to Thinking Sphinx. In this script we'll help you get setup to hack: <b>1.</b> We'll check that you have the right software installed and running. <b>2.</b> We'll set up the test database for specs to run against. EO_WELCOME DONE_SCREEN = <<-EO_DONE <banner>Setup done!</banner> All done! Now you can start hacking by running <b>rake spec</b> EO_DONE REVIEW_YAML = <<-EO_REVIEW_YAML Please review the database details in the yaml file details before continuing. This file is used by the specs to connect to the database. Current details: EO_REVIEW_YAML MYSQL_FAILED = <<-EO_MYSQL_FAILED Looks like we couldn't successfully talk to the mysql database. Don't worry though... EO_MYSQL_FAILED CREATE_DATABASE_FAILED = <<-EO_CREATE_DATABASE_FAILED Looks like we couldn't create a test database to work against. Don't worry though... EO_CREATE_DATABASE_FAILED def show_welcome_screen colour_puts WELCOME_SCREEN wait! end def show_done_screen colour_puts DONE_SCREEN end # create database.yml def create_database_yaml colour_puts "<banner>creating database yaml</banner>" puts config = { 'username' => 'root', 'password' => nil, 'host' => 'localhost' } colour_print " * <b>#{db_yml}</b>... " unless File.exist?(db_yml) open(db_yml,'w') {|f| f << config.to_yaml} colour_puts "<green>created</green>" else config = YAML.load_file(db_yml) colour_puts "<green>already exists</green>" end colour_puts REVIEW_YAML config.each do |(k,v)| colour_puts " * <b>#{k}</b>: #{v}" end puts wait! true end def check_mysql_is_working require 'activerecord' colour_puts "<banner>check mysql is working</banner>" puts connect_to_db print " * connecting to mysql... " begin ActiveRecord::Base.connection.select_value('select sysdate() from dual') colour_puts "<green>successful</green>" puts return true rescue defined?(JRUBY_VERSION) ? Java::JavaSql::SQLException : Mysql::Error colour_puts "<red>failed</red>" puts MYSQL_FAILED end false end # create test db def create_test_database colour_puts "<banner>create test database</banner>" puts connect_to_db colour_print " * <b>creating thinking_sphinx database</b>... " begin ActiveRecord::Base.connection.create_database('thinking_sphinx') colour_puts "<green>successful</green>" puts return true rescue ActiveRecord::StatementInvalid if $!.message[/database exists/] colour_puts "<green>successful</green> (database already existed)" puts return true else colour_puts "<red>failed</red>" colour_puts CREATE_DATABASE_FAILED end end false end # project def ts_root File.expand_path(File.dirname(__FILE__)) end def specs ts_root / 'spec' end def db_yml specs / 'fixtures' / 'database.yml' end def mysql_adapter defined?(JRUBY_VERSION) ? 'jdbcmysql' : 'mysql' end def connect_to_db config = YAML.load_file(db_yml) config.update(:adapter => mysql_adapter, :database => 'test') config.symbolize_keys! ActiveRecord::Base.establish_connection(config) end end class String def /(other) "#{self}/#{other}" end end module ContributeHelper class Dependency def self.name(name=nil) if name then @name = name else @name end end attr_reader :location def initialize @found = false @location = nil end def name; self.class.name end def check; false end def check! @found = check end def found? @found end end class Gem < Dependency def gem_name; self.class.name end def name; "#{super} gem" end def check ::Gem.available? self.gem_name end end def check_for_dependencies colour_puts "<banner>Checking for required software</banner>" puts all_found = true dependencies.each do |klass| dep = klass.new print " * #{dep.name}... " dep.check! if dep.found? if dep.location colour_puts "<green>found at #{dep.location}</green>" else colour_puts "<green>found</green>" end else all_found &= false colour_puts "<red>not found</red>" end end puts if !all_found print "You may wish to try setting additional options. Use ./contribute.rb -h for details" puts end all_found end def colourise_output? @colourise_output = !!(RUBY_PLATFORM !~ /mswin/ || defined?(Win32::Console::ANSI)) if @colourise_output.nil? @colourise_output end DEFAULT_TERMINAL_COLORS = "\e[0m\e[37m\e[40m" MONOCHROME_OUTPUT = "\\1" def subs_colour(data) data = data.gsub(%r{<b>(.*?)</b>}m, colourise_output? ? "\e[1m\\1#{DEFAULT_TERMINAL_COLORS}" : MONOCHROME_OUTPUT) data.gsub!(%r{<red>(.*?)</red>}m, colourise_output? ? "\e[1m\e[31m\\1#{DEFAULT_TERMINAL_COLORS}" : MONOCHROME_OUTPUT) data.gsub!(%r{<green>(.*?)</green>}m, colourise_output? ? "\e[1m\e[32m\\1#{DEFAULT_TERMINAL_COLORS}" : MONOCHROME_OUTPUT) data.gsub!(%r{<yellow>(.*?)</yellow>}m, colourise_output? ? "\e[1m\e[33m\\1#{DEFAULT_TERMINAL_COLORS}" : MONOCHROME_OUTPUT) data.gsub!(%r{<banner>(.*?)</banner>}m, colourise_output? ? "\e[33m\e[44m\e[1m\\1#{DEFAULT_TERMINAL_COLORS}" : MONOCHROME_OUTPUT) return data end def colour_puts(text) puts subs_colour(text) end def colour_print(text) print subs_colour(text) end def wait! colour_puts "<b>Hit Enter to continue, or Ctrl-C to quit.</b>" STDIN.readline rescue Interrupt exit! end end module Dependencies class Mysql < ContributeHelper::Gem name(defined?(JRUBY_VERSION) ? 'jdbc-mysql' : 'mysql') end class Rspec < ContributeHelper::Gem name 'rspec' end class Cucumber < ContributeHelper::Gem name 'cucumber' end class Yard < ContributeHelper::Gem name 'yard' end class Jeweler < ContributeHelper::Gem name 'jeweler' end class AR < ContributeHelper::Gem name 'activerecord' end class Ginger < ContributeHelper::Gem name(OPTIONS.has_key?(:ginger) ? OPTIONS[:ginger] : 'ginger') end class Sphinx < ContributeHelper::Dependency name 'sphinx' def check app_name = OPTIONS.has_key?(:sphinx) ? OPTIONS[:sphinx] : 'searchd' app_name << '.exe' if RUBY_PLATFORM =~ /mswin/ && app_name[-4, 4] != '.exe' !(@location = ENV['PATH'].split(File::PATH_SEPARATOR).map { |path| File.join(path, app_name) }.find { |path| File.file?(path) && File.executable?(path) }).nil? end end end Contribute.new.show