devstructure 0.1.0 → 0.1.1
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/lib/devstructure/blueprint.rb +49 -32
- data/lib/devstructure/puppet.rb +80 -39
- metadata +3 -3
@@ -9,11 +9,11 @@ class DevStructure::Blueprint < Hash
|
|
9
9
|
include DevStructure::Puppet
|
10
10
|
|
11
11
|
def initialize(name, hash)
|
12
|
-
@name = name
|
13
|
-
self["name"] = name
|
14
12
|
super nil
|
15
13
|
clear
|
16
14
|
hash.each { |k, v| self[k.to_s] = v }
|
15
|
+
@name = name
|
16
|
+
self["name"] = name
|
17
17
|
end
|
18
18
|
|
19
19
|
attr_accessor :name
|
@@ -44,7 +44,16 @@ class DevStructure::Blueprint < Hash
|
|
44
44
|
other.walk(
|
45
45
|
:package => lambda { |manager, command, package, version|
|
46
46
|
return if b.packages[package]
|
47
|
-
b.packages[manager]["_packages"].
|
47
|
+
versions = [b.packages[manager]["_packages"][package]].flatten
|
48
|
+
[version].flatten.each { |v| versions.delete v }
|
49
|
+
case versions.length
|
50
|
+
when 0
|
51
|
+
b.packages[manager]["_packages"].delete package
|
52
|
+
when 1
|
53
|
+
b.packages[manager]["_packages"][package] = versions.to_s
|
54
|
+
else
|
55
|
+
b.packages[manager]["_packages"][package] = versions
|
56
|
+
end
|
48
57
|
}
|
49
58
|
)
|
50
59
|
|
@@ -152,69 +161,79 @@ EOF
|
|
152
161
|
|
153
162
|
def puppet
|
154
163
|
disclaimer
|
155
|
-
|
156
|
-
|
164
|
+
manifest = Manifest.new(@name)
|
165
|
+
manifest << Exec.defaults(:path => ENV["PATH"].split(":"))
|
166
|
+
|
167
|
+
# Map managers to their manager.
|
168
|
+
managers = {}
|
169
|
+
walk(:package => lambda { |manager, command, package, version|
|
170
|
+
managers[package] = manager if packages[package] && manager != package
|
171
|
+
})
|
157
172
|
|
158
173
|
# Packages.
|
159
174
|
walk(
|
160
175
|
:before => lambda { |manager, command|
|
161
176
|
p = packages[manager]["_packages"]
|
162
177
|
return if 0 == p.length || 1 == p.length && p[manager]
|
163
|
-
puts "\n\t# Packages that depend on #{manager}."
|
164
|
-
case manager
|
165
|
-
when /rubygems|rip/
|
166
|
-
puts "\tpackage {"
|
167
|
-
when /ruby|python/
|
168
|
-
puts "\texec {"
|
169
|
-
else
|
170
|
-
puts "\tpackage {"
|
171
|
-
end
|
172
178
|
},
|
173
179
|
:package => lambda { |manager, command, package, version|
|
174
180
|
command =~ /gem(\d+\.\d+) install/
|
181
|
+
ruby_version = $1
|
175
182
|
case manager
|
176
183
|
when "apt"
|
177
184
|
unless manager == package
|
178
|
-
|
185
|
+
manifest[manager] << Package.new(package, :ensure => version)
|
179
186
|
end
|
180
187
|
when "rubygems-update"
|
181
188
|
unless manager == package
|
182
|
-
|
183
|
-
:require => [
|
189
|
+
manifest[manager] << Package.new(package,
|
190
|
+
:require => [
|
191
|
+
Puppet::Class[managers[manager]],
|
192
|
+
Package["ruby#{ruby_version}-dev"],
|
193
|
+
Exec["update_rubygems"],
|
194
|
+
],
|
184
195
|
:provider => :gem,
|
185
196
|
:ensure => version
|
186
197
|
)
|
187
198
|
end
|
188
199
|
when /rubygems|rip/
|
189
200
|
options = {
|
190
|
-
:require =>
|
201
|
+
:require => [
|
202
|
+
Puppet::Class[managers[manager]],
|
203
|
+
Package["rubygems#{ruby_version}", "ruby#{ruby_version}-dev"],
|
204
|
+
],
|
191
205
|
:provider => :gem,
|
192
206
|
:ensure => version
|
193
207
|
}
|
194
208
|
options[:require] += [Package[manager]] unless manager == package
|
195
|
-
|
209
|
+
manifest[manager] << Package.new(package, options)
|
196
210
|
when /python/
|
197
|
-
|
198
|
-
:require =>
|
211
|
+
manifest[manager] << Exec.new(sprintf("#{command}", package),
|
212
|
+
:require => [
|
213
|
+
Puppet::Class[managers[manager]],
|
214
|
+
Package[manager, "python-setuptools"],
|
215
|
+
]
|
199
216
|
)
|
200
217
|
|
201
218
|
# TODO Expand Java, Erlang, etc.
|
202
219
|
|
203
220
|
else
|
204
|
-
|
205
|
-
:require =>
|
221
|
+
manifest[manager] << Exec.new(sprintf("#{command}", package,
|
222
|
+
version), :require => [
|
223
|
+
Puppet::Class[managers[manager]],
|
224
|
+
Package[manager],
|
225
|
+
]
|
206
226
|
)
|
207
227
|
end
|
208
228
|
},
|
209
229
|
:after => lambda { |manager, command|
|
210
230
|
p = packages[manager]["_packages"]
|
211
231
|
return if 0 == p.length || 1 == p.length && manager == p.keys.first
|
212
|
-
puts "\t}"
|
213
232
|
|
214
233
|
# Update RubyGems if we're through with gems in Debian's location.
|
215
234
|
return unless manager =~ /^rubygems\d+\.\d+$/
|
216
235
|
return unless p["rubygems-update"]
|
217
|
-
|
236
|
+
manifest[manager] << Exec.new("update_rubygems",
|
218
237
|
:subscribe => Package["rubygems-update"],
|
219
238
|
:path => %w(/usr/bin /var/lib/gems/1.8/bin),
|
220
239
|
:refreshonly => true
|
@@ -225,31 +244,29 @@ EOF
|
|
225
244
|
|
226
245
|
# System files.
|
227
246
|
if 0 < files.length
|
228
|
-
|
229
|
-
puts Package.defaults(
|
247
|
+
manifest << Package.defaults(
|
230
248
|
:before => files.sort.map { |pathname, content|
|
231
249
|
Puppet::File[pathname]
|
232
250
|
}
|
233
251
|
)
|
234
|
-
puts "\tfile {"
|
235
252
|
files.sort.each do |pathname, content|
|
236
253
|
if Hash == content.class
|
237
254
|
if content["_target"]
|
238
|
-
|
255
|
+
manifest << Puppet::File.new(pathname,
|
256
|
+
:ensure => content["_target"])
|
239
257
|
next
|
240
258
|
elsif content["_base64"]
|
241
259
|
content = Base64.decode64(content["_base64"])
|
242
260
|
end
|
243
261
|
end
|
244
|
-
|
262
|
+
manifest << Puppet::File.new(pathname,
|
245
263
|
:content => content,
|
246
264
|
:ensure => :present
|
247
265
|
)
|
248
266
|
end
|
249
|
-
puts "\t}"
|
250
267
|
end
|
251
268
|
|
252
|
-
puts
|
269
|
+
puts manifest
|
253
270
|
end
|
254
271
|
|
255
272
|
def chef
|
data/lib/devstructure/puppet.rb
CHANGED
@@ -9,24 +9,58 @@ end
|
|
9
9
|
|
10
10
|
module DevStructure::Puppet
|
11
11
|
|
12
|
-
# A
|
13
|
-
#
|
14
|
-
|
15
|
-
class Resource
|
12
|
+
# A Puppet manifest that contains a tree of classes that each contain
|
13
|
+
# some resources.
|
14
|
+
class Manifest
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def initialize(name, parent=nil)
|
17
|
+
@name, @parent = name, parent
|
18
|
+
@manifests, @resources = {}, []
|
20
19
|
end
|
21
20
|
|
22
|
-
#
|
23
|
-
def
|
24
|
-
self.new
|
21
|
+
# Return a reference to a sub-manifest of the given name.
|
22
|
+
def [](name)
|
23
|
+
@manifests[name.to_s] ||= self.class.new(name.to_s, @name)
|
24
|
+
end
|
25
|
+
def method_missing(symbol, *args)
|
26
|
+
self[symbol]
|
25
27
|
end
|
26
28
|
|
27
|
-
#
|
28
|
-
def
|
29
|
-
|
29
|
+
# Add a resource to this manifest.
|
30
|
+
def <<(resource)
|
31
|
+
@resources << resource
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s(tab="")
|
35
|
+
out = []
|
36
|
+
out << "#{tab}class #{@name.gsub(".", "--")} {"
|
37
|
+
@manifests.each_value do |manifest|
|
38
|
+
out << manifest.to_s("#{tab}\t")
|
39
|
+
end
|
40
|
+
@resources.each do |resource|
|
41
|
+
out << resource.to_s("#{tab}\t")
|
42
|
+
end
|
43
|
+
out << "#{tab}}"
|
44
|
+
out << "#{tab}include #{@name.gsub(".", "--")}" if @parent
|
45
|
+
out.join("\n")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
# A generic Puppet resource to be subclassed. The name of the class
|
51
|
+
# dictates how the resource will be printed so do not instantiate this
|
52
|
+
# class directly.
|
53
|
+
class Resource < Hash
|
54
|
+
attr_accessor :type, :name, :style
|
55
|
+
|
56
|
+
# A resource.
|
57
|
+
def initialize(name, options={})
|
58
|
+
super nil
|
59
|
+
clear
|
60
|
+
options.each { |k, v| self[k.to_s] = v }
|
61
|
+
@type = self.class.to_s.downcase[/[^:]+$/]
|
62
|
+
@name = name.to_s.downcase
|
63
|
+
@style = :complete
|
30
64
|
end
|
31
65
|
|
32
66
|
# A resource with only a name, typically being listed as a dependency.
|
@@ -34,46 +68,52 @@ module DevStructure::Puppet
|
|
34
68
|
# will be generated.
|
35
69
|
def self.[](*args)
|
36
70
|
if 1 == args.length
|
37
|
-
self.new args[0]
|
71
|
+
self.new args[0]
|
38
72
|
else
|
39
73
|
args.collect { |arg| self[arg] }
|
40
74
|
end
|
41
75
|
end
|
42
76
|
|
77
|
+
# A set of defaults for a resource type.
|
78
|
+
def self.defaults(options)
|
79
|
+
resource = self.new(nil, options)
|
80
|
+
resource.style = :defaults
|
81
|
+
resource
|
82
|
+
end
|
83
|
+
|
43
84
|
# Return Puppet code for this resource. Whether a complete, partial,
|
44
85
|
# or defaults representation is returned depends on which class method
|
45
86
|
# instantiated this resource but can be overridden by passing a Symbol.
|
46
|
-
def to_s(
|
47
|
-
style ||= @style
|
87
|
+
def to_s(tab="")
|
48
88
|
out = []
|
49
89
|
|
50
90
|
# Settle on the indentation level for the rest of the resource.
|
51
91
|
# Raise an exception if the style is invalid.
|
52
|
-
|
92
|
+
tab_params = case @style
|
53
93
|
when :complete
|
54
|
-
out << "
|
55
|
-
"
|
94
|
+
out << "#{tab}#{@type} { \"#{@name}\":"
|
95
|
+
"#{tab}"
|
56
96
|
when :partial
|
57
|
-
out << "\t\
|
58
|
-
"\t
|
97
|
+
out << "#{tab}\t\"#{@name}\":"
|
98
|
+
"#{tab}\t"
|
59
99
|
when :defaults
|
60
|
-
out << "
|
61
|
-
"
|
100
|
+
out << "#{tab}#{@type.capitalize} {"
|
101
|
+
"#{tab}"
|
62
102
|
else
|
63
103
|
raise ArgumentError
|
64
104
|
end
|
65
105
|
|
66
106
|
# Handle the options Hash.
|
67
|
-
if 0 <
|
107
|
+
if 0 < length
|
68
108
|
|
69
109
|
# Note the longest option name so we can line up => operators as
|
70
110
|
# per the Puppet coding standards.
|
71
|
-
l =
|
111
|
+
l = collect { |k, v| k.to_s.length }.max
|
72
112
|
|
73
113
|
# Map options to Puppet code strings. Symbols become unquoted
|
74
114
|
# strings, nils become undefs, and Arrays are flattened. Unless
|
75
115
|
# the value is a Symbol, #inspect is called on the value.
|
76
|
-
out +=
|
116
|
+
out += sort.collect do |k, v|
|
77
117
|
k = "#{k.to_s}#{" " * (l - k.to_s.length)}"
|
78
118
|
v = if v.respond_to?(:flatten)
|
79
119
|
if 1 == v.length
|
@@ -86,23 +126,23 @@ module DevStructure::Puppet
|
|
86
126
|
end
|
87
127
|
v = :undef if v.nil?
|
88
128
|
v = v.inspect.gsub(/\$/, "\\$") unless Symbol == v.class
|
89
|
-
"\t#{
|
129
|
+
"\t#{tab_params}#{k} => #{v},"
|
90
130
|
end
|
91
131
|
|
92
132
|
# Close this resource.
|
93
|
-
case style
|
133
|
+
case @style
|
94
134
|
when :complete
|
95
|
-
out << "
|
135
|
+
out << "#{tab}}"
|
96
136
|
when :partial
|
97
137
|
out << "#{out.pop.chop};"
|
98
138
|
when :defaults
|
99
|
-
out << "
|
139
|
+
out << "#{tab}}"
|
100
140
|
end
|
101
141
|
|
102
142
|
# Don't bother with an empty options Hash. Go ahead and close this
|
103
143
|
# resource.
|
104
144
|
else
|
105
|
-
case style
|
145
|
+
case @style
|
106
146
|
when :complete
|
107
147
|
out << "#{out.pop} }"
|
108
148
|
when :partial
|
@@ -120,15 +160,9 @@ module DevStructure::Puppet
|
|
120
160
|
def inspect
|
121
161
|
"#{@type.capitalize}[\"#{@name}\"]"
|
122
162
|
end
|
123
|
-
|
124
|
-
|
125
|
-
def initialize(name, style, options={})
|
126
|
-
@type = self.class.to_s.downcase[/[^:]+$/]
|
127
|
-
@name = name.to_s.downcase
|
128
|
-
@style = style.to_sym
|
129
|
-
@options = options
|
163
|
+
def pretty_print(pp)
|
164
|
+
pp.text inspect
|
130
165
|
end
|
131
|
-
private :initialize
|
132
166
|
|
133
167
|
end
|
134
168
|
|
@@ -140,4 +174,11 @@ module DevStructure::Puppet
|
|
140
174
|
class File < Resource
|
141
175
|
end
|
142
176
|
|
177
|
+
# A class resource type for dependencies.
|
178
|
+
class Class < Resource
|
179
|
+
def inspect
|
180
|
+
"#{@type.capitalize}[\"#{@name.gsub(".", "--")}\"]"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
143
184
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devstructure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Richard Crowley
|