rerun 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|