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

Pass lambda as an argument to rake task

我正在为 bootstrap 我的 gem 项目构建一个 cli,设置 minitest、guard、travis、git 等...

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

首先,我正在创建一个 "type" 项目的目录结构(gem、gli、美沙酮),然后渲染 erb 中的所有文件 template 项目目录。

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

我喜欢用 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 任务 运行 并获取参数?

然后我想我可以有这样的任务:

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 调用它的任务或如何将调用它的任务的参数传递给它。

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

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