我正在构建一个cli来引导我的宝石项目,设置minitest,guard,travis,git等......
我计划使用Rake,因为我喜欢它处理依赖项,shell命令和清理的方式。
首先,我创建项目“类型”的目录结构(在本例中为gem,gli,methadone),然后呈现项目的erb
目录中的所有template
个文件。
如methadone => gem
和gli => 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
有关调用它的任务或如何将调用它的任务传递给它。
答案 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