如何阻止 rake 将文件依赖项视为可能的任务名称?
How do I stop rake from treating a file dependency as a possible task name?
短版:
我有一个问题:我需要一个 rake 任务的文件依赖与另一个 rake 任务的名称匹配,所以 rake 不依赖文件,而是尝试依赖具有匹配名称的任务。
我如何告诉 rake 只匹配文件的依赖项?还有其他出路吗?
长版:
我正在尝试在我的 Rails 应用程序中创建一个 rake 任务,以压缩我关心的所有文件。而已。简单。
我也很欣赏 rake 中的正常依赖性测试:如果没有文件更改并且 zip 文件已经存在,则不要执行任何操作。
问题是我想包含在 zip 文件中的文件之一(因此被视为任务依赖项)是 test
目录,但 rake test
恰好是一个现有的耙子任务。如果我这样说:
# FILES_TO_INCLUDE being a Rake::FileList...
file 'output.zip' => FILES_TO_INCLUDE.to_a do
...
end
rake 最终也是 运行 rake test
。
由于我一直在添加文件,并且由于 Rails 不时更改内置的 rake 任务,所以我永远无法确定 rake 任务和文件之间不会发生冲突名字。
我该怎么做才能避免这个问题?有没有我遗漏的更好的 rake 用法?
我观察到同样的行为。 FileTask
,由 rake DSL 中的 file
方法定义,继承自主 Rake Task
class 并且,实际上,调用依赖项(或者用 Rake 的语言 prerequisities
) 对于 Task
s 和 FileTask
s 似乎是一样的,也就是说,如果一个文件名已经被定义为 rake 任务,则该任务是 运行。
我想到的唯一解决方案是将路径部分添加到FILES_TO_INCLUDE
中的文件中。它可以像 "./"
前缀一样简单。
所以,我会试试这个:
file 'output.zip' => FILES_TO_INCLUDE.map { |file| "./#{file}" } do
...
end
这种方法似乎对我有效。
此外,对于您的特定情况(创建一些其他文件的 zip 文件),您实际上可以使用 Rake 中已有的现成解决方案,PackageTask
:
Rake::PackageTask.new("rake", "1.2.3") do |p|
p.need_zip = true
p.package_files.include("lib/**/*.rb")
end
这将在 pkg
(可配置)子目录中创建一个 rake-1.2.3.zip
存档。您可能还需要在文件前加上一些目录规范。
我的第一个解决方法是避免使用可能是文件名的符号名称。
例如。在您的情况下:task :do_tests
和 directory 'test'
缺点:如果不总是非常小心就无法工作。
第二个是对符号任务使用特殊语法::@name
PRO: 好记,不用写太多。
现在我正在试验一种技巧,自动执行 :@name
- 事情。
class Object; def rakesym
self
end end
class Symbol; def rakesym
self.to_s.sub(/\A@?/,'@').to_sym
end end
module Rake::DSL
# transform symbol-tasks and -deps to :@XXXX
#
# args is always an array
# [ t ]
# [ t, p0 ] ---> t[p0]
# [ t, p0,p1 ] ---> t[p0,p1]
# [ {t => deps } ]
# [ t, { [prms] => deps } ]
# [ t, p0 => deps ] ---> ERROR
# [ t, p0,p1 => deps ] ---> ERROR
# [ t, {[] => deps}
# [ t, {[params] => deps} ]
#
# deps can be a single value or an array:
# deps:== d0 | [] | [d0] | [ d0,d1,.. ]
def hack_args( *args )
STDOUT.puts "=== args before: #{args.inspect}"
args[0] = args[0].rakesym
if (args[0].is_a? Hash) && (args[0].size == 1)
t,deps = args[0].first
args[0] = { t.rakesym => deps }
end
if (args[-1].is_a? Hash) && (args[-1].size == 1)
x, deps = args[-1].first
deps.map!{|d| d.rakesym } if deps.is_a? Array
args[-1][x] = deps.rakesym
end
STDOUT.puts "=== args after: #{args.inspect}"
return args
end
alias task_o task
def task(*args, &block )
task_o( *hack_args(*args), &block )
end
# ... same for 'file', 'file_create' and 'directory'
end # module Rake::DSL
现在这给出了两个不同的任务:
desc "create html/ directory"
directory 'html'
desc "compile HTML docs"
task :html => HTML_FILES
我可以从 shell 调用:
> rake -D
rake html
create html/ directory
rake @html
compile HTML docs
还有待办事项:
- 处理名称空间。
- 修补
defaul_task_name
短版:
我有一个问题:我需要一个 rake 任务的文件依赖与另一个 rake 任务的名称匹配,所以 rake 不依赖文件,而是尝试依赖具有匹配名称的任务。
我如何告诉 rake 只匹配文件的依赖项?还有其他出路吗?
长版:
我正在尝试在我的 Rails 应用程序中创建一个 rake 任务,以压缩我关心的所有文件。而已。简单。
我也很欣赏 rake 中的正常依赖性测试:如果没有文件更改并且 zip 文件已经存在,则不要执行任何操作。
问题是我想包含在 zip 文件中的文件之一(因此被视为任务依赖项)是 test
目录,但 rake test
恰好是一个现有的耙子任务。如果我这样说:
# FILES_TO_INCLUDE being a Rake::FileList...
file 'output.zip' => FILES_TO_INCLUDE.to_a do
...
end
rake 最终也是 运行 rake test
。
由于我一直在添加文件,并且由于 Rails 不时更改内置的 rake 任务,所以我永远无法确定 rake 任务和文件之间不会发生冲突名字。
我该怎么做才能避免这个问题?有没有我遗漏的更好的 rake 用法?
我观察到同样的行为。 FileTask
,由 rake DSL 中的 file
方法定义,继承自主 Rake Task
class 并且,实际上,调用依赖项(或者用 Rake 的语言 prerequisities
) 对于 Task
s 和 FileTask
s 似乎是一样的,也就是说,如果一个文件名已经被定义为 rake 任务,则该任务是 运行。
我想到的唯一解决方案是将路径部分添加到FILES_TO_INCLUDE
中的文件中。它可以像 "./"
前缀一样简单。
所以,我会试试这个:
file 'output.zip' => FILES_TO_INCLUDE.map { |file| "./#{file}" } do
...
end
这种方法似乎对我有效。
此外,对于您的特定情况(创建一些其他文件的 zip 文件),您实际上可以使用 Rake 中已有的现成解决方案,PackageTask
:
Rake::PackageTask.new("rake", "1.2.3") do |p|
p.need_zip = true
p.package_files.include("lib/**/*.rb")
end
这将在 pkg
(可配置)子目录中创建一个 rake-1.2.3.zip
存档。您可能还需要在文件前加上一些目录规范。
我的第一个解决方法是避免使用可能是文件名的符号名称。
例如。在您的情况下:task :do_tests
和 directory 'test'
缺点:如果不总是非常小心就无法工作。
第二个是对符号任务使用特殊语法::@name
PRO: 好记,不用写太多。
现在我正在试验一种技巧,自动执行 :@name
- 事情。
class Object; def rakesym
self
end end
class Symbol; def rakesym
self.to_s.sub(/\A@?/,'@').to_sym
end end
module Rake::DSL
# transform symbol-tasks and -deps to :@XXXX
#
# args is always an array
# [ t ]
# [ t, p0 ] ---> t[p0]
# [ t, p0,p1 ] ---> t[p0,p1]
# [ {t => deps } ]
# [ t, { [prms] => deps } ]
# [ t, p0 => deps ] ---> ERROR
# [ t, p0,p1 => deps ] ---> ERROR
# [ t, {[] => deps}
# [ t, {[params] => deps} ]
#
# deps can be a single value or an array:
# deps:== d0 | [] | [d0] | [ d0,d1,.. ]
def hack_args( *args )
STDOUT.puts "=== args before: #{args.inspect}"
args[0] = args[0].rakesym
if (args[0].is_a? Hash) && (args[0].size == 1)
t,deps = args[0].first
args[0] = { t.rakesym => deps }
end
if (args[-1].is_a? Hash) && (args[-1].size == 1)
x, deps = args[-1].first
deps.map!{|d| d.rakesym } if deps.is_a? Array
args[-1][x] = deps.rakesym
end
STDOUT.puts "=== args after: #{args.inspect}"
return args
end
alias task_o task
def task(*args, &block )
task_o( *hack_args(*args), &block )
end
# ... same for 'file', 'file_create' and 'directory'
end # module Rake::DSL
现在这给出了两个不同的任务:
desc "create html/ directory"
directory 'html'
desc "compile HTML docs"
task :html => HTML_FILES
我可以从 shell 调用:
> rake -D
rake html
create html/ directory
rake @html
compile HTML docs
还有待办事项:
- 处理名称空间。
- 修补
defaul_task_name