rerun 0.6.6 → 0.7.0.pre1
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.
- data/README.md +8 -3
- data/Rakefile +2 -1
- data/lib/rerun.rb +4 -5
- data/lib/rerun/glob.rb +62 -0
- data/lib/rerun/runner.rb +9 -9
- data/lib/rerun/system.rb +1 -0
- data/lib/rerun/watcher.rb +18 -2
- data/rerun.gemspec +5 -9
- metadata +25 -10
- data/lib/rerun/fswatcher.rb +0 -6
- data/lib/rerun/osxwatcher.rb +0 -95
data/README.md
CHANGED
@@ -102,9 +102,9 @@ Download [growlnotify here](http://growl.info/downloads.php#generaldownloads) no
|
|
102
102
|
|
103
103
|
While the app is (re)running, you can make things happen by pressing keys:
|
104
104
|
|
105
|
-
* **r** restart (as if a file had changed)
|
106
|
-
* **c** clear the screen
|
107
|
-
* **x** exit (just like control-C)
|
105
|
+
* **r** -- restart (as if a file had changed)
|
106
|
+
* **c** -- clear the screen
|
107
|
+
* **x** or **q** -- exit (just like control-C)
|
108
108
|
|
109
109
|
# To Do:
|
110
110
|
|
@@ -198,6 +198,11 @@ Based upon and/or inspired by:
|
|
198
198
|
* Andrés Botero <https://github.com/anbotero>
|
199
199
|
* Dreamcat4
|
200
200
|
|
201
|
+
# Version History
|
202
|
+
|
203
|
+
* v0.7.0
|
204
|
+
* uses Listen gem
|
205
|
+
|
201
206
|
# License
|
202
207
|
|
203
208
|
Open Source MIT License. See "LICENSE" file.
|
data/Rakefile
CHANGED
data/lib/rerun.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
here = File.expand_path(File.dirname(__FILE__))
|
2
2
|
$: << here unless $:.include?(here)
|
3
3
|
|
4
|
+
require "listen" # pull in the Listen gem
|
4
5
|
require "rerun/system"
|
5
6
|
require "rerun/runner"
|
6
7
|
require "rerun/watcher"
|
7
|
-
require "rerun/
|
8
|
-
require "rerun/fswatcher"
|
8
|
+
require "rerun/glob"
|
9
9
|
|
10
|
-
# todo: make sure this works in non-Mac environments (also Macs without growlnotify)
|
11
10
|
module Rerun
|
12
|
-
|
11
|
+
|
13
12
|
DEFAULT_PATTERN = "**/*.{rb,js,css,scss,sass,erb,html,haml,ru}"
|
14
13
|
|
15
|
-
end
|
14
|
+
end
|
16
15
|
|
data/lib/rerun/glob.rb
ADDED
@@ -0,0 +1,62 @@
|
|
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
|
+
|
9
|
+
def initialize glob_string
|
10
|
+
@glob_string = glob_string
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_regexp_string
|
14
|
+
chars = @glob_string.split('')
|
15
|
+
curlies = 0;
|
16
|
+
escaping = false;
|
17
|
+
chars.map do |char|
|
18
|
+
if escaping
|
19
|
+
escaping = false
|
20
|
+
char
|
21
|
+
else
|
22
|
+
case char
|
23
|
+
when '*'
|
24
|
+
".*"
|
25
|
+
when "?"
|
26
|
+
"."
|
27
|
+
when "."
|
28
|
+
"\\."
|
29
|
+
|
30
|
+
when "{"
|
31
|
+
curlies += 1
|
32
|
+
"("
|
33
|
+
when "}"
|
34
|
+
if curlies > 0
|
35
|
+
curlies -= 1
|
36
|
+
")"
|
37
|
+
else
|
38
|
+
char
|
39
|
+
end
|
40
|
+
when ","
|
41
|
+
if curlies > 0
|
42
|
+
"|"
|
43
|
+
else
|
44
|
+
char
|
45
|
+
end
|
46
|
+
when "\\"
|
47
|
+
escaping = true
|
48
|
+
"\\"
|
49
|
+
|
50
|
+
else
|
51
|
+
char
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end.join
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_regexp
|
59
|
+
Regexp.new(to_regexp_string)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/rerun/runner.rb
CHANGED
@@ -23,22 +23,22 @@ module Rerun
|
|
23
23
|
# puts "starting keypress thread #{Thread.current.object_id} from #{from}"
|
24
24
|
while true
|
25
25
|
if c = key_pressed
|
26
|
-
puts "\n#{c.inspect} pressed inside rerun"
|
27
26
|
case c.downcase
|
28
27
|
when 'c'
|
29
|
-
say "
|
28
|
+
say "Clearing screen"
|
30
29
|
clear_screen
|
31
30
|
when 'r'
|
32
|
-
say "
|
31
|
+
say "Restarting"
|
33
32
|
restart
|
34
33
|
break # the break will stop this thread
|
35
|
-
when 'x'
|
34
|
+
when 'x', 'q'
|
36
35
|
die
|
37
36
|
break # the break will stop this thread, in case the 'die' doesn't
|
38
37
|
else
|
38
|
+
puts "\n#{c.inspect} pressed inside rerun"
|
39
39
|
puts [["c", "clear screen"],
|
40
40
|
["r", "restart"],
|
41
|
-
["x", "stop and exit"]
|
41
|
+
["x or q", "stop and exit"]
|
42
42
|
].map{|key, description| " #{key} -- #{description}"}.join("\n")
|
43
43
|
puts
|
44
44
|
end
|
@@ -144,8 +144,8 @@ module Rerun
|
|
144
144
|
end
|
145
145
|
|
146
146
|
unless @watcher
|
147
|
-
watcher_class = osx_foundation? ? OSXWatcher : FSWatcher
|
148
|
-
|
147
|
+
#watcher_class = osx_foundation? ? OSXWatcher : FSWatcher
|
148
|
+
watcher_class = Watcher
|
149
149
|
|
150
150
|
watcher = watcher_class.new do
|
151
151
|
restart unless @restarting
|
@@ -172,7 +172,7 @@ module Rerun
|
|
172
172
|
end
|
173
173
|
|
174
174
|
def signal(signal)
|
175
|
-
say "Sending #{signal}"
|
175
|
+
say "Sending #{signal} to #{@pid}" unless signal == 0
|
176
176
|
Process.kill(signal, @pid)
|
177
177
|
true
|
178
178
|
rescue
|
@@ -221,7 +221,7 @@ module Rerun
|
|
221
221
|
end
|
222
222
|
|
223
223
|
def say msg
|
224
|
-
puts "#{Time.now.strftime("%T")}
|
224
|
+
puts "#{Time.now.strftime("%T")} [rerun] #{msg}"
|
225
225
|
end
|
226
226
|
|
227
227
|
# non-blocking stdin reader.
|
data/lib/rerun/system.rb
CHANGED
data/lib/rerun/watcher.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'listen'
|
2
|
+
|
3
|
+
require "wrong"
|
4
|
+
include Wrong::D
|
5
|
+
|
1
6
|
|
2
7
|
Thread.abort_on_exception = true
|
3
8
|
|
@@ -74,16 +79,25 @@ module Rerun
|
|
74
79
|
prime
|
75
80
|
|
76
81
|
@thread = Thread.new do
|
77
|
-
|
82
|
+
# todo: multiple dirs
|
83
|
+
# todo: convert each dir's pattern to a regex and get Listen to do the file scan for us
|
84
|
+
@listener = Listen::Listener.new(@directories.first.dir) do |modified, added, removed|
|
85
|
+
#d { modified }
|
86
|
+
#d { added }
|
87
|
+
#d { removed }
|
78
88
|
examine
|
79
89
|
sleep(@sleep_time)
|
80
90
|
end
|
91
|
+
@listener.start
|
81
92
|
end
|
82
93
|
|
83
94
|
@thread.priority = @priority
|
84
95
|
|
85
96
|
at_exit { stop } #?
|
86
97
|
|
98
|
+
sleep 1 until @listener.instance_variable_get(:@adapter)
|
99
|
+
puts "Using adapter #{@listener.instance_variable_get(:@adapter)}"
|
100
|
+
|
87
101
|
end
|
88
102
|
|
89
103
|
# kill the filewatcher thread
|
@@ -110,6 +124,7 @@ module Rerun
|
|
110
124
|
private
|
111
125
|
|
112
126
|
def examine
|
127
|
+
|
113
128
|
already_examined = Hash.new()
|
114
129
|
|
115
130
|
@directories.each do |directory|
|
@@ -123,6 +138,7 @@ module Rerun
|
|
123
138
|
all_found_files = @found.keys()
|
124
139
|
all_examined_files = already_examined.keys()
|
125
140
|
intersection = all_found_files - all_examined_files
|
141
|
+
|
126
142
|
intersection.each do |file_name|
|
127
143
|
@client_callback.call(DELETED, file_name)
|
128
144
|
@found.delete(file_name)
|
@@ -171,7 +187,7 @@ module Rerun
|
|
171
187
|
@dir.chop! if @dir =~ %r{/$}
|
172
188
|
end
|
173
189
|
|
174
|
-
def files
|
190
|
+
def files
|
175
191
|
return Dir["#{@dir}/#{@expression}"]
|
176
192
|
end
|
177
193
|
end
|
data/rerun.gemspec
CHANGED
@@ -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.
|
6
|
+
s.version = '0.7.0.pre1'
|
7
7
|
|
8
8
|
s.description = "Restarts your app when a file changes"
|
9
9
|
s.summary = "Launches an app, and restarts it whenever the filesystem changes."
|
@@ -18,18 +18,14 @@ $spec = Gem::Specification.new do |s|
|
|
18
18
|
rerun.gemspec
|
19
19
|
bin/rerun
|
20
20
|
icons/rails_grn_sml.png
|
21
|
-
icons/rails_red_sml.png
|
22
|
-
|
23
|
-
lib/rerun/fswatcher.rb
|
24
|
-
lib/rerun/osxwatcher.rb
|
25
|
-
lib/rerun/runner.rb
|
26
|
-
lib/rerun/system.rb
|
27
|
-
lib/rerun/watcher.rb
|
28
|
-
]
|
21
|
+
icons/rails_red_sml.png] +
|
22
|
+
Dir['lib/**/*.rb']
|
29
23
|
s.executables = ['rerun']
|
30
24
|
s.test_files = s.files.select {|path| path =~ /^spec\/.*_spec.rb/}
|
31
25
|
|
32
26
|
s.extra_rdoc_files = %w[README.md]
|
27
|
+
|
28
|
+
s.add_dependency 'listen'
|
33
29
|
#s.add_dependency 'rack', '>= 0.9.1'
|
34
30
|
#s.add_dependency 'launchy', '>= 0.3.3', '< 1.0'
|
35
31
|
|
metadata
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rerun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.7.0.pre1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Alex Chaffee
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
13
|
-
dependencies:
|
12
|
+
date: 2012-06-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: listen
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
description: Restarts your app when a file changes
|
15
31
|
email: alex@stinky.com
|
16
32
|
executables:
|
@@ -26,12 +42,11 @@ files:
|
|
26
42
|
- bin/rerun
|
27
43
|
- icons/rails_grn_sml.png
|
28
44
|
- icons/rails_red_sml.png
|
29
|
-
- lib/rerun.rb
|
30
|
-
- lib/rerun/fswatcher.rb
|
31
|
-
- lib/rerun/osxwatcher.rb
|
45
|
+
- lib/rerun/glob.rb
|
32
46
|
- lib/rerun/runner.rb
|
33
47
|
- lib/rerun/system.rb
|
34
48
|
- lib/rerun/watcher.rb
|
49
|
+
- lib/rerun.rb
|
35
50
|
homepage: http://github.com/alexch/rerun/
|
36
51
|
licenses: []
|
37
52
|
post_install_message:
|
@@ -46,13 +61,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
46
61
|
version: '0'
|
47
62
|
segments:
|
48
63
|
- 0
|
49
|
-
hash:
|
64
|
+
hash: 2427048464234025513
|
50
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
66
|
none: false
|
52
67
|
requirements:
|
53
|
-
- - ! '
|
68
|
+
- - ! '>'
|
54
69
|
- !ruby/object:Gem::Version
|
55
|
-
version:
|
70
|
+
version: 1.3.1
|
56
71
|
requirements: []
|
57
72
|
rubyforge_project: pivotalrb
|
58
73
|
rubygems_version: 1.8.21
|
data/lib/rerun/fswatcher.rb
DELETED
data/lib/rerun/osxwatcher.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require "rerun/system"
|
2
|
-
require "rerun/watcher"
|
3
|
-
|
4
|
-
#TODO: make it notice deleted files natively, rather than passing to 'examine'
|
5
|
-
#TODO: use http://github.com/spicycode/fsevent
|
6
|
-
module Rerun
|
7
|
-
class OSXWatcher < Rerun::Watcher
|
8
|
-
attr_reader :last_check, :valid_extensions
|
9
|
-
attr_reader :stream
|
10
|
-
|
11
|
-
def start
|
12
|
-
prime
|
13
|
-
timestamp_checked
|
14
|
-
|
15
|
-
dirs = Array(directories.map{|d| d.dir})
|
16
|
-
|
17
|
-
mac_callback = lambda do |stream, ctx, num_events, paths, marks, event_ids|
|
18
|
-
examine
|
19
|
-
# changed_files = extract_changed_files_from_paths(split_paths(paths, num_events))
|
20
|
-
# timestamp_checked
|
21
|
-
# puts "changed files:"
|
22
|
-
# p changed_files
|
23
|
-
# yield changed_files unless changed_files.empty?
|
24
|
-
end
|
25
|
-
|
26
|
-
@stream = OSX::FSEventStreamCreate(OSX::KCFAllocatorDefault, mac_callback, nil, dirs, OSX::KFSEventStreamEventIdSinceNow, @sleep_time, 0)
|
27
|
-
raise "Failed to create stream" unless stream
|
28
|
-
|
29
|
-
OSX::FSEventStreamScheduleWithRunLoop(stream, OSX::CFRunLoopGetCurrent(), OSX::KCFRunLoopDefaultMode)
|
30
|
-
unless OSX::FSEventStreamStart(stream)
|
31
|
-
raise "Failed to start stream"
|
32
|
-
end
|
33
|
-
|
34
|
-
@thread = Thread.new do
|
35
|
-
begin
|
36
|
-
OSX::CFRunLoopRun()
|
37
|
-
rescue Interrupt
|
38
|
-
OSX::FSEventStreamStop(stream)
|
39
|
-
OSX::FSEventStreamInvalidate(stream)
|
40
|
-
OSX::FSEventStreamRelease(stream)
|
41
|
-
@stream = nil
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
@thread.priority = @priority
|
46
|
-
end
|
47
|
-
|
48
|
-
def stop
|
49
|
-
@thread.kill
|
50
|
-
end
|
51
|
-
|
52
|
-
def timestamp_checked
|
53
|
-
@last_check = Time.now
|
54
|
-
end
|
55
|
-
|
56
|
-
def split_paths(paths, num_events)
|
57
|
-
paths.regard_as('*')
|
58
|
-
rpaths = []
|
59
|
-
num_events.times { |i| rpaths << paths[i] }
|
60
|
-
rpaths
|
61
|
-
end
|
62
|
-
|
63
|
-
def extract_changed_files_from_paths(paths)
|
64
|
-
changed_files = []
|
65
|
-
paths.each do |path|
|
66
|
-
next if ignore_path?(path)
|
67
|
-
Dir.glob(path + "*").each do |file|
|
68
|
-
next if ignore_file?(file)
|
69
|
-
changed_files << file if file_changed?(file)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
changed_files
|
73
|
-
end
|
74
|
-
|
75
|
-
def file_changed?(file)
|
76
|
-
File.stat(file).mtime > last_check
|
77
|
-
end
|
78
|
-
|
79
|
-
def ignore_path?(path)
|
80
|
-
path =~ /(?:^|\/)\.(git|svn)/
|
81
|
-
end
|
82
|
-
|
83
|
-
def ignore_file?(file)
|
84
|
-
File.basename(file).index('.') == 0 or not valid_extension?(file)
|
85
|
-
end
|
86
|
-
|
87
|
-
def file_extension(file)
|
88
|
-
file =~ /\.(\w+)$/ and $1
|
89
|
-
end
|
90
|
-
|
91
|
-
def valid_extension?(file)
|
92
|
-
valid_extensions.nil? or valid_extensions.include?(file_extension(file))
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|