rerun 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +79 -22
- data/Rakefile +82 -82
- data/bin/rerun +12 -12
- data/lib/goo.rb +3 -0
- data/lib/rerun.rb +15 -15
- data/lib/rerun/notification.rb +82 -64
- data/lib/rerun/options.rb +142 -119
- data/lib/rerun/runner.rb +375 -334
- data/lib/rerun/system.rb +22 -22
- data/lib/rerun/watcher.rb +130 -119
- data/rerun.gemspec +34 -34
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1489afa035f2da5780ee35de95b95bd272c5440
|
4
|
+
data.tar.gz: 2610078f1caaf80bb29540fd398149b539b88b12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff6bf2054ab858b4a9bfde9600ffb5966be77c63584e1049bf2f4299b01b437fe5fdf83b7e890b55d2ab249243d02cd60ad035ce2ad1145d83f904f9a53b272e
|
7
|
+
data.tar.gz: 88f0dd6fd81c98ab774a4ab2f5a7f545b827f3295d19a4613a0504b42e6de0dd4a13a5d6381e59a43f0f067aca3100ff4d2b177bb3a46f723100c85d369c7764
|
data/README.md
CHANGED
@@ -14,14 +14,18 @@ Rerun's advantage is its simple design. Since it uses `exec` and the standard
|
|
14
14
|
Unix `SIGINT` and `SIGKILL` signals, you're sure the restarted app is really
|
15
15
|
acting just like it was when you ran it from the command line the first time.
|
16
16
|
|
17
|
-
By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature`.
|
17
|
+
By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature,c,h`.
|
18
18
|
Use the `--pattern` option if you want to change this.
|
19
19
|
|
20
20
|
As of version 0.7.0, we use the Listen gem, which tries to use your OS's
|
21
21
|
built-in facilities for monitoring the filesystem, so CPU use is very light.
|
22
22
|
|
23
|
-
Rerun does
|
24
|
-
|
23
|
+
**UPDATE**: Now Rerun *does* work on Windows. Caveats:
|
24
|
+
* not well-tested
|
25
|
+
* after running, it may continue to slurp up some of your console input, so run it in a separate window, and/or use `--background` to disable on-the-fly commands, and/or press `q` to quit instead of CTRL-C
|
26
|
+
* you may need to install the `wdm` gem manually: `gem install wdm`
|
27
|
+
* You may see this persistent `INFO` error message; to remove it, use`--no-notify`:
|
28
|
+
* `INFO: Could not find files for the given pattern(s)`
|
25
29
|
|
26
30
|
# Installation:
|
27
31
|
|
@@ -40,10 +44,19 @@ they're not available. Unfortunately, Rubygems doesn't understand optional
|
|
40
44
|
dependencies very well, so you may have to install extra gems (and/or put them
|
41
45
|
in your Gemfile) to make Rerun work more smoothly on your system.
|
42
46
|
(Learn more at <https://github.com/guard/listen#listen-adapters>.)
|
43
|
-
|
47
|
+
|
48
|
+
On Mac OS X, use
|
44
49
|
|
45
50
|
gem install rb-fsevent
|
46
51
|
|
52
|
+
On Windows, use
|
53
|
+
|
54
|
+
gem install wdm
|
55
|
+
|
56
|
+
On *BSD, use
|
57
|
+
|
58
|
+
gem install rb-kqueue
|
59
|
+
|
47
60
|
# Usage:
|
48
61
|
|
49
62
|
rerun [options] [--] cmd
|
@@ -116,44 +129,56 @@ Procfile processes locally and restart them all when necessary.
|
|
116
129
|
`--dir` directory (or directories) to watch (default = "."). Separate multiple paths with ',' and/or use multiple `-d` options.
|
117
130
|
|
118
131
|
`--pattern` glob to match inside directory. This uses the Ruby Dir glob style -- see <http://www.ruby-doc.org/core/classes/Dir.html#M002322> for details.
|
119
|
-
By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature`.
|
132
|
+
By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature,c,h`.
|
120
133
|
On top of this, it also ignores dotfiles, `.tmp` files, and some other files and directories (like `.git` and `log`).
|
121
134
|
Run `rerun --help` to see the actual list.
|
122
135
|
|
123
|
-
`--ignore pattern` file glob to ignore (can be set many times). To ignore a directory, you must append '/*' e.g.
|
136
|
+
`--ignore pattern` file glob to ignore (can be set many times). To ignore a directory, you must append `'/*'` e.g.
|
124
137
|
`--ignore 'coverage/*'`.
|
125
138
|
|
126
139
|
*On top of --pattern and --ignore, we ignore any changes to files and dirs starting with a dot.*
|
127
140
|
|
128
|
-
`--signal` (or `-s`) use specified signal (instead of the default
|
141
|
+
`--signal` (or `-s`) use specified signal(s) (instead of the default `TERM,INT,KILL`) to terminate the previous process. You can use a comma-delimited list if you want to try a signal, wait up to 5 seconds for the process to die, then try again with a different signal, and so on.
|
129
142
|
This may be useful for forcing the respective process to terminate as quickly as possible.
|
130
143
|
(`--signal KILL` is the equivalent of `kill -9`)
|
131
144
|
|
145
|
+
`--wait sec` (or `-w`) after asking the process to terminate, wait this long (in seconds) before either aborting, or trying the next signal in series. Default: 2 sec
|
146
|
+
|
132
147
|
`--restart` (or `-r`) expect process to restart itself, using signal HUP by default
|
133
148
|
(e.g. `-r -s INT` will send a INT and then resume watching for changes)
|
134
149
|
|
135
|
-
`--clear` (or -c) clear the screen before each run
|
136
|
-
|
137
150
|
`--exit` (or -x) expect the program to exit. With this option, rerun checks the return value; without it, rerun checks that the launched process is still running.
|
138
151
|
|
152
|
+
`--clear` (or -c) clear the screen before each run
|
153
|
+
|
139
154
|
`--background` (or -b) disable on-the-fly commands, allowing the process to be backgrounded
|
140
155
|
|
141
|
-
`--notify NOTIFIER` use `growl` or `osx` for notifications (see below)
|
156
|
+
`--notify NOTIFIER` use `growl` or `osx` or `notify-send` for notifications (see below)
|
142
157
|
|
143
|
-
`--no-notify`
|
158
|
+
`--no-notify` disable notifications
|
144
159
|
|
145
160
|
`--name` set the app name (for display)
|
146
161
|
|
162
|
+
`--force-polling` use polling instead of a native filesystem scan (useful for Vagrant)
|
163
|
+
|
164
|
+
`--quiet` silences most messages
|
165
|
+
|
166
|
+
`--verbose` enables even more messages (unless you also specified `--quiet`, which overrides `--verbose`)
|
167
|
+
|
147
168
|
Also `--version` and `--help`, naturally.
|
148
169
|
|
149
170
|
# Notifications
|
150
171
|
|
151
172
|
If you have `growlnotify` available on the `PATH`, it sends notifications to
|
152
173
|
growl in addition to the console.
|
174
|
+
|
153
175
|
If you have `terminal-notifier`, it sends notifications to
|
154
176
|
the OS X notification center in addition to the console.
|
155
177
|
|
156
|
-
If you have
|
178
|
+
If you have `notify-send`, it sends notifications to Freedesktop-compatible
|
179
|
+
desktops in addition to the console.
|
180
|
+
|
181
|
+
If you have more than one available notification program, Rerun will pick one, or you can choose between them using `--notify growl`, `--notify osx`, `--notify notify-send`, etc.
|
157
182
|
|
158
183
|
If you have a notifier installed but don't want rerun to use it,
|
159
184
|
set the `--no-notify` option.
|
@@ -163,11 +188,14 @@ now that Growl has moved to the App Store.
|
|
163
188
|
|
164
189
|
Install [terminal-notifier](https://github.com/julienXX/terminal-notifier) using `gem install terminal-notifier`. (You may have to put it in your system gemset and/or use `sudo` too.) Using Homebrew to install terminal-notifier is not recommended.
|
165
190
|
|
191
|
+
On Debian/Ubuntu, `notify-send` is availble in the `libnotify-bin` package. On other GNU/Linux systems, it might be in a package with a different name.
|
192
|
+
|
166
193
|
# On-The-Fly Commands
|
167
194
|
|
168
195
|
While the app is (re)running, you can make things happen by pressing keys:
|
169
196
|
|
170
197
|
* **r** -- restart (as if a file had changed)
|
198
|
+
* **f** -- force restart (stop and start)
|
171
199
|
* **c** -- clear the screen
|
172
200
|
* **x** or **q** -- exit (just like control-C)
|
173
201
|
* **p** -- pause/unpause filesystem watching
|
@@ -180,14 +208,31 @@ keys to be trapped, so use the `--background` option.
|
|
180
208
|
The current algorithm for killing the process is:
|
181
209
|
|
182
210
|
* send [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) (or the value of the `--signal` option)
|
183
|
-
* if that doesn't work after
|
211
|
+
* if that doesn't work after 2 seconds, send SIGINT (aka control-C)
|
184
212
|
* if that doesn't work after 2 more seconds, send SIGKILL (aka kill -9)
|
185
213
|
|
186
214
|
This seems like the most gentle and unixy way of doing things, but it does
|
187
|
-
mean that if your program ignores SIGTERM, it takes an extra
|
215
|
+
mean that if your program ignores SIGTERM, it takes an extra 2 to 4 seconds to
|
188
216
|
restart.
|
189
217
|
|
218
|
+
If you want to use your own series of signals, use the `--signal` option. If you want to change the delay before attempting the next signal, use the `--wait` option.
|
219
|
+
|
220
|
+
# Vagrant and VirtualBox
|
221
|
+
|
222
|
+
If running inside a shared directory using Vagrant and VirtualBox, you must pass the `--force-polling` option. You may also have to pass some extra `--ignore` options too; otherwise each scan can take 10 or more seconds on directories with a large number of files or subdirectories underneath it.
|
223
|
+
|
190
224
|
# Troubleshooting
|
225
|
+
|
226
|
+
## Vagrant ##
|
227
|
+
|
228
|
+
Rerun will not pick up changes made to shared folders. This means that the common
|
229
|
+
method of using Vagrant for an execution environment and using the `/vagrant`
|
230
|
+
shared folder for source code will not work.
|
231
|
+
|
232
|
+
Instead, use [shotgun](https://rubygems.org/gems/shotgun).
|
233
|
+
|
234
|
+
## zsh ##
|
235
|
+
|
191
236
|
If you are using `zsh` as your shell, and you are specifying your `--pattern` as `**/*.rb`, you may face this error
|
192
237
|
```
|
193
238
|
Errno::EACCES: Permission denied - <filename>
|
@@ -210,24 +255,17 @@ rerun -p "**/*.rb" rake test
|
|
210
255
|
* Optionally do "bundle install" before and "bundle exec" during launch
|
211
256
|
|
212
257
|
## Nice to have
|
213
|
-
* Smarter --signal option (specifying signal to try and a timeout to wait, repeated)
|
214
258
|
* If the last element of the command is a `.ru` file and there's no other command then use `rackup`
|
215
259
|
* Figure out an algorithm so "-x" is not needed (if possible) -- maybe by accepting a "--port" option or reading `config.ru`
|
216
260
|
* Specify (or deduce) port to listen for to determine success of a web server launch
|
217
261
|
* see also [todo.md](todo.md)
|
218
262
|
|
219
263
|
## Wacky Ideas
|
220
|
-
|
221
|
-
* https://github.com/guard/guard/issues/59
|
222
|
-
* https://github.com/guard/guard/issues/27
|
264
|
+
|
223
265
|
* On OS X:
|
224
266
|
* use a C library using growl's developer API <http://growl.info/developer/>
|
225
267
|
* Use growl's AppleScript or SDK instead of relying on growlnotify
|
226
|
-
* Use OS X notifications
|
227
268
|
* "Failed" icon for notifications
|
228
|
-
* On Linux:
|
229
|
-
* Test on Linux.
|
230
|
-
* Use libnotify or notify-send http://www.linuxjournal.com/content/tech-tip-get-notifications-your-scripts-notify-send
|
231
269
|
|
232
270
|
# Other projects that do similar things
|
233
271
|
|
@@ -321,9 +359,28 @@ Based upon and/or inspired by:
|
|
321
359
|
* James Edward Gray II <https://github.com/JEG2>
|
322
360
|
* Raul E Rangel <https://github.com/ismell> and Antonio Terceiro <https://github.com/terceiro>
|
323
361
|
* Mike Pastore <https://github.com/mwpastore>
|
362
|
+
* Andy Duncan <https://github.com/ajduncan>
|
363
|
+
* Brent Van Minnen
|
364
|
+
* Matthew O'Riordan <https://github.com/mattheworiordan>
|
365
|
+
* Antonio Terceiro <https://github.com/terceiro>
|
366
|
+
* <https://github.com/mattbrictson>
|
367
|
+
* <https://github.com/krissi>
|
324
368
|
|
325
369
|
# Version History
|
326
370
|
|
371
|
+
* v0.12.0 23 January 2018
|
372
|
+
* smarter `--signal` option, allowing you to specify a series of signals to try in order; also `--wait` to change how long between tries
|
373
|
+
* `--force-polling` option (thanks ajduncan)
|
374
|
+
* `f` key to force stop and start (thanks mwpastore)
|
375
|
+
* add `.c` and `.h` files to default ignore list
|
376
|
+
* support for Windows
|
377
|
+
* use `Kernel.spawn` instead of `fork`
|
378
|
+
* use `wdm` gem for Windows Directory Monitor
|
379
|
+
* TODO: fix `INFO` error message
|
380
|
+
* TODO: fix console input contention bug
|
381
|
+
* support for notifications on GNU/Linux using [notify-send](http://www.linuxjournal.com/content/tech-tip-get-notifications-your-scripts-notify-send) (thanks terceiro)
|
382
|
+
* fix `Gem::LoadError - terminal-notifier is not part of the bundle` [bug](https://github.com/alexch/rerun/issues/108) (thanks mattheworiordan)
|
383
|
+
|
327
384
|
* 0.11.0 7 October 2015
|
328
385
|
* better 'changed' message
|
329
386
|
* `--notify osx` option
|
data/Rakefile
CHANGED
@@ -1,82 +1,82 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'rake/clean'
|
3
|
-
require 'rake/testtask'
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
|
6
|
-
task :default => [:spec]
|
7
|
-
task :test => :spec
|
8
|
-
|
9
|
-
desc "Run all specs"
|
10
|
-
RSpec::Core::RakeTask.new('spec') do |t|
|
11
|
-
ENV['ENV'] = "test"
|
12
|
-
t.pattern = 'spec/**/*_spec.rb'
|
13
|
-
t.rspec_opts = ['--color']
|
14
|
-
end
|
15
|
-
|
16
|
-
$rubyforge_project = 'pivotalrb'
|
17
|
-
|
18
|
-
$spec =
|
19
|
-
begin
|
20
|
-
require 'rubygems/specification'
|
21
|
-
data = File.read('rerun.gemspec')
|
22
|
-
spec = nil
|
23
|
-
#Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
24
|
-
spec = eval data
|
25
|
-
spec
|
26
|
-
end
|
27
|
-
|
28
|
-
def package(ext='')
|
29
|
-
"pkg/#{$spec.name}-#{$spec.version}" + ext
|
30
|
-
end
|
31
|
-
|
32
|
-
desc 'Exit if git is dirty'
|
33
|
-
task :check_git do
|
34
|
-
state = `git status 2> /dev/null | tail -n1`
|
35
|
-
clean = (state =~ /working directory clean/)
|
36
|
-
unless clean
|
37
|
-
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
desc 'Build packages'
|
43
|
-
task :package => %w[.gem .tar.gz].map { |e| package(e) }
|
44
|
-
|
45
|
-
desc 'Build and install as local gem'
|
46
|
-
task :install => package('.gem') do
|
47
|
-
sh "gem install #{package('.gem')}"
|
48
|
-
end
|
49
|
-
|
50
|
-
directory 'pkg/'
|
51
|
-
CLOBBER.include('pkg')
|
52
|
-
|
53
|
-
file package('.gem') => %W[pkg/ #{$spec.name}.gemspec] + $spec.files do |f|
|
54
|
-
sh "gem build #{$spec.name}.gemspec"
|
55
|
-
mv File.basename(f.name), f.name
|
56
|
-
end
|
57
|
-
|
58
|
-
file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
|
59
|
-
cmd = <<-SH
|
60
|
-
git archive \
|
61
|
-
--prefix=#{$spec.name}-#{$spec.version}/ \
|
62
|
-
--format=tar \
|
63
|
-
HEAD | gzip > #{f.name}
|
64
|
-
SH
|
65
|
-
sh cmd.gsub(/ +/, ' ')
|
66
|
-
end
|
67
|
-
|
68
|
-
desc 'Publish gem and tarball to rubyforge'
|
69
|
-
task 'release' => [:check_git, package('.gem'), package('.tar.gz')] do |t|
|
70
|
-
puts "Releasing #{$spec.version}"
|
71
|
-
sh "gem push #{package('.gem')}"
|
72
|
-
puts "Tagging and pushing"
|
73
|
-
sh "git tag v#{$spec.version}"
|
74
|
-
sh "git push && git push --tags"
|
75
|
-
end
|
76
|
-
|
77
|
-
desc 'download github issues and pull requests'
|
78
|
-
task 'github' do
|
79
|
-
%w(issues pulls).each do |type|
|
80
|
-
sh "curl -o #{type}.json https://api.github.com/repos/alexch/rerun/#{type}"
|
81
|
-
end
|
82
|
-
end
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
task :default => [:spec]
|
7
|
+
task :test => :spec
|
8
|
+
|
9
|
+
desc "Run all specs"
|
10
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
11
|
+
ENV['ENV'] = "test"
|
12
|
+
t.pattern = 'spec/**/*_spec.rb'
|
13
|
+
t.rspec_opts = ['--color']
|
14
|
+
end
|
15
|
+
|
16
|
+
$rubyforge_project = 'pivotalrb'
|
17
|
+
|
18
|
+
$spec =
|
19
|
+
begin
|
20
|
+
require 'rubygems/specification'
|
21
|
+
data = File.read('rerun.gemspec')
|
22
|
+
spec = nil
|
23
|
+
#Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
24
|
+
spec = eval data
|
25
|
+
spec
|
26
|
+
end
|
27
|
+
|
28
|
+
def package(ext='')
|
29
|
+
"pkg/#{$spec.name}-#{$spec.version}" + ext
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Exit if git is dirty'
|
33
|
+
task :check_git do
|
34
|
+
# state = `git status 2> /dev/null | tail -n1`
|
35
|
+
# clean = (state =~ /working (directory|tree) clean/)
|
36
|
+
# unless clean
|
37
|
+
# warn "can't do that on an unclean git dir"
|
38
|
+
# exit 1
|
39
|
+
# end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Build packages'
|
43
|
+
task :package => %w[.gem .tar.gz].map { |e| package(e) }
|
44
|
+
|
45
|
+
desc 'Build and install as local gem'
|
46
|
+
task :install => package('.gem') do
|
47
|
+
sh "gem install #{package('.gem')}"
|
48
|
+
end
|
49
|
+
|
50
|
+
directory 'pkg/'
|
51
|
+
CLOBBER.include('pkg')
|
52
|
+
|
53
|
+
file package('.gem') => %W[pkg/ #{$spec.name}.gemspec] + $spec.files do |f|
|
54
|
+
sh "gem build #{$spec.name}.gemspec"
|
55
|
+
mv File.basename(f.name), f.name
|
56
|
+
end
|
57
|
+
|
58
|
+
file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
|
59
|
+
cmd = <<-SH
|
60
|
+
git archive \
|
61
|
+
--prefix=#{$spec.name}-#{$spec.version}/ \
|
62
|
+
--format=tar \
|
63
|
+
HEAD | gzip > #{f.name}
|
64
|
+
SH
|
65
|
+
sh cmd.gsub(/ +/, ' ')
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Publish gem and tarball to rubyforge'
|
69
|
+
task 'release' => [:check_git, package('.gem'), package('.tar.gz')] do |t|
|
70
|
+
puts "Releasing #{$spec.version}"
|
71
|
+
sh "gem push #{package('.gem')}"
|
72
|
+
puts "Tagging and pushing"
|
73
|
+
sh "git tag v#{$spec.version}"
|
74
|
+
sh "git push && git push --tags"
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'download github issues and pull requests'
|
78
|
+
task 'github' do
|
79
|
+
%w(issues pulls).each do |type|
|
80
|
+
sh "curl -o #{type}.json https://api.github.com/repos/alexch/rerun/#{type}"
|
81
|
+
end
|
82
|
+
end
|
data/bin/rerun
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
libdir = "#{File.expand_path(File.dirname(File.dirname(__FILE__)))}/lib"
|
5
|
-
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
6
|
-
|
7
|
-
require 'rerun'
|
8
|
-
require 'optparse'
|
9
|
-
|
10
|
-
options = Rerun::Options.parse
|
11
|
-
exit if options.nil?
|
12
|
-
runner = Rerun::Runner.keep_running(options[:cmd], options)
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
libdir = "#{File.expand_path(File.dirname(File.dirname(__FILE__)))}/lib"
|
5
|
+
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
6
|
+
|
7
|
+
require 'rerun'
|
8
|
+
require 'optparse'
|
9
|
+
|
10
|
+
options = Rerun::Options.parse
|
11
|
+
exit if options.nil?
|
12
|
+
runner = Rerun::Runner.keep_running(options[:cmd], options)
|
data/lib/goo.rb
ADDED
data/lib/rerun.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
here = File.expand_path(File.dirname(__FILE__))
|
2
|
-
$: << here unless $:.include?(here)
|
3
|
-
|
4
|
-
require "listen" # pull in the Listen gem
|
5
|
-
require "rerun/options"
|
6
|
-
require "rerun/system"
|
7
|
-
require "rerun/notification"
|
8
|
-
require "rerun/runner"
|
9
|
-
require "rerun/watcher"
|
10
|
-
require "rerun/glob"
|
11
|
-
|
12
|
-
module Rerun
|
13
|
-
|
14
|
-
end
|
15
|
-
|
1
|
+
here = File.expand_path(File.dirname(__FILE__))
|
2
|
+
$: << here unless $:.include?(here)
|
3
|
+
|
4
|
+
require "listen" # pull in the Listen gem
|
5
|
+
require "rerun/options"
|
6
|
+
require "rerun/system"
|
7
|
+
require "rerun/notification"
|
8
|
+
require "rerun/runner"
|
9
|
+
require "rerun/watcher"
|
10
|
+
require "rerun/glob"
|
11
|
+
|
12
|
+
module Rerun
|
13
|
+
|
14
|
+
end
|
15
|
+
|
data/lib/rerun/notification.rb
CHANGED
@@ -1,64 +1,82 @@
|
|
1
|
-
# todo: unit tests
|
2
|
-
|
3
|
-
module Rerun
|
4
|
-
class Notification
|
5
|
-
include System
|
6
|
-
|
7
|
-
attr_reader :title, :body, :options
|
8
|
-
|
9
|
-
def initialize(title, body, options = Options::DEFAULTS.dup)
|
10
|
-
@title = title
|
11
|
-
@body = body
|
12
|
-
@options = options
|
13
|
-
end
|
14
|
-
|
15
|
-
def command
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
|
1
|
+
# todo: unit tests
|
2
|
+
|
3
|
+
module Rerun
|
4
|
+
class Notification
|
5
|
+
include System
|
6
|
+
|
7
|
+
attr_reader :title, :body, :options
|
8
|
+
|
9
|
+
def initialize(title, body, options = Options::DEFAULTS.dup)
|
10
|
+
@title = title
|
11
|
+
@body = body
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def command
|
16
|
+
# todo: strategy or subclass
|
17
|
+
|
18
|
+
s = nil
|
19
|
+
|
20
|
+
if options[:notify] == true or options[:notify] == "growl"
|
21
|
+
if (cmd = command_named("growlnotify"))
|
22
|
+
# todo: check version of growlnotify and warn if it's too old
|
23
|
+
icon_str = ("--image \"#{icon}\"" if icon)
|
24
|
+
s = "#{cmd} -n \"#{app_name}\" -m \"#{body}\" \"#{app_name} #{title}\" #{icon_str}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if s.nil? and options[:notify] == true or options[:notify] == "osx"
|
29
|
+
if (cmd = command_named("terminal-notifier"))
|
30
|
+
icon_str = ("-appIcon \"#{icon}\"" if icon)
|
31
|
+
s = "#{cmd} -title \"#{app_name}\" -message \"#{body}\" \"#{app_name} #{title}\" #{icon_str}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if s.nil? and options[:notify] == true or options[:notify] == "notify-send"
|
36
|
+
if (cmd = command_named('notify-send'))
|
37
|
+
icon_str = "--icon #{icon}" if icon
|
38
|
+
s = "#{cmd} -t 500 --hint=int:transient:1 #{icon_str} \"#{app_name}: #{title}\" \"#{body}\""
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
s
|
43
|
+
end
|
44
|
+
|
45
|
+
def command_named(name)
|
46
|
+
which_command = windows? ? 'where.exe' : 'which'
|
47
|
+
# TODO: remove 'INFO' error message
|
48
|
+
path = `#{which_command} #{name}`.chomp
|
49
|
+
path.empty? ? nil : path
|
50
|
+
end
|
51
|
+
|
52
|
+
def send(background = true)
|
53
|
+
return unless command
|
54
|
+
with_clean_env do
|
55
|
+
`#{command}#{" &" if background}`
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def app_name
|
60
|
+
options[:name]
|
61
|
+
end
|
62
|
+
|
63
|
+
def icon
|
64
|
+
"#{icon_dir}/rails_red_sml.png" if rails?
|
65
|
+
end
|
66
|
+
|
67
|
+
def icon_dir
|
68
|
+
here = File.expand_path(File.dirname(__FILE__))
|
69
|
+
File.expand_path("#{here}/../../icons")
|
70
|
+
end
|
71
|
+
|
72
|
+
def with_clean_env
|
73
|
+
if defined?(Bundler)
|
74
|
+
Bundler.with_clean_env do
|
75
|
+
yield
|
76
|
+
end
|
77
|
+
else
|
78
|
+
yield
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|