Some things I have loved so far about working with rake/ruby:
- File enumeration
- Blending regular expressions where it makes things more readable
- Testability
After checking out lots of other rake files, it is easy to see how much simpler ruby can make things. Along the way I am picking up some idiom’s that (seem) more acceptable and concise.
File Selects
For example, I can do this:
Dir.glob(Path.join(“/path/to/my/files/**”,”*.dll”) + Dir.glob(Path.join(“/path/to/my/files/**”,”*.pdb”)
or better I can use rake’s FileList and a more concise File.join:
FileList.new(Path.join(“path”,”to”,”my”,”files”,”*.{dll,pdb,xml}”))
Directory Ops
I wanted to copy a file structure from one directory to another, but preserving the structure from the original. I had a hard time figuring out the ruby way of doing this, but this seems to do the trick:
FileList.new(File.join(WEB_DIR,"**","*.{spark,asax,aspx,ascx,ashx}"),
File.join(WEB_DIR,"bin","*.{dll,pdb}"),
File.join("#{BUILD_CONFIG_DIR}/**", "*")
).each do |file|
path = File.join(DEPLOY_WEB_DIR,file.gsub(WEB_DIR,""))
target = File.dirname(path)
File.makedirs(target)
cp Pathname.new(file), Pathname.new(target)#bug in ruby for to_str invocation workaround
end
Configuration & Templating
I like the config.yaml RoR convention, so here’s what I came up with. First, two simple classes:
require 'yaml'
class Environment
attr_accessor :development,:test,:production
def [](name)
if name.downcase=="development" then development
elsif name.downcase=="test" then test
elsif name.downcase=="production" then production
end
end
end
class Configuration
attr_accessor :service_path, :database_name, :connection_string, :log_level,:static_files_url ,:dev
# Support templating of member data.
def get_binding
binding
end
end
Plz…Ignore the crappy [] hack in Environment . These two classes will be read in by ERB like so:
desc "Expand templates"
task :expand => [:clean] do
config = YAML::load(File.open(File.join(CONFIG_DIR,"config.yaml")))
b = config[ENVIRONMENT].get_binding
FileList.new(File.join(CONFIG_DIR,"**","*.{template}"),File.join(INSTALLER_DIR,"**","*.{template}")).each do |file|
path = ExpandTemplate.new().write(file,b)
end
end
Here’s my config.yaml. Note how we map to the objects I defined above :
--- !ruby/object:Environment
development: !ruby/object:Configuration
database_name: MaterialsTesting_Dev
connection_string: my_connection_string
log_level: DEBUG
static_files_url: http://static.local.com/MaterialsTesting
test: !ruby/object:Configuration
database_name: MaterialsTesting_Test
connection_string: my_connection_string
log_level: DEBUG
static_files_url: http://static.local.com/MaterialsTesting
production: !ruby/object:Configuration
database_name: MaterialsTesting
connection_string: my_connection_string
log_level: INFO
static_files_url: http://static.local.com/MaterialsTesting
Now we can use the ExpandTemplate call:
class ExpandTemplate
def write(file,b)
template = File.read(file)
erb = ERB.new(template,0,"%<>")
output_file_name = File.join(BUILD_DIR,file.gsub(".template",""))
output = File.open(output_file_name, 'w') do |file|
file.puts erb.result(b)
end
output_file_name
end
end
So far this has been fun ripping out nant scripts and replacing them with rake.
Posted
09-13-2009 1:56 AM
by
Michael Nichols