Ruby 如何使用文件列表作为rake依赖项

Ruby 如何使用文件列表作为rake依赖项,ruby,rake,Ruby,Rake,我正在使用rake为我正在编写的Chrome扩展编译Coffeescript 我的耙子看起来像这样: 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 i

我正在使用rake为我正在编写的Chrome扩展编译Coffeescript

我的耙子看起来像这样:

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
task :build => ['extension'].concat(JS) do
  cp File.join('src', 'manifest.json'), 'extension'
end
当我的
src
目录中只有一个
.coffee
文件时,没有问题。但只要我有多个
.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)
是否可以将
文件列表
指定为依赖项?否则,我如何告诉rake我希望在构建任务期间编译所有Coffeescript文件?

试试以下方法:

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

到目前为止,在我的搜索中,完成我想要的任务的唯一方法似乎是让任务在我的
文件列表中循环并显式编译每个文件(如@nicooga的回答)。或者,我可以循环查看
文件列表中的所有内容
,并将其作为依赖项添加到构建任务中

我不喜欢这两个,因为
rake
FileList
s用于获取文件组,
规则
s用于定义如何处理各种文件,还有一个很好的语法用于定义依赖项,但显然无法将这三者结合在一起

因此,我现在的解决方案是使用第二个选项,将每个文件添加为依赖项。我发现最短的方法是将
concat
文件列表
添加到依赖项数组中。现在我的构建任务如下所示:

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
task :build => ['extension'].concat(JS) do
  cp File.join('src', 'manifest.json'), 'extension'
end

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

Rake的依赖项列表是一个任务名称数组。当您使用文件列表作为其元素之一时,您可以嵌套数组–实际上,这是:

task :build => ['extension', ['src/app.js', 'src/background.js']] do
Rake只使用所有传递的依赖项数组元素的字符串表示,这就是为什么它抱怨无法构建
'src/app.js src/background.js'
任务(注意这是一个字符串)

扩展文件列表(或展平依赖关系数组)将解决此问题,即:

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


虽然游戏进行得很晚,但是文件列表是惰性的,这很有用,特别是当你有很多文件匹配的时候。 想想C或C++,在那里你可能有很多需要依赖的东西。 这里的大多数答案都需要扩展/评估文件列表。因为Rake是Ruby,task是最后一个参数基本上是散列的地方,所以您将对数组进行求值

其中一个答案建议['extension',JS].展平。这种方法将搜索目录并收集所有.js文件。当您有一个总是被执行/调用的任务时,这种方法很好。但是,如果无法执行/调用任务,则不希望评估文件列表并调用其搜索

使用文件列表的最佳方法如下

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

然后,如果“somefile”不存在,或者“somefile”任务甚至没有被调用,那么对Rakefile的读取不会调用文件列表扩展,从而节省大量时间。

不是在我的机器ATM上,因此我无法测试我的直觉,但我想知道问题是否可能是您正在依赖项中嵌套数组。你试过把文件列表弄乱吗?@kopischke是的,这很有效,我会继续使用它。虽然rake不能自动处理这种情况有点烦人。是的,有点,但你可以说这是一个一致的合同。介意我把这变成一个你可以接受的答案吗?这个错误不是由CoffeScript处理规则引起的,而是由作为依赖项添加其输入文件的任务引起的。这就是为什么,当然,也可以工作的原因。更好一点的语法可以是task:build=>JS.add('extension')?@inger更具体一些,但更好的是,我不确定:您仍然需要了解底层的数据结构,我认为使用核心Ruby功能(特别是splat操作符是一种常见的Ruby习惯用法)解决这一问题本身就很好:)。当使用“DSL”时,我更喜欢使用小语言,而不使用(强大的)主语。。它“更简单”,并且允许非Ruby演讲者只查看FileList的API文档。不需要了解下面的一切。