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.
- data/README.txt +124 -37
- data/bin/rook +8 -902
- data/doc-api/classes/BZ2.html +111 -0
- data/doc-api/classes/BZ2/Reader.html +234 -0
- data/doc-api/classes/Digest.html +107 -0
- data/doc-api/classes/Digest/Base.html +254 -0
- data/doc-api/classes/Enumerable.html +430 -0
- data/doc-api/classes/File.html +208 -0
- data/doc-api/classes/FileUtils.html +758 -0
- data/doc-api/classes/Kernel.html +317 -0
- data/doc-api/classes/Rook.html +148 -0
- data/doc-api/classes/Rook/Assertion.html +164 -0
- data/doc-api/classes/Rook/AssertionError.html +111 -0
- data/doc-api/classes/Rook/CommandOptionError.html +113 -0
- data/doc-api/classes/Rook/Commands.html +1158 -0
- data/doc-api/classes/Rook/Cookbook.html +357 -0
- data/doc-api/classes/Rook/CookbookError.html +161 -0
- data/doc-api/classes/Rook/CookbookValidator.html +215 -0
- data/doc-api/classes/Rook/Kitchen.html +875 -0
- data/doc-api/classes/Rook/KitchenHelper.html +386 -0
- data/doc-api/classes/Rook/Main.html +325 -0
- data/doc-api/classes/Rook/Parameters.html +443 -0
- data/doc-api/classes/Rook/Recipe.html +546 -0
- data/doc-api/classes/Rook/RookError.html +111 -0
- data/doc-api/classes/Rook/Util.html +408 -0
- data/doc-api/classes/Rook/Util/UndefinedPropertyError.html +160 -0
- data/doc-api/created.rid +1 -0
- data/doc-api/files/__/README_txt.html +313 -0
- data/doc-api/files/rook/commands_rb.html +115 -0
- data/doc-api/files/rook/cookbook_rb.html +115 -0
- data/doc-api/files/rook/helper/bz2_rb.html +114 -0
- data/doc-api/files/rook/helper/digest_rb.html +114 -0
- data/doc-api/files/rook/helper/enumerable_rb.html +107 -0
- data/doc-api/files/rook/helper/file_rb.html +107 -0
- data/doc-api/files/rook/helper/fileutils_rb.html +124 -0
- data/doc-api/files/rook/helper/kernel_rb.html +107 -0
- data/doc-api/files/rook/kitchen_rb.html +117 -0
- data/doc-api/files/rook/main_rb.html +117 -0
- data/doc-api/files/rook/recipe_rb.html +114 -0
- data/doc-api/files/rook/util_rb.html +115 -0
- data/doc-api/files/rook_rb.html +122 -0
- data/doc-api/fr_class_index.html +50 -0
- data/doc-api/fr_file_index.html +40 -0
- data/doc-api/fr_method_index.html +181 -0
- data/doc-api/index.html +24 -0
- data/doc-api/rdoc-style.css +208 -0
- data/examples/hello_c/Rookbook.rb +37 -0
- data/examples/hello_c/Rookbook.yaml +45 -0
- data/examples/hello_c/hello.c +6 -3
- data/examples/project/README.txt +8 -0
- data/examples/project/Rookbook.props +1 -0
- data/examples/project/Rookbook.rb +120 -0
- data/examples/project/Rookbook.yaml +117 -0
- data/examples/project/bin/example +12 -0
- data/examples/project/example.gemspec +29 -0
- data/examples/project/lib/example.rb +36 -0
- data/examples/{archive → project}/lib/example/bar.rb +0 -0
- data/examples/{archive → project}/lib/example/baz.rb +0 -0
- data/examples/{archive → project}/lib/example/foo.rb +0 -0
- data/examples/project/setup.rb +1331 -0
- data/examples/project/test/test.rb +27 -0
- data/lib/rook.rb +50 -0
- data/lib/rook/commands.rb +426 -0
- data/lib/rook/cookbook.rb +237 -0
- data/lib/rook/helper/bz2.rb +39 -0
- data/lib/rook/helper/digest.rb +76 -0
- data/lib/rook/helper/enumerable.rb +121 -0
- data/lib/rook/helper/file.rb +50 -0
- data/lib/rook/helper/fileutils.rb +340 -0
- data/lib/rook/helper/kernel.rb +108 -0
- data/lib/rook/kitchen.rb +668 -0
- data/lib/rook/main.rb +280 -0
- data/lib/rook/recipe.rb +259 -0
- data/lib/rook/rookbook.schema.yaml +156 -0
- data/lib/rook/util.rb +172 -0
- data/rook.gemspec +56 -0
- metadata +139 -45
- data/examples/archive/COPYING +0 -340
- data/examples/archive/README.txt +0 -1
- data/examples/archive/Rookbook +0 -56
- data/examples/archive/bin/example +0 -0
- data/examples/archive/doc/index.html +0 -0
- data/examples/archive/doc/index.txt +0 -0
- data/examples/archive/lib/example.rb +0 -0
- data/examples/archive/test/test1.rb +0 -0
- data/examples/archive/test/test2.rb +0 -0
- data/examples/hello_c/Rookbook +0 -24
data/README.txt
CHANGED
@@ -1,73 +1,160 @@
|
|
1
|
-
|
2
|
-
.?release: $Release: 0.0.2$
|
3
|
-
.?lastupdated: $Date: 2005-04-30 11:16:15 +0900 (Sat, 30 Apr 2005) $
|
1
|
+
= README
|
4
2
|
|
3
|
+
release:: $Release: 0.1.0 $
|
4
|
+
copyright:: copyright(c) 2006 kuwata-lab.com all rights reserved.
|
5
5
|
|
6
|
-
|
6
|
+
|
7
|
+
|
8
|
+
== Introduction
|
7
9
|
|
8
10
|
Rook is a tool for SCM such as Make, Rake, Ant, and so on.
|
9
|
-
Rook
|
11
|
+
Rook has inspired by Cook which is made by Peter Miller.
|
10
12
|
http://www.canb.auug.org.au/~millerp/cook/cook.html
|
11
13
|
|
14
|
+
Features:
|
15
|
+
* Liken software build process to cooking.
|
16
|
+
* Two-style approach support: YAML-style and Ruby-style.
|
17
|
+
* Natural notation for production rule and optional ingredients.
|
18
|
+
* 'tar.gz', 'tar.bz2', and '.zip' support
|
19
|
+
(requires 'minitar', 'bz2', and 'rubyzip' libraries.)
|
20
|
+
* Able to invoke build command forcedly
|
21
|
+
|
12
22
|
Attention! Rook is under alpha version and specification
|
13
23
|
may change frequently.
|
14
24
|
|
15
25
|
|
16
|
-
.$ Installation
|
17
26
|
|
18
|
-
|
19
|
-
/usr/local/bin or /usr/bin.
|
27
|
+
== Installation
|
20
28
|
|
29
|
+
If you have installed RubyGems, just stype 'gem install -r rook'.
|
30
|
+
$ sudo gem install -r rook
|
21
31
|
|
22
|
-
|
32
|
+
Otherwise download ruby_X.X.X.tar.bz2 and install with setup.rb.
|
33
|
+
$ tar xjf rook_X.X.X.tar.bz2
|
34
|
+
$ cd rook_X.X.X/
|
35
|
+
$ sudo setup.rb
|
23
36
|
|
24
|
-
|
37
|
+
(Must) If you have installed rook without RubyGems, the following
|
38
|
+
libraries must be installed.
|
39
|
+
* abstract.rb (>= 1.0.0) (http://www.rubyforge.org/projects/abstract)
|
40
|
+
* kwalify (>= 0.6.0) (http://www.rubyforge.org/projects/kwalify)
|
25
41
|
|
42
|
+
(Optional) If you want to handle *.tar.gz, *.tar.bz2, or *.zip
|
43
|
+
files, you must install the following libraries.
|
44
|
+
* minitar - http://raa.ruby-lang.org/project/minitar/
|
45
|
+
* bz2 - http://raa.ruby-lang.org/project/bz2/
|
46
|
+
* rubyzip - http://raa.ruby-lang.org/project/rubyzip/
|
26
47
|
|
27
|
-
|
48
|
+
(Optional) Helper script 'ruby_X.X.X/contrib/inline_require.rb'
|
49
|
+
merges 'bin/rook' and rook libraries into a file.
|
50
|
+
$ cd rook_X.X.X/
|
51
|
+
$ unset RUBYLIB
|
52
|
+
$ ruby contrib/inline_require.rb -I lib bin/rook > contrib/rook
|
28
53
|
|
29
|
-
.[ Product ]
|
30
|
-
Product is an output of cooking.
|
31
54
|
|
32
|
-
.[ Ingredient ]
|
33
|
-
Ingredient is materials needed for cooking.
|
34
55
|
|
35
|
-
|
36
|
-
Recipe is a method how to cook product.
|
56
|
+
== Examples
|
37
57
|
|
38
|
-
.
|
39
|
-
|
40
|
-
specified as regular expression.
|
58
|
+
The following is an example of Rookbook.yaml to cook *.c files.
|
59
|
+
(Rookbook is the equivarent to Makefile in Make or Rakefile in Rake.)
|
41
60
|
|
42
|
-
|
43
|
-
|
44
|
-
|
61
|
+
properties:
|
62
|
+
- project: hello
|
63
|
+
- c_flags: '-g -Wall -O2'
|
45
64
|
|
46
|
-
|
47
|
-
|
48
|
-
|
65
|
+
variables:
|
66
|
+
- command: $(project)
|
67
|
+
- objfiles*: Dir.glob('*.c').collect{|f| f.sub(/\.c$/, '.o')}
|
49
68
|
|
69
|
+
recipes:
|
70
|
+
- product: $(command)
|
71
|
+
ingreds: [ $(objfiles) ]
|
72
|
+
desc: create '$(command)' command
|
73
|
+
method: |
|
74
|
+
sys "gcc #{@c_flags} -o #{@product} #{@ingreds.join(' ')}"
|
50
75
|
|
51
|
-
|
76
|
+
- product: *.o
|
77
|
+
ingreds: [ $(1).c ]
|
78
|
+
options: [ $(1).h ]
|
79
|
+
method: |
|
80
|
+
sys "gcc #{@c_flags} -c #{@ingred}"
|
52
81
|
|
53
|
-
|
82
|
+
- product: :clean
|
83
|
+
method: |
|
84
|
+
rm_f Dir.glob("*.o")
|
54
85
|
|
55
86
|
|
56
|
-
|
87
|
+
Rook supports two style of Rookbook: YAML-style and Ruby-style.
|
88
|
+
The following ('Rookbook.rb') is the Ruby-style example of Rookbook
|
89
|
+
which is equivarent to the above YAML-style example.
|
57
90
|
|
58
|
-
|
59
|
-
|
60
|
-
.* [_] Dependency Tree
|
61
|
-
.* [_] Plugin architecture
|
91
|
+
property :project, 'hello'
|
92
|
+
property :c_flags, '-g -Wall -O2'
|
62
93
|
|
94
|
+
command = @project
|
95
|
+
objfiles = Dir.glob('*.c').collect{|f| f.sub(/\.c$/, '.o')}
|
63
96
|
|
64
|
-
|
97
|
+
desc "create '#{command}' command"
|
98
|
+
recipe command, objfiles do |r|
|
99
|
+
sys "gcc #{@c_flags} -o #{@product} #{@ingreds.join(' ')}"
|
100
|
+
end
|
65
101
|
|
66
|
-
|
102
|
+
recipe "*.o", '$(1).c', :options=>['$(1).h'] do |r|
|
103
|
+
sys "gcc #{@c_flags} -c #{@ingred}"
|
104
|
+
end
|
105
|
+
|
106
|
+
recipe :clean do |r|
|
107
|
+
rm_f Dir.glob("*.o")
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
See 'examples/' directory for more examples.
|
112
|
+
|
113
|
+
|
114
|
+
== Documents
|
115
|
+
|
116
|
+
Sorry, there is no documentation.
|
117
|
+
|
118
|
+
|
119
|
+
== Terms
|
120
|
+
|
121
|
+
[ Product ]
|
122
|
+
Output of cooking.
|
67
123
|
|
124
|
+
[ Ingredient ]
|
125
|
+
Materials needed for cooking.
|
68
126
|
|
69
|
-
|
127
|
+
[ Byproduct ]
|
128
|
+
Garbages produced in cooking.
|
70
129
|
|
71
|
-
|
130
|
+
[ Recipe ]
|
131
|
+
Method how to cook product.
|
132
|
+
|
133
|
+
[ Generic recipe ]
|
134
|
+
Recipe which product is specified by pattern.
|
135
|
+
This is equivarent to 'rule' in Rake.
|
136
|
+
|
137
|
+
[ Specific recipe ]
|
138
|
+
Recipe which product is specified by name.
|
139
|
+
This is equivarent to 'file' in Rake.
|
140
|
+
|
141
|
+
[ Symbolic recipe ]
|
142
|
+
Recipe which product is specified by Symbol.
|
143
|
+
This is equivarent to 'task' in Rake.
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
== To Do
|
148
|
+
|
149
|
+
* [_] Documentation
|
150
|
+
* [_] Fingerprint support
|
151
|
+
* [_] Dependency Tree
|
152
|
+
* [_] Plugin architecture
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
== License
|
157
|
+
|
158
|
+
GPL ver2
|
72
159
|
|
73
160
|
|
data/bin/rook
CHANGED
@@ -1,906 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
### $Id: rook 14 2005-04-30 02:16:15Z kwatch $
|
9
|
-
### $Release: 0.0.2$
|
10
|
-
###
|
3
|
+
##
|
4
|
+
## $Rev: 18 $
|
5
|
+
## $Release: 0.1.0 $
|
6
|
+
## copyright(c) 2006 kuwata-lab.com all rights reserved.
|
7
|
+
##
|
11
8
|
|
12
|
-
require '
|
9
|
+
require 'rook'
|
10
|
+
require 'rook/main'
|
13
11
|
|
14
|
-
|
15
|
-
FileUtils.instance_eval "@fileutils_output = $stdout"
|
16
|
-
|
17
|
-
module Rook
|
18
|
-
|
19
|
-
VERSION = ('$Rev: 14 $' =~ /(\d+)/) && $1
|
20
|
-
LAST_UPDATE = ('$Date: 2005-04-30 11:16:15 +0900 (Sat, 30 Apr 2005) $' =~ /([-\d]+)/) && $1
|
21
|
-
RELEASE = ('$Release: 0.0.2$' =~ /([\.\d]+)/) && $1
|
22
|
-
|
23
|
-
$rook_defaults = {
|
24
|
-
:bookname => 'Rookbook', # or 'Cookbook.rb'
|
25
|
-
:target => :default, # or :start
|
26
|
-
:descriptions => {
|
27
|
-
:all => 'create all products',
|
28
|
-
:clean => 'remove by-products',
|
29
|
-
:clear => 'remove all products and by-products',
|
30
|
-
:deploy => 'deploy products',
|
31
|
-
:config => 'configure',
|
32
|
-
:setup => 'setup',
|
33
|
-
:install => 'install products',
|
34
|
-
#:start => 'start cooking',
|
35
|
-
:default => 'default recipe to start'
|
36
|
-
},
|
37
|
-
}
|
38
|
-
$rook_prompt = "rook$ "
|
39
|
-
$rook_current_recipe = nil
|
40
|
-
$rook_properties = {}
|
41
|
-
$rook_context = {}
|
42
|
-
$rook_recipe_desc = nil
|
43
|
-
|
44
|
-
|
45
|
-
class RookError < StandardError
|
46
|
-
end
|
47
|
-
|
48
|
-
class RecipeNotFoundError < RookError
|
49
|
-
end
|
50
|
-
|
51
|
-
class CommandOptionError < RookError
|
52
|
-
end
|
53
|
-
|
54
|
-
class GenericRecipeExecutionError < RookError
|
55
|
-
end
|
56
|
-
|
57
|
-
class RecipeExecutionError < RookError
|
58
|
-
end
|
59
|
-
|
60
|
-
class RecipeError < RookError
|
61
|
-
end
|
62
|
-
|
63
|
-
class IngredientNotFoundError < RookError
|
64
|
-
end
|
65
|
-
|
66
|
-
class CookbookNotFoundError < RookError
|
67
|
-
end
|
68
|
-
|
69
|
-
class AssersionError
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
##
|
74
|
-
##
|
75
|
-
##
|
76
|
-
class Cookbook
|
77
|
-
def initialize(bookname)
|
78
|
-
@bookname = bookname
|
79
|
-
@specific_recipes = []
|
80
|
-
@generic_recipes = []
|
81
|
-
@symbolic_recipes = []
|
82
|
-
#
|
83
|
-
#unless test(?f, @bookname)
|
84
|
-
# raise CookbookNotFoundError.new("`#{@bookname}': cookbook not found.")
|
85
|
-
#end
|
86
|
-
#load(@bookname) ## load cookbook
|
87
|
-
end
|
88
|
-
attr_reader :bookname
|
89
|
-
attr_reader :specific_recipes, :generic_recipes, :symbolic_recipes
|
90
|
-
|
91
|
-
def add_specific_recipe(recipe)
|
92
|
-
@specific_recipes.unshift(recipe)
|
93
|
-
recipe.cookbook = self
|
94
|
-
end
|
95
|
-
|
96
|
-
def add_generic_recipe(recipe)
|
97
|
-
@generic_recipes.unshift(recipe)
|
98
|
-
recipe.cookbook = self
|
99
|
-
end
|
100
|
-
|
101
|
-
def add_symbolic_recipe(recipe)
|
102
|
-
@symbolic_recipes.unshift(recipe)
|
103
|
-
recipe.cookbook = self
|
104
|
-
end
|
105
|
-
|
106
|
-
def add_recipe(recipe)
|
107
|
-
recipe.add_to_cookbook(self)
|
108
|
-
end
|
109
|
-
|
110
|
-
def lookup(product, index=0)
|
111
|
-
if product.is_a?(String) && product[0] == ?:
|
112
|
-
product = product[1, product.length-1].intern
|
113
|
-
end
|
114
|
-
recipe = nil
|
115
|
-
if index == 0
|
116
|
-
case product
|
117
|
-
when Symbol
|
118
|
-
recipe = @symbolic_recipes.find { |r| r.product === product }
|
119
|
-
when String
|
120
|
-
recipe = @specific_recipes.find { |r| r.product === product }
|
121
|
-
if !recipe
|
122
|
-
recipe = @generic_recipes.find { |r| r.product === product }
|
123
|
-
recipe = recipe.specify(product) if recipe
|
124
|
-
end
|
125
|
-
end
|
126
|
-
else
|
127
|
-
case product
|
128
|
-
when Symbol
|
129
|
-
recipes = @symbolic_recipes.find_all { |r| r.product === product }
|
130
|
-
recipe = recipes[index]
|
131
|
-
when String
|
132
|
-
recipes = @specific_recipes.find_all { |r| r.product === product }
|
133
|
-
recipes2 = @generic_recipes.find_all { |r| r.product === product }
|
134
|
-
recipes.concat(recipes2)
|
135
|
-
recipe = recipe[index]
|
136
|
-
recipe = specify(product) if recipe
|
137
|
-
end
|
138
|
-
end
|
139
|
-
return recipe
|
140
|
-
end
|
141
|
-
|
142
|
-
def create_context()
|
143
|
-
context = {
|
144
|
-
:cookbook => self,
|
145
|
-
:dress_level => 0,
|
146
|
-
}
|
147
|
-
return context
|
148
|
-
end
|
149
|
-
|
150
|
-
def _execute()
|
151
|
-
## prework
|
152
|
-
rook_context_bkup = $rook_context
|
153
|
-
$rook_context = create_context()
|
154
|
-
unless test(?f, @bookname)
|
155
|
-
raise CookbookNotFoundError.new("`#{@bookname}': cookbook not found.")
|
156
|
-
end
|
157
|
-
load(@bookname) ## load cookbook
|
158
|
-
## main body
|
159
|
-
yield()
|
160
|
-
## postwork
|
161
|
-
$rook_context = rook_context_bkup
|
162
|
-
end
|
163
|
-
private :_execute
|
164
|
-
|
165
|
-
def start(targets)
|
166
|
-
_execute() do
|
167
|
-
if targets == nil || targets.empty?
|
168
|
-
target = $rook_defaults[:target]
|
169
|
-
recipe = lookup(target)
|
170
|
-
raise AssertionError.new("recipe.class=#{recipe.class.name}") if recipe.kind_of?(GenericRecipe)
|
171
|
-
if recipe
|
172
|
-
recipe.execute()
|
173
|
-
else
|
174
|
-
#raise RecipeNotFoundError.new("#{target}: recipe not found.")
|
175
|
-
puts "*** target is not specified."
|
176
|
-
listup()
|
177
|
-
end
|
178
|
-
else
|
179
|
-
targets.each do |target|
|
180
|
-
target = target[1,target.length-1].intern if target.is_a?(String) && target[0] == ?:
|
181
|
-
recipe = lookup(target)
|
182
|
-
raise RecipeNotFoundError.new("#{target}: recipe not found.") unless recipe
|
183
|
-
raise AssertionError.new("recipe.class=#{recipe.class.name}") if recipe.kind_of?(GenericRecipe)
|
184
|
-
recipe.execute()
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def listup()
|
191
|
-
_listup(@symbolic_recipes, false)
|
192
|
-
_listup(@specific_recipes, false)
|
193
|
-
_listup(@generic_recipes, false)
|
194
|
-
end
|
195
|
-
|
196
|
-
def listup_all()
|
197
|
-
_listup(@symbolic_recipes, true)
|
198
|
-
_listup(@specific_recipes, true)
|
199
|
-
_listup(@generic_recipes, true)
|
200
|
-
end
|
201
|
-
|
202
|
-
def _listup(recipe_list, flag_all=true)
|
203
|
-
_execute() do
|
204
|
-
list = []; hash = {}
|
205
|
-
recipe_list.each do |recipe|
|
206
|
-
next if hash.key?(recipe.product)
|
207
|
-
next unless flag_all || recipe.desc
|
208
|
-
hash[recipe.product] = true
|
209
|
-
list << recipe
|
210
|
-
end
|
211
|
-
list.reverse.each do |recipe|
|
212
|
-
product = recipe.product
|
213
|
-
display_name = recipe.display_name
|
214
|
-
#display_name = product.is_a?(String) ? product : product.inspect
|
215
|
-
description = recipe.desc || '(no description)'
|
216
|
-
puts(" %-20s - %s" % [ display_name, description ])
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
end
|
222
|
-
|
223
|
-
|
224
|
-
##
|
225
|
-
##
|
226
|
-
##
|
227
|
-
class Recipe
|
228
|
-
|
229
|
-
def add_to_cookbook
|
230
|
-
raise AssertionError.new("Recipe#add_to_cookbook() not implemented.")
|
231
|
-
end
|
232
|
-
|
233
|
-
def initialize(product, *ingredients, &steps)
|
234
|
-
@product = product
|
235
|
-
@ingredients = []
|
236
|
-
ingredients.each do |ingred|
|
237
|
-
add_ingredient(ingred)
|
238
|
-
end if ingredients
|
239
|
-
@steps = steps
|
240
|
-
@matched = nil
|
241
|
-
@cookbook = nil
|
242
|
-
@desc = nil
|
243
|
-
end
|
244
|
-
|
245
|
-
def self.create(product, *ingredients, &steps)
|
246
|
-
self.new(product, *ingredients, &steps)
|
247
|
-
end
|
248
|
-
|
249
|
-
attr_accessor :product, :ingredients, :steps, :matched, :cookbook, :desc
|
250
|
-
|
251
|
-
alias :prod :product
|
252
|
-
alias :ingreds :ingredients
|
253
|
-
def ingredient
|
254
|
-
return @ingredients[0]
|
255
|
-
end
|
256
|
-
alias :ingred :ingredient
|
257
|
-
|
258
|
-
attr_writer :display_name
|
259
|
-
def display_name
|
260
|
-
return @display_name || @product
|
261
|
-
end
|
262
|
-
|
263
|
-
def add_ingredient(ingred)
|
264
|
-
case ingred
|
265
|
-
when String, Symbol, Proc, Hash
|
266
|
-
@ingredients << ingred
|
267
|
-
when Array
|
268
|
-
ingred.each do |ingred2|
|
269
|
-
add_ingredient(ingred2)
|
270
|
-
end
|
271
|
-
when Regexp
|
272
|
-
raise ReicpeError.new("#{ingred.to_s}: regexp is not avairable as ingredient.")
|
273
|
-
else
|
274
|
-
raise RecipeError.new("`#{ingred.to_s}'(class #{ingred.class.name}): ingredient is invalid object.")
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
def execute(depth=0)
|
279
|
-
bkup = $rook_current_recipe
|
280
|
-
$rook_current_recipe = self
|
281
|
-
puts "### #{self.product.to_s}" unless $rook_properties[:QUIET]
|
282
|
-
@steps.call(self) if @steps
|
283
|
-
$rook_current_recipe = bkup
|
284
|
-
return true
|
285
|
-
end
|
286
|
-
|
287
|
-
def specify(product)
|
288
|
-
raise AssertionError.new("Root#specify() is called.")
|
289
|
-
end
|
290
|
-
|
291
|
-
end
|
292
|
-
|
293
|
-
|
294
|
-
##
|
295
|
-
##
|
296
|
-
##
|
297
|
-
class SpecificRecipe < Recipe
|
298
|
-
|
299
|
-
def add_to_cookbook(cookbook)
|
300
|
-
cookbook.add_specific_recipe(self)
|
301
|
-
end
|
302
|
-
|
303
|
-
def initialize(product, *ingredients, &steps)
|
304
|
-
super(product, *ingredients, &steps)
|
305
|
-
end
|
306
|
-
|
307
|
-
def self.create(product, *ingredients, &steps)
|
308
|
-
recipe = self.new(product, *ingredients, &steps)
|
309
|
-
if ingredients.find { |ingred| ingred.is_a?(Hash) }
|
310
|
-
raise RecipeError.new("`#{product}': specific recipe can't take a hash as an ingredient.")
|
311
|
-
end
|
312
|
-
return recipe
|
313
|
-
end
|
314
|
-
|
315
|
-
def specify(product)
|
316
|
-
return self
|
317
|
-
end
|
318
|
-
|
319
|
-
def execute(depth=0)
|
320
|
-
flag_execute = false
|
321
|
-
if @ingredients.empty?
|
322
|
-
flag_execute = true
|
323
|
-
else
|
324
|
-
if test(?e, @product)
|
325
|
-
prod_mtime = File.mtime(@product)
|
326
|
-
else
|
327
|
-
prod_mtime = nil
|
328
|
-
flag_execute = true
|
329
|
-
end
|
330
|
-
@ingredients.each do |ingred|
|
331
|
-
ingred_recipe = cookbook().lookup(ingred)
|
332
|
-
if ingred_recipe
|
333
|
-
flag = ingred_recipe.execute(depth+1)
|
334
|
-
flag_execute = true if flag
|
335
|
-
end
|
336
|
-
if !flag_execute && _ingred_newer?(ingred, prod_mtime)
|
337
|
-
flag_execute = true
|
338
|
-
end
|
339
|
-
end
|
340
|
-
unless $rook_properties[:noact]
|
341
|
-
@ingredients.each do |ingred|
|
342
|
-
if ingred.is_a?(String) && !test(?e, ingred)
|
343
|
-
raise IngredientNotFoundError.new("`#{ingred}': ingredient not found (required by `#{@product}').")
|
344
|
-
end
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
348
|
-
if flag_execute || $rook_properties[:FORCE] || (depth == 0 && $rook_properties[:force])
|
349
|
-
begin
|
350
|
-
super(depth)
|
351
|
-
rescue RecipeExecutionError => ex
|
352
|
-
File.delete(@product) if test(?f, @product)
|
353
|
-
raise ex
|
354
|
-
end
|
355
|
-
end
|
356
|
-
return flag_execute
|
357
|
-
end
|
358
|
-
|
359
|
-
def _ingred_newer?(ingred, prod_mtime)
|
360
|
-
return ingred.is_a?(String) && test(?e, ingred) && prod_mtime && prod_mtime < File.mtime(ingred)
|
361
|
-
end
|
362
|
-
|
363
|
-
end
|
364
|
-
|
365
|
-
|
366
|
-
##
|
367
|
-
##
|
368
|
-
##
|
369
|
-
class GenericRecipe < Recipe
|
370
|
-
def add_to_cookbook(cookbook)
|
371
|
-
cookbook.add_generic_recipe(self)
|
372
|
-
end
|
373
|
-
|
374
|
-
def initialize(product_pattern, *ingredients, &steps)
|
375
|
-
super(product_pattern, *ingredients, &steps)
|
376
|
-
end
|
377
|
-
|
378
|
-
def self.create(product_pattern, *ingredients, &steps)
|
379
|
-
recipe = self.new(product_pattern, *ingredients, &steps)
|
380
|
-
return recipe
|
381
|
-
end
|
382
|
-
|
383
|
-
def display_name
|
384
|
-
return @display_name || @product.inspect
|
385
|
-
end
|
386
|
-
|
387
|
-
## generates specific recipe
|
388
|
-
def specify(product)
|
389
|
-
ingred_list = []
|
390
|
-
pattern = @product
|
391
|
-
pattern =~ product
|
392
|
-
m = [ $&, $1, $2, $3, $4, $5 ]
|
393
|
-
@ingredients.each do |ingred|
|
394
|
-
case ingred
|
395
|
-
when String
|
396
|
-
ingred2 = expand_matched(ingred, m)
|
397
|
-
ingred_list << ingred2
|
398
|
-
when Symbol
|
399
|
-
ingred_list << ingred
|
400
|
-
when Proc
|
401
|
-
result = ingred.call(product)
|
402
|
-
ingred_list << result if result
|
403
|
-
when Hash
|
404
|
-
ingred.each do |key, val|
|
405
|
-
case key
|
406
|
-
when :if_exists
|
407
|
-
ingred2 = expand_matched(val, m)
|
408
|
-
ingred_list << ingred2 if test(?e, ingred2)
|
409
|
-
else
|
410
|
-
raise RecipeError.new("`:#{key.id2name}': invalid keyword.")
|
411
|
-
end
|
412
|
-
end
|
413
|
-
else
|
414
|
-
raise RecipeError.new("#{product.to_s}(class #{product.class.name}): invalid product.")
|
415
|
-
end
|
416
|
-
end if @ingredients
|
417
|
-
recipe = SpecificRecipe.new(product, *ingred_list, &@steps)
|
418
|
-
recipe.matched = m
|
419
|
-
recipe.cookbook = self.cookbook()
|
420
|
-
return recipe
|
421
|
-
end
|
422
|
-
|
423
|
-
def execute(depth=0)
|
424
|
-
raise GenericRecipeExecutionError.new("cannot execute generic recipe.")
|
425
|
-
end
|
426
|
-
|
427
|
-
end
|
428
|
-
|
429
|
-
|
430
|
-
##
|
431
|
-
##
|
432
|
-
##
|
433
|
-
class SymbolicRecipe < Recipe
|
434
|
-
|
435
|
-
def add_to_cookbook(cookbook)
|
436
|
-
cookbook.add_symbolic_recipe(self)
|
437
|
-
end
|
438
|
-
|
439
|
-
def initialize(product_pattern, *ingredients, &steps)
|
440
|
-
super(product_pattern, *ingredients, &steps)
|
441
|
-
end
|
442
|
-
|
443
|
-
def self.create(product, *ingredients, &steps)
|
444
|
-
recipe = self.new(product, *ingredients, &steps)
|
445
|
-
if ingredients.find { |ingred| ingred.is_a?(Hash) }
|
446
|
-
raise RecipeError.new("`#{product}': symbolic recipe can't take a hash as an ingredient.")
|
447
|
-
end
|
448
|
-
return recipe
|
449
|
-
end
|
450
|
-
|
451
|
-
def display_name
|
452
|
-
return @display_name || @product.inspect
|
453
|
-
end
|
454
|
-
|
455
|
-
def execute(depth=0)
|
456
|
-
@ingredients.each do |ingred|
|
457
|
-
recipe = cookbook().lookup(ingred)
|
458
|
-
if recipe
|
459
|
-
flag = recipe.execute(depth+1)
|
460
|
-
flag_execute = true if flag
|
461
|
-
end
|
462
|
-
end
|
463
|
-
super(depth)
|
464
|
-
return true
|
465
|
-
#flag_execute = false
|
466
|
-
#if @ingredients.empty?
|
467
|
-
# flag_execute = true
|
468
|
-
#else
|
469
|
-
# @ingredients.each do |ingred|
|
470
|
-
# recipe = cookbook().lookup(ingred)
|
471
|
-
# if recipe
|
472
|
-
# flag = recipe.execute(depth+1)
|
473
|
-
# flag_execute = true if flag
|
474
|
-
# end
|
475
|
-
# end
|
476
|
-
#end
|
477
|
-
#if flag_execute
|
478
|
-
# super(depth)
|
479
|
-
#end
|
480
|
-
#return flag_execute
|
481
|
-
end
|
482
|
-
|
483
|
-
def specify(product)
|
484
|
-
raise AssertionError.new("SymbolicRecipe#specify is called.")
|
485
|
-
end
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
|
-
|
490
|
-
module RookCommand
|
491
|
-
|
492
|
-
##
|
493
|
-
##
|
494
|
-
##
|
495
|
-
def desc(description=nil)
|
496
|
-
$rook_recipe_desc = description
|
497
|
-
end
|
498
|
-
|
499
|
-
def recipe(product, *ingredients, &steps)
|
500
|
-
cookbook = $rook_context[:cookbook]
|
501
|
-
case product
|
502
|
-
when String
|
503
|
-
recipe = Rook::SpecificRecipe.create(product, *ingredients, &steps)
|
504
|
-
cookbook.add_specific_recipe(recipe)
|
505
|
-
when Regexp
|
506
|
-
recipe = Rook::GenericRecipe.create(product, *ingredients, &steps)
|
507
|
-
cookbook.add_generic_recipe(recipe)
|
508
|
-
when Symbol
|
509
|
-
recipe = Rook::SymbolicRecipe.create(product, *ingredients, &steps)
|
510
|
-
cookbook.add_symbolic_recipe(recipe)
|
511
|
-
end
|
512
|
-
## set description
|
513
|
-
if $rook_recipe_desc == nil
|
514
|
-
recipe.desc = $rook_defaults[:descriptions][product]
|
515
|
-
elsif $rook_recipe_desc == false
|
516
|
-
recipe.desc = nil
|
517
|
-
else
|
518
|
-
recipe.desc = $rook_recipe_desc
|
519
|
-
end
|
520
|
-
$rook_recipe_desc = nil
|
521
|
-
return recipe
|
522
|
-
end
|
523
|
-
|
524
|
-
def grecipe(product, *ingredients, &steps)
|
525
|
-
## convert wildcard ('*', '?', and '{}') into Regexp
|
526
|
-
s = product.to_s
|
527
|
-
s = Regexp::quote(s)
|
528
|
-
s.gsub!(/(\\\?+)/) { |m| '(' + ('.' * m.length) + ')' }
|
529
|
-
s.gsub!(/(\\\*)/, '(.*?)')
|
530
|
-
s.gsub!(/(\\\{(.*?)\\\})/) { '(' + $2.gsub(/\\\|/, '|') + ')' }
|
531
|
-
s.gsub!(/%/, '(.*?)')
|
532
|
-
regexp = Regexp::compile("^#{s}$")
|
533
|
-
r = recipe(regexp, *ingredients, &steps)
|
534
|
-
r.display_name = product
|
535
|
-
return r
|
536
|
-
end
|
537
|
-
|
538
|
-
def rook(*targets)
|
539
|
-
bookname = $rook_context[:cookbook].bookname
|
540
|
-
cookbook = Rook::Cookbook.new(bookname)
|
541
|
-
targets = expand_matched(targets, m()) if m()
|
542
|
-
cookbook.start(targets)
|
543
|
-
end
|
544
|
-
|
545
|
-
def dress(product=nil)
|
546
|
-
product = $rook_current_recipe.product if !product
|
547
|
-
$rook_context[:dress_level] += 1
|
548
|
-
recipe = $root_context[:cookbook].lookup(product, $rook_context[:dress_level])
|
549
|
-
recipe.execute()
|
550
|
-
$rook_context[:dress_level] -= 1
|
551
|
-
end
|
552
|
-
|
553
|
-
def set_prompt(prompt)
|
554
|
-
$rook_prompt = prompt
|
555
|
-
end
|
556
|
-
|
557
|
-
def get_prompt()
|
558
|
-
$rook_prompt
|
559
|
-
end
|
560
|
-
|
561
|
-
|
562
|
-
def expand_matched(obj, m=nil)
|
563
|
-
m = $rook_current_recipe.matched unless m
|
564
|
-
return obj unless m
|
565
|
-
case obj
|
566
|
-
when String
|
567
|
-
if m
|
568
|
-
obj = obj.dup
|
569
|
-
obj.gsub!(/\{0\}/, m[0]) if m[0]
|
570
|
-
obj.gsub!(/\{1\}/, m[1]) if m[1]
|
571
|
-
obj.gsub!(/\{2\}/, m[2]) if m[2]
|
572
|
-
obj.gsub!(/\{3\}/, m[3]) if m[3]
|
573
|
-
obj.gsub!(/\{4\}/, m[4]) if m[4]
|
574
|
-
obj.gsub!(/\{5\}/, m[5]) if m[5]
|
575
|
-
end
|
576
|
-
when Array
|
577
|
-
obj = obj.collect { |item| expand_matched(item, m) }
|
578
|
-
end
|
579
|
-
return obj
|
580
|
-
end
|
581
|
-
private :expand_matched
|
582
|
-
|
583
|
-
def m()
|
584
|
-
return $rook_current_recipe.matched
|
585
|
-
end
|
586
|
-
|
587
|
-
def _cmd(cmd_str, prompt, ignore_error)
|
588
|
-
cmd_str = expand_matched(cmd_str, m()) if m()
|
589
|
-
print get_prompt(), cmd_str, "\n" unless $rook_properties[:quiet]
|
590
|
-
unless $rook_properties[:noact]
|
591
|
-
result = system(cmd_str)
|
592
|
-
else
|
593
|
-
result = true
|
594
|
-
end
|
595
|
-
unless result || ignore_error
|
596
|
-
raise Rook::RecipeExecutionError.new("command failed: `#{cmd_str}'")
|
597
|
-
end
|
598
|
-
return result
|
599
|
-
end
|
600
|
-
private :_cmd
|
601
|
-
|
602
|
-
def cmd(cmd_str, prompt=$rook_prompt)
|
603
|
-
_cmd(cmd_str, prompt, false)
|
604
|
-
end
|
605
|
-
alias :sh :cmd
|
606
|
-
alias :cmd :cmd
|
607
|
-
#alias :do :cmd
|
608
|
-
|
609
|
-
def cmd!(cmd_str, prompt=$rook_prompt)
|
610
|
-
cmd(cmd_str, prompt, true)
|
611
|
-
end
|
612
|
-
alias sh! cmd!
|
613
|
-
#alias do! cmd!
|
614
|
-
|
615
|
-
def echo(*args)
|
616
|
-
args = expand_matched(args, m()) if m()
|
617
|
-
unless $rook_properties[:noact]
|
618
|
-
echo_n(*args)
|
619
|
-
puts
|
620
|
-
end
|
621
|
-
end
|
622
|
-
|
623
|
-
def echo_n(*args)
|
624
|
-
unless $rook_properties[:noact]
|
625
|
-
print args.flatten.join(" ")
|
626
|
-
end
|
627
|
-
end
|
628
|
-
|
629
|
-
|
630
|
-
def chdir(dir, &block)
|
631
|
-
dir = expand_matched(dir, m()) if m()
|
632
|
-
opts = {}
|
633
|
-
opts[:noop] = true if $rook_properties[:noact]
|
634
|
-
opts[:verbose] = true if ! $rook_properties[:quiet]
|
635
|
-
print get_prompt() if opts[:verbose]
|
636
|
-
FileUtils.chdir(dir, opts, &block)
|
637
|
-
end
|
638
|
-
alias :cd :chdir
|
639
|
-
|
640
|
-
def _command1(command, args)
|
641
|
-
args = args.flatten
|
642
|
-
args = expand_matched(args, m()) if m()
|
643
|
-
opts = {}
|
644
|
-
opts[:noop] = true if $rook_properties[:noact]
|
645
|
-
opts[:verbose] = true if ! $rook_properties[:quiet]
|
646
|
-
print get_prompt() if opts[:verbose]
|
647
|
-
FileUtils.__send__(command, args, opts)
|
648
|
-
end
|
649
|
-
private :_command1
|
650
|
-
|
651
|
-
def mkdir(*dirs)
|
652
|
-
_command1(:mkdir, dirs)
|
653
|
-
end
|
654
|
-
|
655
|
-
def mkdir_p(*dirs)
|
656
|
-
_command1(:mkdir_p, dirs)
|
657
|
-
end
|
658
|
-
|
659
|
-
def rmdir(*dirs)
|
660
|
-
_command1(:rmdir, dirs)
|
661
|
-
end
|
662
|
-
|
663
|
-
def remove(*files)
|
664
|
-
_command1(:rm, files)
|
665
|
-
end
|
666
|
-
alias :rm :remove
|
667
|
-
|
668
|
-
def remove_r(*files)
|
669
|
-
_command1(:rm_r, files)
|
670
|
-
end
|
671
|
-
alias :rm_r :remove_r
|
672
|
-
|
673
|
-
def remove_rf(*files)
|
674
|
-
_command1(:rm_rf, files)
|
675
|
-
end
|
676
|
-
alias :rm_rf :remove_rf
|
677
|
-
|
678
|
-
|
679
|
-
def _command1_ifexists(command, files)
|
680
|
-
list = files.flatten.find_all { |f| test(?e, f) }
|
681
|
-
_command1(command, list) unless list.empty?
|
682
|
-
end
|
683
|
-
|
684
|
-
def delete(*files)
|
685
|
-
_command1_ifexists(:rm, files)
|
686
|
-
end
|
687
|
-
alias :del :delete
|
688
|
-
|
689
|
-
def delete_r(*files)
|
690
|
-
_command1_ifexists(:rm_r, files)
|
691
|
-
end
|
692
|
-
alias :del_r :delete_r
|
693
|
-
|
694
|
-
def delete_rf(*files)
|
695
|
-
_command1_ifexists(:rm_rf, files)
|
696
|
-
end
|
697
|
-
alias :del_rf :delete_rf
|
698
|
-
|
699
|
-
|
700
|
-
def _command2(command, args)
|
701
|
-
args = args.flatten
|
702
|
-
args = expand_matched(args, m()) if m()
|
703
|
-
src = dest = nil
|
704
|
-
if args.length == 1
|
705
|
-
src = args[0]
|
706
|
-
elsif args.length > 1
|
707
|
-
dest = args.pop
|
708
|
-
src = args
|
709
|
-
end
|
710
|
-
opts = {}
|
711
|
-
opts[:noop] = true if $rook_properties[:noact]
|
712
|
-
opts[:verbose] = true if !$rook_properties[:quiet]
|
713
|
-
print get_prompt() if opts[:verbose]
|
714
|
-
FileUtils.__send__(command, src, dest, opts)
|
715
|
-
end
|
716
|
-
private :_command2
|
717
|
-
|
718
|
-
def copy(*args)
|
719
|
-
_command2(:cp, args)
|
720
|
-
end
|
721
|
-
alias :cp :copy
|
722
|
-
|
723
|
-
def copy_r(*args)
|
724
|
-
_command2(:cp_r, args)
|
725
|
-
end
|
726
|
-
alias :cp_r :copy_r
|
727
|
-
|
728
|
-
def move(*args)
|
729
|
-
_command2(:mv, args)
|
730
|
-
end
|
731
|
-
alias :mv :move
|
732
|
-
|
733
|
-
def store(*args, &filter)
|
734
|
-
args = args.flatten
|
735
|
-
args = expand_matched(args, m()) if m()
|
736
|
-
store_to = args.pop
|
737
|
-
src_files = []
|
738
|
-
args.each do |file|
|
739
|
-
src_files.concat Dir.glob(file)
|
740
|
-
end
|
741
|
-
src_files.delete_if { |f| !filter.call(f) } if filter
|
742
|
-
if ! $rook_properties[:quiet]
|
743
|
-
print get_prompt()
|
744
|
-
print "store #{args.join(' ')} #{store_to}"
|
745
|
-
puts
|
746
|
-
end
|
747
|
-
if ! $rook_properties[:noact]
|
748
|
-
src_files.each do |f|
|
749
|
-
srcdir = File::dirname(f)
|
750
|
-
destdir = "#{store_to}/#{srcdir}"
|
751
|
-
FileUtils.mkdir_p(destdir) unless test(?d, destdir)
|
752
|
-
FileUtils.cp_r(f, destdir) unless test(?d, f)
|
753
|
-
end
|
754
|
-
end
|
755
|
-
end
|
756
|
-
|
757
|
-
end
|
758
|
-
|
759
|
-
|
760
|
-
module Rook
|
761
|
-
##
|
762
|
-
##
|
763
|
-
##
|
764
|
-
class Main
|
765
|
-
def initialize(argv = ARGV)
|
766
|
-
@argv = argv
|
767
|
-
end
|
768
|
-
|
769
|
-
def execute
|
770
|
-
options, properties = parse_argv(@argv)
|
771
|
-
if properties[:help]
|
772
|
-
properties.delete(:help)
|
773
|
-
options[?h] = true
|
774
|
-
end
|
775
|
-
if properties[:version]
|
776
|
-
properties.delete(:version)
|
777
|
-
options[?v] = true
|
778
|
-
end
|
779
|
-
if options[?h] || options[?v]
|
780
|
-
command = File::basename($0)
|
781
|
-
puts "#{command} - a SCM (Software Cooking Method) tool" if options[?h]
|
782
|
-
puts version() if options[?v]
|
783
|
-
puts usage() if options[?h]
|
784
|
-
return
|
785
|
-
end
|
786
|
-
properties[:noact] = true if options[?n]
|
787
|
-
properties[:quiet] = true if options[?q]
|
788
|
-
properties[:quiet] = properties[:QUIET] = true if options[?Q]
|
789
|
-
properties[:force] = true if options[?f]
|
790
|
-
properties[:force] = properties[:FORCE] = true if options[?F]
|
791
|
-
$rook_properties = properties
|
792
|
-
$rook_prompt = options[?p] if options[?p]
|
793
|
-
#
|
794
|
-
bookname = options[?b] || $rook_defaults[:bookname]
|
795
|
-
cookbook = Cookbook.new(bookname)
|
796
|
-
if options[?l] || options[?T]
|
797
|
-
cookbook.listup()
|
798
|
-
elsif options[?L]
|
799
|
-
cookbook.listup_all()
|
800
|
-
else
|
801
|
-
targets = @argv
|
802
|
-
cookbook.start(targets)
|
803
|
-
#elsif !@argv.empty?
|
804
|
-
# targets = @argv
|
805
|
-
# cookbook.start(targets)
|
806
|
-
#elsif cookbook.lookup($rook_defaults[:target]) == nil
|
807
|
-
# puts "*** target is not specified."
|
808
|
-
# cookbook.listup()
|
809
|
-
#else
|
810
|
-
# target = $rook_defaults[:target]
|
811
|
-
# cookbook.start([target])
|
812
|
-
end
|
813
|
-
end
|
814
|
-
|
815
|
-
def usage()
|
816
|
-
command = File::basename($0)
|
817
|
-
s = ""
|
818
|
-
s << "usage: #{command} [options] target-product\n"
|
819
|
-
s << " -h : help\n"
|
820
|
-
s << " -v : version\n"
|
821
|
-
s << " -b cookbook : cookbook (default `#{$rook_defaults[:bookname]}')\n"
|
822
|
-
s << " -p prompt : set prompt\n"
|
823
|
-
s << " -n : no execute\n"
|
824
|
-
s << " -q : quiet\n"
|
825
|
-
s << " -Q : more quiet\n"
|
826
|
-
s << " -l : list described recipes\n"
|
827
|
-
s << " -L : list all recipes\n"
|
828
|
-
s << " -f : force\n"
|
829
|
-
s << " -F : force strongly\n"
|
830
|
-
end
|
831
|
-
|
832
|
-
def version()
|
833
|
-
return "Release: #{Rook::RELEASE} (Revision: #{Rook::VERSION})"
|
834
|
-
end
|
835
|
-
|
836
|
-
def parse_argv(argv)
|
837
|
-
options = []
|
838
|
-
properties = {}
|
839
|
-
while argv[0] && argv[0][0] == ?-
|
840
|
-
optstr = argv.shift.dup
|
841
|
-
optstr.gsub!(/\A-/, '')
|
842
|
-
if optstr[0] == ?-
|
843
|
-
optstr.gsub!(/\A-/, '')
|
844
|
-
if optstr =~ /\A([-\w]+)(=(.*))?\z/
|
845
|
-
prop_name = $1.gsub(/-/, '_')
|
846
|
-
prop_value = $3
|
847
|
-
properties[prop_name.intern] = prop_value == nil ? true : parse_value(prop_value)
|
848
|
-
end
|
849
|
-
else
|
850
|
-
while optstr && !optstr.empty?
|
851
|
-
optchar = optstr[0]
|
852
|
-
optstr.gsub!(/\A./, '')
|
853
|
-
case optchar
|
854
|
-
when ?h, ?v, ?n, ?q, ?Q, ?f, ?F, ?l, ?L
|
855
|
-
options[optchar] = true
|
856
|
-
when ?b, ?p
|
857
|
-
arg = optstr.empty? ? ARGV.shift : opstr
|
858
|
-
optstr = nil
|
859
|
-
unless arg
|
860
|
-
case optchar
|
861
|
-
when ?f ; msg = "-#{optchar.chr}: cookbook required."
|
862
|
-
when ?p ; msg = "-#{optchar.chr}: prompt required."
|
863
|
-
end
|
864
|
-
raise CommandOptionError.new(msg)
|
865
|
-
end
|
866
|
-
options[optchar] = arg
|
867
|
-
else
|
868
|
-
raise CommandOptionError.new("-#{optchar.chr}: invalid option.")
|
869
|
-
end
|
870
|
-
end
|
871
|
-
end
|
872
|
-
end
|
873
|
-
return options, properties
|
874
|
-
end
|
875
|
-
|
876
|
-
def parse_value(value)
|
877
|
-
case value
|
878
|
-
when 'true', 'yes' ; return true
|
879
|
-
when 'false', 'no' ; return false
|
880
|
-
when 'nil', 'null' ; return nil
|
881
|
-
when /\A\d+\z/ ; return value.to_i # eval(value)
|
882
|
-
when /\A\d+\.\d+\z/ ; return value.to_f # eval(value)
|
883
|
-
when /\A\/(.*)\/\z/ ; return Regexp.compile($1) # eval(value)
|
884
|
-
when /\A:(.*)\z/ ; return $1.intern # eval(value)
|
885
|
-
when /\A'.*'\z/ ; return eval(value)
|
886
|
-
when /\A".*"\z/ ; return eval(value) # unsafe?
|
887
|
-
else ; return value
|
888
|
-
end
|
889
|
-
end
|
890
|
-
end
|
891
|
-
|
892
|
-
end
|
893
|
-
|
894
|
-
|
895
|
-
#if __FILE__ == $0
|
896
|
-
include RookCommand
|
897
|
-
begin
|
898
|
-
main = Rook::Main.new(ARGV)
|
899
|
-
main.execute
|
900
|
-
rescue Rook::RookError => ex
|
901
|
-
$stderr.puts "[ERROR] #{ex.message}"
|
902
|
-
#if ex.class == CommandOptionError
|
903
|
-
# $stderr.puts main.usage()
|
904
|
-
#end
|
905
|
-
end
|
906
|
-
#end
|
12
|
+
Rook::Main.main(ARGV)
|