【问题标题】:How do I stop rake from treating a file dependency as a possible task name?如何阻止 rake 将文件依赖项视为可能的任务名称?
【发布时间】:2016-05-07 05:11:43
【问题描述】:

短版:

我有一个问题:一个 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 任务和文件名之间不会发生冲突。

我可以做些什么来避免这个问题?有没有我错过的更好的 rake 用法?

【问题讨论】:

    标签: ruby-on-rails ruby rake


    【解决方案1】:

    我观察到同样的行为。 FileTask,由 rake DSL 中的 file 方法定义,继承自主 Rake Task 类,实际上,调用依赖项(或用 Rake 的语言 prerequisities)似乎与 @ 相同987654326@s 和 FileTasks,即如果文件名已经定义为 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 存档。您可能还需要在文件前面加上一些目录规范。

    【讨论】:

      【解决方案2】:

      我的第一个解决方法是避免可能是文件名的符号名称。
      例如。在您的情况下:task :do_testsdirectory 'test'
      缺点:如果不始终非常小心,将无法正常工作。

      第二个是对符号任务使用特殊语法::@name
      PRO:容易记住,不需要写太多。

      现在我正在尝试一种 hack,自动执行 :@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
      

      还是 TODO:

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

      【讨论】:

        猜你喜欢
        • 2017-10-04
        • 2020-05-20
        • 2011-12-26
        • 2016-07-15
        • 1970-01-01
        • 2012-01-22
        • 2016-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多