2016-12-29 2 views
3

Я строй консоли для начальной загрузки моих драгоценных проектов, создание MiniTest, охранник, Трэвис, мерзавец и т.д ...Pass лямбды в качестве аргумента разгребать задачу

Я собирался использовать Rake, потому что мне нравится, как он обрабатывает зависимости, команды оболочки и очистку.

Сначала я создаю структуру каталогов «типа» проекта (gem, gli, метадон в этом случае), а затем все файлы 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, которая может выполняться в контексте задачи, вызвавшей ее, и принимать аргументы?

Тогда я думаю, я мог бы задачи, как:

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 о задачах, которые назвали его или как передать ему аргументы из вызываемой задачи.

ответ

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