filewatcher 0.5.2 → 0.5.3

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: 675a76cd6578899a746e89329be478bed350c571
4
- data.tar.gz: ed6ad81fc1932e4898f8b5b917dfe4337eb69fb2
3
+ metadata.gz: 4e284fa33515d0d74bc7cf8ddc014678e14f3700
4
+ data.tar.gz: 55d15b651a1246f50f1982ceab55a51afb5c5477
5
5
  SHA512:
6
- metadata.gz: 8408d2a878bf84b097f8a2b36aae9ecb0adfef11656f9f51b27530ddefcdc6520d5fa36f996afa0abae02da38d23c03caf51232d748380004b89e408419bf963
7
- data.tar.gz: e1ee55b9f7a851cd9787dd6e4692ac686d693464fe240f818da02b062b0b35cbd04ced05103b878f3d7ee6fd1ff8bf2f4958272b47bb1871096c608287ad03e1
6
+ metadata.gz: 623df61d04ce2ab7b920d1718ddfbf7ac1791f617b17bac3e740a9b72235c9dabb0ea3824afe16cf07ac6d5e5391b4e41663c58701dcf465811c1e7c98044d4c
7
+ data.tar.gz: 4564616b0ecc6d8cdb781ea9d84790c2a60c3c89cb63f5cf915cefaf5810369b00e13c78fc3c2fee532a0d69b576d56666f252a19e542a11a129ae98dbe1d9c2
data/README.md CHANGED
@@ -6,13 +6,9 @@ Filewatcher
6
6
  [![Dependency Status](https://gemnasium.com/thomasfl/filewatcher.png?travis)](https://gemnasium.com/thomasfl/filewatcher)
7
7
  [![Code Climate](https://codeclimate.com/github/thomasfl/filewatcher.png)](https://codeclimate.com/github/thomasfl/filewatcher)
8
8
 
9
- Lightweight filewatcher weighing less than 200 LoC. No dependencies or platform specific code.
10
- Works everywhere. Monitors changes in the filesystem by polling. Has no config files.
11
- When running filewatcher from the command line, you specify which files to monitor and what action
12
- to perform on updates.
9
+ Lightweight filewatcher weighing less than 200 LoC. No dependencies or platform specific code. Works everywhere. Monitors changes in the filesystem by polling. Has no config files. When running filewatcher from the command line, you specify which files to monitor and what action to perform on updates.
13
10
 
14
- For example to search recursively for javascript files and run jshint when a file is
15
- updated, added, renamed or deleted:
11
+ For example to search recursively for javascript files and run jshint when a file is updated, added, renamed or deleted:
16
12
 
17
13
  Linux/OSX:
18
14
 
@@ -60,7 +56,7 @@ In Linux/OSX:
60
56
 
61
57
  Place filenames or filenames in quotes to use ruby filename globbing instead
62
58
  of shell filename globbing. This will make filewatcher look for files in
63
- subdirectories too. To watch all javascript files in subdirectories:
59
+ subdirectories too. To watch all javascript files in subdirectories in Windows:
64
60
 
65
61
  > filewatcher "**/*.js" "node %FILENAME%"
66
62
 
@@ -77,7 +73,7 @@ python, ruby, perl, php, javascript or awk script.
77
73
  Print a list of all files matching *.css first and then output the filename
78
74
  when a file is beeing updated by using the --list/-l option:
79
75
 
80
- $ filewatcher -l *.css 'echo file: $FILENAME'
76
+ $ filewatcher -l '**/*.css' 'echo file: $FILENAME'
81
77
 
82
78
  Watch the "src" and "test" folders recursively, and run test when the
83
79
  filesystem gets updated:
@@ -93,7 +89,7 @@ The `--restart` option kills the command if it's still running when a filesystem
93
89
 
94
90
  The `--dontwait` option starts the command on startup without waiting for filesystem updates. To start a webserver and have it automatically restart when html files are updated:
95
91
 
96
- $ filewatcher --restart --dontwait "*.html" "python -m SimpleHTTPServer"
92
+ $ filewatcher --restart --dontwait "**/*.html" "python -m SimpleHTTPServer"
97
93
 
98
94
  Available enviroment variables
99
95
  ------------------------------
@@ -104,17 +100,24 @@ node whenever a javascript file is updated:
104
100
 
105
101
  $ filewatcher *.js 'node $FILENAME'
106
102
 
107
- The environment variables $FILEPATH, $FILEDIR and $FSEVENT is also available.
103
+ Environment variables available from the command string:
104
+
105
+ BASENAME File basename.
106
+ FILENAME Relative filename.
107
+ ABSOLUTE_FILENAME Asolute filename.
108
+ RELATIVE_FILENAME Same as FILENAME but starts with "./"
109
+ EVENT Event type. Is either 'changed', 'delete' or 'new'.
110
+ DIRNAME Absolute directory name.
108
111
 
109
112
  Command line options
110
113
  --------------------
111
114
 
112
115
  Useful command line options:
113
116
 
114
- --list, -l: Print name of files being watched on startup
117
+ --list, -l: Print name of matching files on startup
115
118
  --restart, -r: Run command in separate fork and kill it on filesystem updates
116
119
  --dontwait, -d: Run the command before any filesystem updates
117
- --spinner, -s: Display an animated spinner
120
+ --spinner, -s: Display an animated spinner while scanning
118
121
 
119
122
  Other command line options:
120
123
 
@@ -174,21 +177,17 @@ To detect if a file is updated, added or deleted:
174
177
  end
175
178
  end
176
179
 
177
- When a file is renamed it is detected as a deletion followed by a file addition.
180
+ When a file is renamed it is detected as a new file followed by a file deletion.
178
181
 
179
- To check for changes more often than the default once every second:
182
+ The API takes some of the same options as the command line interface. To watch all files recursively except files that matches *.rb, display a spinner and only wait for 0.1 seconds between each scan:
180
183
 
181
- FileWatcher.new(["README.rdoc"]).watch(0.5) do |filename|
182
- puts "Updated " + filename
184
+ FileWatcher.new('**/*.*', exclude: '**/*.rb', spinner: true, interval: 0.1).watch() do |filename|
185
+ puts filename
183
186
  end
184
187
 
185
- Print the names of the files found before watching files and folders:
188
+ To do the same from the command line, use the same options:
186
189
 
187
- FileWatcher.new(["lib/"],true).watch do |filename|
188
- puts "Updated " + filename
189
- end
190
- => Watching files:
191
- lib/filewatcher.rb
190
+ $ filewatcher '**/*.*' --exclude '**/*.rb' --spinner --interval 0.1 'echo $FILENAME'
192
191
 
193
192
  Use patterns to match filenames in current directory and subdirectories. The
194
193
  pattern is not a regular expression; instead it follows rules similar to shell
@@ -222,9 +221,25 @@ over the network)
222
221
  filewatcher.finalize # Ensure all filesystem changes made prior to
223
222
  # ending the watch are handled.
224
223
 
225
- The filewatcher library is just a single file with 147 LOC (including comments)
224
+ If basename, relative filename or absolute filename is necessay use the stanard lib 'pathname' like this:
225
+
226
+ require 'pathname'
227
+
228
+ FileWatcher.new(["**/*.*"]).watch() do |filename|
229
+ path = Pathname.new(filename)
230
+ puys "Basename : " + path.basename.to_s
231
+ puts "Relative filename: " + File.join(Pathname.new('.').to_s, path.to_s)
232
+ puts "Absolute filename: " + File.join(Pathname.new('.').realpath.to_s, path.to_s)
233
+ end
234
+
235
+ The filewatcher library is a single file with 180 LOC (including comments)
226
236
  with no dependencies.
227
237
 
238
+ Changelog
239
+ ---------
240
+ 0.5.3 Exclude files. More environment variables. Options in ruby api.
241
+ 0.5.2 Start, stop and finalize API.
242
+ 0.5.1 Kill and restart long running command with --restart option.
228
243
 
229
244
  Credits
230
245
  -------
data/Rakefile CHANGED
@@ -7,4 +7,13 @@ task :default => :test
7
7
  desc "Run tests"
8
8
  task :test do
9
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
10
19
  end
@@ -20,6 +20,10 @@ Examples:
20
20
  filewatcher "myfile" "echo 'myfile has changed'"
21
21
  filewatcher '*.rb' 'ruby $FILENAME'
22
22
  filewatcher '**/*.rb' 'ruby $FILENAME' # Watch subdirectories
23
+
24
+ Other available environment variables are BASENAME, ABSOLUTE_FILENAME,
25
+ RELATIVE_FILENAME, EVENT and DIRNAME.
26
+
23
27
  Options:
24
28
  EOS
25
29
 
@@ -74,8 +78,20 @@ if(options[:restart])
74
78
  child_pid = nil
75
79
  end
76
80
 
81
+ if(options[:exclude] != "")
82
+ options[:exclude] = split_files_void_escaped_whitespace(options[:exclude].split(" "))
83
+ end
84
+
77
85
  begin
78
- fw = FileWatcher.new(files, options[:list], options[:dontwait], options[:spinner])
86
+ fw = FileWatcher.new(files, options)
87
+
88
+ if(options[:list])
89
+ puts 'Watching:'
90
+ fw.last_found_filenames.each do |filename|
91
+ puts " #{filename}"
92
+ end
93
+ end
94
+
79
95
  fw.watch(options[:interval]) do |filename, event|
80
96
  cmd = nil
81
97
  if(options[:exec] and File.exist?(filename))
@@ -104,10 +120,16 @@ begin
104
120
  if(cmd)
105
121
  path = Pathname.new(filename)
106
122
  env = {
107
- 'FILENAME'=> path.to_s,
108
- 'FILEDIR' => File.join(Pathname.new('.').realpath.to_s, path.parent.to_s),
109
- 'FSEVENT' => event.to_s
123
+ 'FILENAME' => filename,
124
+ 'BASENAME' => path.basename.to_s,
125
+ 'FILEDIR' => File.join(Pathname.new('.').realpath.to_s, path.parent.to_s), # Deprecated
126
+ 'FSEVENT' => event.to_s, # Deprecated,
127
+ 'EVENT' => event.to_s,
128
+ 'DIRNAME' => File.join(Pathname.new('.').realpath.to_s, path.parent.to_s),
129
+ 'ABSOLUTE_FILENAME' => File.join(Pathname.new('.').realpath.to_s, path.to_s),
130
+ 'RELATIVE_FILENAME' => File.join(Pathname.new('.').to_s, path.to_s)
110
131
  }
132
+
111
133
  if(event != :delete)
112
134
  ENV['FILEPATH'] = path.realpath.to_s
113
135
  end
@@ -6,7 +6,7 @@ class FileWatcher
6
6
  attr_accessor :filenames
7
7
 
8
8
  def self.VERSION
9
- return '0.5.2'
9
+ return '0.5.3'
10
10
  end
11
11
 
12
12
  def update_spinner(label)
@@ -15,26 +15,31 @@ class FileWatcher
15
15
  print "#{' ' * 30}\r#{label} #{@spinner.rotate!.first}\r"
16
16
  end
17
17
 
18
- def initialize(unexpanded_filenames, print_filelist=false, dontwait=false, show_spinner=false)
18
+ def initialize(unexpanded_filenames, *args)
19
+ if(args.first)
20
+ options = args.first
21
+ else
22
+ options = {}
23
+ end
19
24
  @unexpanded_filenames = unexpanded_filenames
25
+ @unexpanded_excluded_filenames = options[:exclude]
20
26
  @filenames = nil
21
27
  @stored_update = nil
22
28
  @keep_watching = false
23
29
  @pausing = false
24
30
  @last_snapshot = mtime_snapshot
25
31
  @end_snapshot = nil
26
- @dontwait = dontwait
27
- @show_spinner = show_spinner
28
- puts 'Watching:' if print_filelist
29
- @filenames.each do |filename|
30
- raise 'File does not exist' unless File.exist?(filename)
31
- puts filename if print_filelist
32
- end
32
+ @dontwait = options[:dontwait]
33
+ @show_spinner = options[:spinner]
34
+ @interval = options[:interval]
33
35
  end
34
36
 
35
37
  def watch(sleep=0.5, &on_update)
36
38
  trap("SIGINT") {return }
37
39
  @sleep = sleep
40
+ if(@interval and @interval > 0)
41
+ @sleep = @interval
42
+ end
38
43
  @stored_update = on_update
39
44
  @keep_watching = true
40
45
  if(@dontwait)
@@ -44,11 +49,11 @@ class FileWatcher
44
49
  @end_snapshot = mtime_snapshot if @pausing
45
50
  while @keep_watching && @pausing
46
51
  update_spinner('Pausing')
47
- Kernel.sleep sleep
52
+ Kernel.sleep @sleep
48
53
  end
49
54
  while @keep_watching && !filesystem_updated? && !@pausing
50
55
  update_spinner('Watching')
51
- Kernel.sleep sleep
56
+ Kernel.sleep @sleep
52
57
  end
53
58
  # test and null @updated_file to prevent yielding the last
54
59
  # file twice if @keep_watching has just been set to false
@@ -102,6 +107,19 @@ class FileWatcher
102
107
  def mtime_snapshot
103
108
  snapshot = {}
104
109
  @filenames = expand_directories(@unexpanded_filenames)
110
+
111
+ if(@unexpanded_excluded_filenames != nil and @unexpanded_excluded_filenames.size > 0)
112
+ # Remove files in the exclude filenames list
113
+ @filtered_filenames = []
114
+ @excluded_filenames = expand_directories(@unexpanded_excluded_filenames)
115
+ @filenames.each do |filename|
116
+ if(not(@excluded_filenames.include?(filename)))
117
+ @filtered_filenames << filename
118
+ end
119
+ end
120
+ @filenames = @filtered_filenames
121
+ end
122
+
105
123
  @filenames.each do |filename|
106
124
  mtime = File.exist?(filename) ? File.stat(filename).mtime : Time.new(0)
107
125
  snapshot[filename] = mtime
@@ -138,6 +156,10 @@ class FileWatcher
138
156
  return false
139
157
  end
140
158
 
159
+ def last_found_filenames
160
+ @last_snapshot.keys
161
+ end
162
+
141
163
  def expand_directories(patterns)
142
164
  if(!patterns.kind_of?Array)
143
165
  patterns = [patterns]
@@ -27,12 +27,22 @@ describe FileWatcher do
27
27
  lambda { |it| elements.all? { |element| it.include? element }}
28
28
  end
29
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
+
30
40
  it "should handle absolute paths with globs" do
31
41
  filewatcher = FileWatcher.new(File.expand_path('test/fixtures/**/*'))
32
42
 
33
43
  filewatcher.filenames.should.satisfy &includes_all(fixtures.map { |it| File.expand_path(it) })
34
44
  end
35
-
45
+
36
46
  it "should handle globs" do
37
47
  filewatcher = FileWatcher.new('test/fixtures/**/*')
38
48
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filewatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Flemming
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-21 00:00:00.000000000 Z
11
+ date: 2015-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trollop