如何阻止rake将文件依赖关系视为可能的任务名称?

时间:2016-05-07 05:11:44

标签: ruby-on-rails ruby rake

简短版:

我遇到了一个问题:我需要一个rake任务所需的文件依赖项与另一个rake任务的名称匹配,因此rake尝试依赖具有匹配名称的任务而不是依赖于该文件。

如何告诉rake只将依赖项与文件匹配? 还有其他方法吗?

长版

我正在尝试在我的Rails应用程序中创建一个rake任务,该任务会压缩我关心的所有文件。而已。容易。

我也很欣赏rake中的正常依赖测试:如果没有文件发生变化且zip文件已经存在,请不要做任何事情。

问题是我希望包含在zip文件中的一个文件(因此被视为任务依赖项)是test目录,但rake test恰好是现有的rake任务。如果我这样说:

# FILES_TO_INCLUDE being a Rake::FileList...
file 'output.zip' => FILES_TO_INCLUDE.to_a do
  ...
end

rake最终也会运行rake test

由于我一直在添加文件,并且由于Rails不时会更改内置的rake任务,因此我无法确定rake任务和文件名之间是否存在冲突。

我可以做些什么来避免这个问题?我错过了更好的耙子用途吗?

2 个答案:

答案 0 :(得分:1)

我观察到同样的行为。由rake DSL中的FileTask方法定义的file继承自主Rake Task类,实际上是调用依赖项(或者用Rake的语言prerequisitiesTaskFileTask似乎相同,即如果文件名已被定义为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

这将在rake-1.2.3.zip(可配置)子目录中创建pkg存档。您可能还需要在文件前添加一些目录规范。

答案 1 :(得分:0)

我的第一种解决方法是避免使用符号名,而该符号名可能是文件名。
例如。您的情况:task :do_testsdirectory 'test'
CON:如果不总是非常小心,则无法正常工作。

2nd对符号任务使用特殊的语法::@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

我可以从外壳调用:

> rake -D
rake html
    create html/ directory

rake @html
    compile HTML docs

待办事项:

  • 处理名称空间。
  • 修补defaul_task_name