linecook 0.6.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/History +60 -0
- data/License.txt +22 -0
- data/README +98 -0
- data/bin/linecook +58 -0
- data/cookbook +0 -0
- data/lib/linecook/attributes.rb +22 -0
- data/lib/linecook/commands/command.rb +48 -0
- data/lib/linecook/commands/command_error.rb +6 -0
- data/lib/linecook/commands/env.rb +23 -0
- data/lib/linecook/commands/helper.rb +51 -0
- data/lib/linecook/commands/helpers.rb +28 -0
- data/lib/linecook/commands/init.rb +82 -0
- data/lib/linecook/commands/package.rb +39 -0
- data/lib/linecook/commands/vbox.rb +85 -0
- data/lib/linecook/commands.rb +6 -0
- data/lib/linecook/cookbook.rb +104 -0
- data/lib/linecook/helper.rb +117 -0
- data/lib/linecook/package.rb +197 -0
- data/lib/linecook/recipe.rb +103 -0
- data/lib/linecook/shell/posix.rb +145 -0
- data/lib/linecook/shell/test.rb +254 -0
- data/lib/linecook/shell/unix.rb +117 -0
- data/lib/linecook/shell/utils.rb +138 -0
- data/lib/linecook/shell.rb +11 -0
- data/lib/linecook/template.rb +111 -0
- data/lib/linecook/test/file_test.rb +77 -0
- data/lib/linecook/test/regexp_escape.rb +86 -0
- data/lib/linecook/test.rb +172 -0
- data/lib/linecook/utils.rb +53 -0
- data/lib/linecook/version.rb +8 -0
- data/lib/linecook.rb +6 -0
- data/templates/Gemfile +2 -0
- data/templates/README +90 -0
- data/templates/Rakefile +149 -0
- data/templates/_gitignore +5 -0
- data/templates/attributes/project_name.rb +4 -0
- data/templates/cookbook +9 -0
- data/templates/files/file.txt +1 -0
- data/templates/helpers/project_name/echo.erb +5 -0
- data/templates/project_name.gemspec +30 -0
- data/templates/recipes/project_name.rb +20 -0
- data/templates/scripts/project_name.yml +7 -0
- data/templates/templates/template.txt.erb +3 -0
- data/templates/vbox/setup/virtual_box +86 -0
- data/templates/vbox/ssh/id_rsa +27 -0
- data/templates/vbox/ssh/id_rsa.pub +1 -0
- metadata +166 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'linecook/package'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Linecook
|
5
|
+
class Cookbook
|
6
|
+
class << self
|
7
|
+
def config_file(dir)
|
8
|
+
Dir.glob(File.join(dir, '{C,c}ookbook')).first
|
9
|
+
end
|
10
|
+
|
11
|
+
def init(dir)
|
12
|
+
path = config_file(dir)
|
13
|
+
config = path ? YAML.load_file(path) : nil
|
14
|
+
|
15
|
+
new(dir, config || {})
|
16
|
+
end
|
17
|
+
|
18
|
+
def gems
|
19
|
+
return [] unless Object.const_defined?(:Gem)
|
20
|
+
|
21
|
+
Gem.source_index.latest_specs.select do |spec|
|
22
|
+
config_file(spec.full_gem_path) != nil
|
23
|
+
end.collect do |spec|
|
24
|
+
spec.name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
PATTERNS = [
|
30
|
+
File.join('attributes', '**', '*.rb'),
|
31
|
+
File.join('files', '**', '*'),
|
32
|
+
File.join('recipes', '**', '*.rb'),
|
33
|
+
File.join('templates', '**', '*.erb')
|
34
|
+
]
|
35
|
+
|
36
|
+
attr_reader :dir
|
37
|
+
attr_reader :config
|
38
|
+
|
39
|
+
def initialize(dir='.', config={})
|
40
|
+
@dir = File.expand_path(dir)
|
41
|
+
@config = {
|
42
|
+
'manifest' => {},
|
43
|
+
'paths' => ['.'],
|
44
|
+
'gems' => self.class.gems
|
45
|
+
}.merge(config)
|
46
|
+
end
|
47
|
+
|
48
|
+
def manifest
|
49
|
+
@manifest ||= begin
|
50
|
+
manifest = {}
|
51
|
+
|
52
|
+
paths = split config['paths']
|
53
|
+
gems = split config['gems']
|
54
|
+
gems = resolve gems
|
55
|
+
|
56
|
+
(gems + paths).each do |path|
|
57
|
+
path = File.expand_path(path, dir)
|
58
|
+
start = path.length + 1
|
59
|
+
|
60
|
+
PATTERNS.each do |pattern|
|
61
|
+
Dir.glob(File.join(path, pattern)).each do |full_path|
|
62
|
+
next unless File.file?(full_path)
|
63
|
+
|
64
|
+
rel_path = full_path[start, full_path.length - start]
|
65
|
+
manifest[rel_path] = full_path
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
overrides = config['manifest']
|
71
|
+
manifest.merge!(overrides)
|
72
|
+
manifest
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def env(path=nil)
|
77
|
+
Package.env(manifest, path)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def split(str) # :nodoc:
|
83
|
+
str.kind_of?(String) ? str.split(':') : str
|
84
|
+
end
|
85
|
+
|
86
|
+
def resolve(gems) # :nodoc:
|
87
|
+
return gems if gems.empty?
|
88
|
+
specs = latest_specs
|
89
|
+
|
90
|
+
gems.collect do |name|
|
91
|
+
spec = specs[name] or raise "no such gem: #{name.inspect}"
|
92
|
+
spec.full_gem_path
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def latest_specs # :nodoc:
|
97
|
+
latest = {}
|
98
|
+
Gem.source_index.latest_specs.each do |spec|
|
99
|
+
latest[spec.name] = spec
|
100
|
+
end
|
101
|
+
latest
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'linecook/template'
|
2
|
+
|
3
|
+
module Linecook
|
4
|
+
class Helper < Template
|
5
|
+
attr_reader :const_name
|
6
|
+
attr_reader :sources
|
7
|
+
|
8
|
+
def initialize(const_name, sources)
|
9
|
+
@const_name = const_name
|
10
|
+
@sources = sources.select {|source| File.file?(source) }
|
11
|
+
@section_paths, @definition_paths = @sources.partition {|path| File.basename(path)[0] == ?_ }
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def build
|
16
|
+
eval MODULE_TEMPLATE, binding, __FILE__, MODULE_TEMPLATE_LINE
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
def sections
|
21
|
+
@sections ||= begin
|
22
|
+
sections = {}
|
23
|
+
|
24
|
+
@section_paths.each do |path|
|
25
|
+
key = File.basename(path)[1..-1]
|
26
|
+
key.chomp! File.extname(path)
|
27
|
+
sections[key.to_sym] = File.read(path)
|
28
|
+
end
|
29
|
+
|
30
|
+
sections
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def definitions
|
35
|
+
@definitions ||= @definition_paths.collect do |path|
|
36
|
+
name = File.basename(path).chomp File.extname(path)
|
37
|
+
desc, signature, body = parse File.read(path)
|
38
|
+
|
39
|
+
eval ERB_TEMPLATE, binding, __FILE__, ERB_TEMPLATE_LINE
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def parse(str)
|
46
|
+
head, body = str.split(/^--.*\n/, 2)
|
47
|
+
head, body = '', head if body.nil?
|
48
|
+
signature, desc = parse_head(head)
|
49
|
+
|
50
|
+
[desc.join("\n"), signature.join("\n"), body]
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_head(head)
|
54
|
+
found_signature = false
|
55
|
+
head.split("\n").partition do |line|
|
56
|
+
found_signature = true if line =~ /^\s*\(.*?\)/
|
57
|
+
found_signature
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_name(name)
|
62
|
+
case name
|
63
|
+
when /_check$/ then name.sub(/_check$/, '?')
|
64
|
+
when /_bang$/ then name.sub(/_bang$/, '!')
|
65
|
+
else name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def module_nest(const_name, indent=" ", line_sep="\n")
|
70
|
+
nestings = const_name.split(/::/).collect {|name| ["module #{name}", "end"]}
|
71
|
+
nestings << {:indent => indent, :line_sep => line_sep}
|
72
|
+
|
73
|
+
nest(*nestings) { yield }
|
74
|
+
end
|
75
|
+
|
76
|
+
MODULE_TEMPLATE_LINE = __LINE__ + 2
|
77
|
+
MODULE_TEMPLATE = "self." + ERB.new(<<-DOC, nil, '<>').src
|
78
|
+
require 'erb'
|
79
|
+
<%= sections[:header] %>
|
80
|
+
|
81
|
+
# Generated by Linecook, do not edit.
|
82
|
+
<% module_nest(const_name, '') do %>
|
83
|
+
<%= sections[:head] %>
|
84
|
+
<% definitions.each do |definition| %>
|
85
|
+
|
86
|
+
<%= definition %>
|
87
|
+
<% end %>
|
88
|
+
<%= sections[:tail] %>
|
89
|
+
<% end %>
|
90
|
+
|
91
|
+
<%= sections[:footer] %>
|
92
|
+
DOC
|
93
|
+
|
94
|
+
ERB_TEMPLATE_LINE = __LINE__ + 2
|
95
|
+
ERB_TEMPLATE = ERB.new(<<-DOC, nil, '<>').src
|
96
|
+
# :stopdoc:
|
97
|
+
<%= name.upcase %>_LINE = __LINE__ + 2
|
98
|
+
<%= name.upcase %> = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
99
|
+
<%= body %>
|
100
|
+
|
101
|
+
END_OF_TEMPLATE
|
102
|
+
# :startdoc:
|
103
|
+
|
104
|
+
<% desc.each do |line| %>
|
105
|
+
# <%= line %>
|
106
|
+
<% end %>
|
107
|
+
def <%= method_name(name) %><%= signature %>
|
108
|
+
eval(<%= name.upcase %>, binding, __FILE__, <%= name.upcase %>_LINE)
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def _<%= method_name(name) %>(*args, &block) # :nodoc:
|
113
|
+
capture { <%= method_name(name) %>(*args, &block) }
|
114
|
+
end
|
115
|
+
DOC
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'linecook/utils'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module Linecook
|
5
|
+
class Package
|
6
|
+
class << self
|
7
|
+
def load_env(path)
|
8
|
+
(path ? YAML.load_file(path) : nil) || {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def env(manifest, path)
|
12
|
+
default = {CONFIG_KEY => {MANIFEST_KEY => manifest}}
|
13
|
+
overrides = load_env(path)
|
14
|
+
Utils.serial_merge(default, overrides)
|
15
|
+
end
|
16
|
+
|
17
|
+
def init(env={})
|
18
|
+
env.kind_of?(Package) ? env : new(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
CONFIG_KEY = 'linecook'
|
23
|
+
MANIFEST_KEY = 'manifest'
|
24
|
+
REGISTRY_KEY = 'registry'
|
25
|
+
CACHE_KEY = 'cache'
|
26
|
+
FILES_KEY = 'files'
|
27
|
+
TEMPLATES_KEY = 'templates'
|
28
|
+
RECIPES_KEY = 'recipes'
|
29
|
+
PATHS_KEY = 'paths'
|
30
|
+
GEMS_KEY = 'gems'
|
31
|
+
|
32
|
+
attr_reader :env
|
33
|
+
|
34
|
+
def initialize(env={})
|
35
|
+
@env = env
|
36
|
+
end
|
37
|
+
|
38
|
+
def config
|
39
|
+
env[CONFIG_KEY] ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def cache
|
43
|
+
config[CACHE_KEY] ||= {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def manifest
|
47
|
+
config[MANIFEST_KEY] ||= {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def registry
|
51
|
+
config[REGISTRY_KEY] ||= {}
|
52
|
+
end
|
53
|
+
|
54
|
+
def reverse_registry
|
55
|
+
cache[:reverse_registry] ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def tempfiles
|
59
|
+
cache[:tempfiles] ||= []
|
60
|
+
end
|
61
|
+
|
62
|
+
def register(source_path, build_path=nil)
|
63
|
+
source_path = File.expand_path(source_path)
|
64
|
+
build_path ||= File.basename(source_path)
|
65
|
+
|
66
|
+
count = 0
|
67
|
+
registry.each_key do |path|
|
68
|
+
if path.kind_of?(String) && path.index(build_path) == 0
|
69
|
+
count += 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
if count > 0
|
74
|
+
build_path = "#{build_path}.#{count}"
|
75
|
+
end
|
76
|
+
|
77
|
+
registry[build_path] = source_path
|
78
|
+
reverse_registry[source_path.to_sym] = build_path
|
79
|
+
|
80
|
+
build_path
|
81
|
+
end
|
82
|
+
|
83
|
+
def registered?(source_path)
|
84
|
+
source_path = File.expand_path(source_path)
|
85
|
+
reverse_registry.has_key?(source_path.to_sym)
|
86
|
+
end
|
87
|
+
|
88
|
+
def built?(build_path)
|
89
|
+
registry.has_key?(build_path)
|
90
|
+
end
|
91
|
+
|
92
|
+
def tempfile?(source_path)
|
93
|
+
tempfiles.find {|tempfile| tempfile.path == source_path }
|
94
|
+
end
|
95
|
+
|
96
|
+
def build(build_path, source_path=nil)
|
97
|
+
case
|
98
|
+
when built?(build_path)
|
99
|
+
raise "already built: #{build_path}"
|
100
|
+
|
101
|
+
when source_path
|
102
|
+
register(source_path, build_path)
|
103
|
+
|
104
|
+
else
|
105
|
+
tempfile = Tempfile.new File.basename(build_path)
|
106
|
+
|
107
|
+
register(tempfile.path, build_path)
|
108
|
+
tempfiles << tempfile
|
109
|
+
|
110
|
+
tempfile
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def build_path(source_path)
|
115
|
+
source_path = File.expand_path(source_path)
|
116
|
+
reverse_registry[source_path.to_sym]
|
117
|
+
end
|
118
|
+
|
119
|
+
def source_path(build_path)
|
120
|
+
registry[build_path]
|
121
|
+
end
|
122
|
+
|
123
|
+
def files
|
124
|
+
normalize(FILES_KEY)
|
125
|
+
end
|
126
|
+
|
127
|
+
def templates
|
128
|
+
normalize(TEMPLATES_KEY)
|
129
|
+
end
|
130
|
+
|
131
|
+
def recipes
|
132
|
+
normalize(RECIPES_KEY)
|
133
|
+
end
|
134
|
+
|
135
|
+
def export(dir, options={})
|
136
|
+
close
|
137
|
+
|
138
|
+
options = {
|
139
|
+
:allow_move => true
|
140
|
+
}.merge(options)
|
141
|
+
|
142
|
+
allow_move = options[:allow_move]
|
143
|
+
|
144
|
+
results = {}
|
145
|
+
registry.each_pair do |build_path, source_path|
|
146
|
+
target_path = File.join(dir, build_path)
|
147
|
+
target_dir = File.dirname(target_path)
|
148
|
+
|
149
|
+
unless File.exists?(target_dir)
|
150
|
+
FileUtils.mkdir_p(target_dir)
|
151
|
+
end
|
152
|
+
|
153
|
+
if allow_move && tempfile?(source_path)
|
154
|
+
FileUtils.mv(source_path, target_path)
|
155
|
+
else
|
156
|
+
FileUtils.cp(source_path, target_path)
|
157
|
+
end
|
158
|
+
|
159
|
+
results[build_path] = target_path
|
160
|
+
end
|
161
|
+
results
|
162
|
+
end
|
163
|
+
|
164
|
+
def close
|
165
|
+
tempfiles.each do |tempfile|
|
166
|
+
tempfile.close unless tempfile.closed?
|
167
|
+
end
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def normalize(key)
|
174
|
+
obj = config[key]
|
175
|
+
|
176
|
+
case obj
|
177
|
+
when Hash
|
178
|
+
obj
|
179
|
+
|
180
|
+
when nil
|
181
|
+
config[key] = {}
|
182
|
+
|
183
|
+
when Array
|
184
|
+
hash = {}
|
185
|
+
obj.each {|entry| hash[entry] = entry }
|
186
|
+
config[key] = hash
|
187
|
+
|
188
|
+
when String
|
189
|
+
config[key] = obj.split(':')
|
190
|
+
normalize(key)
|
191
|
+
|
192
|
+
else
|
193
|
+
raise "invalid #{key}: #{obj.inspect}"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'linecook/template'
|
2
|
+
require 'linecook/attributes'
|
3
|
+
require 'linecook/package'
|
4
|
+
require 'linecook/utils'
|
5
|
+
|
6
|
+
module Linecook
|
7
|
+
class Recipe < Template
|
8
|
+
class << self
|
9
|
+
def build(env)
|
10
|
+
package = Package.new(env)
|
11
|
+
|
12
|
+
package.recipes.each do |recipe_name, target_name|
|
13
|
+
new(target_name, env).evaluate(recipe_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
package.close
|
17
|
+
package
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias target erbout
|
22
|
+
|
23
|
+
attr_reader :target_name
|
24
|
+
|
25
|
+
def initialize(target_name, env={})
|
26
|
+
@target_name = target_name
|
27
|
+
@package = Package.init(env)
|
28
|
+
@attributes = Attributes.new(@package.env)
|
29
|
+
@erbout = @package.build(target_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def source_path(*relative_path)
|
33
|
+
path = File.join(*relative_path)
|
34
|
+
@package.manifest[path] or raise "no such file in manifest: #{path.inspect}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def target_path(source_path)
|
38
|
+
@package.build_path(source_path) ||
|
39
|
+
@package.register(source_path, File.join("#{target_name}.d", File.basename(source_path)))
|
40
|
+
end
|
41
|
+
|
42
|
+
def target_file(name, content=nil)
|
43
|
+
tempfile = @package.build File.join("#{target_name}.d", name)
|
44
|
+
|
45
|
+
tempfile << content if content
|
46
|
+
yield(tempfile) if block_given?
|
47
|
+
|
48
|
+
target_path tempfile.path
|
49
|
+
end
|
50
|
+
|
51
|
+
def attrs
|
52
|
+
@attributes.current
|
53
|
+
end
|
54
|
+
|
55
|
+
def attributes(attributes_name)
|
56
|
+
path = source_path('attributes', "#{attributes_name}.rb")
|
57
|
+
|
58
|
+
@attributes.instance_eval(File.read(path), path)
|
59
|
+
@attributes.reset(false)
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def helpers(helper_name)
|
64
|
+
require Utils.underscore(helper_name)
|
65
|
+
extend Utils.constantize(helper_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def evaluate(recipe_name=target_name)
|
69
|
+
path = source_path('recipes', "#{recipe_name}.rb")
|
70
|
+
instance_eval(File.read(path), path)
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
def file_path(file_name)
|
75
|
+
path = source_path('files', file_name)
|
76
|
+
target_path path
|
77
|
+
end
|
78
|
+
|
79
|
+
def capture_path(name, &block)
|
80
|
+
content = capture(false) { instance_eval(&block) }
|
81
|
+
target_file(name, content)
|
82
|
+
end
|
83
|
+
|
84
|
+
def recipe_path(recipe_name, target_name = recipe_name)
|
85
|
+
source_path =
|
86
|
+
@package.built?(target_name) ?
|
87
|
+
@package.source_path(target_name) :
|
88
|
+
Recipe.new(target_name, @package).evaluate(recipe_name).target.path
|
89
|
+
|
90
|
+
target_path source_path
|
91
|
+
end
|
92
|
+
|
93
|
+
def template_path(template_name, locals={})
|
94
|
+
path = source_path('templates', "#{template_name}.erb")
|
95
|
+
target_file template_name, Template.build(File.read(path), locals, path)
|
96
|
+
end
|
97
|
+
|
98
|
+
def close
|
99
|
+
@package.close
|
100
|
+
@package.registry
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
# Generated by Linecook, do not edit.
|
4
|
+
module Linecook
|
5
|
+
module Shell
|
6
|
+
module Posix
|
7
|
+
# :stopdoc:
|
8
|
+
COMMENT_LINE = __LINE__ + 2
|
9
|
+
COMMENT = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
10
|
+
# <%= str %>
|
11
|
+
END_OF_TEMPLATE
|
12
|
+
# :startdoc:
|
13
|
+
|
14
|
+
# Writes a comment
|
15
|
+
def comment(str)
|
16
|
+
eval(COMMENT, binding, __FILE__, COMMENT_LINE)
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def _comment(*args, &block) # :nodoc:
|
21
|
+
capture { comment(*args, &block) }
|
22
|
+
end
|
23
|
+
|
24
|
+
# :stopdoc:
|
25
|
+
HEREDOC_LINE = __LINE__ + 2
|
26
|
+
HEREDOC = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
27
|
+
<<<%= options[:indent] ? '-' : ' '%><%= options[:quote] ? "\"#{delimiter}\"" : delimiter %>
|
28
|
+
<% yield %>
|
29
|
+
<%= delimiter %>
|
30
|
+
|
31
|
+
END_OF_TEMPLATE
|
32
|
+
# :startdoc:
|
33
|
+
|
34
|
+
# Makes a heredoc statement surrounding the contents of the block. Options:
|
35
|
+
|
36
|
+
#
|
37
|
+
|
38
|
+
# delimiter the delimiter used, by default HEREDOC_n where n increments
|
39
|
+
|
40
|
+
# indent add '-' before the delimiter
|
41
|
+
|
42
|
+
# quote quotes the delimiter
|
43
|
+
|
44
|
+
def heredoc(options={})
|
45
|
+
delimiter = options[:delimiter] || begin
|
46
|
+
@heredoc_count ||= -1
|
47
|
+
"HEREDOC_#{@heredoc_count += 1}"
|
48
|
+
end
|
49
|
+
eval(HEREDOC, binding, __FILE__, HEREDOC_LINE)
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def _heredoc(*args, &block) # :nodoc:
|
54
|
+
capture { heredoc(*args, &block) }
|
55
|
+
end
|
56
|
+
|
57
|
+
# :stopdoc:
|
58
|
+
NOT_IF_LINE = __LINE__ + 2
|
59
|
+
NOT_IF = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
60
|
+
only_if("! #{cmd}", &block)
|
61
|
+
END_OF_TEMPLATE
|
62
|
+
# :startdoc:
|
63
|
+
|
64
|
+
def not_if(cmd, &block)
|
65
|
+
eval(NOT_IF, binding, __FILE__, NOT_IF_LINE)
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def _not_if(*args, &block) # :nodoc:
|
70
|
+
capture { not_if(*args, &block) }
|
71
|
+
end
|
72
|
+
|
73
|
+
# :stopdoc:
|
74
|
+
ONLY_IF_LINE = __LINE__ + 2
|
75
|
+
ONLY_IF = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
76
|
+
if <%= cmd %>
|
77
|
+
then
|
78
|
+
<% indent { yield } %>
|
79
|
+
fi
|
80
|
+
|
81
|
+
END_OF_TEMPLATE
|
82
|
+
# :startdoc:
|
83
|
+
|
84
|
+
def only_if(cmd)
|
85
|
+
eval(ONLY_IF, binding, __FILE__, ONLY_IF_LINE)
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def _only_if(*args, &block) # :nodoc:
|
90
|
+
capture { only_if(*args, &block) }
|
91
|
+
end
|
92
|
+
|
93
|
+
# :stopdoc:
|
94
|
+
SET_LINE = __LINE__ + 2
|
95
|
+
SET = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
96
|
+
<% if block_given? %>
|
97
|
+
<% reset_file = "LINECOOK_RESET_OPTIONS_#{next_count}" %>
|
98
|
+
<%= reset_file %>=`mktemp /tmp/line_cook_reset_fileXXXXXX`
|
99
|
+
set -o | sed 's/\(.*\) on/set -o \1/' | sed 's/\(.*\) off/set +o \1/' > $<%= reset_file %>
|
100
|
+
<% end %><% options.keys.sort_by {|opt| opt.to_s }.each do |opt| %>
|
101
|
+
set <%= options[opt] ? '-' : '+' %>o <%= opt %>
|
102
|
+
<% end %>
|
103
|
+
<% if block_given? %>
|
104
|
+
|
105
|
+
<% indent { yield } %>
|
106
|
+
|
107
|
+
source $<%= reset_file %>
|
108
|
+
<% end %>
|
109
|
+
|
110
|
+
END_OF_TEMPLATE
|
111
|
+
# :startdoc:
|
112
|
+
|
113
|
+
# Sets bash options for the duration of a block. If no block is given,
|
114
|
+
|
115
|
+
# set simply sets the options as specified.
|
116
|
+
def set(options)
|
117
|
+
eval(SET, binding, __FILE__, SET_LINE)
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
|
121
|
+
def _set(*args, &block) # :nodoc:
|
122
|
+
capture { set(*args, &block) }
|
123
|
+
end
|
124
|
+
|
125
|
+
# :stopdoc:
|
126
|
+
UNSET_LINE = __LINE__ + 2
|
127
|
+
UNSET = "self." + ERB.new(<<'END_OF_TEMPLATE', nil, '<>').src
|
128
|
+
<% keys.each do |key| %>
|
129
|
+
unset <%= key %>
|
130
|
+
<% end %>
|
131
|
+
END_OF_TEMPLATE
|
132
|
+
# :startdoc:
|
133
|
+
|
134
|
+
# Unsets a list of variables.
|
135
|
+
def unset(*keys)
|
136
|
+
eval(UNSET, binding, __FILE__, UNSET_LINE)
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def _unset(*args, &block) # :nodoc:
|
141
|
+
capture { unset(*args, &block) }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|