Skip to content

Instantly share code, notes, and snippets.

@phillipkoebbe
Created February 1, 2010 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phillipkoebbe/291830 to your computer and use it in GitHub Desktop.
Save phillipkoebbe/291830 to your computer and use it in GitHub Desktop.
#! /usr/bin/env ruby
require 'optparse'
# This hash will hold all of the options
# parsed from the command-line by
# OptionParser.
$options = {}
optparse = OptionParser.new do |opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: kuke [options] feature tags"
$options[:debug] = false
opts.on('--debug', 'Output what would be otherwise executed.') do
$options[:debug] = true
require 'rubygems'
require 'ruby-debug'
end
$options[:dry_run] = false
opts.on('--dry-run', 'Invokes formatters without executing the steps.') do
$options[:dry_run] = true
end
$options[:isolate_features] = false
opts.on('-i', '--isolate-features', 'Start the culerity server for each feature. Applies to rails mode only.') do
$options[:isolate_features] = true
end
$options[:rails] = true
opts.on('--no-rails', 'Not running in a Rails project, so things specific to Rails can be skipped.') do
$options[:rails] = false
end
# This displays the help screen, all programs are
# assumed to have this option.
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
# Parse the command-line. Remember there are two forms
# of the parse method. The 'parse' method simply parses
# ARGV, while the 'parse!' method parses ARGV and removes
# any options found there, as well as any parameters for
# the options. What's left is the list of files to resize.
optparse.parse!
zero_cmd = "zeroall './log' '*.log'"
$culerity_stop_cmd = 'rake culerity:rails:stop > /dev/null'
feature_path = './cuke/features'
$feature_path_reg_ex = /\.\/cuke\/features[\/]?/
step_path = './cuke/steps'
shared_path = "#{step_path}/shared/"
cuke_cmd = 'cucumber -s -r ./cuke/support/'
cuke_cmd += ' --dry-run' if $options[:dry_run]
if $options[:rails]
cuke_cmd = "./script/#{cuke_cmd}"
cuke_cmd += " -r #{shared_path}"
end
def run_or_print(cmd, suppress_newlines = false)
if $options[:debug]
puts cmd
else
system cmd
puts "\n\n" unless suppress_newlines
end
end
def start_culerity_server
culerity_pid = 'tmp/culerity_rails_server.pid'
rm_culerity_pid_cmd = "rm #{culerity_pid} &> /dev/null"
culerity_start_cmd = 'rake culerity:rails:start > /dev/null'
# just in case it didn't get shut down properly during the last run
run_or_print $culerity_stop_cmd, true
run_or_print rm_culerity_pid_cmd, true
run_or_print culerity_start_cmd, true
end
def split_feature(feature_file)
file = File.basename(feature_file, '.feature')
# now get rid of the file_name and the feature_path
path = File.dirname(feature_file).gsub($feature_path_reg_ex, '')
return {:path => path, :file => file}
end
def remove_feature(feature_file)
feature_to_remove = split_feature(feature_file)
$features.delete_if { |f| f[:path] == feature_to_remove[:path] && f[:file] == feature_to_remove[:file] }
end
feature_list = ARGV.at(0) if ARGV.size > 0
tag_list = ARGV.at(1).gsub('@', '') if ARGV.size > 1
only = {
:features => [],
:tags => []
}
except = {
:features => [],
:tags => []
}
if feature_list.nil?
# run all features
feature_list = '**/*'
else
# going to either run certain ones or exclude certain ones
feature_list.split(',').each do |f|
if f[0].chr == '~'
except[:features] << f[1..f.length]
else
only[:features] << f
end
end
# if we have an exception, we want to get all features by default
feature_list = '**/*' if except[:features].any?
# unless we specifically say we want only certain ones
feature_list = nil if only[:features].any?
end
$features = []
# since I'm storing steps differently than default,
# need to grab all of the features and run them individually.
# features/x.feature uses features/steps/x_steps.rb not
# features/step_definitions/x.rb (or whatever). see below
# for path generation.
if only[:features].any?
only[:features].each do |f|
Dir.glob("#{feature_path}/#{f}.feature").each do |feature_file|
$features << split_feature(feature_file)
end
end
else
Dir.glob("#{feature_path}/#{feature_list}.feature").each do |feature_file|
$features << split_feature(feature_file)
end
end
if except[:features].any?
except[:features].each do |f|
Dir.glob("#{feature_path}/#{f}.feature").each do |feature_file|
remove_feature(feature_file)
end
end
end
tags = ''
unless tag_list.nil?
# going to either run certain ones or exclude certain ones
tag_list.split(',').each do |t|
if t[0].chr == '~'
except[:tags] << "~@#{t[1..t.length]}"
else
only[:tags] << "@#{t}"
end
end
tags += "-t #{only[:tags].join(',')} " if only[:tags].any?
tags += "-t #{except[:tags].join(' -t ')}" if except[:tags].any?
end
# if isolate_features is false, run the culerity server for the whole thing.
# Sometimes a java out of memory error will crop up, in which case turning
# isolate_features on will cause the culerity server to be started and stopped
# with each feature. If a particular feature gets too big, it will have to be
# split across files.
if $options[:rails] && !$options[:isolate_features] && !$options[:dry_run]
run_or_print zero_cmd, true
start_culerity_server
end
js_feature_regex = /_js$/
$features.each do |f|
path = f[:path]
file = f[:file]
ENV['CULERITY_ENABLE_JAVASCRIPT'] = js_feature_regex.match(file) ? 'TRUE' : 'FALSE'
step_file = "#{step_path}/#{path}/#{file}_steps.rb".gsub('//', '/')
step_file = File.exist?(step_file) ? "-r #{step_file}" : ''
feature_file = "#{feature_path}/#{path}/#{file}.feature #{tags}".gsub('//', '/')
if $options[:rails] && $options[:isolate_features] && !$options[:dry_run]
run_or_print zero_cmd, true
start_culerity_server
end
run_or_print "#{cuke_cmd} #{step_file} #{feature_file}".gsub(' ', ' ')
if $options[:rails] && $options[:isolate_features] && !$options[:dry_run]
run_or_print($culerity_stop_cmd, true)
sleep(2) # give it a little time to get shutdown
end
end
run_or_print($culerity_stop_cmd, true) if $options[:rails] && !$options[:isolate_features] && !$options[:dry_run]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment