位置:首页 > Ruby > Ruby任务构建工具Rake入门教程与基础用法

Ruby任务构建工具Rake入门教程与基础用法

时间:2026-08-17  |  作者:星际追番人  |  阅读:0

Rake 简介

Ruby中任务构建工具rake的入门学习教程

Rake,全称 Ruby Make,一个用 Ruby 开发的代码构建工具。

但是,为什么 Ruby 需要 Rake?

按理说,Ruby 代码无需编译,似乎不需要 Rake。其实,Rake 还有一个重要用途:把它当作任务管理工具来使用

这样做有两个不可替代的好处:

以任务的方式创建和运行脚本

当然,你可以用脚本创建每一个希望自动运行的任务。

但对于大型应用来说,你几乎总是需要为数据库迁移(比如 Rails 中的 db:migrate)、清空缓存、代码维护等编写脚本。每一项任务可能都要写若干脚本,管理起来会很头疼。

把它们用任务的方式整理到一起,管理就会轻松很多。

追踪和管理任务之间的依赖

Rake 还提供了轻松管理任务之间依赖的方式。

举个例子,“migrate”任务和“schema:dump”任务都依赖于“connect_to_database”任务。那么在“migrate”任务调用之前,“connect_to_database”任务会自动执行。

这种依赖链,正是 Rake 的杀手锏。

下面直接进入正题:如何用 Rake 编写一个任务脚本。

顺序执行

在 Rake 中定义任务后,可以指定它们的执行顺序。

比如每天早晨起床后的例行公事:

  • 关闭闹钟
  • 梳洗打扮
  • 泡杯咖啡
  • 遛狗

Rakefile 中这样描述:

 task :turn_off_alarm do
  puts "Turned off alarm. Would ha ve liked 5 more minutes, though."
 end

 task :groom_myself do
  puts "Brushed teeth."
  puts "Showered."
  puts "Sha ved."
 end

 task :make_coffee do
  cups = ENV["COFFEE_CUPS"] || 2
  puts "Made #{cups} cups of coffee. Shakes are gone."
 end

 task :walk_dog do
  puts "Dog walked."
 end

 task :ready_for_the_day => [:turn_off_alarm, :groom_myself, :make_coffee, :walk_dog] do
  puts "Ready for the day!"
 end

运行 rake ready_for_the_day,所有任务会按照预定顺序依次执行:

 Turned off alarm. Would ha ve liked 5 more minutes, though.
 Brushed teeth.
 Showered.
 Sha ved.
 Made 5 cups of coffee. Shakes are gone.
 Dog walked.
 Ready for the day!

另外,你还可以通过 rake make_coffee COFFEE_CUPS=5 在命令行中给变量赋值,灵活性十足。

命名空间

像上面那样定义任务当然没问题。

但如果你还需要定义工作相关、交通相关的事物,所有任务混在一起显然不合适。毕竟上面那些只是起床的例行事务,跟其他范畴无关。

通过 namespace 可以定义出类似 Rails 中 rake db:migrate 那样的任务,描画出事物间清晰的边界。

将上面的任务包括在 namespace 的代码块中:

 namespace :morning do
  task :turn_of_alarm
  ....
 end

这时候调用命令就需要稍作变化:rake COFFEE_CUPS=3 morning:ready_for_the_day

是不是跟 Rails 中的 rake 任务调用方式很像?

默认 Task

假如我们忘记或不想写详细的任务名称,直接执行 rake 会怎样?

结果会是 rake aborted!,也就是任务被中断的报错。

既然存在这种可能性,我们就需要消除隐患。设置默认任务就能解决:

 task :default => 'morning:turn_off_alarm'

当你直接执行 rake 命令时,会执行默认操作,帮你关闭闹钟。

描述你的 Task

当任务逐渐增多,管理问题就暴露出来了。

除了命名空间,我们还需要文档类的支持,帮助梳理任务,并直观地告诉你每个任务的目的和功能。这时可以试试用 desc 描述任务:

 ...
 desc "Make coffee"
 task :make_coffee do
  cups = ENV["COFFEE_CUPS"] || 2
  puts "Made #{cups} cups of coffee. Shakes are gone."
 end
 ...

上面的描述不仅可以在文档中查看,使用 rake -T 也能清晰地了解到每个任务是做什么的。

输出结果按字母顺序排序:

 rake morning:make_coffee    # Make coffee

调取 Task

Rake 还允许在不同任务之间互相调用。

比如你想在下午也来杯咖啡,不用重复定义,直接调用上午的泡法即可:

namespace :afternoon do
  task :make_coffee do
   Rake::Task['morning:make_coffee'].invoke
   puts "Ready for the rest of the day!"
  end
 end

Rake 脚本编写

先来个简单的例子。

假设你是一个火星成员(老版本那些,比如燕儿虎跑之类的),周末打算去车车那边打火锅,然后集体 PC 去。对应这个情况,需要制定三个任务:搭车找车车、烤鱼和网吧 PC。

用 vim 创建一个名为 rakefile 的文件。Rake 会在当前路径下寻找 RakefilerakefileRakeFile.rbrakefile.rb 这些名称。

然后键入如下代码:

desc "任务1 -- 搭车去车车那里"#这据说是个苦差,因为太远了 
task :busboy do 
puts "发现挫男" 
end 
 
