rook 0.0.2 → 0.1.0

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.
Files changed (87) hide show
  1. data/README.txt +124 -37
  2. data/bin/rook +8 -902
  3. data/doc-api/classes/BZ2.html +111 -0
  4. data/doc-api/classes/BZ2/Reader.html +234 -0
  5. data/doc-api/classes/Digest.html +107 -0
  6. data/doc-api/classes/Digest/Base.html +254 -0
  7. data/doc-api/classes/Enumerable.html +430 -0
  8. data/doc-api/classes/File.html +208 -0
  9. data/doc-api/classes/FileUtils.html +758 -0
  10. data/doc-api/classes/Kernel.html +317 -0
  11. data/doc-api/classes/Rook.html +148 -0
  12. data/doc-api/classes/Rook/Assertion.html +164 -0
  13. data/doc-api/classes/Rook/AssertionError.html +111 -0
  14. data/doc-api/classes/Rook/CommandOptionError.html +113 -0
  15. data/doc-api/classes/Rook/Commands.html +1158 -0
  16. data/doc-api/classes/Rook/Cookbook.html +357 -0
  17. data/doc-api/classes/Rook/CookbookError.html +161 -0
  18. data/doc-api/classes/Rook/CookbookValidator.html +215 -0
  19. data/doc-api/classes/Rook/Kitchen.html +875 -0
  20. data/doc-api/classes/Rook/KitchenHelper.html +386 -0
  21. data/doc-api/classes/Rook/Main.html +325 -0
  22. data/doc-api/classes/Rook/Parameters.html +443 -0
  23. data/doc-api/classes/Rook/Recipe.html +546 -0
  24. data/doc-api/classes/Rook/RookError.html +111 -0
  25. data/doc-api/classes/Rook/Util.html +408 -0
  26. data/doc-api/classes/Rook/Util/UndefinedPropertyError.html +160 -0
  27. data/doc-api/created.rid +1 -0
  28. data/doc-api/files/__/README_txt.html +313 -0
  29. data/doc-api/files/rook/commands_rb.html +115 -0
  30. data/doc-api/files/rook/cookbook_rb.html +115 -0
  31. data/doc-api/files/rook/helper/bz2_rb.html +114 -0
  32. data/doc-api/files/rook/helper/digest_rb.html +114 -0
  33. data/doc-api/files/rook/helper/enumerable_rb.html +107 -0
  34. data/doc-api/files/rook/helper/file_rb.html +107 -0
  35. data/doc-api/files/rook/helper/fileutils_rb.html +124 -0
  36. data/doc-api/files/rook/helper/kernel_rb.html +107 -0
  37. data/doc-api/files/rook/kitchen_rb.html +117 -0
  38. data/doc-api/files/rook/main_rb.html +117 -0
  39. data/doc-api/files/rook/recipe_rb.html +114 -0
  40. data/doc-api/files/rook/util_rb.html +115 -0
  41. data/doc-api/files/rook_rb.html +122 -0
  42. data/doc-api/fr_class_index.html +50 -0
  43. data/doc-api/fr_file_index.html +40 -0
  44. data/doc-api/fr_method_index.html +181 -0
  45. data/doc-api/index.html +24 -0
  46. data/doc-api/rdoc-style.css +208 -0
  47. data/examples/hello_c/Rookbook.rb +37 -0
  48. data/examples/hello_c/Rookbook.yaml +45 -0
  49. data/examples/hello_c/hello.c +6 -3
  50. data/examples/project/README.txt +8 -0
  51. data/examples/project/Rookbook.props +1 -0
  52. data/examples/project/Rookbook.rb +120 -0
  53. data/examples/project/Rookbook.yaml +117 -0
  54. data/examples/project/bin/example +12 -0
  55. data/examples/project/example.gemspec +29 -0
  56. data/examples/project/lib/example.rb +36 -0
  57. data/examples/{archive → project}/lib/example/bar.rb +0 -0
  58. data/examples/{archive → project}/lib/example/baz.rb +0 -0
  59. data/examples/{archive → project}/lib/example/foo.rb +0 -0
  60. data/examples/project/setup.rb +1331 -0
  61. data/examples/project/test/test.rb +27 -0
  62. data/lib/rook.rb +50 -0
  63. data/lib/rook/commands.rb +426 -0
  64. data/lib/rook/cookbook.rb +237 -0
  65. data/lib/rook/helper/bz2.rb +39 -0
  66. data/lib/rook/helper/digest.rb +76 -0
  67. data/lib/rook/helper/enumerable.rb +121 -0
  68. data/lib/rook/helper/file.rb +50 -0
  69. data/lib/rook/helper/fileutils.rb +340 -0
  70. data/lib/rook/helper/kernel.rb +108 -0
  71. data/lib/rook/kitchen.rb +668 -0
  72. data/lib/rook/main.rb +280 -0
  73. data/lib/rook/recipe.rb +259 -0
  74. data/lib/rook/rookbook.schema.yaml +156 -0
  75. data/lib/rook/util.rb +172 -0
  76. data/rook.gemspec +56 -0
  77. metadata +139 -45
  78. data/examples/archive/COPYING +0 -340
  79. data/examples/archive/README.txt +0 -1
  80. data/examples/archive/Rookbook +0 -56
  81. data/examples/archive/bin/example +0 -0
  82. data/examples/archive/doc/index.html +0 -0
  83. data/examples/archive/doc/index.txt +0 -0
  84. data/examples/archive/lib/example.rb +0 -0
  85. data/examples/archive/test/test1.rb +0 -0
  86. data/examples/archive/test/test2.rb +0 -0
  87. data/examples/hello_c/Rookbook +0 -24
