guard / guard

Guard is a command line tool to easily handle events on file system modifications.
MIT License
6.24k stars 481 forks source link

Guard-shell executes twice #297

Closed jabalsad closed 11 years ago

jabalsad commented 12 years ago

I setup an example project with the following structure:

Gemfile
Guardfile

The contents of these files are:

# Gemfile
source :rubygems
gem "guard"
gem "guard-shell"

and

# Guardfile
guard 'shell' do
  watch(/^test\.txt$/) {|m| `echo #{m.inspect} #{File.mtime(m[0])}` }
end

I then continue to run guard. Whenever I echo something into that file, guard registers a change twice. In one shell:

$ echo blah >> test.txt

In the shell running guard:

> [test.txt] 2012-06-26 00:40:22 +0200
> [test.txt] 2012-06-26 00:40:22 +0200

The same behaviour accounts for vim/nano etc. Interestingly, when I just run echo blah > test.txt, guard only fires once.

Any idea how I can prevent this from happening or whether this is expected behaviour? (See my original stackoverflow question here: http://stackoverflow.com/questions/11198446/guard-executes-shell-scripts-twice)

jabalsad commented 12 years ago

I tried opening the issue on guard-shell's github page, but it seems that option is disabled.

jabalsad commented 12 years ago

Will update the issue with debug output if necessary (don't have access to it right now unfortunately)

thibaudgg commented 12 years ago

Hi @jabalsad,

Matt Solt & Christopher Powell also have the same issue on google group.

@guard/core-team do you have an idea from when it could come? (also do you already encountered that issue)

netzpirat commented 12 years ago

The given example works fine on OS X, so I guess this is a Listen inotify adapter issue.

Before Listen was created, the adapter watched for :recursive, :attrib, :create, :move_self and :close_write events. We came to this event list by analyzing several command and editor write behavior reported in various issues, which is documented in the wiki under Analysis of inotify events for different editors. Append to a file echo 'blah' >> file is missing, perhaps someone on Linux can add this info to the wiki page.

Listen actually watches for :recursive, :attrib, :close, :modify, :move, :create, :delete, :delete_self and :move_self. Since I wasn't part of the Listen dev team, I cannot say what the reason was to switch the event list.

thibaudgg commented 12 years ago

I have updated linux event in Listen, can you please try it by adding:

gem 'listen', :github => 'guard/listen', :branch => 'linux_events'

in your Gemfile. Thanks

jabalsad commented 12 years ago

That fixes the issue, much appreciated!

ryanlchan commented 12 years ago

This also fixes the issue for me on Ubuntu. Thank you!

Edit: Actually, on second review, this seems to mostly fix the issue. I am still getting the double run, albeit less frequently.

gerrywastaken commented 12 years ago

Noob mistake for me (actually noob, just started with ruby), I had a:

require 'rubygems'

which I had moved from the top of my spec_helper file into the Spork.prefork block and this was causing the doubling up for me. I believe I was tricked by the following comment:

# Loading more in this block will cause your tests to run faster.

Hopefully this might help some others who find themselves here via Google like I did.

thibaudgg commented 12 years ago

Nice, I'll release a new release of Listen today. Thanks!

thibaudgg commented 12 years ago

Listen 0.4.7 released!

dvandersluis commented 12 years ago

I have updated Listen to 0.4.7 but am also experiencing this issue often. Since updating from 1.0.2 to 1.2.1, the guard prompt is often > > rather than >, and I have noticed that when this occurs, my guards execute twice. I'm running on Ubuntu 10.04.3.

netzpirat commented 12 years ago

I had the double prompt > > issue very often before 1.2.0, but never had the double run issue. I guess these two issues are not related. With 1.2.0 I worked a full day with the readline interactor and haven't seen the double prompt once. I have switched to the coolline interactor and it feels more robust than the readline interactor. If you're on Ruby 1.9.3, then I recommend to switch to coolline. Coolline uses >> as prompt, so one can notice which interactor type is running.

prusswan commented 11 years ago

I am glad that this had been resolved, but can I ask if there is a way to print the cause (such as the list of modified files) for each triggered run?

thibaudgg commented 11 years ago

@prusswan you can use the debug option: guard -d

prusswan commented 11 years ago

@thibaudgg I tried that but it only shows the features that will be executed, but not the files that have been changed (i.e. model/controller), at least for cucumber

In the end I used the following watch expression, which works on ubuntu:

    watch(%r{^(.+)$}) { |m| `notify-send #{m[1]} modified` }
odigity commented 11 years ago

I'm running listen 0.4.7, but am still getting the double-run (and double-prompt) problem.

japgolly commented 11 years ago

I'm still getting this (inconsistently) with listen 0.4.7. Save a file once with vim in linux, guard runs twice.

> DEBUG (14:56:27): Stop interactor
DEBUG (14:56:27): Command execution: hash stty
DEBUG (14:56:27): Command execution: clear; 

DEBUG (14:56:27): Trying to run Guard::RSpec#run_on_modifications with ["test/spec/generators/init_spec.rb"]
DEBUG (14:56:27): Hook :run_on_changes_begin executed for Guard::RSpec
Running: test/spec/generators/init_spec.rb
DEBUG (14:56:27): Command execution: bin/rspec --color --order default   -f nested -r /home/golly/.rvm/gems/ruby-1.9.3-p194/gems/guard-rspec-1.2.0/lib/guard/rspec/formatters/notification_rspec.rb -f Guard::RSpec::Formatter::NotificationRSpec --out /dev/null --failure-exit-code 2 test/spec/generators/init_spec.rb 
...
DEBUG (14:56:28): Command execution: hash stty
DEBUG (14:56:28): Start interactor
> DEBUG (14:56:29): Stop interactor
DEBUG (14:56:29): Command execution: hash stty
DEBUG (14:56:29): Command execution: clear; 

DEBUG (14:56:29): Trying to run Guard::RSpec#run_on_modifications with ["test/spec/generators/init_spec.rb"]
DEBUG (14:56:29): Hook :run_on_changes_begin executed for Guard::RSpec
Running: test/spec/generators/init_spec.rb
DEBUG (14:56:29): Command execution: bin/rspec --color --order default   -f nested -r /home/golly/.rvm/gems/ruby-1.9.3-p194/gems/guard-rspec-1.2.0/lib/guard/rspec/formatters/notification_rspec.rb -f Guard::RSpec::Formatter::NotificationRSpec --out /dev/null --failure-exit-code 2 test/spec/generators/init_spec.rb 
...
DEBUG (14:56:30): Command execution: hash stty
DEBUG (14:56:30): Start interactor
> 
japgolly commented 11 years ago

Actually just a thought: Vim (on any platform I think) creates swap files while the editor is open. I think that Vim updating both of these files on save is what's causing Guard to run twice.

Is there anyway to tell Guard to ignore a notification if it matches a certain regex? This should match Vim swap files: /^(?:.*[\\\/])?\.[^\\\/]+\.sw[p-z]$/

netzpirat commented 11 years ago

Yes, that could be the a cause. I think prior to the Listen integration, Vim swap files have been ignore by Guard, but I see that this isn't the case for Listen anymore. Can someone with this problem verify this by using the ignore DSL method and open an issue on Listen if this solves the problem?

japgolly commented 11 years ago

Alrighty, I added this to my Guardfile and have been coding away for a while now.

    # Ignore Vim swap files
    ignore /^(?:.*[\\\/])?\.[^\\\/]+\.sw[p-z]$/

Unfortunately the issue is still occurring. The good news is that after adding the ignore directive I've only experienced the problem twice in the last 2 hours, much better than before where I couldn't go 15 minutes without the problem occurring.

prusswan commented 11 years ago

This is not directly related, but I noticed that my watcher for showing modified files, is triggered a lot more often when associated with guard-shell (rather than guard-rspec or guard-cucumber), even for files that are not really being modified (I can do a run_all and start seeing notifications for various source files even though only tests are being executed). Do plugins perform further filtering of file changes on their own?

    watch(%r{^(.+)$}) { |m| `notify-send #{m[1]} modified` }
japgolly commented 11 years ago

Thanks for the tip prusswan. I added that snippet and found that Vim also creates an intermediary file and deletes (or moves) it nearly immediately.

This seems to be working better so far:

    # Ignore Vim swap files                                                                                              
    ignore /~$/                                                                                                          
    ignore /^(?:.*[\\\/])?\.[^\\\/]+\.sw[p-z]$/                                                                          
rymai commented 11 years ago

@prusswan Yep, guard-rspec –as many other Guard plugins– cleans the modified paths, see here for the actual cleaning code.

prusswan commented 11 years ago

@japgolly glad it helped. Unfortunately I can't ignore my source code, so perhaps the behavior of guard-shell (as opposed to other plugins) needs to be examined

japgolly commented 11 years ago

Hi again. Unfortunately even with the aforementioned charge to my Guardfile to ignore Vim swap files, I'm still getting this error. I've kept on some debugging info and it turns out that the same filename in some cases, is simply sending two notifications. I'm not sure why.

Example:

WATCH --------> test/spec/res_patch_manager_spec.rb modified
...[tests run here]...
WATCH --------> test/spec/res_patch_manager_spec.rb modified
...[tests run again]...

I was hoping it would just be a few filters I was missing but I think the fix in 0.4.7 hasn't fixed this completely.

rschmitty commented 11 years ago

I'm also running into the double run on file save. Running with bundle exec guard -p --debug

watch(%r{^(.+)$}) { |m| `notify-send #{m[1]} modified` }

Will tell me that spec/requests/static_pages_spec.rb has been modified twice after I save it once. Here is output of starting up guard and saving the file once: http://pastebin.com/LA8NA0QQ

I'm using force polling as this is a shared folder in a virtual machine

I only get notifications of the file I actual saved as being modified, no temp/swap files are alerted

thibaudgg commented 11 years ago

@rschmitty can you please try to launch the Listen gem specs suite on your system (Windows) to see if it's all green.

rschmitty commented 11 years ago

@thibaudgg Here is the output for the listen gem run from the same environment as my normal project I have issues with (files on windows, shared in linux VM)

http://jsbin.com/alitap/1

thibaudgg commented 11 years ago

@rschmitty so the specs suite is run from the linux VM right? Is it the Listen 0.5 spec suite?

Symlinks stuff seems to fail badly, it could be related to https://github.com/guard/listen/issues/25

@Maher4Ever do you have any thoughts?

rschmitty commented 11 years ago

Correct, run from the VM running linux, ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]

Looks like 0.5 spec: http://pastebin.com/j9XRdEHT

I basically cloned from git, created a .rvmrc, and then ran bundle and rspec. Let me know if I can provide any further info to help debug! Thx

neersighted commented 11 years ago

Bump, I'm getting this issue too (with guard-rspec and guard-spork) on Ubuntu 12.04.

enwood commented 11 years ago

I'm also getting this issue with guard v1.3.2, guard-minitest, and guard-spork v1.1.0 on Mac OS X Snow Leopard.

A save to any test file triggers a complete double-run of tests.

My Guardfile is here: http://pastebin.com/Mxr4ydS5. My test_helper.rb is here: http://pastebin.com/WfxY1wwm

(I am using the spork_incompatible_args branch of guard-minitest at https://github.com/singlebrook/guard-minitest.git to get around the troubling passing of the "-r" option to Spork.)

thibaudgg commented 11 years ago

Yeah it's an issue wit Listen 0.5 https://github.com/guard/guard/issues/297#issuecomment-8323185 I just need to find time to fix it.

cczona commented 11 years ago

+1

thibaudgg commented 11 years ago

This should have been fixed in the polling/double Listen branch. Please can you give it a try by adding that in your Gemfile:

gem 'listen', github: 'guard/listen', branch: 'polling/double'

Thanks!

cczona commented 11 years ago

.spec: --drb.

Gemfile: ... group :development, :test do gem 'sqlite3' gem 'rspec-rails' gem 'guard-rspec' gem 'listen', github: 'guard/listen', branch: 'polling/double' gem 'guard-spork' gem 'spork' end ...

`$ bundle install $ bundle exec guard'

[~/repo/example] bundle exec guard Guard uses TerminalNotifier to send notifications. Guard is now watching at '/Users/cczona/repo/example' Guard::RSpec is running, with RSpec 2! Running all specs No DRb server is running. Running in local process instead ... ........

Finished in 0.2224 seconds 8 examples, 0 failures

Randomized with seed 12499

Guard::RSpec is running, with RSpec 2! Running all specs No DRb server is running. Running in local process instead ... ........

Finished in 0.2513 seconds 8 examples, 0 failures

Randomized with seed 12448

thibaudgg commented 11 years ago

Running all specs twice seems to be another issue, have you try without the --drb option?

cczona commented 11 years ago

Same result without --drb, including 'No DRb server" either way.

Should I open a new issue or is there an existing one you'd prefer this be added to?

thibaudgg commented 11 years ago

That's weird, but editing/touching a file also launch the spec twice? Can you please give your Gemfile & Guardfile?

cczona commented 11 years ago

Yep, the spec runs twice when guard launches, then twice again when a file changes. I've gisted the Gemfile & Guardfile here: https://gist.github.com/3768936

thibaudgg commented 11 years ago

@cczona remove the guard 'rspec', :version => 2 do block duplication and it will be good. Have guard-rspec twice in your Guardfile will quite logically execute it twice...

thibaudgg commented 11 years ago

Fixed in Listen 0.5.2

linduxed commented 10 years ago

I'm having this exact issue, although for me it's not just twice but occasionally three repetitions.

This is my Guardfile:

guard 'shell' do
  watch(%r{^src/(.*)\.hs$}) { |m| system("runghc spec/#{m[1]}Spec.hs" )}
  watch(%r{^spec/(.*)$}) { |m| system("runghc #{m[0]}") }
end

I currently don't use a Gemfile, since this is not a Ruby project, but I've only got versions higher than 0.7.3 installed for Listen, so that shouldn't be an issue.

I'm using Ruby 2.0.0-p247.

jrabary commented 10 years ago

+1

rymai commented 10 years ago

This is now probably the same issue as guard/guard#495. It should be fixed directly in guard-shell.

cohama commented 10 years ago

I tried above patch with Vim on Ubuntu13.04. But nothing changed. guard-shell executes three times.