filewatcher 0.5.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile DELETED
@@ -1,19 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'rake/testtask'
4
-
5
- task :default => :test
6
-
7
- desc "Run tests"
8
- task :test do
9
- sh "bacon -Ilib -Itest --automatic --quiet"
10
- delete_list =
11
- %w(test/fixtures/file3.txt
12
- test/fixtures/file4.txt
13
- test/fixtures/file5.txt
14
- test/fixtures/file6.txt
15
- test/fixtures/file7.txt)
16
- delete_list.each do |file|
17
- FileUtils.rm(file)
18
- end
19
- end
@@ -1,168 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'filewatcher'
4
- require 'trollop'
5
- require 'pathname'
6
- require 'thread'
7
-
8
- options = Trollop::options do
9
- version "filewatcher, version #{FileWatcher.VERSION} by Thomas Flemming 2016"
10
- banner <<-EOS
11
- Filewatcher scans the filesystem and executes shell commands when files changes.
12
-
13
- Usage:
14
- filewatcher [--restart] '<filenames or patterns>' '<shell command>'
15
- Where
16
- filename: filename(s) to scan.
17
- shell command: shell command to execute when file changes on disk.
18
-
19
- Examples:
20
- filewatcher "myfile" "echo 'myfile has changed'"
21
- filewatcher '*.rb' 'ruby $FILENAME'
22
- filewatcher '**/*.rb' 'ruby $FILENAME' # Watch subdirectories
23
-
24
- Other available environment variables are BASENAME, ABSOLUTE_FILENAME,
25
- RELATIVE_FILENAME, EVENT and DIRNAME.
26
-
27
- Options:
28
- EOS
29
-
30
- opt :dontwait, "Do not wait for filesystem updates before running", :short => 'd', :type => :boolean, :default => false
31
- opt :daemon, "Run in the background as system daemon.", :short => 'D', :type => :boolean, :default => false
32
- opt :restart, "Restart process when filesystem is updated", :short => 'r', :type => :boolean, :default => false
33
- opt :list, "Print name of files being watched"
34
- opt :exec, "Execute file as a script when file is updated.", :short => 'e', :type => :boolean, :default => false
35
- opt :include, "Include files", :type => :string, :default => "*"
36
- opt :exclude, "Exclude file(s) matching", :type => :string, :default => ""
37
- opt :interval, "Interval to scan filesystem.", :short => 'i', :type => :float, :default => 0.5
38
- opt :spinner, "Show an ascii spinner", :short => 's', :type => :boolean, :default => false
39
- end
40
-
41
- Trollop::die Trollop::educate if(ARGV.size == 0)
42
-
43
- files = []
44
- ARGV[0...-1].each do |a|
45
- files << a
46
- end
47
-
48
- if(ARGV.length == 1)
49
- files << ARGV[0]
50
- end
51
-
52
- def split_files_void_escaped_whitespace(files)
53
- splitted_filenames = []
54
- files.each do |name|
55
- name = name.gsub(/\\\s/,'_ESCAPED_WHITESPACE_')
56
- splitted_filenames << name.split(/\s/)
57
- end
58
- files = splitted_filenames.flatten.uniq
59
- splitted_filenames = []
60
- files.each do |name|
61
- splitted_filenames << name.gsub('_ESCAPED_WHITESPACE_','\ ')
62
- end
63
- files = splitted_filenames
64
- end
65
-
66
- files = split_files_void_escaped_whitespace(files)
67
- child_pid = nil
68
-
69
- def restart(child_pid, env, cmd)
70
- Process.kill(9, child_pid)
71
- Process.wait(child_pid)
72
- rescue Errno::ESRCH
73
- # already killed
74
- ensure
75
- return Process.spawn(env, cmd)
76
- end
77
-
78
- if(options[:exclude] != "")
79
- options[:exclude] = split_files_void_escaped_whitespace(options[:exclude].split(" "))
80
- end
81
-
82
- begin
83
- fw = FileWatcher.new(files, options)
84
-
85
- if(options[:list])
86
- puts 'Watching:'
87
- fw.last_found_filenames.each do |filename|
88
- puts " #{filename}"
89
- end
90
- end
91
-
92
- Process.daemon(true, true) if options[:daemon]
93
-
94
- fw.watch(options[:interval]) do |filename, event|
95
- cmd = nil
96
- if(options[:exec] and File.exist?(filename))
97
- extension = filename[/(\.[^\.]*)$/,0]
98
- runners = {
99
- ".py" => "python",
100
- ".js" => "node",
101
- ".rb" => "ruby",
102
- ".pl" => "perl",
103
- ".awk" => "awk",
104
- ".php" => "php",
105
- ".phtml" => "php",
106
- ".php4" => "php",
107
- ".php3" => "php",
108
- ".php5" => "php",
109
- ".phps" => "php"
110
- }
111
- runner = runners[extension]
112
- if(runner)
113
- cmd = "env #{runner.to_s} #{filename}"
114
- end
115
- elsif(ARGV.length > 1)
116
- cmd = ARGV[-1]
117
- end
118
-
119
- if(cmd)
120
- path = Pathname.new(filename)
121
- env = {
122
- 'FILENAME' => filename,
123
- 'BASENAME' => path.basename.to_s,
124
- 'FILEDIR' => File.join(Pathname.new('.').realpath.to_s, path.parent.to_s), # Deprecated
125
- 'FSEVENT' => event.to_s, # Deprecated,
126
- 'EVENT' => event.to_s,
127
- 'DIRNAME' => File.join(Pathname.new('.').realpath.to_s, path.parent.to_s),
128
- 'ABSOLUTE_FILENAME' => File.join(Pathname.new('.').realpath.to_s, path.to_s),
129
- 'RELATIVE_FILENAME' => File.join(Pathname.new('.').to_s, path.to_s)
130
- }
131
-
132
- if(event != :delete)
133
- ENV['FILEPATH'] = path.realpath.to_s
134
- end
135
-
136
- if(options[:restart])
137
- if child_pid.nil?
138
- child_pid = Process.spawn(env, cmd)
139
- else
140
- child_pid = restart(child_pid, env, cmd)
141
- end
142
- else
143
- begin
144
- pid = Process.spawn(env, cmd)
145
- Process.wait()
146
- rescue SystemExit, Interrupt
147
- exit(0)
148
- end
149
- end
150
-
151
- else
152
- case(event)
153
- when :changed
154
- print "file updated"
155
- when :delete
156
- print "file deleted"
157
- when :new
158
- print "new file"
159
- else
160
- print event.to_s
161
- end
162
- puts ": " + filename
163
- end
164
-
165
- end
166
- rescue SystemExit, Interrupt
167
- fw.finalize
168
- end
@@ -1 +0,0 @@
1
- content1
@@ -1 +0,0 @@
1
- content2
@@ -1 +0,0 @@
1
-
@@ -1 +0,0 @@
1
- puts "Hello world from Ruby!!!"
@@ -1 +0,0 @@
1
-
@@ -1 +0,0 @@
1
- puts "This is file6.rb executing"
@@ -1,181 +0,0 @@
1
- require 'rubygems'
2
- require 'bacon'
3
- require 'fileutils'
4
- require File.expand_path("../lib/filewatcher.rb",File.dirname(__FILE__))
5
-
6
-
7
-
8
- describe FileWatcher do
9
-
10
- fixtures =
11
- %w(test/fixtures/file4.rb
12
- test/fixtures/subdir/file6.rb
13
- test/fixtures/subdir/file5.rb
14
- test/fixtures/file2.txt
15
- test/fixtures/file1.txt
16
- test/fixtures/file3.rb)
17
-
18
- explicit_relative_fixtures = fixtures.map { |it| "./#{it}" }
19
-
20
- subfolder = 'test/fixtures/new_sub_folder'
21
-
22
- after do
23
- FileUtils.rm_rf subfolder
24
- end
25
-
26
- def includes_all(elements)
27
- lambda { |it| elements.all? { |element| it.include? element }}
28
- end
29
-
30
- it "should exclude selected file patterns" do
31
- filewatcher = FileWatcher.new(File.expand_path('test/fixtures/**/*'), :exclude => [File.expand_path("test/fixtures/**/*.txt")])
32
- filtered_fixtures =
33
- %w(test/fixtures/file4.rb
34
- test/fixtures/subdir/file6.rb
35
- test/fixtures/subdir/file5.rb
36
- test/fixtures/file3.rb)
37
- filewatcher.filenames.should.satisfy &includes_all(filtered_fixtures.map { |it| File.expand_path(it) })
38
- end
39
-
40
- it "should handle absolute paths with globs" do
41
- filewatcher = FileWatcher.new(File.expand_path('test/fixtures/**/*'))
42
-
43
- filewatcher.filenames.should.satisfy &includes_all(fixtures.map { |it| File.expand_path(it) })
44
- end
45
-
46
- it "should handle globs" do
47
- filewatcher = FileWatcher.new('test/fixtures/**/*')
48
-
49
- filewatcher.filenames.should.satisfy &includes_all(fixtures)
50
- end
51
-
52
-
53
- it "should handle explicit relative paths with globs" do
54
- filewatcher = FileWatcher.new('./test/fixtures/**/*')
55
-
56
- filewatcher.filenames.should.satisfy &includes_all(explicit_relative_fixtures)
57
- end
58
-
59
- it "should handle explicit relative paths" do
60
- filewatcher = FileWatcher.new('./test/fixtures')
61
-
62
- filewatcher.filenames.should.satisfy &includes_all(explicit_relative_fixtures)
63
- end
64
-
65
- it "should handle tilde expansion" do
66
- filename = File.expand_path('~/file_watcher_1.txt')
67
- open(filename, 'w') { |f| f.puts 'content1' }
68
-
69
- filewatcher = FileWatcher.new('~/file_watcher_1.txt')
70
-
71
- begin
72
- filewatcher.filenames.should == [filename]
73
- ensure
74
- FileUtils.rm(filename)
75
- end
76
- end
77
-
78
- it "should detect file deletions" do
79
- filename = "test/fixtures/file1.txt"
80
- open(filename,"w") { |f| f.puts "content1" }
81
- filewatcher = FileWatcher.new(["test/fixtures"])
82
- filewatcher.filesystem_updated?.should.be.false
83
- FileUtils.rm(filename)
84
- filewatcher.filesystem_updated?.should.be.true
85
- end
86
-
87
- it "should detect file additions" do
88
- filename = "test/fixtures/file1.txt"
89
- FileUtils.rm(filename) if File.exists?(filename)
90
- filewatcher = FileWatcher.new(["test/fixtures"])
91
- filewatcher.filesystem_updated?.should.be.false
92
- open(filename,"w") { |f| f.puts "content1" }
93
- filewatcher.filesystem_updated?.should.be.true
94
- end
95
-
96
- it "should detect file updates" do
97
- filename = "test/fixtures/file1.txt"
98
- open(filename,"w") { |f| f.puts "content1" }
99
- filewatcher = FileWatcher.new(["test/fixtures"])
100
- filewatcher.filesystem_updated?.should.be.false
101
- sleep 1
102
- open(filename,"w") { |f| f.puts "content2" }
103
- filewatcher.filesystem_updated?.should.be.true
104
- end
105
-
106
- it "should detect new files in subfolders" do
107
- FileUtils::mkdir_p subfolder
108
-
109
- filewatcher = FileWatcher.new(["./test/fixtures"])
110
- filewatcher.filesystem_updated?.should.be.false
111
-
112
- open(subfolder + "/file.txt","w") { |f| f.puts "xyz" }
113
- filewatcher.filesystem_updated?.should.be.true
114
- end
115
-
116
- it "should detect new subfolders" do
117
- filewatcher = FileWatcher.new(["test/fixtures"])
118
- filewatcher.filesystem_updated?.should.be.false
119
-
120
- FileUtils::mkdir_p subfolder
121
- filewatcher.filesystem_updated?.should.be.true
122
- end
123
-
124
- it "should be stoppable" do
125
- filewatcher = FileWatcher.new(["test/fixtures"])
126
- thread = Thread.new(filewatcher){filewatcher.watch(0.1)}
127
- sleep 0.2 # thread needs a chance to start
128
- filewatcher.stop
129
- thread.join.should.equal thread # Proves thread successfully joined
130
- end
131
-
132
- it "should be pauseable/resumable" do
133
- filewatcher = FileWatcher.new(["test/fixtures"])
134
- filewatcher.filesystem_updated?.should.be.false
135
- processed = []
136
- thread = Thread.new(filewatcher,processed) do
137
- filewatcher.watch(0.1){|f,e| processed << f }
138
- end
139
- sleep 0.2 # thread needs a chance to start
140
- filewatcher.pause
141
- (1..4).each do |n|
142
- open("test/fixtures/file#{n}.txt","w") { |f| f.puts "content#{n}" }
143
- end
144
- sleep 0.2 # Give filewatcher time to respond
145
- processed.should.equal [] #update block should not have been called
146
- filewatcher.resume
147
- sleep 0.2 # Give filewatcher time to respond
148
- processed.should.equal [] #update block still should not have been called
149
- added_files = []
150
- (5..7).each do |n|
151
- added_files << "test/fixtures/file#{n}.txt"
152
- open(added_files.last,"w") { |f| f.puts "content#{n}" }
153
- end
154
- sleep 0.2 # Give filewatcher time to respond
155
- filewatcher.stop
156
- processed.should.satisfy &includes_all(added_files)
157
- end
158
-
159
- it "should process all remaining changes at finalize" do
160
- filewatcher = FileWatcher.new(["test/fixtures"])
161
- filewatcher.filesystem_updated?.should.be.false
162
- processed = []
163
- thread = Thread.new(filewatcher,processed) do
164
- filewatcher.watch(0.1){|f,e| processed << f }
165
- end
166
- sleep 0.2 # thread needs a chance to start
167
- filewatcher.stop
168
- thread.join
169
- added_files = []
170
- (1..4).each do |n|
171
- added_files << "test/fixtures/file#{n}.txt"
172
- open(added_files.last,"w") { |f| f.puts "content#{n}" }
173
- end
174
- filewatcher.finalize
175
- puts "What is wrong with finalize:"
176
- puts "Expect: #{added_files.inspect}"
177
- puts "Actual: #{processed.inspect}"
178
- # processed.should.satisfy &includes_all(added_files)
179
- end
180
-
181
- end