├── .gitignore ├── Gemfile ├── lib └── guard │ ├── rake │ ├── templates │ │ └── Guardfile │ ├── version.rb │ └── task.rb │ └── rake.rb ├── Guardfile ├── Rakefile ├── guard-rake.gemspec ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .rvmrc 2 | pkg 3 | Gemfile.lock 4 | .idea 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem 'rake' 4 | 5 | gemspec 6 | -------------------------------------------------------------------------------- /lib/guard/rake/templates/Guardfile: -------------------------------------------------------------------------------- 1 | guard 'rake', :task => 'build' do 2 | watch(%r{^my_file.rb}) 3 | end 4 | -------------------------------------------------------------------------------- /lib/guard/rake/version.rb: -------------------------------------------------------------------------------- 1 | module Guard 2 | module RakeVersion 3 | VERSION = "1.1.0" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard :shell do 2 | 3 | watch(%r{^(Rakefile|lib/guard/rake/task.rb)$}) do |m| 4 | system("rake guard") 5 | end 6 | 7 | end 8 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require "guard/rake/task" 3 | 4 | Guard::Rake::Task.new 5 | 6 | task :guard => ['Rakefile','lib/guard/rake/task.rb'] 7 | -------------------------------------------------------------------------------- /guard-rake.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require 'guard/rake/version' 4 | 5 | Gem::Specification.new do |s| 6 | s.name = 'guard-rake' 7 | s.version = Guard::RakeVersion::VERSION 8 | s.authors = ['Scott Barron'] 9 | s.email = ['scott@elitists.net'] 10 | s.homepage = 'http://github.com/rubyist/guard-rake' 11 | s.summary = %q{Guard for running rake tasks} 12 | s.description = %q{guard-rake automatically runs Rake tasks from your Rakefile} 13 | s.license = "MIT" 14 | 15 | s.add_dependency 'guard' 16 | s.add_dependency 'guard-shell' 17 | s.add_dependency 'rake' 18 | 19 | s.files = `git ls-files`.split("\n") 20 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 21 | s.executables = `git ls-files -- bin/*`.split("\n").map {|f| File.basename(f) } 22 | s.require_paths = ['lib'] 23 | end 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2011 Scott Barron 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /lib/guard/rake/task.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rake' 4 | require 'rake/tasklib' 5 | require 'rake/application' 6 | require 'erb' 7 | 8 | # This file was inspired by https://github.com/troessner/reek/blob/master/lib/reek/rake/task.rb 9 | module Guard 10 | # 11 | # Defines a task library for running Guard-Rake. 12 | # 13 | # @public 14 | module Rake 15 | 16 | GUARDFILE_TEMPLATE = <<~HEREDOC 17 | guard :shell do 18 | <% all_tasks.each do |t, files| %> 19 | watch(%r{^(<%= files.join('|') %>)$}) do |m| 20 | system("rake <%= t %>") 21 | end 22 | <% end %> 23 | end 24 | HEREDOC 25 | 26 | class Task < ::Rake::TaskLib 27 | 28 | # Name of task. Defaults to :guard. 29 | # @public 30 | attr_writer :name 31 | 32 | # The template code, default value is Guard::Rake::GUARDFILE_TEMPLATE 33 | attr_accessor :template 34 | 35 | attr_accessor :guardfile 36 | 37 | # @public 38 | def initialize(name = 'guard', guardfile='Guardfile') 39 | @name = name 40 | @template = Guard::Rake::GUARDFILE_TEMPLATE 41 | @guardfile = guardfile 42 | 43 | yield self if block_given? 44 | 45 | define_task 46 | end 47 | 48 | private 49 | 50 | def define_task 51 | desc "Create Guardfile from rake tasks." 52 | task(@name) do 53 | all_tasks = {} 54 | current_task = nil 55 | `rake -P`.each_line do |line| 56 | if line.start_with? "rake" then 57 | current_task = line[5..-1].strip 58 | else 59 | #its a dependency 60 | filename = line.strip 61 | if File.file?(filename) then 62 | all_tasks[current_task] = [] unless all_tasks[current_task] 63 | all_tasks[current_task] << filename 64 | end 65 | end 66 | end 67 | File.write(@guardfile, ERB.new(@template).result(binding)) 68 | end 69 | end 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /lib/guard/rake.rb: -------------------------------------------------------------------------------- 1 | require 'guard' 2 | require 'guard/version' 3 | require 'rake' 4 | 5 | module Guard 6 | class Rake < Plugin 7 | class << self 8 | attr_accessor :rakefile_loaded 9 | end 10 | 11 | def initialize(options={}) 12 | super 13 | @options = { 14 | :run_on_start => true, 15 | :run_on_all => true, 16 | :task_args => [] 17 | }.update(options) 18 | @task = @options[:task] 19 | end 20 | 21 | def start 22 | UI.info "Starting guard-rake #{@task}" 23 | load_rakefile unless self.class.rakefile_loaded 24 | run_rake_task if @options[:run_on_start] 25 | true 26 | end 27 | 28 | def stop 29 | UI.info "Stopping guard-rake #{@task}" 30 | true 31 | end 32 | 33 | def reload 34 | stop 35 | start 36 | end 37 | 38 | def run_all 39 | run_rake_task if @options[:run_on_all] 40 | end 41 | 42 | if ::Guard::VERSION < "1.1" 43 | def run_on_change(paths) 44 | run_rake_task(paths) 45 | end 46 | else 47 | def run_on_modifications(paths) 48 | run_rake_task(paths) 49 | end 50 | end 51 | 52 | def run_rake_task(paths=[]) 53 | UI.info "running #{@task}" 54 | ::Rake::Task.tasks.each { |t| t.reenable } 55 | ::Rake::Task[@task].invoke(*@options[:task_args], paths) 56 | 57 | Notifier.notify( 58 | "watched files: #{paths}", 59 | :title => "running rake task: #{@task}", 60 | :image => :success 61 | ) 62 | rescue Exception => e 63 | UI.error "#{self.class.name} failed to run rake task <#{@task}>, exception was:\n\t#{e.class}: #{e.message}" 64 | UI.debug "\n#{e.backtrace.join("\n")}" 65 | 66 | Notifier.notify( 67 | " #{e.class}: #{e.message}", :title => "fail to run rake task: #{@task}", :image => :failed) 68 | throw :task_has_failed 69 | end 70 | 71 | def load_rakefile 72 | ARGV.clear 73 | ::Rake.application.init 74 | ::Rake.application.load_rakefile 75 | self.class.rakefile_loaded = true 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Guard::Rake 2 | 3 | Guard::Rake allows you to automatically run a Rake task when files are 4 | modified. 5 | 6 | ## Install 7 | 8 | Please be sure to have [Guard](https://github.com/guard/guard) installed 9 | before continuing. 10 | 11 | Install the gem: 12 | ```bash 13 | $ gem install guard-rake 14 | ``` 15 | 16 | Add it to your `Gemfile` 17 | 18 | ```ruby 19 | gem 'guard-rake' 20 | ``` 21 | 22 | Add the default Guard::Rake template to your `Guardfile` by running this 23 | command: 24 | 25 | ```bash 26 | $ guard init rake 27 | ``` 28 | 29 | ## Usage 30 | 31 | Please read the [Guard usage documentation](https://github.com/guard/guard#readme). 32 | 33 | ## Guardfile 34 | 35 | Guard::Rake comes with a default template that looks like this: 36 | 37 | ```ruby 38 | guard 'rake', :task => 'doit' do 39 | watch(%r{^some_files/.+$}) 40 | end 41 | ``` 42 | 43 | This will run the rake task `doit` from your `Rakefile` whenever any of 44 | the watched files change. 45 | 46 | ### List of available options: 47 | 48 | ```ruby 49 | :task => 'doit' # name of the task to be executed, required 50 | :run_on_all => false # runs when the 'run_all' signal is received from Guard (enter is pressed), default: true 51 | :run_on_start => true # runs when guard is started, default: true 52 | :task_args => [] # arguments to pass to Rake::Task#invoke, default: [] 53 | ``` 54 | 55 | ### Rake task arguments 56 | By default, the changed file paths will be passed into the rake task. Example: 57 | 58 | ```ruby 59 | task :doit, :paths do |t, args| 60 | args.paths # Will contain an array of changed paths 61 | end 62 | ``` 63 | 64 | You may also use this in conjunction with the :task_args options. Anything in :task_args will 65 | be passed in first, then the array of changed paths. Example: 66 | 67 | ```ruby 68 | # Guardfile 69 | guard 'rake', :task => 'doit', :task_args => ['a', 'b'] do 70 | watch(%r{^some_files/.+$}) 71 | end 72 | 73 | # Rakefile 74 | task :doit, [:first, :second, :paths] do |t, args| 75 | args.first # "a" 76 | args.second # "b" 77 | args.paths # ['changed1.rb', 'changed2.rb'] 78 | end 79 | ``` 80 | 81 | ## Second usage 82 | 83 | This second usage will describe how to create a rake task that generates Guardfile from rake tasks. 84 | 85 | First, add this to your Gemfile: 86 | 87 | ```ruby 88 | gem 'guard-rake' 89 | gem 'guard-shell' 90 | ``` 91 | 92 | You will need some tasks with file dependencies in your Rakefile. I'f you don't have those, try put this code in your Rakefile: 93 | 94 | ```ruby 95 | files = Rake::FileList.new('*.md') 96 | desc "Create a book" 97 | task 'book' => files do 98 | sh "cat #{files.join(" ")} > book.txt" 99 | end 100 | ``` 101 | 102 | Now you are ready to import our rake task, put Inside your `Rakefile`: 103 | 104 | ```ruby 105 | require "guard/rake/task" 106 | 107 | Guard::Rake::Task.new 108 | ``` 109 | 110 | You can see you have two new tasks: 111 | 112 | ``` 113 | $ rake -T 114 | rake book # Create a book 115 | rake guard # Create Guardfile from rake tasks 116 | ``` 117 | 118 | And the book task have these dependencies: 119 | 120 | ``` 121 | $ rake -P 122 | rake book 123 | README.md 124 | rake guard 125 | ``` 126 | 127 | If you call the `guard` task it will create `Guardfile`: 128 | 129 | ``` 130 | $ rake guard 131 | $ cat Guardfile 132 | guard :shell do 133 | 134 | watch(%r{^(README.md)$}) do |m| 135 | system("rake book") 136 | end 137 | 138 | end 139 | ``` 140 | 141 | You can also add the `Rakefile` dependency: 142 | 143 | ``` 144 | task :guard => ['Rakefile'] 145 | ``` 146 | 147 | And using the `guard` task it will produce this `Guardfile`: 148 | 149 | ```ruby 150 | guard :shell do 151 | 152 | watch(%r{^(README.md)$}) do |m| 153 | system("rake book") 154 | end 155 | 156 | watch(%r{^(Rakefile)$}) do |m| 157 | system("rake guard") 158 | end 159 | 160 | end 161 | ``` 162 | 163 | ### Advanced usage 164 | 165 | If you want update your `Guardfile` with other content, it's best to create your own ERB template: 166 | 167 | ```ruby 168 | Guard::Rake::Task.new do |t| 169 | t.template=File.read('Guardfile.erb') 170 | end 171 | ``` 172 | 173 | And then create your `Guardfile.erb` as a template: 174 | 175 | ```ruby 176 | guard :shell do 177 | <% all_tasks.each do |t, files| %> 178 | watch(%r{^(<%= files.join('|') %>)$}) do |m| 179 | system("rake <%= t %>") 180 | end 181 | <% end %> 182 | 183 | <%# Add your custom code here %> 184 | end 185 | 186 | <%# Or here %> 187 | ``` 188 | 189 | ## Development 190 | 191 | - Source hosted at [GitHub](https://github.com/rubyist/guard-rake) 192 | - Report issues and feature requests to [GitHub Issues](https://github.com/rubyist/guard-rake/issues) 193 | 194 | Pull requests welcome! 195 | 196 | ## License 197 | 198 | (The MIT License) 199 | 200 | Copyright (c) 2011 Scott Barron 201 | 202 | Permission is hereby granted, free of charge, to any person obtaining 203 | a copy of this software and associated documentation files (the 204 | 'Software'), to deal in the Software without restriction, including 205 | without limitation the rights to use, copy, modify, merge, publish, 206 | distribute, sublicense, and/or sell copies of the Software, and to 207 | permit persons to whom the Software is furnished to do so, subject to 208 | the following conditions: 209 | 210 | The above copyright notice and this permission notice shall be 211 | included in all copies or substantial portions of the Software. 212 | 213 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 214 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 215 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 216 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 217 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 218 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 219 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 220 | --------------------------------------------------------------------------------