用 Rake 自动执行任务

https://www6.software.ibm.com/developerworks/cn/education/opensource/os-rubyrake/index.html

:twisted:

[color=red]访问上面的link , 需要ibm的开发者id[/color]

[img]http://bd7lx.iteye.com/upload/picture/pic/175/957b4f6e-da66-4a71-a410-04c22397c91b.jpg[/img]

级别: 中级

Pat Eyler , 独立作家, Seattle Ruby Brigade

2005 年 9 月 27 日

了解有关 Rake 依赖性管理工具的信息 —— 该工具的公共用法,可执行的配置文件的语法,以及如何使用 Ruby 编程语言扩展 Rake。

开始之前

关于本教程

Rake 对所有人而言都是极好的工具箱补充项。如果您还没有开始使用 Rake 来自动化日常的计算任务,那么今天就应该看一看它了。

本教程介绍了开发项目环境中任务自动化的历史,然后简要地比较了几个自动化(或依赖性管理)工具,展示了关于 Rake 的入门级信息,并提供了几个如何使用它的扩展例子。

为了充分利用本教程,您应该在系统上安装 Ruby 和 Rake。可以在 参考资料 中找到关于获得和安装这些工具的更多信息。



第 2 页, 总 共 10 页

:wink:

[size=18]自动化的简要历史[/size]

“如果某件事只执行一次,就直接处理它 —— 如果做两次,就让它自动完成。”普遍的系统管理常识就是如此。
[size=24]
项目中的自动化[/size]

人们都不善于执行重复工作。我们会逐渐厌烦,并开始省略步骤或错过表明出错的指示器。当尽力完成同一件事情 5 次、50 次或 500 次时,我们的表现实际上会更糟糕。

幸好,我们十分善于构建工具代替我们来完成这类工作。自动化在计算领域中具有很长的历史 —— 但是,每个人通常都是完成相同的阶段。所有的编程实际上都是自动化的一种形式,因此使用编码技能来简化我们自己的工作也谈不上是巨大的跨越。我们真正需要明白的是要解决什么问题。

让我们在较小的范围内回顾自动化的历史。在项目开始时,开发人员经常需要创建一个新的程序版本。这通常意味着要创建一个 tarball —— 如果程序员十分聪明,足以用 Ruby 开发的话,那么也许是 RubyGem。

在决定使用 shell 脚本之前,不应多次重复该过程 —— 或运行时的错误。这个最简单的脚本重复了前面例子中包含的步骤,但添加一些错误处理不会花费太多精力,运行脚本比手工裁减版本提高了一大步,而且这样做可能具有一定的智能性。

编写您自己的脚本的缺点就是您在使用 shell 脚本编程技术完成一些令人激动的事,但您正将项目中宝贵的开发时间用于编写这些自动化的脚本。大约就在此时大多数开发人员发现了 make。

Make 是一个 UNIX® 的本机实用程序,是为管理软件编译过程而设计的。它十分通用,足以用于许多其他环境中,即使它已用于将文档编译成书,维护 Web 站点以及裁减发行版。但是,make 也有自身的约束。它具有自己的语法,这取决于制表符的(tabbed)和非制表符的(nontabbed)空白空间。许多其他工具已经进行了扩展,可以弥补 make 的一些不足,如 Aegis 和 Ant,但这两者也都具有自己的问题。

Make 以及类似的工具都有改进的余地,但是它们都不可能让 Ruby 黑客十分开心。您从这里要去哪里?幸好,可以使用一些 Ruby 选项。Rant 是一个由 Stefan Lang 编写的工具(请参阅 参考资料)。Rant 仍处于开发周期的初级阶段,因此它可能还没有成熟到足以适用于每个人。Jim Weirich 编写的 Rake 是一个在 Ruby 社区中广泛使用的成熟系统。

Rake 是用 Ruby 编写的,并使用 Ruby 作为它的语法,因此学习曲线很短。Rake 使用 Ruby 的元编程功能来扩展语言,使之更利落地适应自动化任务。Rake 附带的 rdoc 中列出了一些优点(请注意,前两个是诸如 make 的其他任务自动化工具所共有的):

* 用户可以用先决条件指定任务。
* Rake 支持规则模式来合并隐式任务。
* Rake 是轻量级的。它可以用其他项目发布为单个文件。依靠 Rake 的项目不需要在目标系统上安装 Rake。

:oops:



第 3 页, 总 共 10 页


[size=18]
Rake 入门[/size]

既然您已经看到 Rake 来自哪里,就让我们看一看如何使用它。

[size=24]调用 Rake[/size]

Rake 是像这样从命令行来使用的:rake [options ...] [VAR=VALUE] [targets ...]。VAR=VALUE 对被直接添加到 ENV 散列,并且可以通过访问 ENV['VAR'] 由 Rake 进程访问。

这些选项可以作为 GNU 样式长选项或在传统的 UNIX 样式中使用。表 1 中展示了这两个版本。
表 1. Rake 的命令行选项 GNU 样式长选项 传统的短选项 选项含义
--dry-run -n 显示所调用或执行的任务,而不是执行它们
--help -H 显示简要的帮助消息,并退出
--libdir dir -I dir 在 include 路径中添加目录
--no-search -N 不要搜索 Rake 文件的父目录
--prereqs -P 显示所有的任务列表及其直接先决条件
--quiet -q 不要响应 Rake 所执行的命令
--rakefile file -f file 使用给定文件作为 Rake 文件,而不是使用默认的
--require file -r file 在执行 Rake 文件之前需要给定文件
--tasks -T 显示主要任务和注释
--trace -t 启用全回溯跟踪(full backtrace),并打开系统跟踪
--usage -h 显示命令语法概述,然后退出
--verbose -v 显示所有系统命令
--version -V 显示 Rake 版本,然后退出


