Instiki

From EggeWiki

I created a setup script to help me get Instiki running from source. So far I have it working with SQLite, but I'd like to get mysql working as well.

#!/usr/bin/env ruby

require 'stringio'
require 'ftools'
require 'find'

def get(prompt) 
  print prompt 
  res = readline.chomp 
  throw :quit_requested if res == "!" 
  res 
end

def choose(prompt, list)
  (1..list.length).each {|x| puts "#{x}) #{list[x-1]}"}
  i = get(prompt + " (1-#{list.length}): ")
  list[i.to_i - 1]
end

def show_configs(configs, io)
  configs.each do |name,settings|
    io.puts "#{name}:"
    settings.each {|k,v| io.puts "  #{k}: #{v}"}
    io.puts
  end
end

# OpenSLL will probably be able to come up with a better random password than the Ruby code, so we'll use it if the system has it
def random_password(size = 8)
  if @hasOpenSSL == nil then
    `which OpenSSL`
    @hasOpenSSL = ($? == 0)
  end
  if @hasOpenSSL
    `OpenSSL rand 8 -base64`.chomp()
  else
    chars = (('a'..'z').to_a + (0..9).to_a) - %w(i o 0 1 l 0)
    (1..size).collect{|a| chars[rand(chars.size)] }.join
  end
end

puts "This script will help you configure your database.yml file."

adapters = []

`which mysql`
if $? == 0 then
  adapters << "mysql"
end

# SQLite seems to return 1 for it's normal return code
`which sqlite3`
if $? == 0 then 
  adapters << "sqlite3"
else
  puts $?
end

adapter = choose('Select a database adapter', adapters)

configs = { 'development' => {}, 'test' => {}, 'production' => {}}

configs.each {|k,v| v['adapter'] = adapter}
case adapter
when "sqlite3"
  configs.each {|k,v| v['database'] = "db/#{k}.db.sqlite3"}
when "mysql"
  configs.each {|k,v| 
    v['host'] = 'localhost'
    %w{ /var/run/mysqld/mysqld.sock /var/mysqld.sock }.each {|sock|
      if File.exists?(sock) then
        v['socket'] = sock
        break
      end
    }
    v['database'] = "instiki_#{k}"
    v['username'] = "inst_#{k[0..3]}"
    v['password'] = random_password
  }
end

str = StringIO.new()

show_configs(configs, str)

puts "Created database config:"
puts str.string

if File.file?('config/database.yml') then
  if get("Would you like to replace database.yml with the above config? (Y/n) ").downcase == 'n' then
    puts "Cancelled"
    exit 1
  end
  # backup the svn version
  if !File.file?('config/database.yml.old')
    File.move("config/database.yml", "config/database.yml.old", true)
  end
end

File.open("config/database.yml", "w") do |file|
  show_configs(configs, file)
end

case adapter
when "sqlite3"
  Find.find('db') { |f| File.delete(f) if f =~ /.*\.db/ }
when "mysql"
  configs.each {|k,v|
    sql = "create database IF NOT EXISTS #{v['database']}; grant all on #{v['database']}.* to '#{v['username']}'@'localhost' identified by '#{v['password']}';"
    `mysql -u root -e "#{sql}"`
  }
end

configs.each do |env,k|
  system("rake migrate RAILS_ENV=#{env}")
end