poll-rerun 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: afdc9586c6a6101dea11606085d1d10fc0887d60
4
+ data.tar.gz: c8129748d4c63516fd44e28c2ff8c728515c788c
5
+ SHA512:
6
+ metadata.gz: 4c33ce48a27db3773cd195621f3682d0b3e395d494f939bac3cfcb84155cfa414a2d87f180f7ef82a655f6e26347b93a3a29db387702b79ee798fe7a8a18bca2
7
+ data.tar.gz: 9b74cab2dae5b506441edfeb8f88b12f3b5768cab495a0b66a108a98fa8d989224fd473c9a9acda0a1678a0394539d61a7423d738313eaa9847888496116b0e7
data/LICENSE ADDED
@@ -0,0 +1,34 @@
1
+ Rerun
2
+ Copyright (c) 2009 Alex Chaffee <alex@stinky.com>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to
6
+ deal in the Software without restriction, including without limitation the
7
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
+ sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+
21
+ ---
22
+
23
+ rerun partially based on code from Rspactor
24
+ Copyright (c) 2009 Mislav Marohnić
25
+ License as above (MIT open source).
26
+
27
+ rerun partially based on code from FileSystemWatcher
28
+ http://paulhorman.com/filesystemwatcher/
29
+ No license provided; assumed public domain.
30
+
31
+ rerun partially based on code from Shotgun
32
+ Copyright (c) 2009 Ryan Tomayko <tomayko.com/about>
33
+ License as above (MIT open source).
34
+
data/README.md ADDED
@@ -0,0 +1,377 @@
1
+ # Rerun
2
+
3
+ This is a fork of the original rerun available here:
4
+ <http://github.com/alexch/rerun>
5
+
6
+ The only difference between this version and the original is the versioning that also includes the `--force-polling` flag.
7
+
8
+ Rerun launches your program, then watches the filesystem. If a relevant file
9
+ changes, then it restarts your program.
10
+
11
+ Rerun works for both long-running processes (e.g. apps) and short-running ones
12
+ (e.g. tests). It's basically a no-frills command-line alternative to Guard,
13
+ Shotgun, Autotest, etc. that doesn't require config files and works on any
14
+ command, not just Ruby programs.
15
+
16
+ Rerun's advantage is its simple design. Since it uses `exec` and the standard
17
+ Unix `SIGINT` and `SIGKILL` signals, you're sure the restarted app is really
18
+ acting just like it was when you ran it from the command line the first time.
19
+
20
+ By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature`.
21
+ Use the `--pattern` option if you want to change this.
22
+
23
+ As of version 0.7.0, we use the Listen gem, which tries to use your OS's
24
+ built-in facilities for monitoring the filesystem, so CPU use is very light.
25
+
26
+ Rerun does not work on Windows. Sorry, but you can't do much relaunching
27
+ without "fork".
28
+
29
+ # Installation:
30
+
31
+ gem install rerun
32
+
33
+ ("sudo" may be required on older systems, but try it without sudo first.)
34
+
35
+ If you are using RVM you might want to put this in your global gemset so it's
36
+ available to all your apps. (There really should be a better way to distinguish
37
+ gems-as-libraries from gems-as-tools.)
38
+
39
+ rvm @global do gem install rerun
40
+
41
+ The Listen gem looks for certain platform-dependent gems, and will complain if
42
+ they're not available. Unfortunately, Rubygems doesn't understand optional
43
+ dependencies very well, so you may have to install extra gems (and/or put them
44
+ in your Gemfile) to make Rerun work more smoothly on your system.
45
+ (Learn more at <https://github.com/guard/listen#listen-adapters>.)
46
+ For example, on Mac OS X, use
47
+
48
+ gem install rb-fsevent
49
+
50
+ # Usage:
51
+
52
+ rerun [options] [--] cmd
53
+
54
+ For example, if you're running a Sinatra app whose main file is `app.rb`:
55
+
56
+ rerun ruby app.rb
57
+
58
+ If the first part of the command is a `.rb` filename, then `ruby` is
59
+ optional, so the above can also be accomplished like this:
60
+
61
+ rerun app.rb
62
+
63
+ Rails doesn't automatically notice all config file changes, so you can force it
64
+ to restart when you change a config file like this:
65
+
66
+ rerun --dir config rails s
67
+
68
+ Or if you're using Thin to run a Rack app that's configured in config.ru
69
+ but you want it on port 4000 and in debug mode, and only want to watch
70
+ the `app` and `web` subdirectories:
71
+
72
+ rerun --dir app,web -- thin start --debug --port=4000 -R config.ru
73
+
74
+ The `--` is to separate rerun options from cmd options. You can also
75
+ use a quoted string for the command, e.g.
76
+
77
+ rerun --dir app "thin start --debug --port=4000 -R config.ru"
78
+
79
+ Rackup can also be used to launch a Rack server, so let's try that:
80
+
81
+ rerun -- rackup --port 4000 config.ru
82
+
83
+ Want to mimic [autotest](https://github.com/grosser/autotest)? Try
84
+
85
+ rerun -x rake
86
+
87
+ or
88
+
89
+ rerun -cx rspec
90
+
91
+ And if you're using [Spork](https://github.com/sporkrb/spork) with Rails, you
92
+ need to [restart your spork server](https://github.com/sporkrb/spork/issues/201)
93
+ whenever certain Rails environment files change, so why not put this in your
94
+ Rakefile...
95
+
96
+ desc "run spork (via rerun)"
97
+ task :spork do
98
+ sh "rerun --pattern '{Gemfile,Gemfile.lock,spec/spec_helper.rb,.rspec,spec/factories/**,config/environment.rb,config/environments/test.rb,config/initializers/*.rb,lib/**/*.rb}' -- spork"
99
+ end
100
+
101
+ and start using `rake spork` to launch your spork server?
102
+
103
+ (If you're using Guard instead of Rerun, check out
104
+ [guard-spork](https://github.com/guard/guard-spork)
105
+ for a similar solution.)
106
+
107
+ How about regenerating your HTML files after every change to your
108
+ [Erector](http://erector.rubyforge.org) widgets?
109
+
110
+ rerun -x erector --to-html my_site.rb
111
+
112
+ Use Heroku Cedar? `rerun` is now compatible with `foreman`. Run all your
113
+ Procfile processes locally and restart them all when necessary.
114
+
115
+ rerun foreman start
116
+
117
+ # Options:
118
+
119
+ `--dir` directory (or directories) to watch (default = "."). Separate multiple paths with ',' and/or use multiple `-d` options.
120
+
121
+ `--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.
122
+ By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature`.
123
+ On top of this, it also ignores dotfiles, `.tmp` files, and some other files and directories (like `.git` and `log`).
124
+ Run `rerun --help` to see the actual list.
125
+
126
+ `--ignore pattern` file glob to ignore (can be set many times). To ignore a directory, you must append '/*' e.g.
127
+ `--ignore 'coverage/*'`.
128
+
129
+ *On top of --pattern and --ignore, we ignore any changes to files and dirs starting with a dot.*
130
+
131
+ `--signal` (or `-s`) use specified signal (instead of the default SIGTERM) to terminate the previous process.
132
+ This may be useful for forcing the respective process to terminate as quickly as possible.
133
+ (`--signal KILL` is the equivalent of `kill -9`)
134
+
135
+ `--restart` (or `-r`) expect process to restart itself, using signal HUP by default
136
+ (e.g. `-r -s INT` will send a INT and then resume watching for changes)
137
+
138
+ `--clear` (or -c) clear the screen before each run
139
+
140
+ `--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.
141
+
142
+ `--background` (or -b) disable on-the-fly commands, allowing the process to be backgrounded
143
+
144
+ `--notify NOTIFIER` use `growl` or `osx` for notifications (see below)
145
+
146
+ `--no-notify` don't use growl (or osx) notifications
147
+
148
+ `--name` set the app name (for display)
149
+
150
+ `--force-polling` use polling instead of a native filesystem scan (useful for Vagrant)
151
+
152
+ Also `--version` and `--help`, naturally.
153
+
154
+ # Notifications
155
+
156
+ If you have `growlnotify` available on the `PATH`, it sends notifications to
157
+ growl in addition to the console.
158
+ If you have `terminal-notifier`, it sends notifications to
159
+ the OS X notification center in addition to the console.
160
+
161
+ If you have both, Rerun will pick one, or you can choose between them using `--notify growl` or `--notify osx` respectively.
162
+
163
+ If you have a notifier installed but don't want rerun to use it,
164
+ set the `--no-notify` option.
165
+
166
+ Download [growlnotify here](http://growl.info/downloads.php#generaldownloads)
167
+ now that Growl has moved to the App Store.
168
+
169
+ 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.
170
+
171
+ # On-The-Fly Commands
172
+
173
+ While the app is (re)running, you can make things happen by pressing keys:
174
+
175
+ * **r** -- restart (as if a file had changed)
176
+ * **c** -- clear the screen
177
+ * **x** or **q** -- exit (just like control-C)
178
+ * **p** -- pause/unpause filesystem watching
179
+
180
+ If you're backgrounding or using Pry or a debugger, you might not want these
181
+ keys to be trapped, so use the `--background` option.
182
+
183
+ # Signals
184
+
185
+ The current algorithm for killing the process is:
186
+
187
+ * send [SIGTERM](http://en.wikipedia.org/wiki/SIGTERM) (or the value of the `--signal` option)
188
+ * if that doesn't work after 4 seconds, send SIGINT (aka control-C)
189
+ * if that doesn't work after 2 more seconds, send SIGKILL (aka kill -9)
190
+
191
+ This seems like the most gentle and unixy way of doing things, but it does
192
+ mean that if your program ignores SIGTERM, it takes an extra 4 to 6 seconds to
193
+ restart.
194
+
195
+ # Vagrant and VirtualBox
196
+
197
+ 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.
198
+
199
+ # Troubleshooting
200
+ If you are using `zsh` as your shell, and you are specifying your `--pattern` as `**/*.rb`, you may face this error
201
+ ```
202
+ Errno::EACCES: Permission denied - <filename>
203
+ ```
204
+ This is because `**/*.rb` gets expanded into the command by `zsh` instead of passing it through to rerun. The solution is to simply quote ('' or "") the pattern.
205
+ i.e
206
+ ```
207
+ rerun -p **/*.rb rake test
208
+ ```
209
+ becomes
210
+ ```
211
+ rerun -p "**/*.rb" rake test
212
+ ```
213
+
214
+ # To Do:
215
+
216
+ ## Must have for v1.0
217
+ * ".rerun" file to specify options per project or in $HOME.
218
+ * Make sure to pass through quoted options correctly to target process [bug]
219
+ * Optionally do "bundle install" before and "bundle exec" during launch
220
+
221
+ ## Nice to have
222
+ * Smarter --signal option (specifying signal to try and a timeout to wait, repeated)
223
+ * If the last element of the command is a `.ru` file and there's no other command then use `rackup`
224
+ * Figure out an algorithm so "-x" is not needed (if possible) -- maybe by accepting a "--port" option or reading `config.ru`
225
+ * Specify (or deduce) port to listen for to determine success of a web server launch
226
+ * see also [todo.md](todo.md)
227
+
228
+ ## Wacky Ideas
229
+ * Make it work on Windows, like Guard now does. See
230
+ * https://github.com/guard/guard/issues/59
231
+ * https://github.com/guard/guard/issues/27
232
+ * On OS X:
233
+ * use a C library using growl's developer API <http://growl.info/developer/>
234
+ * Use growl's AppleScript or SDK instead of relying on growlnotify
235
+ * "Failed" icon for notifications
236
+ * On Linux:
237
+ * Use libnotify or notify-send http://www.linuxjournal.com/content/tech-tip-get-notifications-your-scripts-notify-send
238
+
239
+ # Other projects that do similar things
240
+
241
+ * Restartomatic: <http://github.com/adammck/restartomatic>
242
+ * Shotgun: <http://github.com/rtomayko/shotgun>
243
+ * Rack::Reloader middleware: <http://github.com/rack/rack/blob/5ca8f82fb59f0bf0e8fd438e8e91c5acf3d98e44/lib/rack/reloader.rb>
244
+ * The Sinatra FAQ has a discussion at <http://www.sinatrarb.com/faq.html#reloading>
245
+ * Kicker: <http://github.com/alloy/kicker/>
246
+ * Watchr: <https://github.com/mynyml/watchr>
247
+ * Guard: <http://github.com/guard/guard>
248
+ * Autotest: <https://github.com/grosser/autotest>
249
+
250
+ # Why would I use this instead of Shotgun?
251
+
252
+ Shotgun does a "fork" after the web framework has loaded but before
253
+ your application is loaded. It then loads your app, processes a
254
+ single request in the child process, then exits the child process.
255
+
256
+ Rerun launches the whole app, then when it's time to restart, uses
257
+ "kill" to shut it down and starts the whole thing up again from
258
+ scratch.
259
+
260
+ So rerun takes somewhat longer than Shotgun to restart the app, but
261
+ does it much less frequently. And once it's running it behaves more
262
+ normally and consistently with your production app.
263
+
264
+ Also, Shotgun reloads the app on every request, even if it doesn't
265
+ need to. This is fine if you're loading a single file, but if your web
266
+ pages all load other files (CSS, JS, media) then that adds up quickly.
267
+ (I can only assume that the developers of shotgun are using caching or a
268
+ front web server so this isn't a pain point for them.)
269
+
270
+ And hey, does Shotgun reload your Worker processes if you're using Foreman and
271
+ a Procfile? I'm pretty sure it doesn't.
272
+
273
+ YMMV!
274
+
275
+ # Why would I use this instead of Rack::Reloader?
276
+
277
+ Rack::Reloader is certifiably beautiful code, and is a very elegant use
278
+ of Rack's middleware architecture. But because it relies on the
279
+ LOADED_FEATURES variable, it only reloads .rb files that were 'require'd,
280
+ not 'load'ed. That leaves out (non-Erector) template files, and also,
281
+ at least the way I was doing it, sub-actions (see
282
+ [this thread](http://groups.google.com/group/sinatrarb/browse_thread/thread/7329727a9296e96a#
283
+ )).
284
+
285
+ Rack::Reloader also doesn't reload configuration changes or redo other
286
+ things that happen during app startup. Rerun takes the attitude that if
287
+ you want to restart an app, you should just restart the whole app. You know?
288
+
289
+ # Why would I use this instead of Guard?
290
+
291
+ Guard is very powerful but requires some up-front configuration.
292
+ Rerun is meant as a no-frills command-line alternative requiring no knowledge
293
+ of Ruby nor config file syntax.
294
+
295
+ # Why did you write this?
296
+
297
+ I've been using [Sinatra](http://sinatrarb.com) and loving it. In order
298
+ to simplify their system, the Rat Pack removed auto-reloading from
299
+ Sinatra proper. I approve of this: a web application framework should be
300
+ focused on serving requests, not on munging Ruby ObjectSpace for
301
+ dev-time convenience. But I still wanted automatic reloading during
302
+ development. Shotgun wasn't working for me (see above) so I spliced
303
+ Rerun together out of code from Rspactor, FileSystemWatcher, and Shotgun
304
+ -- with a heavy amount of refactoring and rewriting. In late 2012 I
305
+ migrated the backend to the Listen gem, which was extracted from Guard,
306
+ so it should be more reliable and performant on multiple platforms.
307
+
308
+ # Credits
309
+
310
+ Rerun: [Alex Chaffee](http://alexchaffee.com), <mailto:alex@stinky.com>, <http://github.com/alexch/>
311
+
312
+ Based upon and/or inspired by:
313
+
314
+ * Shotgun: <http://github.com/rtomayko/shotgun>
315
+ * Rspactor: <http://github.com/mislav/rspactor>
316
+ * (In turn based on http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/ )
317
+ * FileSystemWatcher: <http://paulhorman.com/filesystemwatcher/>
318
+
319
+ ## Patches by:
320
+
321
+ * David Billskog <billskog@gmail.com>
322
+ * Jens B <https://github.com/dpree>
323
+ * Andrés Botero <https://github.com/anbotero>
324
+ * Dreamcat4
325
+ * <https://github.com/FND>
326
+ * Barry Sia <https://github.com/bsia>
327
+ * Paul Rangel <https://github.com/ismell>
328
+ * James Edward Gray II <https://github.com/JEG2>
329
+ * Raul E Rangel <https://github.com/ismell> and Antonio Terceiro <https://github.com/terceiro>
330
+ * Mike Pastore <https://github.com/mwpastore>
331
+ * Andy Duncan <https://github.com/ajduncan>
332
+
333
+ # Version History
334
+
335
+ *
336
+ * `--force-polling` option (thanks ajduncan)
337
+
338
+ * 0.11.0 7 October 2015
339
+ * better 'changed' message
340
+ * `--notify osx` option
341
+ * `--restart` option (with bugfix by Mike Pastore)
342
+ * use Listen 3 gem
343
+ * add `.feature` files to default watchlist (thanks @jmuheim)
344
+
345
+ * v0.10.0 4 May 2014
346
+ * add '.coffee,.slim,.md' to default pattern (thanks @xylinq)
347
+ * --ignore option
348
+
349
+ * v0.9.0 6 March 2014
350
+ * --dir (or -d) can be specified more than once, for multiple directories (thanks again Barry!)
351
+ * --name option
352
+ * press 'p' to pause/unpause filesystem watching (Barry is the man!)
353
+ * works with Listen 2 (note: needs 2.3 or higher)
354
+ * cooldown works, thanks to patches to underlying Listen gem
355
+ * ignore all dotfiles, and add actual list of ignored dirs and files
356
+
357
+ * v0.8.2
358
+ * bugfix, forcing Rerun to use Listen v1.0.3 while we work out the troubles we're having with Listen 1.3 and 2.1
359
+
360
+ * v0.8.1
361
+ * bugfix release (#30 and #34)
362
+
363
+ * v0.8.0
364
+ * --background option (thanks FND!) to disable the keyboard listener
365
+ * --signal option (thanks FND!)
366
+ * --no-growl option
367
+ * --dir supports multiple directories (thanks Barry!)
368
+
369
+ * v0.7.1
370
+ * bugfix: make rails icon work again
371
+
372
+ * v0.7.0
373
+ * uses Listen gem (which uses rb-fsevent for lightweight filesystem snooping)
374
+
375
+ # License
376
+
377
+ Open Source MIT License. See "LICENSE" file.
data/Rakefile ADDED
@@ -0,0 +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
+ 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 ADDED
@@ -0,0 +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)
Binary file
Binary file
data/lib/goo.rb ADDED
@@ -0,0 +1,3 @@
1
+ goooo
2
+ goooo
3
+ goooo
data/lib/rerun/glob.rb ADDED
@@ -0,0 +1,85 @@
1
+ # based on http://cpan.uwinnipeg.ca/htdocs/Text-Glob/Text/Glob.pm.html#glob_to_regex_string-
2
+
3
+ # todo: release as separate gem
4
+ #
5
+ module Rerun
6
+ class Glob
7
+ NO_LEADING_DOT = '(?=[^\.])' # todo
8
+ START_OF_FILENAME = '(\A|\/)' # beginning of string or a slash
9
+ END_OF_STRING = '\z'
10
+
11
+ def initialize glob_string
12
+ @glob_string = glob_string
13
+ end
14
+
15
+ def to_regexp_string
16
+ chars = @glob_string.split('')
17
+
18
+ chars = smoosh(chars)
19
+
20
+ curlies = 0
21
+ escaping = false
22
+ string = chars.map do |char|
23
+ if escaping
24
+ escaping = false
25
+ char
26
+ else
27
+ case char
28
+ when '**'
29
+ "([^/]+/)*"
30
+ when '*'
31
+ ".*"
32
+ when "?"
33
+ "."
34
+ when "."
35
+ "\\."
36
+
37
+ when "{"
38
+ curlies += 1
39
+ "("
40
+ when "}"
41
+ if curlies > 0
42
+ curlies -= 1
43
+ ")"
44
+ else
45
+ char
46
+ end
47
+ when ","
48
+ if curlies > 0
49
+ "|"
50
+ else
51
+ char
52
+ end
53
+ when "\\"
54
+ escaping = true
55
+ "\\"
56
+
57
+ else
58
+ char
59
+
60
+ end
61
+ end
62
+ end.join
63
+ START_OF_FILENAME + string + END_OF_STRING
64
+ end
65
+
66
+ def to_regexp
67
+ Regexp.new(to_regexp_string)
68
+ end
69
+
70
+ def smoosh chars
71
+ out = []
72
+ until chars.empty?
73
+ char = chars.shift
74
+ if char == "*" and chars.first == "*"
75
+ chars.shift
76
+ chars.shift if chars.first == "/"
77
+ out.push("**")
78
+ else
79
+ out.push(char)
80
+ end
81
+ end
82
+ out
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,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
+ return unless mac?
17
+
18
+ # todo: strategy or subclass
19
+
20
+ s = nil
21
+
22
+ if options[:notify] == true or options[:notify] == "growl"
23
+ if (cmd = command_named("growlnotify"))
24
+ # todo: check version of growlnotify and warn if it's too old
25
+ icon_str = ("--image \"#{icon}\"" if icon)
26
+ s = "#{cmd} -n \"#{app_name}\" -m \"#{body}\" \"#{app_name} #{title}\" #{icon_str}"
27
+ end
28
+ end
29
+
30
+ if s.nil? and options[:notify] == true or options[:notify] == "osx"
31
+ if (cmd = command_named("terminal-notifier"))
32
+ icon_str = ("-appIcon \"#{icon}\"" if icon)
33
+ s = "#{cmd} -title \"#{app_name}\" -message \"#{body}\" \"#{app_name} #{title}\" #{icon_str}"
34
+ end
35
+ end
36
+
37
+ s
38
+ end
39
+
40
+ def command_named(name)
41
+ path = `which #{name}`.chomp
42
+ path.empty? ? nil : path
43
+ end
44
+
45
+ def send(background = true)
46
+ return unless command
47
+ `#{command}#{" &" if background}`
48
+ end
49
+
50
+ def app_name
51
+ options[:name]
52
+ end
53
+
54
+ def icon
55
+ "#{icon_dir}/rails_red_sml.png" if rails?
56
+ end
57
+
58
+ def icon_dir
59
+ here = File.expand_path(File.dirname(__FILE__))
60
+ File.expand_path("#{here}/../../icons")
61
+ end
62
+
63
+ end
64
+ end