查看 Rake 文件

Rake 是在 Ruby 中用 Ruby 编写的,但是您不需要知道太多 Ruby 就可以以最简单的形式使用 Rake。Rake 中的基本单元是任务(task)。Rake 还具有动作(action)和规则(rule)的概念。

Rake 任务

任务具有一个先决条件集合(可能为空)和一个一旦满足先决条件就执行一次的动作集合。您应像这样定义任务:task :name。如果任务具有先决条件,就像这样定义:task :name => [ :prereq1, :prereq2]。这两种定义都定义了不带指定动作的任务。

动作是 Ruby 代码块,由作为任务的一部分执行的 Rake 命令组成。这是很重要的:您一旦意识到 Rake 是一个用于运行 Ruby 代码的 Ruby 框架,就会发现新的可能性。清单 1 中展示了一个带有一个动作的简单任务。该定义的第一行声明了一个名为 hello 的任务,该任务没有先决条件。(实际上,它使用 task 方法来创建任务 —— 在 Ruby 中,您通常最终会使用对象和方法,却没有意识到这一点。)do |t| 部分开始动作列表,允许所有动作通过名称 t 引用任务(我们将在后面更仔细地查看它)。所列出的惟一一个动作就是显示一条较短的问候消息。最后一行的 end 语句标志该任务的结束。

清单 1. 简单的 Rake 任务


task :hello do |t|
puts "Hello World"
end



符号和字符串

Ruby 初学者可能会混淆符号和字符串。基本差异就是符号将成为该名称的单个实例 —— 如果您在多个地方使用 :foo,就只创建一个符号对象。诸如 "foo" 的字符串在每次使用时都是不同的对象。

看上去无关紧要但在实际使用中变得很重要的差异就是审美差异,尤其是在元编程(编写基于 Ruby 的语言,如 Rake)中。可以编写一些诸如 task :grovel do 的语句与必须编写 task("grovel") do 感觉不同。第一种风格有助于使 Rake 看上去像一种真正的语言,而不只是一个 Ruby 脚本。

Rake 中可以使用三种类型的任务:任务(task)、文件任务(file task)和目录任务(directory task)。您已经到看常规任务了,因此让我们讨论一下文件任务和目录任务。

文件任务用于从其他文件生成一个或多个文件。您用 file 方法而非 task 方法来创建文件任务:file "name" => [ :prereq ]。除了使用 file 而非 task 之外,该定义还使用 "name" 代替 :name —— 这是怎么回事呢?让我们快速看一看隐藏的原因。file 和 task 都是方法,并且接收一个散列作为参数(如果您需要,可以简单地编写一个定义,如 file("name" => [ :prereq ]))。在 Ruby 中,散列可以接收符号(symbol)或字符串(string)作为键 —— :name 是一个符号,而 "name" 是一个字符串,因此两者都是可以接受的。

目录任务是特定类型的文件任务。它们是这样定义的:directory "name"。您不可以直接为目录任务声明先决条件。但是如果您具有一个依赖于先决条件的目录任务,则仍然有办法使用它们。因为 Ruby 将这些定义保持为开放的,您可以返回去并在稍后添加它们。清单 2 展示了一个例子。(后面的小节将继续讨论这个主题。)

清单 2. 使用多个任务定义来添加先决条件


directory "scratch"
file "scratch" => [ "fixtures" ] do |f|
cp Dir["fixtures/*.orig"] f.name
end


该方法第一眼看上去可能有些奇怪。代码在第一行声明了一个文件任务 —— 尽管您使用的是 directory 方法 —— 然后重新打开它以添加先决条件和动作。

不要使用花括号

下面是一些很重要的事情。每个代码块是用 do . . . end 对,而非 { . . . } 划分的。这是因为 { . . . } 具有极高的优先级。如果您使用花括号,如在 rule '.html' => [ '.txt' ] { . . . } 中,那么这一块将与 [ '.txt' ] 数组关联,而不是与 rule 方法关联。这根本不是您所希望的。不要感到难过,就使用 do . . . end 块。

单个动作具有多个新方法。发生三件不同的事情。cp 方法执行类 shell 的 cp。源文件列表是用 Dir 方法构建的。然后,任务的 name 方法获得目标目录的名称。

Rake 规则

规则允许 Rake 动态生成任务。规则的定义如清单 3 中所示。(该示例规则让您将以 .txt 扩展名结尾的单个文件转换成具有 .html 扩展名的 HTML 文件,而无需为每一个编写单独的任务。)此外,您用参数 hash 和 block 调用 rule 方法。规则不同于各种各样的任务,因为您可以使用 regex 作为参数的键,使用 proc 作为其值(分别是规则模式和源文件)。但是要注意,如果您是用 regex 作为规则模式,就必须在参数 hash 外面使用圆括号。

清单 3. 简单的规则定义


rule '.html' => [ '.txt' ] do
# do conversion stuff
end


规则可以使用复杂的名称。例如,清单 3 中的规则定义更改为 rule (/\.html$/ => [ proc {|task_name| task_name.sub(/\.[^.]+$/, '.txt') } ] do。它使用 proc 方法来动态构建先决条件。请记住,在使用 regexp 时,Ruby 要求 rule 方法使用圆括号。


第 3 页, 总 共 10 页


因为文章比较长, 为了不损伤原文的layout只节选前面的3页, 完整请下载附件


http://docs.google.com/View?docid=adgp94frh63f_18dn35d5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值