rerun 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5186659055558e298a987ddc358c03fb2ca23dc
4
- data.tar.gz: 93afa739db65f198c20d09520efcfa6e08800e06
3
+ metadata.gz: a237bdcfe8672bdd765c6a480fbd397e30f0fc45
4
+ data.tar.gz: 46a4241842ffad57cfdb560bf2b7da0088f35c47
5
5
  SHA512:
6
- metadata.gz: 60e098c424e134c5456c0ed871f62224bb2fe33f93aed659e554a55729b56f2cdd06a4c910a5f6a498c8d1a131d67e82861a0acfdcca874cb0799031eacd289a
7
- data.tar.gz: 5f0fbd5006a6bae73e8ac6104ec6d4c7648ee79baf9c3ba01b14e6ed544386922b6472e3d3fec9e852dea6f4857449673b3b7a93ac7ce4798ef697748b8ac5fa
6
+ metadata.gz: 3abd42a820c468ae5c5ac50095a888106967e0c64dfe4bdb4c8aca3adef2ce84e85262278a7c9c5382a276437c359de5f875b578da7624c001b2b0d4d7c5d458
7
+ data.tar.gz: 20964c0461cb634bbe11ea931b2eb25d740e4dd228c6a6e8ab18cdf6e2a368376b8e47c3614a073385323856d0ad6238db5031cfb3fbc732415c7fce5d4f9f38
data/README.md CHANGED
@@ -14,7 +14,7 @@ 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 only `*.{rb,js,css,coffee,scss,sass,erb,html,haml,ru,slim,md}` files are watched.
17
+ By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature`.
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
@@ -116,7 +116,7 @@ Procfile processes locally and restart them all when necessary.
116
116
  `--dir` directory (or directories) to watch (default = "."). Separate multiple paths with ',' and/or use multiple `-d` options.
117
117
 
118
118
  `--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,css,coffee,scss,sass,erb,html,haml,ru,slim,md`.
119
+ By default it watches files ending in: `rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature`.
120
120
  On top of this, it also ignores dotfiles, `.tmp` files, and some other files and directories (like `.git` and `log`).
121
121
  Run `rerun --help` to see the actual list.
122
122
 
@@ -125,31 +125,44 @@ Run `rerun --help` to see the actual list.
125
125
 
126
126
  *On top of --pattern and --ignore, we ignore any changes to files and dirs starting with a dot.*
127
127
 
128
- `--signal` (or -s) use specified signal (instead of the default SIGTERM) to terminate the previous process.
128
+ `--signal` (or `-s`) use specified signal (instead of the default SIGTERM) to terminate the previous process.
129
129
  This may be useful for forcing the respective process to terminate as quickly as possible.
130
130
  (`--signal KILL` is the equivalent of `kill -9`)
131
131
 
132
+ `--restart` (or `-r`) expect process to restart itself, using signal HUP by default
133
+ (e.g. `-r -s INT` will send a INT and then resume watching for changes)
134
+
132
135
  `--clear` (or -c) clear the screen before each run
133
136
 
134
137
  `--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.
135
138
 
136
139
  `--background` (or -b) disable on-the-fly commands, allowing the process to be backgrounded
137
140
 
138
- `--no-growl` don't use growl
141
+ `--notify NOTIFIER` use `growl` or `osx` for notifications (see below)
142
+
143
+ `--no-notify` don't use growl (or osx) notifications
139
144
 
140
145
  `--name` set the app name (for display)
141
146
 
142
147
  Also `--version` and `--help`, naturally.
143
148
 
144
- # Growl Notifications
149
+ # Notifications
145
150
 
146
151
  If you have `growlnotify` available on the `PATH`, it sends notifications to
147
- growl in addition to the console. If you have growl but don't want rerun to use it,
148
- set the `--no-growl` option.
152
+ growl in addition to the console.
153
+ If you have `terminal-notifier`, it sends notifications to
154
+ the OS X notification center in addition to the console.
155
+
156
+ If you have both, Rerun will pick one, or you can choose between them using `--notify growl` or `--notify osx` respectively.
157
+
158
+ If you have a notifier installed but don't want rerun to use it,
159
+ set the `--no-notify` option.
149
160
 
