将lambda作为rake任务的参数传递

时间:2016-12-29 08:18:47

标签: ruby rake

我正在构建一个cli来引导我的宝石项目,设置minitest,guard,travis,git等......

我计划使用Rake,因为我喜欢它处理依赖项,shell命令和清理的方式。

首先,我创建项目“类型”的目录结构(在本例中为gem,gli,methadone),然后呈现项目的erb目录中的所有template个文件。

methadone => gemgli => gem所示methadone !=> gli。这意味着methadone需要gem中的所有文件,但可能会添加新文件/目录,也可能会修改现有文件/目录。

我喜欢用Rake任务表达这些依赖关系是多么容易。

但我觉得很奇怪,我必须在3个不同的地方编写相同的代码,如下所示:

代码:

require 'rake'
require 'rake/clean'

desc "Bootstrap gem"
task :gem, [:project_name] do |t, args|
  Project.new(t.name, args.project_name).bootstrap
end

desc "Bootstrap methadone"
task :methadone, [:project_name] => :gem do |t, args|
  Project.new(t.name, args.project_name).bootstrap
end

desc "Bootstrap gli"
task :gli, [:project_name] => :gem do |t, args|
  Project.new(t.name, args.project_name).bootstrap
end

class Project
  attr_reader :project_name, :template_name
  def initialize template_name, project_name
    @project_name = project_name
    @template_name = template_name
  end

  def bootstrap 
    create_project_dirs 
    render 
  end

  def create_project_dirs   
    puts "Copying dirs from #{template_dir} to #{project_dir}"
  end

  def render   
    puts "Rendering #{project_name} templates..."
  end

  def template_dir
    File.expand_path(File.join(__dir__, "templates", template_name))
  end

  def project_dir
    File.expand_path(File.join(__dir__, project_name))
  end
end



CLEAN.include('templates')

template_files = %w( templates/gem/foo.erb templates/gem/bar.erb templates/methadone/foo.erb templates/gli/foo.erb )
template_files.each do |f|
  file f do |t|
    path = t.name
    mkdir_p File.dirname path
    touch path
  end
end

desc "Setup tmp project"
task :setup => template_files

文件结构:

$ tree .
.
├── Rakefile
├── some.rake
└── templates
    ├── gem
    │   ├── bar.erb
    │   └── foo.erb
    ├── gli
    │   └── foo.erb
    └── methadone
        └── foo.erb

4 directories, 6 files

是否可以制作一个Rake任务,该任务可以在调用它的任务的上下文中运行并采用args?

然后我想我可以完成一项任务:

desc "Bootstrap gem"
task :gem, [:project_name] => :bootstrap ??

desc "Bootstrap methadone"
task :methadone, [:project_name] => [:gem, :bootstrap]

desc "Bootstrap gli"
task :gli, [:project_name] =>[:gem, :bootstrap]

task :bootstrap ??
  Project.new(t.name, args.project_name).bootstrap
end

输出:

$ rake methadone['some_gem']
Copying dirs from /Users/max/Dropbox/work/tmp/devify_dependency/templates/gem to /Users/max/Dropbox/work/tmp/devify_dependency/some_gem
Rendering some_gem templates...
Copying dirs from /Users/max/Dropbox/work/tmp/devify_dependency/templates/methadone to /Users/max/Dropbox/work/tmp/devify_dependency/some_gem
Rendering some_gem templates...

但就目前而言,我不知道如何告诉:bootstrap有关调用它的任务或如何将调用它的任务传递给它。

1 个答案:

答案 0 :(得分:2)

如果我理解你想要实现的目标,那么有一个非常简单的重构:

BOOTSTRAP = lambda do |t, args|
  Project.new(t.name, args.project_name).bootstrap
end

desc "Bootstrap gem"
task :gem, [:project_name], &BOOTSTRAP

desc "Bootstrap methadone"
task :methadone, [:project_name], &BOOTSTRAP

desc "Bootstrap gli"
task :gli, [:project_name] => :gem, &BOOTSTRAP