2015-10-28 18 views
0

我想要使用Rake将Haml文件转换为HTML文件,这样如果Haml文件没有更改,我不会重新生成现有的HTML。如何处理Rake中独立目录中的输入和输出?

但是,我不希望我的输入文件,输出文件和Rakefile都冲入一个目录。相反,我希望我的输入文件位于src/,输出文件位于build/output/。所以,我想先从:

Rakefile 
src/ 
    slides.haml 

,我想结束:

Rakefile 
src/ 
    slides.haml 
build/ 
    output/ 
    slides.html 

我已经试过的耙码数位,没有运气。

首先,我尝试了穴居人的做法,硬编码的确切的文件我想:

task "build/output/slides.html" => "src/slides.haml" do 
    touch task.name 
end 

task :slides => "src/slides.haml" 
task :default => "slides" 

运行rake --trace结果:

** Invoke default (first_time) 
** Invoke slides (first_time) 
** Invoke src/slides.haml (first_time, not_needed) 
** Execute slides 
** Execute default 

目录未建,而我呢没有一个空的build/output/slides.html文件。

理想情况下,我更喜欢rule-和-FileList的方法,使用诸如this SO answerthis "Rake cheatshet" entry之类的东西。然而,我在这个主题上尝试了一些变化,我得到了相同的结果,这表明我有更深刻的东西混乱了。我已经将我的Rakefile修剪回穴居人的方法,只是为了尝试讨论这里发生的事情。

为什么Rake不能识别我的"build/output/slides.html"任务?在Rake中使用子目录(输入或输出)有什么魔力?

回答

0

我错过了文件任务使用file而不是task,并且还有directory任务。

穴居方式的工作版本是:

namespace :build do 
    directory "build/output" 

    file "build/output/slides.html" => ["build/output", "src/slides.haml"] do |t| 
    touch t.name 
    end 

    task :all => "build/output/slides.html" 
end 

task :default => ['build:all'] 
0

首先,任务声明为task :name => dependency。您的:slides任务将命名一个源而不是输出依赖项。另外,您的:default任务取决于文件"slides"而不是任务:slides。改变这些线是

task :slides => "build/output/slides.html" 
task :default => :slides 

接下来,代码将实际执行应该是一个规则,而不是一个任务块,并且你可以通过#{t.<param>}访问规则的内部信息:

rule "build/output/slides.html" => "src/slides.html" do |t| 
    sh "mkdir -p $(dirname #{t.name})" 
    sh "touch #{t.name}" 
end 

有更好的方法来使规则更通用,建立源文件列表并将它们映射到输出等。一些有用的教程在这里https://github.com/ruby/rake#presentations-and-articles-about-rake

也可能有更多的Ruby方式使build/output/目录(如果它不存在),而不是调用shell来执行它。

+0

感谢这个!我会给予你赏金,主要是因为你触发了我(当试图弄清楚我的错误在哪里你的答案),以确切地注意到我的穴居人方法出错了。 – CommonsWare