desc "任务2 -- 烤鱼" 
task :bitchfish do 
puts "老板,先烤九斤鱼" 
end 
 
desc "任务3 -- 网吧PC" 
task :pc do 
puts "我选中路" 
end 

打开命令行工具,进入这个文件所在目录,然后运行下面的命令,大致会得到类似结果:

D:work> rake busboy 
(in D:/work) 
发现挫男 

D:work> rake bitchfish 
(in D:/work) 
老板,先烤九斤鱼 

D:workruby_worksruby_book> rake laundry 
(in D:/work) 
我选中路 

(备注:文字部分没啥逻辑,纯粹娱乐……)

分析

看完上面那段,相信你已经知道怎么玩了。

下面介绍些基础知识,方便加深理解。从这个文件可以看出,一共定义了 3 个任务。desc 是 Rake 定义的方法,表示对下面定义任务的描述。

这个描述会在使用 rake --tasksrake -T 命令时输出在屏幕上:

D:work> rake --tasks 
(in D:/work) 
rake bitchfish   # 任务2 -- 烤鱼 
rake busboy      # 任务1 -- 搭车去车车那里(这据说是个苦差,因为太远了) 
rake pc          # 任务3 -- 网吧PC 

task 是 Rake 最重要的方法。它的方法定义是 task(args, &block)

任务体是一个 block,本例中只是简单输出你要做的工作。需要注意的是代码中的 puts "发现挫男" 完全是一个普通的 Ruby 语句,puts 是 Ruby 中进行输出的一般方法。

可以看出,Rake 任务可以完全使用 Ruby 的能力,这让它非常强大。

go……go……go……go……

加入依赖关系

很显然,在我们定义的任务中,“烤鱼”依赖于“搭车去车车那里”。

别处有没有烤鱼吃不知道,反正地点就定在那。因此,我们需要在任务定义中加入这个依赖关系。修改后的文件如下:

desc "任务1 -- 搭车去车车那里" 
task :busboy do 
puts "发现挫男" 
end 
 
desc "任务2 -- 烤鱼" 
task :bitchfish => :busboy do 
puts "老板,先烤九斤鱼" 
end 
 
desc "任务3 -- 网吧PC" 
task :pc do 
puts "我选中路" 
end 

再次运行烤鱼任务,你会看到:

D:work> rake bitchfish 
(in D:/work) 
发现挫男 
老板,先烤九斤鱼 

加入命名空间

跟任何编程语言类似,当你的 rake 文件很多、任务很多时,你需要关注命名冲突问题。

命名空间(namespace)是一个自然的解决方案。你可以为上面的三个任务定义一个叫做 dan 的命名空间:

namespace :dan do 
desc "任务1 -- 搭车去车车那里" 
task :busboy do 
puts "发现挫男" 
end 
…… 
end 

再次运行 rake --tasks,你会得到:

D:work> rake --tasks 
(in D:/work) 
rake dan:bitchfish  # 任务2 -- 烤鱼 
rake dan:pc         # 任务3 -- 网吧PC 
rake dan:busboy     # 任务1 -- 搭车去车车那里 

现在你需要使用 rake dan:bitchfish 才能启动烤鱼这个任务了。

顺便说一句,你可以在你的 rakefile 中使用多个命名空间,对任务进行分类。

了解了上面两个知识点后,我们来看两个具体的实例。

在一个任务中调用另外一个任务

当任务众多时,你很可能需要在一个任务中调用另外一个任务。

假设我们把今天所有要做的工作定义为一个任务:today。在这个任务中,有两个任务需要被调用:烤鱼和网吧 PC。

当然,由于烤鱼依赖于搭车去车车那里,我们还是需要搭车去的。在文件的顶部定义一个 today 的任务:

desc "今天的任务" 
task :today do 
Rake::Task["dan:bitchfish"].invoke 
Rake::Task["dan:pc"].invoke 
end 
 
namespace :dan do 
…… 
end 

可见,调用其它任务的方式很简单,只需调用 Rake::Task["task_name"].invoke 方法。

在命令行中启动 rake today,可以得到:

D:work> rake today 
(in D:/work) 
发现挫男 
老板,先烤九斤鱼 
我选中路 

默认任务

可以为 Rake 增加一个默认任务,这样只需简单地执行 rake 命令就能触发它。

在上面的 rakefile 中,我们可以把 today 任务作为默认任务:

task :default => [:today] 

然后直接在命令行中调用 rake,就能得到跟 rake today 同样的输出结果。

完整的 rakefile

以上就是我们简单的一个 Rake 任务定义。

下面是完整的修改后的 rakefile

task :default => [:today] 
 
desc "今天的任务" 
task :today do 
 Rake::Task["dan:bitchfish"].invoke 
 Rake::Task["dan:pc"].invoke 
end 
 
namesoace :dan do 
 desc "任务1 -- 搭车去车车那里(这据说是个苦差,因为太远了)" 
 task :busboy do 
  puts "发现挫男" 
 end 
 
 desc "任务2 -- 烤鱼" 
 task :bitchfish do 
  puts "老板,先烤九斤鱼" 
 end 
 
 desc "任务3 -- 网吧PC" 
 task :pc do 
  puts "我选中路" 
 end 
end 

看完上面两个例子,估计 rake 任务就算全部了解了。

剩下的不过是一些代码上的花活儿,多耍便是。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多