Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 153 lines (117 sloc) 3.704 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
#!/usr/bin/ruby

require 'yaml'

use_color = true
project_root = Dir.pwd
project_name = File.basename(project_root)
support_root = "#{File.expand_path(File.dirname(__FILE__))}/support/takeup/#{project_name}"

interpolator = lambda do |*args|
  string = args[0]
  extras = args[1] || {}

  if string
    result = string.dup
    result.gsub!(':project_root', project_root)
    result.gsub!(':project_name', project_name)
    result.gsub!(':support_root', support_root)

    extras.each_pair do |key, value|
      result.gsub!(key, value) if value
    end

    result
  end
end

processes = []

config = YAML.load(File.read("#{support_root}/manifest.yml"))

config.each do |process|
  pid_file = interpolator.call(process['pid_file'])

  processes << { 'name' => process['name'],
                 'pid_file' => pid_file,
                 'start' => interpolator.call(process['start'], ':pid_file' => pid_file),
                 'stop' => interpolator.call(process['stop'], ':pid_file' => pid_file),
                 'required' => !!process['required'] }
end

def running?(process)
  File.exist?(process['pid_file'])
end

pid_checker = lambda do
  entries = []

  running = use_color ? "\e[32mon\e[0m" : 'on'
  off = use_color ? "\e[31moff\e[0m" : 'off'

  processes.each do |process|
    if process['pid_file']
      name = process['name'] || File.basename(process['pid_file']).sub('.pid', '')
      status = running?(process) ? running : off
      entries << [name, status]
    end
  end

  entries
end

project_title = use_color ? "\e[32m#{project_name.capitalize}\e[0m" : project_name.capitalize
skipped = use_color ? "\e[31m - skipped\e[0m" : ' - skipped'
projects_for_regex = processes.map{|p| p['name'] && Regexp.escape(p['name'])}.compact.join('|')
debug_mode = !!ARGV.delete('--debug')

run_command = lambda do |command|
  cmd = command.dup

  if debug_mode
    puts `#{cmd}`
  else
    cmd << ' > /dev/null 2>&1'
    system cmd
  end
end

start_process = lambda do |process|
  if process['start'] && (process['pid_file'].nil? || !running?(process))
    if process['name']
      puts "-> Starting #{process['name']}"
    end

    run_command.call(process['start'])
  elsif process['pid_file'] && running?(process)
    puts skipped
  end
end

stop_process = lambda do |process|
  if process['stop'] && (process['pid_file'].nil? || running?(process))
    if process['name']
      puts "-> Stopping #{process['name']}"
    end

    run_command.call(process['stop'])
  elsif process['pid_file'] && !running?(process)
    puts "-> Stopping #{process['name']}"
    puts skipped
  end
end

case ARGV[0].to_s.strip

when ''
  puts "\n#{project_title}"
  processes.each{ |p| start_process.call(p) }
  puts "\n"

when 'minimal'
  puts "\n#{project_title} (minimal)"
  processes.select{ |p| p['required'] }.each{|p| start_process.call(p) }
  puts "\n"

when /^(?:#{projects_for_regex})$/
  puts "\n#{project_title}"
  p = processes.find{ |p| p['name'] == ARGV[0].to_s.strip }
  start_process.call(p)
  puts "\n"

when /^(?:done|off|down|stop|enough|quit|not)$/i
  puts "\n#{project_title}"

  if ARGV[1].to_s.strip =~ /^(?:#{projects_for_regex})$/
    p = processes.find{ |p| p['name'] == ARGV[1].to_s.strip }
    stop_process.call(p)
  else
    processes.reverse.each{ |p| stop_process.call(p) }
  end

  puts "\n"

when /^(?:status|st)$/i
  entries = pid_checker.call
  width = entries.map(&:first).max.to_s.size + 6

  entries = entries.map do |entry|
    "#{entry.first}".ljust(width) + entry.last
  end

  statuses = entries.empty? ? 'no pids defined' : entries.join("\n ")
  puts <<-STATUS
#{project_title}

#{statuses}

STATUS

else
  puts 'Error: command not recognized.'
end
Something went wrong with that request. Please try again.