150
161
  Download [growlnotify here](http://growl.info/downloads.php#generaldownloads)
151
162
  now that Growl has moved to the App Store.
152
163
 
164
+ 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
+
153
166
  # On-The-Fly Commands
154
167
 
155
168
  While the app is (re)running, you can make things happen by pressing keys:
@@ -174,6 +187,21 @@ This seems like the most gentle and unixy way of doing things, but it does
174
187
  mean that if your program ignores SIGTERM, it takes an extra 4 to 6 seconds to
175
188
  restart.
176
189
 
190
+ # Troubleshooting
191
+ If you are using `zsh` as your shell, and you are specifying your `--pattern` as `**/*.rb`, you may face this error
192
+ ```
193
+ Errno::EACCES: Permission denied - <filename>
194
+ ```
195
+ 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.
196
+ i.e
197
+ ```
198
+ rerun -p **/*.rb rake test
199
+ ```
200
+ becomes
201
+ ```
202
+ rerun -p "**/*.rb" rake test
203
+ ```
204
+
177
205
  # To Do:
178
206
 
179
207
  ## Must have for v1.0
@@ -186,6 +214,7 @@ restart.
186
214
  * If the last element of the command is a `.ru` file and there's no other command then use `rackup`
187
215
  * Figure out an algorithm so "-x" is not needed (if possible) -- maybe by accepting a "--port" option or reading `config.ru`
188
216
  * Specify (or deduce) port to listen for to determine success of a web server launch
217
+ * see also [todo.md](todo.md)
189
218
 
190
219
  ## Wacky Ideas
191
220
  * Make it work on Windows, like Guard now does. See
@@ -289,9 +318,19 @@ Based upon and/or inspired by:
289
318
  * <https://github.com/FND>
290
319
  * Barry Sia <https://github.com/bsia>
291
320
  * Paul Rangel <https://github.com/ismell>
321
+ * James Edward Gray II <https://github.com/JEG2>
322
+ * Raul E Rangel <https://github.com/ismell> and Antonio Terceiro <https://github.com/terceiro>
323
+ * Mike Pastore <https://github.com/mwpastore>
292
324
 
293
325
  # Version History
294
326
 
327
+ * 0.11.0 7 October 2015
328
+ * better 'changed' message
329
+ * `--notify osx` option
330
+ * `--restart` option (with bugfix by Mike Pastore)
331
+ * use Listen 3 gem
332
+ * add `.feature` files to default watchlist (thanks @jmuheim)
333
+
295
334
  * v0.10.0 4 May 2014
296
335
  * add '.coffee,.slim,.md' to default pattern (thanks @xylinq)
297
336
  * --ignore option
data/Rakefile CHANGED
@@ -73,3 +73,10 @@ task 'release' => [:check_git, package('.gem'), package('.tar.gz')] do |t|
73
73
  sh "git tag v#{$spec.version}"
74
74
  sh "git push && git push --tags"
75
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
@@ -4,6 +4,7 @@ $: << here unless $:.include?(here)
4
4
  require "listen" # pull in the Listen gem
5
5
  require "rerun/options"
6
6
  require "rerun/system"
7
+ require "rerun/notification"
7
8
  require "rerun/runner"
8
9
  require "rerun/watcher"
9
10
  require "rerun/glob"
@@ -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
@@ -8,19 +8,25 @@ $spec = Gem::Specification.load(File.join(libdir, "..", "rerun.gemspec"))
8
8
 
9
9
  module Rerun
10
10
  class Options
11
- DEFAULT_PATTERN = "**/*.{rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md}"
11
+ DEFAULT_PATTERN = "**/*.{rb,js,coffee,css,scss,sass,erb,html,haml,ru,yml,slim,md,feature}"
12
12
  DEFAULT_DIRS = ["."]
13
13
 
14
14
  DEFAULTS = {
15
15
  :pattern => DEFAULT_PATTERN,
16
16
  :signal => "TERM",
17
- :growl => true,
17
+ :notify => true,
18
18
  :name => Pathname.getwd.basename.to_s.capitalize,
19
- :ignore => []
19
+ :ignore => [],
20
+ :dir => DEFAULT_DIRS
20
21
  }
21
22
 
22
23
  def self.parse args = ARGV
23
- options = DEFAULTS.dup
24
+
25
+ default_options = DEFAULTS.dup
26
+ options = {
27
+ ignore: []
28
+ }
29
+
24
30
  opts = OptionParser.new("", 24, ' ') do |opts|
25
31
  opts.banner = "Usage: rerun [options] [--] cmd"
26
32
 
@@ -49,6 +55,11 @@ module Rerun
49
55
  options[:signal] = signal
50
56
  end
51
57
 
58
+ opts.on("-r", "--restart", "expect process to restart itself (uses the HUP signal unless overridden using --signal)") do |signal|
59
+ options[:restart] = true
60
+ default_options[:signal] = "HUP"
61
+ end
62
+
52
63
  opts.on("-c", "--clear", "clear screen before each run") do
53
64
  options[:clear] = true
54
65
  end
@@ -65,8 +76,15 @@ module Rerun
65
76
  options[:name] = name
66
77
  end
67
78
 
68
- opts.on("--no-growl", "don't use growl") do
79
+ opts.on("--no-growl", "don't use growl [OBSOLETE]") do
69
80
  options[:growl] = false
81
+ $stderr.puts "--no-growl is obsolete; use --no-notify instead"
82
+ return
83
+ end
84
+
85
+ opts.on("--[no-]notify [notifier]", "send messages through growl (requires growlnotify) or osx (requires terminal-notifier gem)") do |notifier|
86
+ notifier = true if notifier.nil?
87
+ options[:notify] = notifier
70
88
  end
71
89
 
72
90
  opts.on_tail("-h", "--help", "--usage", "show this message") do
@@ -89,8 +107,10 @@ module Rerun
89
107
  nil
90
108
  else
91
109
  opts.parse! args
92
- options[:cmd] = args.join(" ")
93
- options[:dir] ||= DEFAULT_DIRS
110
+ default_options[:cmd] = args.join(" ")
111
+
112
+ options = default_options.merge(options)
113
+
94
114
  options
95
115
  end
96
116
  end
@@ -60,8 +60,12 @@ module Rerun
60
60
 
61
61
  def restart
62
62
  @restarting = true
63
- stop
64
- start
63
+ if @options[:restart]
64
+ restart_with_signal(@options[:signal])
65
+ else
66
+ stop
67
+ start
68
+ end
65
69
  @restarting = false
66
70
  end
67
71
 
@@ -75,7 +79,7 @@ module Rerun
75
79
  @watcher.pause
76
80
  @pausing = true
77
81
  else
78
- say "Resuming"
82
+ say "Resuming."
79
83
  @watcher.unpause
80
84
  @pausing = false
81
85
  end
@@ -113,19 +117,19 @@ module Rerun
113
117
  @options[:name]
114
118
  end
115
119
 
120
+ def restart_with_signal(restart_signal)
121
+ if @pid && (@pid != 0)
122
+ notify "restarting", "We will be with you shortly."
123
+ signal(restart_signal)
124
+ end
125
+ end
126
+
116
127
  def start
117
128
  if windows?
118
129
  raise "Sorry, Rerun does not work on Windows."
119
130
  end
120
131
 
121
- if (!@already_running)
122
- taglines = [
123
- "To infinity... and beyond!",
124
- "Charge!",
125
- ]
126
- notify "launched", taglines[rand(taglines.size)]
127
- @already_running = true
128
- else
132
+ if @already_running
129
133
  taglines = [
130
134
  "Here we go again!",
131
135
  "Keep on trucking.",
@@ -133,6 +137,13 @@ module Rerun
133
137
  "The road goes ever on and on, down from the door where it began.",
134
138
  ]
135
139
  notify "restarted", taglines[rand(taglines.size)]
140
+ else
141
+ taglines = [
142
+ "To infinity... and beyond!",
143
+ "Charge!",
144
+ ]
145
+ notify "launched", taglines[rand(taglines.size)]
146
+ @already_running = true
136
147
  end
137
148
 
138
149
  clear_screen if clear?
@@ -181,21 +192,35 @@ module Rerun
181
192
 
182
193
  watcher = Watcher.new(:directory => dirs, :pattern => pattern, :ignore => ignore) do |changes|
183
194
 
184
- message = [:modified, :added, :removed].map do |change|
185
- count = changes[change].size
186
- if count and count > 0
187
- "#{count} #{change}"
188
- end
189
- end.compact.join(", ")
195
+ message = change_message(changes)
196
+
190
197
  say "Change detected: #{message}"
191
198
  restart unless @restarting
192
199
  end
193
200
  watcher.start
194
201
  @watcher = watcher
195
202
  say "Watching #{dir.join(', ')} for #{pattern}" +
196
- (ignore.empty? ? "" : " (ignoring #{ignore.join(',')})") +
197
- " using #{watcher.adapter.class.name.split('::').last} adapter"
203
+ (ignore.empty? ? "" : " (ignoring #{ignore.join(',')})")
204
+ end
205
+ end
206
+
207
+ def change_message(changes)
208
+ message = [:modified, :added, :removed].map do |change|
209
+ count = changes[change] ? changes[change].size : 0
210
+ if count > 0
211
+ "#{count} #{change}"
212
+ end
213
+ end.compact.join(", ")
214
+
215
+ changed_files = changes.values.flatten
216
+ if changed_files.count > 0
217
+ message += ": "
218
+ message += changes.values.flatten[0..3].map { |path| path.split('/').last }.join(', ')
219
+ if changed_files.count > 3
220
+ message += ", ..."
221
+ end
198
222
  end
223
+ message
199
224
  end
200
225
 
201
226
  def die
@@ -257,8 +282,8 @@ module Rerun
257
282
  @git_head = File.exists?(git_head_file) && File.read(git_head_file)
258
283
  end
259
284
 
260
- def notify(title, body)
261
- growl title, body if @options[:growl]
285
+ def notify(title, body, background = true)
286
+ Notification.new(title, body, @options).send(background) if @options[:notify]
262
287
  puts
263
288
  say "#{app_name} #{title}"
264
289
  end
@@ -13,31 +13,9 @@ module Rerun
13
13
  RUBY_PLATFORM =~ /linux/i
14
14
  end
15
15
 
16
- # do we have growl or not?
17
- def growl_available?
18
- mac? && (growlcmd != "")
19
- end
20
-
21
- def growlcmd
22
- growlnotify = `which growlnotify`.chomp
23
- # todo: check version of growlnotify and warn if it's too old
24
- growlnotify
25
- end
26
-
27
- def icon
28
- here = File.expand_path(File.dirname(__FILE__))
29
- icondir = File.expand_path("#{here}/../../icons")
16
+ def rails?
30
17
  rails_sig_file = File.expand_path(".")+"/config/boot.rb"
31
- "#{icondir}/rails_red_sml.png" if File.exists? rails_sig_file
32
- end
33
-
34
- def growl(title, body, background = true)
35
- if growl_available?
36
- icon_str = ("--image \"#{icon}\"" if icon)
37
- s = "#{growlcmd} -n \"#{app_name}\" -m \"#{body}\" \"#{app_name} #{title}\" #{icon_str}"
38
- s += " &" if background
39
- `#{s}`
40
- end
18
+ File.exists? rails_sig_file
41
19
  end
42
20
 
43
21
  end
@@ -85,13 +85,6 @@ module Rerun
85
85
  [dotfiles] + @ignore.map { |x| Rerun::Glob.new(x).to_regexp }
86
86
  end
87
87
 
88
- def adapter
89
- @listener.registry[:adapter] || (timeout(4) do
90
- sleep 1 until adapter = @listener.registry[:adapter]
91
- adapter
92
- end)
93
- end
94
-
95
88
  # kill the file watcher thread
96
89
  def stop
97
90
  @thread.wakeup rescue ThreadError
@@ -115,11 +108,11 @@ module Rerun
115
108
  end
116
109
 
117
110
  def unpause
118
- @listener.unpause if @listener
111
+ @listener.start if @listener
119
112
  end
120
113
 
121
114
  def running?
122
- @listener && @listener.instance_variable_get(:@adapter)
115
+ @listener && @listener.processing?
123
116
  end
124
117
 
125
118
  end
@@ -3,7 +3,7 @@ $spec = Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'rerun'
6
- s.version = '0.10.0'
6
+ s.version = '0.11.0'
7
7
 
8
8
  s.description = "Restarts your app when a file changes. A no-frills, command-line alternative to Guard, Shotgun, Autotest, etc."
9
9
  s.summary = "Launches an app, and restarts it whenever the filesystem changes. A no-frills, command-line alternative to Guard, Shotgun, Autotest, etc."
@@ -25,7 +25,7 @@ $spec = Gem::Specification.new do |s|
25
25
 
26
26
  s.extra_rdoc_files = %w[README.md]
27
27
 
28
- s.add_runtime_dependency 'listen', '~> 2.7', '>= 2.7.3'
28
+ s.add_runtime_dependency 'listen', '~> 3.0'
29
29
 
30
30
  s.homepage = "http://github.com/alexch/rerun/"
31
31
  s.require_paths = %w[lib]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rerun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Chaffee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-05 00:00:00.000000000 Z
11
+ date: 2015-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: listen
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.7'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 2.7.3
19
+ version: '3.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '2.7'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 2.7.3
26
+ version: '3.0'
33
27
  description: Restarts your app when a file changes. A no-frills, command-line alternative
34
28
  to Guard, Shotgun, Autotest, etc.
35
29
  email: alex@stinky.com
@@ -47,6 +41,7 @@ files:
47
41
  - icons/rails_red_sml.png
48
42
  - lib/rerun.rb
49
43
  - lib/rerun/glob.rb
44
+ - lib/rerun/notification.rb
50
45
  - lib/rerun/options.rb
51
46
  - lib/rerun/runner.rb
52
47
  - lib/rerun/system.rb
@@ -72,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
67
  version: '0'
73
68
  requirements: []
74
69
  rubyforge_project:
75
- rubygems_version: 2.2.2
70
+ rubygems_version: 2.4.8
76
71
  signing_key:
77
72
  specification_version: 2
78
73
  summary: Launches an app, and restarts it whenever the filesystem changes. A no-frills,