Ruby 灵活的Rake任务
我想对多个目录使用以下Rake任务。每个目录需要定义稍微不同的常量。我如何处理这个问题并保持干燥Ruby 灵活的Rake任务,ruby,rake,Ruby,Rake,我想对多个目录使用以下Rake任务。每个目录需要定义稍微不同的常量。我如何处理这个问题并保持干燥 namespace :assets do EXT = 'js' OBJDIR = 'public/javascripts' LIBFILE = "#{OBJDIR}/packaged.#{EXT}" SRC = FileList["#{OBJDIR}/*.#{EXT}"].select {|file| !file.match(/\.min\.#{EXT}|packa
namespace :assets do
EXT = 'js'
OBJDIR = 'public/javascripts'
LIBFILE = "#{OBJDIR}/packaged.#{EXT}"
SRC = FileList["#{OBJDIR}/*.#{EXT}"].select {|file| !file.match(/\.min\.#{EXT}|packaged\.#{EXT}/)}
OBJ = SRC.collect {|fn| File.join(OBJDIR, File.basename(fn).ext("min.#{EXT}"))}
MINE = %w(4sq app fb mbp).collect {|x| x + ".#{EXT}"}
desc "Build #{LIBFILE}"
task :build => LIBFILE
desc "Remove minified files"
task :clean do
rm_f OBJ
end
desc "Remove #{LIBFILE}"
task :clobber do
rm_f LIBFILE
end
file LIBFILE => OBJ do
sh "cat #{OBJ} >> #{LIBFILE}"
end
rule ".min.#{EXT}" => lambda{ |objfile| find_source(objfile) } do |t|
if EXT == 'js'
if MINE.include?(File.basename(t.source))
sh "closure --js #{t.source} --js_output_file #{t.name}"
else
sh "closure --warning_level QUIET --third_party --js #{t.source} --js_output_file #{t.name}"
end
elsif EXT == 'css'
sh "yuicompressor #{t.source} -o #{t.name}"
end
end
def find_source(objfile)
base = File.basename(objfile, ".min.#{EXT}")
SRC.find {|s| File.basename(s, ".#{EXT}") == base}
end
end
首先,必须用变量替换常量。 下一个问题是设置变量。 任务可以获取变量 例如:
namespace :assets do |x1,x2|
task :doit, :ext, :objdir do |tsk, args|
puts tsk
p args
end
end
您可以通过以下方式调用它:
rake assets:doit[js,objdir]
结果:
assets:doit called with {:ext=>"js", :objdir=>"objdir"}
assets2:set set: {:ext=>"js", :objdir=>"objdir"}
assets2:doit called with {:ext=>"js", :objdir=>"objdir"}
如果要避免为每个任务设置变量,可以添加“设置”任务:
namespace :assets2 do |x1,x2|
task :set, :ext, :objdir do |tsk, args|
@args = args
puts "#{tsk} set: #{@args.inspect}"
end
task :doit do |tsk|
puts "#{tsk} called with #{@args.inspect}"
end
end
电话:
rake assets2:set[js,objdir]assets2:doit
结果:
assets:doit called with {:ext=>"js", :objdir=>"objdir"}
assets2:set set: {:ext=>"js", :objdir=>"objdir"}
assets2:doit called with {:ext=>"js", :objdir=>"objdir"}
您可以定义配置文件,而不是设置所有参数
有一个缺点。以下任务将不起作用:
rake assets:doit[js,objdir] assets:doit[c,objdir2]
资产:doit将被调用一次。忽略第二个调用,任务已执行。没有检查不同的参数(一种解决方案:也许您可以重置任务)
编辑:我找到并测试了一个“reset”-方法:您只需要添加tsk.reenable
namespace :assets do |x1,x2|
task :doit, :ext, :objdir do |tsk, args|
puts "#{tsk} called with #{args.inspect}"
tsk.reenable
end
end
另一个问题是:如果参数包含空格。你可能会有麻烦
==============
规则的一般生成代码:(参见注释)
首先,必须用变量替换常量。 下一个问题是设置变量。 任务可以获取变量 例如:
namespace :assets do |x1,x2|
task :doit, :ext, :objdir do |tsk, args|
puts tsk
p args
end
end
您可以通过以下方式调用它:
rake assets:doit[js,objdir]
结果:
assets:doit called with {:ext=>"js", :objdir=>"objdir"}
assets2:set set: {:ext=>"js", :objdir=>"objdir"}
assets2:doit called with {:ext=>"js", :objdir=>"objdir"}
如果要避免为每个任务设置变量,可以添加“设置”任务:
namespace :assets2 do |x1,x2|
task :set, :ext, :objdir do |tsk, args|
@args = args
puts "#{tsk} set: #{@args.inspect}"
end
task :doit do |tsk|
puts "#{tsk} called with #{@args.inspect}"
end
end
电话:
rake assets2:set[js,objdir]assets2:doit
结果:
assets:doit called with {:ext=>"js", :objdir=>"objdir"}
assets2:set set: {:ext=>"js", :objdir=>"objdir"}
assets2:doit called with {:ext=>"js", :objdir=>"objdir"}
您可以定义配置文件,而不是设置所有参数
有一个缺点。以下任务将不起作用:
rake assets:doit[js,objdir] assets:doit[c,objdir2]
资产:doit将被调用一次。忽略第二个调用,任务已执行。没有检查不同的参数(一种解决方案:也许您可以重置任务)
编辑:我找到并测试了一个“reset”-方法:您只需要添加tsk.reenable
namespace :assets do |x1,x2|
task :doit, :ext, :objdir do |tsk, args|
puts "#{tsk} called with #{args.inspect}"
tsk.reenable
end
end
另一个问题是:如果参数包含空格。你可能会有麻烦
==============
规则的一般生成代码:(参见注释)
在你的帮助下,我终于明白了。以下是迄今为止对我有效的方法:
namespace :assets do
task :set, [:ext, :objdir] do |t, args|
@ext = args.ext
@objdir = args.objdir
@bundle = "#{@objdir}/bundle.#{@ext}"
@src = FileList["#{@objdir}/*.#{@ext}"].select {|file| !file.match(/\.min\.#{@ext}|#{Regexp.escape(@bundle)}/)}
@min = @src.collect {|fn| File.join(@objdir, File.basename(fn).ext("min.#{@ext}"))}
Rake::Task.define_task 'assets:build' => @bundle
Rake::FileTask.define_task @bundle => @min do
sh "cat #{@min} > #{@bundle}"
end
Rake::Task.create_rule ".min.#{@ext}" => lambda{ |objfile| find_source(objfile) } do |t|
if @ext == 'js'
if @mine.include?(File.basename(t.source))
sh "closure --js #{t.source} --js_output_file #{t.name}"
else
sh "closure --warning_level QUIET --third_party --js #{t.source} --js_output_file #{t.name}"
end
elsif @ext == 'css'
sh "yuicompressor #{t.source} -o #{t.name}"
end
end
end
desc "Remove minified files"
task :clean do
rm_f @min
end
desc "Remove bundle"
task :clobber do
rm_f @bundle
end
def find_source(objfile)
base = File.basename(objfile, ".min.#{@ext}")
@src.find {|s| File.basename(s, ".#{@ext}") == base}
end
end
在你的帮助下,我终于明白了。以下是迄今为止对我有效的方法:
namespace :assets do
task :set, [:ext, :objdir] do |t, args|
@ext = args.ext
@objdir = args.objdir
@bundle = "#{@objdir}/bundle.#{@ext}"
@src = FileList["#{@objdir}/*.#{@ext}"].select {|file| !file.match(/\.min\.#{@ext}|#{Regexp.escape(@bundle)}/)}
@min = @src.collect {|fn| File.join(@objdir, File.basename(fn).ext("min.#{@ext}"))}
Rake::Task.define_task 'assets:build' => @bundle
Rake::FileTask.define_task @bundle => @min do
sh "cat #{@min} > #{@bundle}"
end
Rake::Task.create_rule ".min.#{@ext}" => lambda{ |objfile| find_source(objfile) } do |t|
if @ext == 'js'
if @mine.include?(File.basename(t.source))
sh "closure --js #{t.source} --js_output_file #{t.name}"
else
sh "closure --warning_level QUIET --third_party --js #{t.source} --js_output_file #{t.name}"
end
elsif @ext == 'css'
sh "yuicompressor #{t.source} -o #{t.name}"
end
end
end
desc "Remove minified files"
task :clean do
rm_f @min
end
desc "Remove bundle"
task :clobber do
rm_f @bundle
end
def find_source(objfile)
base = File.basename(objfile, ".min.#{@ext}")
@src.find {|s| File.basename(s, ".#{@ext}") == base}
end
end
谢谢你的帮助,我明白你的意思。我试过这个,但似乎不起作用。
文件
任务似乎没有以这种方式正确定义,构建
任务也没有定义依赖项。我发现了这个错误:检测到循环依赖项:TOP=>资产:build=>=>
似乎变量只在任务定义内可用。我认为问题在于,定义构建时。此时,任务集未执行,因此数据未知。请看一下新资产。这可能是朝着解决问题迈出的一步。看起来,规则是全局的,而不是在名称空间内。谢谢你的帮助,我知道你在说什么。我试过这个,但似乎不起作用。文件
任务似乎没有以这种方式正确定义,构建
任务也没有定义依赖项。我发现了这个错误:检测到循环依赖项:TOP=>资产:build=>=>
似乎变量只在任务定义内可用。我认为问题在于,定义构建时。此时,任务集未执行,因此数据未知。请看一下新资产。这可能是朝着解决问题迈出的一步。看起来,规则是全局的,而不是在名称空间内。