Rails每周一题(十五): Rake

简介

 

简单而言,Rake是一个由ruby编写的build工具。

 

DSL

 

Rake是由ruby实现的,它的rakefile完全是由ruby语法定义的,所以它是一种内部DSL--基于另一种语言(宿主语言)编写的DSL。

 

Dependency Based Programming

 

Rake跟ant和make一样,是一种Dependency Based Programming。

 

Dependency Based Programming是一种基于依赖的编程方法,它的一条原则是依赖链中的任何任务只执行一次。

 

task :codeGen do
  # do the code generation
end

task :compile => :codeGen do
  #do the compilation
end

task :dataLoad => :codeGen do
  # load the test data
end

task :test => [:compile, :dataLoad] do
  # run the tests
end

 

    在上面这个例子中,test依赖于compile和dataLoad两个task,而compile和dataLoad都分别依赖于codeGen。当执行test这个task的时候,首先会执行codeGen(但只是一次),再执行compile和dataLoad(执行的顺序跟定义顺序无关)。

 

Task

 

Rake的task主要分类为regular task和file task两类。

 

Regular task类似于ant中的task,而file task类似于make中的task。

 

上面那个例子就是regular task,再让我们来看一下file task的例子:

 

file 'main.o' => ["main.c", "greet.h"] do
  sh "cc -c -o main.o main.c"
end
    
file 'greet.o' => ['greet.c'] do
  sh "cc -c -o greet.o greet.c"
end
   
file "hello" => ["main.o", "greet.o"] do
  sh "cc -o hello main.o greet.o"
end

 

  File task创建的目的是为了方便执行如编译等任务。因为在执行编译任务时,并不需要每次都编译所有文件,而只需编译那些还未被编译或者是经过修改的文件。

 

  如上面那个例子中所示,File task的前置条件就是一些文件,而是否执行当前任务的前提就是:当前任务名称中的文件不存在或者它比前置条件中的文件要老。

 

  比如"main.o"任务,它的执行条件是:"main.o"文件不存在,或者"main.c"、"greet.h"中的任一文件要比"main.o"文件要新。(这里的新老比较的是文件的最后修改时间)

 

 

lib

 

Rake的标准库非常丰富,有一些常用的task,这使得rakefile的编写变得更加简单。

 

 

调用

 

Rake任务通过命令行调用, 具体请见:http://docs.rubyrake.org/user_guide/chapter02.html

 

其它

 

1. Rule: 为一些类似的task,我们希望可以把它抽象出来。Rule的存在就是为解决这个问题的。

 

比如我们尝试调用"mycode.o"这个task,但发现并没有这个task的定义存在。那么,rake就会尝试去寻找可以匹配这个任务的rule。然后发现有这样一条rule存在:

 

rule '.o' => ['.c'] do |t|
  sh "cc #{t.source} -c -o #{t.name}" 
end

 

这条rule会匹配所有以".o"结尾的task,但它有一个前提:必须有一个相同名字,而且以".c"结尾的文件存在。所以,如果rake找到了"mycode.c"文件,它就会自动创建一个把"mycode.c"编译成"mycode.o"的任务。

 

 

2. Call one task from inside another task

 

有时候,我们希望一个task在另一个task运行中的某个环节执行,那么需要在一个task的执行中,而不是前置,去调用另一个task。

 

task :primary do
   Rake::Task[:secondary].invoke
end

task :secondary do
  puts "Doing Secondary Task" 
end

 

Secondary task的执行和其它task无异,secondary task的前置task也会先执行。但最需要注意的一点是,如果secondary task在之前已经被执行过,那么就不会再执行,即使如这样显示的invoke(遵循Dependency Based Programming的原则)。

 

如果你确实想无论如何都再次执行secondary task,那么就跳出task的范畴,用ruby方法来代替secondary task吧。

 

Reference

 

Rake API: http://rake.rubyforge.org/

 

User Guide: http://docs.rubyrake.org/user_guide/index.html

 

Using the Rake Build Language:  http://martinfowler.com/articles/rake.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值