webbynode-blueprint 0.0.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/LICENSE +20 -0
- data/README.rdoc +81 -0
- data/VERSION.yml +4 -0
- data/lib/blueprint/blueprint.rb +54 -0
- data/lib/blueprint/components.rb +104 -0
- data/lib/blueprint/utils.rb +172 -0
- data/lib/blueprint.rb +14 -0
- data/test/blueprint_test.rb +113 -0
- data/test/test_helper.rb +10 -0
- metadata +64 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Webbynode
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= blueprint
|
2
|
+
|
3
|
+
Blueprint is a DSL that allows creating MyStacks and CommunityStacks to be deployed on Webbynode.
|
4
|
+
|
5
|
+
The current incarnation is to be considered early alpha, and only builds the Hash required to describe the components of the Stack.
|
6
|
+
|
7
|
+
As code advances, this will become a full API for interacting with Webbynode and maintaining stacks.
|
8
|
+
|
9
|
+
Before upcoming sections, kudos to Sean O'Halpin, the guy behind the ruby lib/gem {Doodle}[http://doodle.rubyforge.org/] for allowing me to use his Doodle::Util module on this. Thanks Sean!
|
10
|
+
|
11
|
+
== Example
|
12
|
+
|
13
|
+
Code of a blueprint will be something like this:
|
14
|
+
|
15
|
+
rails_rs = blueprint(:type => "readystack", :name => "rs.rails") do |f|
|
16
|
+
# this blueprint delivers "rs.rails"
|
17
|
+
f.provides "rs.rails"
|
18
|
+
|
19
|
+
# dependencies and order of execution -- top => bottom
|
20
|
+
# apache2/ngnix, mysql/postgre, passenger/mongrel
|
21
|
+
f.requires :group => "webservers",
|
22
|
+
:with => ["apache2", "nginx"]
|
23
|
+
f.requires :group => "database",
|
24
|
+
:with => ["mysql-server", "postgresqlserver"]
|
25
|
+
f.requires "rails"
|
26
|
+
f.requires :group => "proxy",
|
27
|
+
:with => ["passenger", "mongrel_cluster"]
|
28
|
+
|
29
|
+
# attributes
|
30
|
+
f.attributes :required => 'y'
|
31
|
+
f.outputs :installed_gems => "^Installed following gems: (.*)",
|
32
|
+
:success_indicator => "^SUCCESS: (.*)"
|
33
|
+
|
34
|
+
# always installs rails
|
35
|
+
f.dependency "rails", :render_as => "hidden"
|
36
|
+
|
37
|
+
# gives two webserver/proxy combo options:
|
38
|
+
# apache2 + passenger or nginx + mongrel
|
39
|
+
f.parameter "webserver-proxy", :label => "WebServer and Proxy" do |p|
|
40
|
+
p.attributes :required => "y"
|
41
|
+
|
42
|
+
p.aggregate "Apache2 and Passenger", :render_as => "radio" do |agr|
|
43
|
+
agr.dependency "apache2"
|
44
|
+
agr.dependency "passenger"
|
45
|
+
end
|
46
|
+
|
47
|
+
p.aggregate "Nginx and Mongrel Cluster", :render_as => "radio" do |agr|
|
48
|
+
agr.dependency "nginx"
|
49
|
+
agr.dependency "mongrel_cluster"
|
50
|
+
end
|
51
|
+
|
52
|
+
# doesn't install webserver/proxy
|
53
|
+
p.aggregate "No webserver & proxy", :render_as => "radio" do |agr|
|
54
|
+
agr.parameter "-"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# database options: mysql or postgresql
|
59
|
+
f.parameter "database-server", :label => "Database Server" do |p|
|
60
|
+
p.attributes :required => "y"
|
61
|
+
|
62
|
+
p.dependency "mysql-server", :label => "MySQL", :render_as => "radio"
|
63
|
+
p.dependency "postgresqlserver", :label => "PostgreSQL", :render_as => "radio"
|
64
|
+
p.no_op "No database server", :render_as => "radio"
|
65
|
+
end
|
66
|
+
|
67
|
+
# list of gems
|
68
|
+
f.aggregate "Additional Gems" do |agr|
|
69
|
+
%w{will_paginate thoughtbot-paperclip
|
70
|
+
rspec authlogic hpricot capistrano}.each do |gem|
|
71
|
+
|
72
|
+
agr.parameter "gem_#{gem}", :label => gem, :render_as => "checkbox"
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
== Copyright
|
80
|
+
|
81
|
+
Copyright (c) 2009 Webbynode. See LICENSE for details.
|
data/VERSION.yml
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "blueprint/components"
|
2
|
+
require "blueprint/utils"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
class Blueprint
|
6
|
+
include Utils
|
7
|
+
include BlueprintComponents
|
8
|
+
|
9
|
+
def initialize(blueprint_def)
|
10
|
+
@def = blueprint_def
|
11
|
+
end
|
12
|
+
|
13
|
+
def provides(*args)
|
14
|
+
opts = args.last.is_a?(Hash) ? args.pop : nil
|
15
|
+
s = (@def[:content] = args.pop)
|
16
|
+
|
17
|
+
if opts
|
18
|
+
@def.merge!(opts)
|
19
|
+
|
20
|
+
else
|
21
|
+
@def[:script] = "#{s}.sh"
|
22
|
+
@def[:email] = "#{s}.markdown"
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
(errors ||= []) << "provides requires an argument" unless @def.has_key?(:email)
|
27
|
+
(errors ||= []) << "no email template found for #{@def[:content]}" unless @def.has_key?(:email)
|
28
|
+
(errors ||= []) << "no script found for #{@def[:content]}" unless @def.has_key?(:script)
|
29
|
+
|
30
|
+
raise "Errors: #{errors * ", "}" if errors
|
31
|
+
end
|
32
|
+
|
33
|
+
def requires(req)
|
34
|
+
if req.is_a?(Hash)
|
35
|
+
requirement_def = { :group => req[:group], :contains => req[:with] }
|
36
|
+
else
|
37
|
+
requirement_def = { :group => req, :contains => req }
|
38
|
+
end
|
39
|
+
|
40
|
+
(@def[:dependencies] ||= []) << requirement_def
|
41
|
+
end
|
42
|
+
|
43
|
+
def attributes(attrs)
|
44
|
+
@def[:attributes] = attrs
|
45
|
+
end
|
46
|
+
|
47
|
+
def outputs(attrs)
|
48
|
+
@def[:output_params] = attrs
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_yaml
|
52
|
+
stringify_keys(@def, true).to_yaml
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "blueprint/utils"
|
2
|
+
|
3
|
+
module BlueprintComponents
|
4
|
+
class Component
|
5
|
+
class << self
|
6
|
+
attr_accessor :item_type
|
7
|
+
attr_accessor :block
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.creates(*args, &block)
|
11
|
+
self.item_type = args.pop
|
12
|
+
if block_given?
|
13
|
+
self.block = block
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def attributes(*args)
|
18
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
19
|
+
@def.merge!(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(*args)
|
23
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
24
|
+
@def = { :item_type => self.class.item_type }.merge(opts)
|
25
|
+
if self.class.block
|
26
|
+
@def.merge!(self.class.block.call(args, opts))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Value < Component
|
32
|
+
include BlueprintComponents
|
33
|
+
|
34
|
+
creates "value" do |args, opts|
|
35
|
+
{ :content => args.pop }.merge(opts)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Parameter < Component
|
40
|
+
include BlueprintComponents
|
41
|
+
|
42
|
+
def value(*args)
|
43
|
+
val = Value.new(*args)
|
44
|
+
unless val.definition[:label]
|
45
|
+
val.definition[:label] = val.definition[:content]
|
46
|
+
end
|
47
|
+
add_child val
|
48
|
+
end
|
49
|
+
|
50
|
+
creates "param" do |args, opts|
|
51
|
+
{ :content => args.pop }.merge(opts)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Aggregate < Component
|
56
|
+
include BlueprintComponents
|
57
|
+
|
58
|
+
creates "aggregate" do |args, opts|
|
59
|
+
{ :label => args.pop }.merge(opts)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Dependency < Component
|
64
|
+
include BlueprintComponents
|
65
|
+
|
66
|
+
creates "dependency" do |args, opts|
|
67
|
+
{ :content => args.pop }.merge(opts)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def parameter(*args, &block)
|
72
|
+
param = Parameter.new(*args)
|
73
|
+
yield param if block_given?
|
74
|
+
add_child param
|
75
|
+
end
|
76
|
+
|
77
|
+
def dependency(*args, &block)
|
78
|
+
dep = Dependency.new(*args)
|
79
|
+
yield dep if block_given?
|
80
|
+
add_child dep
|
81
|
+
end
|
82
|
+
|
83
|
+
def no_op(*args, &block)
|
84
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
85
|
+
dependency nil, { :label => args.pop }.merge(opts)
|
86
|
+
end
|
87
|
+
|
88
|
+
def aggregate(*args, &block)
|
89
|
+
aggregate = Aggregate.new(*args)
|
90
|
+
yield aggregate if block_given?
|
91
|
+
add_child aggregate
|
92
|
+
end
|
93
|
+
|
94
|
+
def definition
|
95
|
+
@def
|
96
|
+
end
|
97
|
+
|
98
|
+
module_function
|
99
|
+
|
100
|
+
def add_child(control)
|
101
|
+
(@def[:children] ||= []) << control.definition
|
102
|
+
control
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# Shameless copy of Doodle::Utils (by Sean O'Halpin - http://doodle.rubyforge.org/)
|
2
|
+
module Utils
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
# unnest arrays by one level of nesting, e.g. [1, [[2], 3]] =>
|
6
|
+
# [1, [2], 3].
|
7
|
+
def flatten_first_level(enum)
|
8
|
+
enum.inject([]) {|arr, i|
|
9
|
+
if i.kind_of?(Array)
|
10
|
+
arr.push(*i)
|
11
|
+
else
|
12
|
+
arr.push(i)
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
# convert a CamelCasedWord to a snake_cased_word
|
18
|
+
# based on version in facets/string/case.rb, line 80
|
19
|
+
def snake_case(camel_cased_word)
|
20
|
+
# if all caps, just downcase it
|
21
|
+
if camel_cased_word =~ /^[A-Z]+$/
|
22
|
+
camel_cased_word.downcase
|
23
|
+
else
|
24
|
+
camel_cased_word.to_s.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
|
25
|
+
end
|
26
|
+
end
|
27
|
+
alias :snakecase :snake_case
|
28
|
+
|
29
|
+
# resolve a constant of the form Some::Class::Or::Module -
|
30
|
+
# doesn't work with constants defined in anonymous
|
31
|
+
# classes/modules
|
32
|
+
def const_resolve(constant)
|
33
|
+
constant.to_s.split(/::/).reject{|x| x.empty?}.inject(Object) { |prev, this| prev.const_get(this) }
|
34
|
+
end
|
35
|
+
|
36
|
+
# deep copy of object (unlike shallow copy dup or clone)
|
37
|
+
def deep_copy(obj)
|
38
|
+
Marshal.load(Marshal.dump(obj))
|
39
|
+
end
|
40
|
+
|
41
|
+
# normalize hash keys using method (e.g. +:to_sym+, +:to_s+)
|
42
|
+
#
|
43
|
+
# [+hash+] target hash to update
|
44
|
+
# [+recursive+] recurse into child hashes if +true+ (default is not to recurse)
|
45
|
+
# [+method+] method to apply to key (default is +:to_sym+)
|
46
|
+
def normalize_keys!(hash, recursive = false, method = :to_sym)
|
47
|
+
if hash.kind_of?(Hash)
|
48
|
+
hash.keys.each do |key|
|
49
|
+
normalized_key = key.respond_to?(method) ? key.send(method) : key
|
50
|
+
v = hash.delete(key)
|
51
|
+
if recursive
|
52
|
+
if v.kind_of?(Hash)
|
53
|
+
v = normalize_keys!(v, recursive, method)
|
54
|
+
elsif v.kind_of?(Array)
|
55
|
+
v = v.map{ |x| normalize_keys!(x, recursive, method) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
hash[normalized_key] = v
|
59
|
+
end
|
60
|
+
end
|
61
|
+
hash
|
62
|
+
end
|
63
|
+
|
64
|
+
# normalize hash keys using method (e.g. :to_sym, :to_s)
|
65
|
+
# - returns copy of hash
|
66
|
+
# - optionally recurse into child hashes
|
67
|
+
# see #normalize_keys! for details
|
68
|
+
def normalize_keys(hash, recursive = false, method = :to_sym)
|
69
|
+
if recursive
|
70
|
+
h = deep_copy(hash)
|
71
|
+
else
|
72
|
+
h = hash.dup
|
73
|
+
end
|
74
|
+
normalize_keys!(h, recursive, method)
|
75
|
+
end
|
76
|
+
|
77
|
+
# convert keys to symbols
|
78
|
+
# - updates target hash in place
|
79
|
+
# - optionally recurse into child hashes
|
80
|
+
def symbolize_keys!(hash, recursive = false)
|
81
|
+
normalize_keys!(hash, recursive, :to_sym)
|
82
|
+
end
|
83
|
+
|
84
|
+
# convert keys to symbols
|
85
|
+
# - returns copy of hash
|
86
|
+
# - optionally recurse into child hashes
|
87
|
+
def symbolize_keys(hash, recursive = false)
|
88
|
+
normalize_keys(hash, recursive, :to_sym)
|
89
|
+
end
|
90
|
+
|
91
|
+
# convert keys to strings
|
92
|
+
# - updates target hash in place
|
93
|
+
# - optionally recurse into child hashes
|
94
|
+
def stringify_keys!(hash, recursive = false)
|
95
|
+
normalize_keys!(hash, recursive, :to_s)
|
96
|
+
end
|
97
|
+
|
98
|
+
# convert keys to strings
|
99
|
+
# - returns copy of hash
|
100
|
+
# - optionally recurse into child hashes
|
101
|
+
def stringify_keys(hash, recursive = false)
|
102
|
+
normalize_keys(hash, recursive, :to_s)
|
103
|
+
end
|
104
|
+
|
105
|
+
# simple (!) pluralization - if you want fancier, override this method
|
106
|
+
def pluralize(string)
|
107
|
+
s = string.to_s
|
108
|
+
if s =~ /s$/
|
109
|
+
s + 'es'
|
110
|
+
else
|
111
|
+
s + 's'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# caller
|
116
|
+
def doodle_caller
|
117
|
+
if $DEBUG
|
118
|
+
caller
|
119
|
+
else
|
120
|
+
[caller[-1]]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# execute block - catch any exceptions and return as value
|
125
|
+
def try(&block)
|
126
|
+
begin
|
127
|
+
block.call
|
128
|
+
rescue Exception => e
|
129
|
+
e
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# normalize a name to contain only those characters which are
|
134
|
+
# valid for a Ruby constant
|
135
|
+
def normalize_const(const)
|
136
|
+
const.to_s.gsub(/[^A-Za-z_0-9]/, '')
|
137
|
+
end
|
138
|
+
|
139
|
+
# lookup a constant along the module nesting path
|
140
|
+
def const_lookup(const, context = self)
|
141
|
+
#p [:const_lookup, const, context]
|
142
|
+
const = Utils.normalize_const(const)
|
143
|
+
result = nil
|
144
|
+
if !context.kind_of?(Module)
|
145
|
+
context = context.class
|
146
|
+
end
|
147
|
+
klasses = context.to_s.split(/::/)
|
148
|
+
#p klasses
|
149
|
+
|
150
|
+
path = []
|
151
|
+
0.upto(klasses.size - 1) do |i|
|
152
|
+
path << Doodle::Utils.const_resolve(klasses[0..i].join('::'))
|
153
|
+
end
|
154
|
+
path = (path.reverse + context.ancestors).flatten
|
155
|
+
#p [:const, context, path]
|
156
|
+
path.each do |ctx|
|
157
|
+
#p [:checking, ctx]
|
158
|
+
if ctx.const_defined?(const)
|
159
|
+
result = ctx.const_get(const)
|
160
|
+
break
|
161
|
+
end
|
162
|
+
end
|
163
|
+
if result.nil?
|
164
|
+
raise NameError, "Uninitialized constant #{const} in context #{context}"
|
165
|
+
else
|
166
|
+
result
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
extend ClassMethods
|
171
|
+
include ClassMethods
|
172
|
+
end
|
data/lib/blueprint.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'blueprint/blueprint'
|
2
|
+
require 'blueprint/components'
|
3
|
+
require 'blueprint/utils'
|
4
|
+
|
5
|
+
def blueprint(*args, &block)
|
6
|
+
blueprint_def = args.last.is_a?(Hash) ? args.pop : {}
|
7
|
+
blueprint = Blueprint.new(blueprint_def)
|
8
|
+
|
9
|
+
if block_given?
|
10
|
+
yield blueprint
|
11
|
+
end
|
12
|
+
|
13
|
+
blueprint
|
14
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BlueprintTest < Test::Unit::TestCase
|
4
|
+
def rails_blueprint
|
5
|
+
blueprint(:type => "stack", :name => "rails") do |f|
|
6
|
+
f.provides "rails"
|
7
|
+
|
8
|
+
f.parameter "version", :label => "Rails Version", :render_as => "combobox" do |p|
|
9
|
+
p.value "2.3.2"
|
10
|
+
p.value "2.2.2"
|
11
|
+
p.value "2.1.2"
|
12
|
+
end
|
13
|
+
|
14
|
+
f.parameter "doc_rdoc", :label => "Install rdoc", :render_as => "checkbox"
|
15
|
+
f.parameter "doc_ri", :label => "Install ri", :render_as => "checkbox"
|
16
|
+
|
17
|
+
f.parameter "create-dummyapp",
|
18
|
+
:label => "Create dummy app?",
|
19
|
+
:render_as => "checkbox",
|
20
|
+
:attributes => {:default => "y"}
|
21
|
+
f.parameter "dummyapp-path",
|
22
|
+
:label => "Path for dummy app",
|
23
|
+
:render_as => "text",
|
24
|
+
:attributes => {
|
25
|
+
"required" => "y",
|
26
|
+
"default" => "/var/rails",
|
27
|
+
"validation" => "^((?:\/[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*(?:\-[a-zA-Z0-9]+)*)+)$",
|
28
|
+
"validation_error" => "Use a valid path without an ending slash (ie, <code>/var/www</code>)"
|
29
|
+
}
|
30
|
+
|
31
|
+
f.parameter "dummyapp-database",
|
32
|
+
:label => "Database for dummy app",
|
33
|
+
:render_as => "combobox" do |p|
|
34
|
+
|
35
|
+
p.value "sqlite3", :label => "SQLite 3"
|
36
|
+
p.value "mysql", :label => "MySQL"
|
37
|
+
p.value "sqlite2", :label => "SQLite 2"
|
38
|
+
p.value "postgresql", :label => "PostgreSQL"
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def rails_readystack_blueprint
|
45
|
+
blueprint(:type => "readystack", :name => "rs.rails") do |f|
|
46
|
+
# this blueprint delivers "rs.rails"
|
47
|
+
f.provides "rs.rails"
|
48
|
+
|
49
|
+
# dependencies and order of execution -- top => bottom
|
50
|
+
# apache2/ngnix, mysql/postgre, passenger/mongrel
|
51
|
+
f.requires :group => "webservers",
|
52
|
+
:with => ["apache2", "nginx"]
|
53
|
+
f.requires :group => "database",
|
54
|
+
:with => ["mysql-server", "postgresqlserver"]
|
55
|
+
f.requires "rails"
|
56
|
+
f.requires :group => "proxy",
|
57
|
+
:with => ["passenger", "mongrel_cluster"]
|
58
|
+
|
59
|
+
# attributes
|
60
|
+
f.attributes :required => 'y'
|
61
|
+
f.outputs :installed_gems => "^Installed following gems: (.*)",
|
62
|
+
:success_indicator => "^SUCCESS: (.*)"
|
63
|
+
|
64
|
+
# always installs rails
|
65
|
+
f.dependency "rails", :render_as => "hidden"
|
66
|
+
|
67
|
+
# gives two webserver/proxy combo options:
|
68
|
+
# apache2 + passenger or nginx + mongrel
|
69
|
+
f.parameter "webserver-proxy", :label => "WebServer and Proxy" do |p|
|
70
|
+
p.attributes :required => "y"
|
71
|
+
|
72
|
+
p.aggregate "Apache2 and Passenger", :render_as => "radio" do |agr|
|
73
|
+
agr.dependency "apache2"
|
74
|
+
agr.dependency "passenger"
|
75
|
+
end
|
76
|
+
|
77
|
+
p.aggregate "Nginx and Mongrel Cluster", :render_as => "radio" do |agr|
|
78
|
+
agr.dependency "nginx"
|
79
|
+
agr.dependency "mongrel_cluster"
|
80
|
+
end
|
81
|
+
|
82
|
+
# doesn't install webserver/proxy
|
83
|
+
p.aggregate "No webserver & proxy", :render_as => "radio" do |agr|
|
84
|
+
agr.parameter "-"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# database options: mysql or postgresql
|
89
|
+
f.parameter "database-server", :label => "Database Server" do |p|
|
90
|
+
p.attributes :required => "y"
|
91
|
+
|
92
|
+
p.dependency "mysql-server", :label => "MySQL", :render_as => "radio"
|
93
|
+
p.dependency "postgresqlserver", :label => "PostgreSQL", :render_as => "radio"
|
94
|
+
p.no_op "No database server", :render_as => "radio"
|
95
|
+
end
|
96
|
+
|
97
|
+
# list of gems
|
98
|
+
f.aggregate "Additional Gems" do |agr|
|
99
|
+
%w{will_paginate thoughtbot-paperclip
|
100
|
+
rspec authlogic hpricot capistrano}.each do |gem|
|
101
|
+
|
102
|
+
agr.parameter "gem_#{gem}", :label => gem, :render_as => "checkbox"
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
should "probably rename this file and start testing for real" do
|
110
|
+
puts rails_blueprint.to_yaml
|
111
|
+
puts rails_readystack_blueprint.to_yaml
|
112
|
+
end
|
113
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: webbynode-blueprint
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Felipe Coury
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-29 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: felipe@webbynode.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- README.rdoc
|
27
|
+
- VERSION.yml
|
28
|
+
- lib/blueprint
|
29
|
+
- lib/blueprint/blueprint.rb
|
30
|
+
- lib/blueprint/components.rb
|
31
|
+
- lib/blueprint/utils.rb
|
32
|
+
- lib/blueprint.rb
|
33
|
+
- test/blueprint_test.rb
|
34
|
+
- test/test_helper.rb
|
35
|
+
- LICENSE
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/webbynode/blueprint
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options:
|
40
|
+
- --inline-source
|
41
|
+
- --charset=UTF-8
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.2.0
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: Wanna build a stack? Give us the blueprint.
|
63
|
+
test_files: []
|
64
|
+
|