@@ -0,0 +1,237 @@
1
+ ##
2
+ ## $Rev: 31 $
3
+ ## $Release: 0.1.0 $
4
+ ## copyright(c) 2006 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+
8
+ require 'kwalify'
9
+
10
+ require 'rook/util'
11
+
12
+
13
+
14
+ module Rook
15
+
16
+
17
+
18
+ class CookbookValidator < Kwalify::Validator
19
+
20
+
21
+ filename = nil
22
+ path = $:.find { |dir| test(?f, filename = "#{dir}/rook/rookbook.schema.yaml") }
23
+ path or raise RookError.new("schema file ('rookbook.schema.yaml') is not found.")
24
+ parser = Kwalify::YamlParser.new(File.read(filename))
25
+ @@schema = parser.parse()
26
+
27
+
28
+ def initialize()
29
+ super(@@schema)
30
+ end
31
+
32
+
33
+ def create_error(path, message)
34
+ return Kwalify::ValidationError.new(message, path)
35
+ end
36
+
37
+
38
+ #PROPERTY_NAME_PATTERN = /\A[a-zA-Z_][-\w]*\*?\z/
39
+
40
+
41
+ ##
42
+ def validate_hook(value, rule, path, errors)
43
+ case rule.name
44
+ when 'MATERIAL'
45
+ unless value.is_a?(String) || value.is_a?(Symbol)
46
+ errors << create_error(path, "String or Symbol is required.")
47
+ end
48
+ when 'PROPERTY'
49
+ unless value.key?('value') || value.key?('expr')
50
+ errors << create_error(path, "either 'value' or 'expr' is required.")
51
+ end
52
+ when 'PROP'
53
+ value.each do |k, v|
54
+ if !k.is_a?(String)
55
+ errors << error("#{path}/#{k}", "property name is not a string.")
56
+ elsif k !~ /\A[a-zA-Z_][-\w]*\*?\z/ && k != '.desc'
57
+ errors << error("#{path}/#{k}", "invlaid property name.")
58
+ elsif k[-1] == ?* && !v.is_a?(String)
59
+ errors << create_error("#{path}/#{k}", "expr is not a string.")
60
+ end
61
+ end
62
+ end if rule.name
63
+ end
64
+
65
+
66
+ end
67
+
68
+
69
+
70
+ class CookbookError < RookError
71
+
72
+
73
+ def initialize(message, validation_errors)
74
+ @errors = validation_errors
75
+ end
76
+ attr_reader :errors
77
+
78
+
79
+ end
80
+
81
+
82
+
83
+ ##
84
+ ## represents cookbook
85
+ ##
86
+ ## ex.
87
+ ## cookbooks, errors = Cookbook.load_yamlfile('Rookbook.yaml')
88
+ ## if errors && !errors.empty?
89
+ ## puts "%d: [%s] %s" % [errors.linenum, errors.path, errors.message]
90
+ ## end
91
+ ##
92
+ class Cookbook
93
+ include Assertion
94
+ #include DslHelper
95
+
96
+
97
+ @@validator = CookbookValidator.new
98
+
99
+
100
+ ##
101
+ def initialize(bookname=nil, load_yaml=true, expand_tab=true)
102
+ @precookings = []
103
+ @properties = []
104
+ @variables = []
105
+ @materials = []
106
+ @recipes = []
107
+ @bookname = bookname
108
+ load_yamlfile(bookname, expand_tab) if bookname && load_yaml
109
+ end
110
+ attr_reader :properties, :variables, :recipes, :materials, :precookings
111
+ attr_accessor :bookname
112
+
113
+
114
+ def precooking
115
+ return @precookings.map { |hash| hash['code'] }.join("\n")
116
+ end
117
+
118
+
119
+ def load_yamlfile(bookname, tab_expand=true)
120
+ yaml_str = File.read(bookname)
121
+ yaml_str = Util.untabify(yaml_str) if tab_expand
122
+ return load_yamlstr(yaml_str)
123
+ end
124
+
125
+
126
+ def load_yamlstr(yaml_str)
127
+ parser = Kwalify::YamlParser.new(yaml_str)
128
+ errors = []
129
+ while parser.has_next?
130
+ ydoc = parser.parse()
131
+ next if ydoc.nil?
132
+ errs = @@validator.validate(ydoc)
133
+ if errs && !errs.empty?
134
+ parser.set_errors_linenum(errs)
135
+ errors += errs
136
+ else
137
+ load_ydoc(ydoc, parser)
138
+ end
139
+ end
140
+ errors.empty? or raise CookbookError.new("invalid cookbook", errors)
141
+ end
142
+
143
+
144
+ def load_ydoc(ydoc, parser=nil)
145
+ ydoc = ydoc.dup
146
+ #
147
+ code = ydoc['precooking']
148
+ ydoc['precookings'] = [ { 'code'=>code } ] if code
149
+ #
150
+ [ 'properties', 'variables' ].each do |key|
151
+ next unless ydoc[key]
152
+ list = []
153
+ ydoc[key].each_with_index do |prop, i|
154
+ opts = {}
155
+ prop.keys.each do |k| opts[k.to_s] = prop[k] if k.is_a?(Symbol) end
156
+ prop.each do |name, val|
157
+ next unless name.is_a?(String)
158
+ vkey = name[-1] == ?* ? 'expr' : 'value'
159
+ #name[-1,1] = '' if name[-1] == ?* # TypeError: can't modify frozen string
160
+ name = name[0, name.length-1] if name[-1] == ?*
161
+ h = { 'name'=>name, vkey=>val }
162
+ h.update(opts)
163
+ list << h
164
+ end
165
+ end
166
+ ydoc[key] = list
167
+ end
168
+ #
169
+ @precookings += _load_section(ydoc['precookings'], 'code', parser, 1) { |h, i| "/precooking" }
170
+ @recipes += _load_section(ydoc['recipes'], 'method', parser, 1) { |h, i| "/recipes/#{i}/method" }
171
+ @properties += _load_section(ydoc['properties*'], 'expr', parser, 0) { |h, i| "/properties*/#{i}/expr" }
172
+ @variables += _load_section(ydoc['variables*'], 'expr', parser, 0) { |h, i| "/variables*/#{i}/expr" }
173
+ @properties += _load_section(ydoc['properties'], 'expr', parser, 0) { |h, i| "/properties/#{i}/#{h['name']}*" }
174
+ @variables += _load_section(ydoc['variables'], 'expr', parser, 0) { |h, i| "/variables/#{i}/#{h['name']}*" }
175
+ #
176
+ list = ydoc['materials']
177
+ @materials += list if list
178
+ end
179
+
180
+
181
+ def _load_section(section, attr, parser, delta)
182
+ list = []
183
+ section.each_with_index do |hash, i|
184
+ if parser && hash[attr]
185
+ path = yield(hash, i)
186
+ hash['linenum'] = parser.path_linenum(path) + delta
187
+ end
188
+ list << hash
189
+ end if section
190
+ return list
191
+ end
192
+ private :_load_section
193
+
194
+
195
+ #--
196
+ #def load_dsl(ruby_code)
197
+ # eval(ruby_code, binding(), @bookname, 1)
198
+ #end
199
+ #++
200
+
201
+
202
+ #--
203
+ #def self.load_yamlfile(bookname, tab_expand=true)
204
+ # str = File.read(bookname)
205
+ # str = Util.untabify(str) if tab_expand
206
+ # return load_yamlstr(str, bookname)
207
+ #end
208
+ #
209
+ #
210
+ #def self.load_yamlstr(yaml_str, bookname)
211
+ # parser = Kwalify::YamlParser.new(yaml_str)
212
+ # ydocs = []
213
+ # errors = []
214
+ # books = []
215
+ # while parser.has_next?
216
+ # ydoc = parser.parse()
217
+ # errs = @@validator.validate(ydoc)
218
+ # if errs && !errs.empty?
219
+ # errors += errs
220
+ # else
221
+ # cookbook = self.new
222
+ # cookbook.bookname = bookname
223
+ # cookbook.load_ydoc(ydoc, parser)
224
+ # books << cookbook
225
+ # end
226
+ # end
227
+ # errors.empty? or raise CookbookError.new("invalid cookbook", errors)
228
+ # return books
229
+ #end
230
+ #++
231
+
232
+
233
+ end
234
+
235
+
236
+
237
+ end
@@ -0,0 +1,39 @@
1
+ ##
2
+ ## $Rev: 20 $
3
+ ## $Release: 0.1.0 $
4
+ ## copyright(c) 2006 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+ ## download 'bz2' from http://raa.ruby-lang.org/project/bz2/
8
+
9
+ require 'bz2'
10
+
11
+
12
+ module BZ2
13
+
14
+
15
+ class Reader
16
+
17
+ alias _initialize initialize
18
+
19
+ def initialize(object, small=false)
20
+ _initialize(object, small)
21
+ @_io = object
22
+ end
23
+
24
+ def pos
25
+ @_io.pos
26
+ end
27
+
28
+ def pos=(index)
29
+ @_io.pos = index
30
+ end
31
+
32
+ def rewind
33
+ @_io.rewind
34
+ end
35
+
36
+ end
37
+
38
+
39
+ end
@@ -0,0 +1,76 @@
1
+ ##
2
+ ## $Rev$
3
+ ## $Release: 0.1.0 $
4
+ ## copyright(c) 2006 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+
8
+ require 'digest'
9
+
10
+
11
+
12
+ class Digest::Base
13
+
14
+
15
+ ##
16
+ ## create digest object from file content
17
+ ##
18
+ ## ex.
19
+ ## require 'digest/md5'
20
+ ## digest = Digest::MD5.create_from_file('largefile.mov')
21
+ ## puts digest.hexdigest
22
+ ##
23
+ ## this is faster than 'Digest::MD5.new(File.read("largefile.mov"))'
24
+ ## when file size is large.
25
+ ##
26
+ def self.create_from_file(filename)
27
+ digest = self.new
28
+ File.open(filename) do |f|
29
+ #size = 4 * 1024 # 4KB
30
+ #size = 8 * 1024 # 8KB
31
+ size = 16 * 1024 # 16KB
32
+ #size = 32 * 1024 # 32KB
33
+ #size = 64 * 1024 # 64KB
34
+ #size = 128 * 1024 # 128KB
35
+ #size = 256 * 1024 # 256KB
36
+ #size = 512 * 1024 # 512KB
37
+ #size = 1 * 1024 * 1024 # 1MB
38
+ #size = 4 * 1024 * 1024 # 4MB
39
+ buf = ''
40
+ digest.update(buf) while f.read(size, buf)
41
+ end
42
+ return digest
43
+ end
44
+
45
+
46
+ ##
47
+ ## return hex-digest value of file content
48
+ ##
49
+ ## ex.
50
+ ## require 'digest/md5'
51
+ ## puts Digest::MD5.hex_digest('largefile.mov')
52
+ ##
53
+ ## this is faster than 'Digest::MD5.hex_digest(File.read(filename))'
54
+ ## when file size is large.
55
+ ##
56
+ def self.file_hexdigest(filename)
57
+ return self.create_from_file(filename).hexdigest
58
+ end
59
+
60
+
61
+ ##
62
+ ## return digest value of file content
63
+ ##
64
+ ## ex.
65
+ ## require 'digest/md5'
66
+ ## puts Digest::MD5.digest('largefile.mov')
67
+ ##
68
+ ## this is faster than 'Digest::MD5.digest(File.read(filename))'
69
+ ## when file size is large.
70
+ ##
71
+ def self.file_digest(filename)
72
+ return self.create_from_file(filename).digest
73
+ end
74
+
75
+
76
+ end
@@ -0,0 +1,121 @@
1
+ ##
2
+ ## $Rev: 20 $
3
+ ## $Release: 0.1.0 $
4
+ ## copyright(c) 2006 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+
8
+ module Enumerable
9
+
10
+
11
+ ##
12
+ ## apply method with args
13
+ ##
14
+ ## ex.
15
+ ## [1, 2, 3].apply(:'+', 5) #=> [6, 7, 8]
16
+ ##
17
+ def apply(method_name, *args)
18
+ return self.collect { |item| item.__send__(method_name, *args) }
19
+ end
20
+
21
+
22
+ ##
23
+ ## add prefix for each item
24
+ ##
25
+ ## ex.
26
+ ## ['a', 'b', 'c'].add_prefix('dir/') #=> ["dir/a", "dir/b", "dir/c"]
27
+ ##
28
+ def add_prefix(prefix)
29
+ return self.collect { |item| "#{prefix}#{item}" }
30
+ end
31
+
32
+
33
+ ##
34
+ ## add suffix for each item
35
+ ##
36
+ ## ex.
37
+ ## ['a', 'b', 'c'].add_suffix('.txt') #=> ["a.txt", "b.txt", "c.txt"]
38
+ ##
39
+ def add_suffix(suffix)
40
+ return self.collect { |item| "#{item}#{suffix}" }
41
+ end
42
+
43
+
44
+ ##
45
+ ## add prefix and suffix for each item
46
+ ##
47
+ ## ex.
48
+ ## ['a','b','c'].sandwich('p/', '.s') #=> ["p/a.s", "p/b.s", "p/c.s"]
49
+ ##
50
+ def sandwich(prefix, suffix)
51
+ return self.collect { |item| "#{prefix}#{item}#{suffix}" }
52
+ end
53
+
54
+
55
+ ##
56
+ ## apply 'sub()' method to each item
57
+ ##
58
+ ## ex.
59
+ ## ['a.txt', 'b.txt'].each_sub(/\.txt$/, '.html') #=> ["a.html", "b.html"]
60
+ ##
61
+ def each_sub(pattern, replace, &block)
62
+ if replace
63
+ return self.collect { |item| item.sub(pattern, replace) }
64
+ else
65
+ return self.collect { |item| item.sub(pattern, &block) }
66
+ end
67
+ end
68
+
69
+
70
+ ##
71
+ ## apply 'gsub()' method to each item
72
+ ##
73
+ ## ex.
74
+ ## ['a.txt', 'b.txt'].each_gsub(/\.txt$/, '.html') #=> ["a.html", "b.html"]
75
+ ##
76
+ def each_gsub(pattern, replace, &block)
77
+ if replace
78
+ return self.collect { |item| item.gsub(pattern, replace) }
79
+ else
80
+ return self.collect { |item| item.gsub(pattern, &block) }
81
+ end
82
+ end
83
+
84
+
85
+ ##
86
+ ## delete suffix for each item
87
+ ##
88
+ ## ex.
89
+ ## ['a.txt', 'b.txt'].delete_suffix() #=> ["a", "b"]
90
+ ##
91
+ def delete_suffix(suffix=/\.\w+\z/)
92
+ unless suffix.is_a?(Regexp)
93
+ suffix = Regexp.compile("#{suffix.to_s}\\z")
94
+ end
95
+ return self.collect { |item| item.sub(suffix, '') }
96
+ end
97
+
98
+
99
+ ##
100
+ ## get basename of each item
101
+ ##
102
+ ## ex.
103
+ ## ['dir1/a.txt', 'b.txt'].basenames() #=> ['a.txt', 'b.txt']
104
+ ##
105
+ def basenames
106
+ return self.collect { |item| File.basename(item) }
107
+ end
108
+
109
+
110
+ ##
111
+ ## get dirname of each item
112
+ ##
113
+ ## ex.
114
+ ## ['dir1/a.txt', 'b.txt'].dirnames() #=> ['dir1', '.']
115
+ ##
116
+ def dirnames
117
+ return self.collect { |item| File.dirname(item) }
118
+ end
119
+
120
+
121
+ end