chisel 0.0.1 → 0.0.2
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/bin/chisel +107 -32
- data/lib/chisel/ruby/array.rb +1 -1
- data/lib/chisel/site_directory.rb +10 -2
- data/lib/chisel/view.rb +3 -1
- data/lib/chisel/view_helper.rb +3 -3
- data/lib/filesystemwatcher/filesystemwatcher.rb +330 -0
- data/lib/filesystemwatcher/servicestate.rb +75 -0
- metadata +43 -27
data/bin/chisel
CHANGED
@@ -1,45 +1,120 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'chisel/wrapper'
|
4
|
+
require 'filesystemwatcher/filesystemwatcher'
|
4
5
|
require 'optparse'
|
6
|
+
require 'webrick'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
include WEBrick
|
9
|
+
include Chisel
|
10
|
+
|
11
|
+
def start_webrick(config = {})
|
12
|
+
server = HTTPServer.new(config)
|
13
|
+
|
14
|
+
yield server if block_given?
|
15
|
+
['INT', 'TERM'].each do |signal|
|
16
|
+
trap(signal) { server.shutdown }
|
17
|
+
end
|
18
|
+
|
19
|
+
puts "\n*** Press Ctrl-C to stop the server ***\n\n"
|
20
|
+
|
21
|
+
server.start
|
22
|
+
end
|
11
23
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
24
|
+
# Set up default command-line options
|
25
|
+
|
26
|
+
options = {}
|
27
|
+
options[:verbose] = false
|
28
|
+
options[:server] = false
|
29
|
+
options[:watch] = false
|
30
|
+
options[:port] = 4000
|
31
|
+
|
32
|
+
# Parse out options
|
33
|
+
|
34
|
+
OptionParser.new do |opts|
|
35
|
+
opts.banner = 'Usage: chisel [options] [new|resource] [command]'
|
36
|
+
|
37
|
+
opts.on('-v', '--verbose', 'Run verbosely') do |v|
|
38
|
+
options[:verbose] = v
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('-s', '--server [port]', 'Run local WEBrick server (default port 4000)') do |port|
|
42
|
+
options[:server] = true
|
43
|
+
options[:port] = port.to_i if port
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on('-w', '--watch', 'Watch filesystem for changes and update automatically') do |w|
|
47
|
+
options[:watch] = w
|
48
|
+
end
|
49
|
+
|
50
|
+
end.parse!
|
51
|
+
|
52
|
+
# Run the appropriate command
|
53
|
+
|
54
|
+
if ARGV.count == 0
|
55
|
+
|
56
|
+
site_dir = SiteDirectory.new('.')
|
57
|
+
|
58
|
+
w = Wrapper.new(site_dir)
|
59
|
+
w.run
|
60
|
+
|
61
|
+
if options[:watch]
|
62
|
+
puts 'File system watcher not yet implemented. Sorry!'
|
63
|
+
# TODO: Implement file system watcher
|
16
64
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
65
|
+
# watcher = FileSystemWatcher.new
|
66
|
+
# watcher.addDirectory(site_dir.realdirpath.to_s, '*.*')
|
67
|
+
#
|
68
|
+
# site_dir.entries.each do |entry|
|
69
|
+
#
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# watcher.sleepTime = 1
|
73
|
+
# watcher.start do |status, file|
|
74
|
+
# w1 = Wrapper.new(site_dir)
|
75
|
+
# w1.run
|
76
|
+
# end
|
77
|
+
# watcher.join
|
78
|
+
end
|
79
|
+
|
80
|
+
if options[:server]
|
81
|
+
output_dir = site_dir.output_dir.realdirpath.to_s
|
82
|
+
start_webrick(:DocumentRoot => output_dir, :Port => options[:port])
|
83
|
+
end
|
84
|
+
|
85
|
+
else
|
86
|
+
|
87
|
+
case ARGV[0].downcase
|
88
|
+
|
89
|
+
when 'new'
|
90
|
+
# TODO: Add checking for existing site, with option to "force" creation
|
91
|
+
|
92
|
+
if ARGV.length == 1 then
|
93
|
+
puts 'Creating new Chisel site in the current directory...'
|
94
|
+
SiteDirectory.create('.')
|
95
|
+
puts 'Done. Run \'chisel\' to create your site.'
|
96
|
+
else
|
97
|
+
dir = ARGV[1]
|
98
|
+
puts "Creating new Chisel site in directory '#{dir}'..."
|
99
|
+
SiteDirectory.create(dir)
|
100
|
+
puts "Done. Go into \'#{dir}\' and run \'chisel\' to create your site."
|
101
|
+
end
|
102
|
+
|
103
|
+
when 'resource'
|
27
104
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
site_dir.create_resource(ARGV[2])
|
37
|
-
end
|
105
|
+
if ARGV.length == 1 then
|
106
|
+
# TODO: Something
|
107
|
+
else
|
108
|
+
site_dir = SiteDirectory.new('.')
|
109
|
+
case ARGV[1].downcase
|
110
|
+
when 'new'
|
111
|
+
# TODO: Check that ARGV[2] exists and show help otherwise
|
112
|
+
site_dir.create_resource(ARGV[2])
|
38
113
|
end
|
39
|
-
|
40
|
-
when 'help'
|
41
|
-
|
42
114
|
end
|
43
115
|
|
116
|
+
when 'help'
|
117
|
+
|
44
118
|
end
|
119
|
+
|
45
120
|
end
|
data/lib/chisel/ruby/array.rb
CHANGED
@@ -61,9 +61,9 @@ module Chisel
|
|
61
61
|
self.output_dir.join(*resource.id, view_with_extension(view))
|
62
62
|
end
|
63
63
|
|
64
|
-
def page_output_path(page)
|
64
|
+
def page_output_path(page, view_output_dir)
|
65
65
|
page = view_with_extension(page)
|
66
|
-
self.
|
66
|
+
self.site_relative_path(page, view_output_dir)
|
67
67
|
end
|
68
68
|
|
69
69
|
def layout_view_path(layout_name)
|
@@ -73,6 +73,14 @@ module Chisel
|
|
73
73
|
def view_path(view)
|
74
74
|
self.view_dir.join("#{view_with_extension(view)}.erb")
|
75
75
|
end
|
76
|
+
|
77
|
+
def site_relative_path(relative_path, view_output_dir)
|
78
|
+
if relative_path[0] == '/'
|
79
|
+
self.output_dir.join(relative_path[1..-1])
|
80
|
+
else
|
81
|
+
view_output_dir.join(relative_path)
|
82
|
+
end
|
83
|
+
end
|
76
84
|
|
77
85
|
def view_with_extension(view)
|
78
86
|
view = "#{view}index" if view[-1] == '/'
|
data/lib/chisel/view.rb
CHANGED
@@ -26,7 +26,7 @@ module Chisel
|
|
26
26
|
|
27
27
|
@path = Pathname.new(options[:path]) if options[:path]
|
28
28
|
@site_dir = SiteDirectory.new(options[:site_dir]) if options[:site_dir]
|
29
|
-
|
29
|
+
|
30
30
|
if options[:resource]
|
31
31
|
@type = :resource
|
32
32
|
@resource = options[:resource]
|
@@ -96,6 +96,8 @@ module Chisel
|
|
96
96
|
|
97
97
|
header_vars = {}
|
98
98
|
if options[:resource]
|
99
|
+
resource_key = options[:resource].resource_type.to_sym
|
100
|
+
header_vars[resource_key] = options[:resource]
|
99
101
|
header_vars[:resource] = options[:resource]
|
100
102
|
end
|
101
103
|
|
data/lib/chisel/view_helper.rb
CHANGED
@@ -35,14 +35,14 @@ module Chisel
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def link_to_page(page, text, options = {})
|
38
|
-
page_output_path = @site_dir.page_output_path(page)
|
38
|
+
page_output_path = @site_dir.page_output_path(page, @output_path.dirname)
|
39
39
|
href = page_output_path.relative_path_from(@output_path.dirname).to_s
|
40
40
|
|
41
41
|
link_to(href, text, options)
|
42
42
|
end
|
43
43
|
|
44
44
|
def path_to(site_relative_path)
|
45
|
-
@site_dir.
|
45
|
+
@site_dir.site_relative_path(site_relative_path, @output_path.dirname).relative_path_from(@output_path.dirname)
|
46
46
|
end
|
47
47
|
|
48
48
|
def link_to(href, text, options = {})
|
@@ -53,7 +53,7 @@ module Chisel
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
href = href[0..-11] if href.end_with?('index.html')
|
56
|
+
href = href[0..-11] if href.end_with?('index.html') and href != 'index.html'
|
57
57
|
|
58
58
|
"<a href=\"#{href}\"#{attribute_string}>#{text}</a>"
|
59
59
|
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
require "digest/md5"
|
2
|
+
require "thread"
|
3
|
+
require "#{File.dirname(__FILE__)}/servicestate.rb"
|
4
|
+
|
5
|
+
# This class will watch a directory or a set of directories and alert you of
|
6
|
+
# new files, modified files, deleted files. You can optionally only be alerted
|
7
|
+
# when a files md5 hash has been changed so you only are alerted to real changes.
|
8
|
+
# this of course means slower performance and higher cpu/io usage.
|
9
|
+
class FileSystemWatcher
|
10
|
+
include ServiceState
|
11
|
+
|
12
|
+
CREATED = 0
|
13
|
+
MODIFIED = 1
|
14
|
+
DELETED = 2
|
15
|
+
|
16
|
+
# the time to wait before checking the directories again
|
17
|
+
attr_accessor :sleepTime, :priority, :directories
|
18
|
+
|
19
|
+
# you can optionally use the file contents md5 to detect if a file has changed
|
20
|
+
attr_accessor :useMD5
|
21
|
+
|
22
|
+
def initialize(dir=nil, expression="**/*")
|
23
|
+
@sleepTime = 5
|
24
|
+
@useMD5 = false
|
25
|
+
@priority = 0
|
26
|
+
@stopWhen = nil
|
27
|
+
|
28
|
+
@directories = Array.new()
|
29
|
+
@files = Array.new()
|
30
|
+
|
31
|
+
@foundFiles = nil
|
32
|
+
@firstLoad = true
|
33
|
+
@watchThread = nil
|
34
|
+
|
35
|
+
initializeState()
|
36
|
+
|
37
|
+
if dir then
|
38
|
+
addDirectory(dir, expression)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# add a directory to be watched
|
43
|
+
# @param dir the directory to watch
|
44
|
+
# @param expression the glob pattern to search under the watched directory
|
45
|
+
def addDirectory(dir, expression="**/*")
|
46
|
+
if FileTest.exists?(dir) && FileTest.readable?(dir) then
|
47
|
+
@directories << FSWatcher::Directory.new(dir, expression)
|
48
|
+
else
|
49
|
+
raise FSWatcher::InvalidDirectoryError, "Dir '#{dir}' either doesnt exist or isnt readable"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def removeDirectory(dir)
|
54
|
+
@directories.delete(dir)
|
55
|
+
end
|
56
|
+
|
57
|
+
# add a specific file to the watch list
|
58
|
+
# @param file the file to watch
|
59
|
+
def addFile(file)
|
60
|
+
if FileTest.exists?(file) && FileTest.readable?(file) then
|
61
|
+
@files << file
|
62
|
+
else
|
63
|
+
raise FSWatcher::InvalidFileError, "File '#{file}' either doesnt exist or isnt readable"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def removeFile(file)
|
68
|
+
@files.delete(file)
|
69
|
+
end
|
70
|
+
|
71
|
+
# start watching the specified files/directories
|
72
|
+
def start(&block)
|
73
|
+
if isStarted? then
|
74
|
+
raise RuntimeError, "already started"
|
75
|
+
end
|
76
|
+
|
77
|
+
setState(STARTED)
|
78
|
+
|
79
|
+
@firstLoad = true
|
80
|
+
@foundFiles = Hash.new()
|
81
|
+
|
82
|
+
# we watch in a new thread
|
83
|
+
@watchThread = Thread.new {
|
84
|
+
# we will be stopped if someone calls stop or if someone set a stopWhen that becomes true
|
85
|
+
while !isStopped? do
|
86
|
+
if (!@directories.empty?) or (!@files.empty?) then
|
87
|
+
# this will hold the list of the files we looked at this iteration
|
88
|
+
# allows us to not look at the same file again and also to compare
|
89
|
+
# with the foundFile list to see if something was deleted
|
90
|
+
alreadyExamined = Hash.new()
|
91
|
+
|
92
|
+
# check the files in each watched directory
|
93
|
+
if not @directories.empty? then
|
94
|
+
@directories.each { |dirObj|
|
95
|
+
examineFileList(dirObj.getFiles(), alreadyExamined, &block)
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
# now examine any files the user wants to specifically watch
|
100
|
+
examineFileList(@files, alreadyExamined, &block) if not @files.empty?
|
101
|
+
|
102
|
+
# see if we have to delete files from our found list
|
103
|
+
if not @firstLoad then
|
104
|
+
if not @foundFiles.empty? then
|
105
|
+
# now diff the found files and the examined files to see if
|
106
|
+
# something has been deleted
|
107
|
+
allFoundFiles = @foundFiles.keys()
|
108
|
+
allExaminedFiles = alreadyExamined.keys()
|
109
|
+
intersection = allFoundFiles - allExaminedFiles
|
110
|
+
intersection.each { |fileName|
|
111
|
+
# callback
|
112
|
+
block.call(DELETED, fileName)
|
113
|
+
# remove deleted file from the foundFiles list
|
114
|
+
@foundFiles.delete(fileName)
|
115
|
+
}
|
116
|
+
end
|
117
|
+
else
|
118
|
+
@firstLoad = false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# go to sleep
|
123
|
+
sleep(@sleepTime)
|
124
|
+
end
|
125
|
+
}
|
126
|
+
|
127
|
+
# set the watch thread priority
|
128
|
+
@watchThread.priority = @priority
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
# kill the filewatcher thread
|
133
|
+
def stop()
|
134
|
+
setState(STOPPED)
|
135
|
+
@watchThread.wakeup()
|
136
|
+
end
|
137
|
+
|
138
|
+
# wait for the filewatcher to finish
|
139
|
+
def join()
|
140
|
+
@watchThread.join() if @watchThread
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
# loops over the file list check for new or modified files
|
147
|
+
def examineFileList(fileList, alreadyExamined, &block)
|
148
|
+
fileList.each { |fileName|
|
149
|
+
# expand the file name to the fully qual path
|
150
|
+
fullFileName = File.expand_path(fileName)
|
151
|
+
|
152
|
+
# dont examine the same file 2 times
|
153
|
+
if not alreadyExamined.has_key?(fullFileName) then
|
154
|
+
# we cant do much if the file isnt readable anyway
|
155
|
+
if File.readable?(fullFileName) then
|
156
|
+
# set that we have seen this file
|
157
|
+
alreadyExamined[fullFileName] = true
|
158
|
+
|
159
|
+
# get the file info
|
160
|
+
modTime, size = File.mtime(fullFileName), File.size(fullFileName)
|
161
|
+
|
162
|
+
# on the first iteration just load all of the files into the foundList
|
163
|
+
if @firstLoad then
|
164
|
+
@foundFiles[fullFileName] = FSWatcher::FoundFile.new(fullFileName, modTime, size, false, @useMD5)
|
165
|
+
else
|
166
|
+
# see if we have found this file already
|
167
|
+
foundFile = @foundFiles[fullFileName]
|
168
|
+
|
169
|
+
if foundFile then
|
170
|
+
|
171
|
+
# if a file is marked as new, we still need to make sure it isnt still
|
172
|
+
# being written to. we do this by checking the file sizes.
|
173
|
+
if foundFile.isNew? then
|
174
|
+
|
175
|
+
# if the file size is the same then it is probably done being written to
|
176
|
+
# unless the writer is really slow
|
177
|
+
if size == foundFile.size then
|
178
|
+
|
179
|
+
# callback
|
180
|
+
block.call(CREATED, fullFileName)
|
181
|
+
|
182
|
+
# mark this file as a changed file now
|
183
|
+
foundFile.updateModTime(modTime)
|
184
|
+
|
185
|
+
# generate the md5 for the file since we know it is done
|
186
|
+
# being written to
|
187
|
+
foundFile.genMD5() if @useMD5
|
188
|
+
|
189
|
+
else
|
190
|
+
|
191
|
+
# just update the size so we can check again at the next iteration
|
192
|
+
foundFile.updateSize(size)
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
elsif modTime > foundFile.modTime then
|
197
|
+
|
198
|
+
# if the mod times are different on files we already have
|
199
|
+
# found this is an update
|
200
|
+
willYield = true
|
201
|
+
|
202
|
+
# if we are using md5's then compare them
|
203
|
+
if @useMD5 then
|
204
|
+
filesMD5 = FSWatcher.genFileMD5(fullFileName)
|
205
|
+
if filesMD5 && foundFile.md5 then
|
206
|
+
if filesMD5.to_s == foundFile.md5.to_s then
|
207
|
+
willYield = false
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# if we are yielding then the md5s are dif so
|
212
|
+
# update the cached md5 value
|
213
|
+
foundFile.setMD5(filesMD5) if willYield
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
block.call(MODIFIED, fullFileName) if willYield
|
218
|
+
foundFile.updateModTime(modTime)
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
else
|
223
|
+
|
224
|
+
# this is a new file for our list. dont update the md5 here since
|
225
|
+
# the file might not yet be done being written to
|
226
|
+
@foundFiles[fullFileName] = FSWatcher::FoundFile.new(fullFileName, modTime, size)
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
}
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Util classes for the FileSystemWatcher
|
237
|
+
module FSWatcher
|
238
|
+
# The directory to watch
|
239
|
+
class Directory
|
240
|
+
attr_reader :dir, :expression
|
241
|
+
|
242
|
+
def initialize(dir, expression)
|
243
|
+
@dir, @expression = dir, expression
|
244
|
+
@dir.chop! if @dir =~ %r{/$}
|
245
|
+
end
|
246
|
+
|
247
|
+
def getFiles()
|
248
|
+
return Dir[@dir + "/" + @expression]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# A FoundFile entry for the FileSystemWatcher
|
253
|
+
class FoundFile
|
254
|
+
attr_reader :status, :fileName, :modTime, :size, :md5
|
255
|
+
|
256
|
+
def initialize(fileName, modTime, size, isNewFile=true, useMD5=false)
|
257
|
+
@fileName, @modTime, @size, @isNewFile = fileName, modTime, size, isNewFile
|
258
|
+
@md5 = nil
|
259
|
+
if useMD5 then
|
260
|
+
genMD5()
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def updateModTime(modTime)
|
265
|
+
@modTime = modTime
|
266
|
+
@isNewFile = false
|
267
|
+
end
|
268
|
+
|
269
|
+
def updateSize(size)
|
270
|
+
@size = size
|
271
|
+
end
|
272
|
+
|
273
|
+
def isNew?
|
274
|
+
return @isNewFile
|
275
|
+
end
|
276
|
+
|
277
|
+
def setMD5(newMD5)
|
278
|
+
@md5 = newMD5
|
279
|
+
end
|
280
|
+
|
281
|
+
# generate my files md5 value
|
282
|
+
def genMD5()
|
283
|
+
@md5 = FSWatcher.genFileMD5(@fileName)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# utility function for generating md5s from a files contents
|
288
|
+
def FSWatcher.genFileMD5(fileName)
|
289
|
+
if FileTest.file?(fileName) then
|
290
|
+
f = File.open(fileName)
|
291
|
+
contents = f.read()
|
292
|
+
f.close()
|
293
|
+
return MD5.new(contents) if contents
|
294
|
+
end
|
295
|
+
return nil
|
296
|
+
end
|
297
|
+
|
298
|
+
# if the directory you want to watch doesnt exist or isnt readable this is thrown
|
299
|
+
class InvalidDirectoryError < StandardError; end
|
300
|
+
|
301
|
+
# if the file you want to watch doesnt exist or isnt readable this is thrown
|
302
|
+
class InvalidFileError < StandardError; end
|
303
|
+
end
|
304
|
+
|
305
|
+
#--- main program ----
|
306
|
+
if __FILE__ == $0
|
307
|
+
watcher = FileSystemWatcher.new()
|
308
|
+
watcher.addDirectory("/cygdrive/c/Inetpub/ftproot/", "*.xml")
|
309
|
+
watcher.sleepTime = 3
|
310
|
+
watcher.useMD5 = true
|
311
|
+
|
312
|
+
test = false
|
313
|
+
watcher.stopWhen {
|
314
|
+
test == true
|
315
|
+
}
|
316
|
+
|
317
|
+
watcher.start() { |status,file|
|
318
|
+
if status == FileSystemWatcher::CREATED then
|
319
|
+
puts "created: #{file}"
|
320
|
+
elsif status == FileSystemWatcher::MODIFIED then
|
321
|
+
puts "modified: #{file}"
|
322
|
+
elsif status == FileSystemWatcher::DELETED then
|
323
|
+
puts "deleted: #{file}"
|
324
|
+
end
|
325
|
+
}
|
326
|
+
|
327
|
+
sleep(10)
|
328
|
+
test = true
|
329
|
+
watcher.join()
|
330
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
# The Runnable module is a generic mixin for including state and
|
4
|
+
# status information in a class
|
5
|
+
module ServiceState
|
6
|
+
# state constants
|
7
|
+
NOT_STARTED = 0
|
8
|
+
STARTED = 1
|
9
|
+
STOPPED = 2
|
10
|
+
CONFIGURED = 3
|
11
|
+
|
12
|
+
attr_reader :startTime, :endTime
|
13
|
+
|
14
|
+
# Initialize the state information
|
15
|
+
def initializeState()
|
16
|
+
@configured = false
|
17
|
+
@startTime = 0
|
18
|
+
@stopTime = 0
|
19
|
+
|
20
|
+
@stateMutex = Mutex.new()
|
21
|
+
@stopWhen = nil
|
22
|
+
setState(NOT_STARTED)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set the callback for when someone calls setState. You
|
26
|
+
# will be passed the state CONSTANT being set
|
27
|
+
def onStateChange(&callbackBlock)
|
28
|
+
@stateCallback = callbackBlock
|
29
|
+
end
|
30
|
+
|
31
|
+
# All methods, inside this class or not, should use this
|
32
|
+
# method to change the state of the JobRunner
|
33
|
+
# @param newState The new state value
|
34
|
+
def setState(newState)
|
35
|
+
@stateMutex.synchronize {
|
36
|
+
if newState == CONFIGURED then
|
37
|
+
@configured = true
|
38
|
+
else
|
39
|
+
@state = newState
|
40
|
+
if isStarted? then
|
41
|
+
@startTime = Time.now()
|
42
|
+
elsif isStopped?
|
43
|
+
@stopTime = Time.now()
|
44
|
+
end
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
if defined?(@stateCallback) then
|
49
|
+
@stateCallback.call(newState)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def isConfigured?
|
54
|
+
return @configured
|
55
|
+
end
|
56
|
+
|
57
|
+
def isStarted?
|
58
|
+
return @state == STARTED
|
59
|
+
end
|
60
|
+
|
61
|
+
def isStopped?
|
62
|
+
if @state == STOPPED then
|
63
|
+
return true
|
64
|
+
elsif @stopWhen && @stopWhen.call() then
|
65
|
+
setState(STOPPED)
|
66
|
+
return true
|
67
|
+
else
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def stopWhen(&block)
|
73
|
+
@stopWhen = block
|
74
|
+
end
|
75
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,45 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: chisel
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
4
5
|
prerelease:
|
5
|
-
version: 0.0.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Rockwell Schrock
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
date: 2011-06-20 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: RedCloth
|
16
|
+
requirement: &2152864840 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 4.2.7
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2152864840
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: maruku
|
27
|
+
requirement: &2152864360 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.6.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2152864360
|
16
36
|
description: Chisel is tool to generate simple, resource-based static Web sites.
|
17
37
|
email: schrockwell@gmail.com
|
18
|
-
executables:
|
38
|
+
executables:
|
19
39
|
- chisel
|
20
40
|
extensions: []
|
21
|
-
|
22
41
|
extra_rdoc_files: []
|
23
|
-
|
24
|
-
files:
|
42
|
+
files:
|
25
43
|
- lib/chisel/new_site/_config.yml
|
26
44
|
- lib/chisel/new_site/_views/_layout/main.html.erb
|
27
45
|
- lib/chisel/new_site/index.html.erb
|
@@ -36,33 +54,31 @@ files:
|
|
36
54
|
- lib/chisel/view.rb
|
37
55
|
- lib/chisel/view_helper.rb
|
38
56
|
- lib/chisel/wrapper.rb
|
57
|
+
- lib/filesystemwatcher/filesystemwatcher.rb
|
58
|
+
- lib/filesystemwatcher/servicestate.rb
|
39
59
|
- bin/chisel
|
40
60
|
homepage: https://github.com/schrockwell/chisel
|
41
61
|
licenses: []
|
42
|
-
|
43
62
|
post_install_message:
|
44
63
|
rdoc_options: []
|
45
|
-
|
46
|
-
require_paths:
|
64
|
+
require_paths:
|
47
65
|
- lib
|
48
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
67
|
none: false
|
50
|
-
requirements:
|
51
|
-
- -
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version:
|
54
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
73
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version:
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
60
78
|
requirements: []
|
61
|
-
|
62
79
|
rubyforge_project:
|
63
80
|
rubygems_version: 1.8.5
|
64
81
|
signing_key:
|
65
82
|
specification_version: 3
|
66
83
|
summary: A static Web site generator.
|
67
84
|
test_files: []
|
68
|
-
|