将 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 => gem
和 gli => gem
但 methadone !=> 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
我正在为 bootstrap 我的 gem 项目构建一个 cli,设置 minitest、guard、travis、git 等...
我正计划使用 Rake,因为我喜欢它处理依赖项、shell 命令和清理的方式。
首先,我正在创建一个 "type" 项目的目录结构(gem、gli、美沙酮),然后渲染 erb
中的所有文件 template
项目目录。
如图所示 methadone => gem
和 gli => gem
但 methadone !=> 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