如何使用FileLists作为rake依赖项

时间:2013-01-25 19:40:05

标签: ruby rake

我正在使用rake帮助编译我正在编写的Chrome扩展程序的Coffeescript。

我的Rakefile看起来像这样:

COFFEE = FileList['src/*.coffee']
JS = COFFEE.ext 'js'

directory 'extension'

rule '.js' => ['.coffee', 'extension'] do |t|
  `coffee -c -o extension #{t.source}`
end

desc "Build the extension in the 'extension' directory"
task :build => ['extension', JS] do
  cp File.join('src', 'manifest.json'), 'extension'
end

当我在.coffee目录中只有一个src文件时,没有问题。但是,只要我有多个.coffee个文件就会出错:

$ rake build
> rake aborted!
> Don't know how to build task 'src/app.js src/background.js'
>
> Tasks: TOP => build
> (See full trace by running task with --trace)

是否可以将FileList指定为依赖项?我怎么告诉rake我希望在构建任务期间编译所有Coffeescript文件?

4 个答案:

答案 0 :(得分:8)

Rake的依赖列表是一个任务名称数组。当您使用FileList作为其元素之一时,您可以有效地嵌套数组:

task :build => ['extension', ['src/app.js', 'src/background.js']] do

Rake只使用所有传递的依赖关系数组元素的字符串表示,这就是为什么它抱怨无法构建'src/app.js src/background.js'任务(注意这是一个字符串)。

Splat your FileList(或展平依赖数组)将解决问题,即:

task :build => ['extension', *JS] do

task :build => ['extension', JS].flatten do

答案 1 :(得分:1)

试试这个:

files = Dir.entries('path/to/scripts').select { |f| f.include? '.coffee' }
files.each do |file_path|
  `coffee -c -o extension #{file_path}`
end

答案 2 :(得分:0)

到目前为止,在我的搜索中,看起来完成我想要的唯一方法是要么有一个循环遍历FileList的任务并且明确地编译每个任务(比如来自@nicooga的答案)。或者,我可以循环遍历FileList中的所有内容,并将其添加为构建任务的依赖项。

我不喜欢其中任何一个,因为rakeFileList用于获取文件组,rule用于定义如何处理各种文件,以及一个很好的语法定义依赖关系,但显然无法将所有这三者结合在一起。

所以,我现在的解决方案是使用第二个选项,将每个文件添加为依赖项。我发现这样做的最短路径是将concat FileList放到依赖关系数组上。所以现在我的构建任务看起来像这样:

task :build => ['extension'].concat(JS) do
  cp File.join('src', 'manifest.json'), 'extension'
end

感谢@kopischke的评论,使用splat运算符甚至可以将其缩短为['extension' *JS]

答案 3 :(得分:0)

该游戏很晚,但是FileList很懒,这很有用,尤其是当您有很多文件匹配时。 想想C或C ++,您可能会在其中拥有许多需要依赖的东西。

这里的大多数答案都需要对FileList进行扩展/评估。由于Rake是Ruby,而task是最后一个参数基本上是Hash的位置,因此您将评估数组。

答案之一表明['extension',JS] .flatten。这种方法将搜索目录并收集所有.js文件。当您的任务将始终执行/调用时,此方法很好。但是,如果任务不会被执行/调用,您不想评估FileList并调用其搜索。

使用FileList的最佳方法是以下

fl = FileList['extension', "src/*.coffee"] do |c|
   c.ext('js')
end
file "somefile" => fl do
   #some stuff
end

然后,如果“ somefile”不存在,或者甚至没有调用“ somefile”任务,则读取Rakefile不会调用FileList扩展,从而节省了大量时间。