poll-rerun 0.11.1

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 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