#!/usr/bin/env ruby -w
require 'fileutils'
require 'erb'
require 'optparse'
include FileUtils
def main(basedir,force)
if Dir.exists? basedir
if force
rm_rf basedir, :verbose => true, :secure => true
else
STDERR.puts "error: #{basedir} exists, use --force to override"
return 1
end
end
mkdir_p basedir
gemname = File.basename(basedir)
chdir File.dirname(basedir)
%x[bundle gem #{gemname}]
chdir gemname
template_dirs_in(:full).each { |dir| mkdir_p dir }
copy_file "Rakefile"
copy_file "test/tc_something.rb"
copy_file "features/executable.feature", :as => "#{gemname}.feature", :binding => binding
copy_file "features/support/env.rb"
copy_file "features/step_definitions/executable_steps.rb", :as => "#{gemname}_steps.rb"
copy_file "bin/executable", :as => gemname, :executable => true
add_to_file "#{gemname}.gemspec", [
" s.add_development_dependency('rdoc')",
" s.add_development_dependency('aruba')",
], :before => /^end\s*$/
return 0
end
# Add content to a file
#
# +file+:: path to the file
# +lines+:: Array of String representing the lines to add
# +options+:: Hash of options:
# :before:: A regexp that will appear right after the new content. i.e.
# this is where to insert said content.
def add_to_file(file,lines,options = {})
new_lines = []
found_line = false
File.open(file).readlines.each do |line|
line.chomp!
if options[:before] && options[:before] === line
found_line = true
new_lines += lines
end
new_lines << line
end
raise "No line matched #{options[:before]}" if options[:before] && !found_line
new_lines += lines unless options[:before]
File.open(file,'w') do |fp|
new_lines.each { |line| fp.puts line }
end
end
# Copies a file, running it through ERB
#
# +relative_path+:: path to the file, relative to the project root, minus the .erb extension
# You should use forward slashes to separate paths; this method
# will handle making the ultimate path OS independent.
# +options+:: Options to affect how the copy is done:
# :from:: The name of the profile from which to find the file, "full" by default
# :as:: The name the file should get if not the one in relative_path
# :executable:: true if this file should be set executable
# :binding:: the binding to use for the template
def copy_file(relative_path,options = {})
options[:from] ||= :full
relative_path = File.join(relative_path.split(/\//))
template_path = File.join(template_dir(options[:from]),relative_path + ".erb")
template = ERB.new(File.open(template_path).readlines.join(''))
relative_path_parts = File.split(relative_path)
relative_path_parts[-1] = options[:as] if options[:as]
erb_binding = options[:binding] or binding
File.open(File.join(relative_path_parts),'w') do |file|
file.puts template.result(erb_binding)
file.chmod(0755) if options[:executable]
end
end
# Get the location of the templates for profile "from"
def template_dir(from)
File.join(File.dirname(EXE),'..','templates',from.to_s)
end
def template_dirs_in(profile)
template_dir = template_dir(:full)
Dir["#{template_dir}/**/*"].select { |x|
File.directory? x
}.map { |dir|
dir.gsub(/^#{template_dir}\//,'')
}
end
options = {}
option_parser = OptionParser.new do |opts|
executable = File.basename(__FILE__)
opts.banner = "Usage: #{executable} [options] app_name"
opts.on("--force","Overwrite files if they exist") do
options[:force] = true
end
end
option_parser.parse!
EXE = File.expand_path(__FILE__)
if ARGV.empty?
STDERR.puts("error: app_dir required")
exit 2
else
exit main(ARGV[0],options[:force])
end