Skip to content

Commit

Permalink
Merge pull request #450 from timmfin/watch-multiple-directories
Browse files Browse the repository at this point in the history
Add the possibility to watch multiple directories
  • Loading branch information
rymai committed Jul 30, 2013
2 parents 47b818d + 84db64b commit 8dcddfc
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 22 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
@@ -1,6 +1,8 @@
## Master

- [#443][] Escape `notify-send` arguments. ([@netzpirat][])
- [#460][], [#463][] Better Windows support. ([@cablegram][])
- [#450][] Allow multiple watch directories. ([@timmfin][])

## 1.8.1 - 17 June, 2013

Expand Down Expand Up @@ -776,6 +778,7 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
[#414]: https://github.com/guard/guard/issues/414
[#416]: https://github.com/guard/guard/issues/416
[#443]: https://github.com/guard/guard/issues/443
[#450]: https://github.com/guard/guard/issues/450
[#453]: https://github.com/guard/guard/issues/453
[#460]: https://github.com/guard/guard/issues/460
[#463]: https://github.com/guard/guard/issues/463
Expand Down Expand Up @@ -871,4 +874,4 @@ The Listen integration has been supervised by [@thibaudgg][] and executed by [@M
[@waldo]: https://github.com/waldo
[@wereHamster]: https://github.com/wereHamster
[@yannlugrin]: https://github.com/yannlugrin
[@zonque]: https://github.com/zonque
[@zonque]: https://github.com/zonque
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -218,10 +218,11 @@ $ guard -d # shortcut

#### `-w`/`--watchdir` option

Guard can watch any directory instead of the current directory:
Guard can watch any number of directories instead of only the current directory:

```bash
$ guard --watchdir ~/your/fancy/project
$ guard -w ~/your/fancy/project ~/your/fancier/project2 #multiple directories
$ guard -w ~/your/fancy/project # shortcut
```

Expand Down
43 changes: 31 additions & 12 deletions lib/guard.rb
Expand Up @@ -38,20 +38,25 @@ class << self
# @option options [Boolean] notify if system notifications should be shown
# @option options [Boolean] debug if debug output should be shown
# @option options [Array<String>] group the list of groups to start
# @option options [String] watchdir the director to watch
# @option options [Array<String>] watchdir the directories to watch
# @option options [String] guardfile the path to the Guardfile
# @deprecated @option options [Boolean] watch_all_modifications watches all file modifications if true
# @deprecated @option options [Boolean] no_vendor ignore vendored dependencies
#
def setup(options = {})
@running = true
@lock = Mutex.new
@options = options.dup
@watchdir = (options[:watchdir] && File.expand_path(options[:watchdir])) || Dir.pwd
@runner = ::Guard::Runner.new
@scope = { :plugins => [], :groups => [] }

Dir.chdir(@watchdir)
@running = true
@lock = Mutex.new
@options = options.dup
@runner = ::Guard::Runner.new
@scope = { :plugins => [], :groups => [] }

@watchdirs = [Dir.pwd]

if options[:watchdir]
# Ensure we have an array
@watchdirs = Array(options[:watchdir]).map { |dir| File.expand_path dir }
end

::Guard::UI.clear(:force => true)
setup_debug
deprecated_options_warning
Expand Down Expand Up @@ -99,19 +104,33 @@ def setup_guards
#
def setup_listener
listener_callback = lambda do |modified, added, removed|

# Convert to relative paths (respective to the watchdir it came from)
@watchdirs.each do |watchdir|
[modified, added, removed].each do |paths|
paths.map! do |path|
if path.start_with? watchdir
path.sub "#{watchdir}#{File::SEPARATOR}", ''
else
path
end
end
end
end
::Guard::Dsl.reevaluate_guardfile if ::Guard::Watcher.match_guardfile?(modified)

::Guard.within_preserved_state do
runner.run_on_changes(modified, added, removed)
end
end

listener_options = { :relative_paths => true }
listener_options = {}
%w[latency force_polling].each do |option|
listener_options[option.to_sym] = options[option] if options.key?(option)
end

@listener = Listen.to(@watchdir, listener_options).change(&listener_callback)
listen_args = @watchdirs + [listener_options]
@listener = Listen.to(*listen_args).change(&listener_callback)
end

# Sets up traps to catch signals used to control Guard.
Expand Down Expand Up @@ -190,7 +209,7 @@ def start(options = {})
within_preserved_state do
::Guard::UI.debug 'Guard starts all plugins'
runner.run(:start)
::Guard::UI.info "Guard is now watching at '#{ @watchdir }'"
::Guard::UI.info "Guard is now watching at '#{ @watchdirs.join "', '" }'"
listener.start
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/guard/cli.rb
Expand Up @@ -48,9 +48,9 @@ class CLI < Thor
:banner => 'Run only the passed plugins'

method_option :watchdir,
:type => :string,
:type => :array,
:aliases => '-w',
:banner => 'Specify the directory to watch'
:banner => 'Specify the directories to watch'

method_option :guardfile,
:type => :string,
Expand Down
13 changes: 7 additions & 6 deletions spec/guard_spec.rb
Expand Up @@ -37,9 +37,10 @@
::Guard.listener.directories.should eq ['/usr']
end

it "changes the current work dir to the watchdir" do
Dir.should_receive(:chdir).with('/tmp')
::Guard.setup(:watchdir => '/tmp')
it "respect the watchdir option with multiple directories" do
::Guard.setup(:watchdir => ['/usr', '/bin'])

::Guard.listener.directories.should eq ['/usr', '/bin']
end

it "call setup_signal_traps" do
Expand Down Expand Up @@ -273,7 +274,7 @@
before { ::Guard.stub(:options).and_return("latency" => 1.5) }

it "pass option to listener" do
Listen.should_receive(:to).with(anything, { :relative_paths => true, :latency => 1.5 }) { listener }
Listen.should_receive(:to).with(anything, { :latency => 1.5 }) { listener }
::Guard.setup_listener
end
end
Expand All @@ -282,7 +283,7 @@
before { ::Guard.stub(:options).and_return("force_polling" => true) }

it "pass option to listener" do
Listen.should_receive(:to).with(anything, { :relative_paths => true, :force_polling => true }) { listener }
Listen.should_receive(:to).with(anything, { :force_polling => true }) { listener }
::Guard.setup_listener
end
end
Expand Down Expand Up @@ -616,7 +617,7 @@ class Guard::FooBar < Guard::Guard;
end

it "displays an info message" do
::Guard.instance_variable_set('@watchdir', '/foo/bar')
::Guard.instance_variable_set('@watchdirs', ['/foo/bar'])
::Guard::UI.should_receive(:info).with("Guard is now watching at '/foo/bar'")

::Guard.start
Expand Down

0 comments on commit 8dcddfc

Please sign in to comment.