stackfu 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
 
5
5
  require 'echoe'
6
6
 
7
- Echoe.new('stackfu', '0.1.5') do |p|
7
+ Echoe.new('stackfu', '0.1.6') do |p|
8
8
  p.description = "StackFu Backend"
9
9
  p.url = "http://stackfu.com/cli"
10
10
  p.author = "Felipe Coury"
@@ -18,21 +18,27 @@ module StackFu::Commands
18
18
 
19
19
  def extract_settings(target)
20
20
  target_name = parameters[0]
21
- server_name = parameters[1]
21
+ server_name = parameters[1]
22
22
 
23
- target_class = StackFu::ApiHooks.const_get(target.capitalize)
24
- begin
25
- target = target_class.find(target_name)
26
- rescue ActiveResource::ResourceNotFound
27
- error "#{target.capitalize} '#{target_name}' was not found"
28
- return
29
- end
23
+ if target_name.include?('/')
24
+ user_name, target_name = target_name.split('/')
25
+ user = User.new(:id => user_name)
26
+ target = Script.new(user.get(target_name))
27
+ else
28
+ begin
29
+ target_class = StackFu::ApiHooks.const_get(target.capitalize)
30
+ target = target_class.find(target_name)
31
+ rescue ActiveResource::ResourceNotFound
32
+ error "#{target.capitalize} '#{target_name}' was not found"
33
+ return
34
+ end
30
35
 
31
- begin
32
- target = target_class.find(target_name)
33
- rescue ActiveResource::ResourceNotFound
34
- error "#{target.capitalize} '#{target_name}' was not found"
35
- return
36
+ begin
37
+ target = target_class.find(target_name)
38
+ rescue ActiveResource::ResourceNotFound
39
+ error "#{target.capitalize} '#{target_name}' was not found"
40
+ return
41
+ end
36
42
  end
37
43
 
38
44
  unless target
@@ -82,9 +82,9 @@ module StackFu::Commands
82
82
  create_file "#{script_name}/executables/#{script.description.downcase.gsub(" ", "_")}.sh.erb", script.body
83
83
  end
84
84
 
85
- puts "Script #{script_name} dumped successfully..."
85
+ done "Script #{script_name} dumped."
86
86
  else
87
- puts "Script '#{script_name}' was not found"
87
+ error "Script '#{script_name}' was not found"
88
88
  end
89
89
  end
90
90
 
@@ -99,7 +99,7 @@ module StackFu::Commands
99
99
  end
100
100
 
101
101
  def create_folder(folder)
102
- puts "\tcreate #{folder}/"
102
+ puts "\t#{"create".foreground(:green)} #{folder}/"
103
103
  mkdir folder
104
104
  end
105
105
 
@@ -110,7 +110,7 @@ module StackFu::Commands
110
110
  end
111
111
 
112
112
  def create_file(file, contents)
113
- puts "\tcreate #{file}"
113
+ puts "\t#{"create".foreground(:green)} #{file}"
114
114
  write_file(file, contents)
115
115
  end
116
116
 
@@ -31,6 +31,14 @@ module StackFu::Commands
31
31
  what = 'script'
32
32
  begin
33
33
  item_name = parameters.shift
34
+
35
+ unless item_name
36
+ error "Missing script name.",
37
+ "Try again using 'stackfu generate [script_name]'."
38
+ return false
39
+ end
40
+
41
+
34
42
  items = {}
35
43
  while (p = parameters.shift)
36
44
  name, type = p.split(":")
@@ -72,11 +80,11 @@ module StackFu::Commands
72
80
  create("#{item_name}/executables", "#{item.first}.sh.erb", item.last)
73
81
  end or create("#{item_name}/executables")
74
82
 
75
- puts "#{what.titleize} #{item_name} created successfully"
83
+ done "#{what.titleize} #{item_name} created successfully"
76
84
  rescue Exceptions::InvalidParameter
77
- puts $!.message
85
+ error $!.message
78
86
  rescue IOError, Errno::EEXIST
79
- puts "There was an error creating your #{what}: #{$!.message}"
87
+ error "#{$!.message}"
80
88
  end
81
89
  end
82
90
 
@@ -89,13 +97,13 @@ module StackFu::Commands
89
97
 
90
98
  def create(d, f=nil, contents=nil)
91
99
  unless File.directory?(d)
92
- puts "\tcreate #{d}/"
100
+ puts "\t#{"create".foreground(:green)} #{d}/"
93
101
  ::FileUtils.mkdir_p(d)
94
102
  end
95
103
 
96
104
  if f.present?
97
105
  f = "#{d}/#{f}"
98
- puts "\tcreate #{f}"
106
+ puts "\t#{"create".foreground(:green)} #{f}"
99
107
  File.open(f, "w") do |file|
100
108
  file.write(contents)
101
109
  end
@@ -3,22 +3,22 @@ module StackFu::Commands
3
3
  def default(parameters, options)
4
4
  stackfu = "stackfu".foreground(:green).bright
5
5
 
6
- puts "#{"StackFu #{StackFu::VERSION}".foreground(:green).bright}, a server deployment manager."
7
- puts " (c) 2009-2020 StackFu - http://stackfu.com"
6
+ puts "#{"StackFu #{StackFu::VERSION}".foreground(:green).bright} - social server provisioning."
7
+ puts " (c) 2010-2020 StackFu - http://stackfu.com"
8
8
  puts ""
9
9
  puts " Usage:"
10
10
  puts " #{stackfu} #{"command".foreground(:cyan)} [arguments...] [options...]"
11
11
  puts ""
12
12
  puts " Examples:"
13
- puts " #{stackfu} #{"generate".foreground(:cyan)} stack lamp"
13
+ puts " #{stackfu} #{"generate".foreground(:cyan)} lamp"
14
14
  puts " #{stackfu} #{"pub".foreground(:cyan)}"
15
15
  puts " #{stackfu} #{"deploy".foreground(:cyan)} lamp server1"
16
16
  puts ""
17
17
  puts " Commands:"
18
18
  puts " #{"help".foreground(:cyan)} you already know about this one, dontcha?"
19
19
  puts " #{"config".foreground(:cyan)} configure StackFu CLI options"
20
- puts " #{"server".foreground(:cyan)} create, delete, update and deploy to StackFu servers"
21
- puts " #{"generate".foreground(:cyan)} [stack|plugin] creates a new stack or plugin in current_dir/name"
20
+ puts " #{"list".foreground(:cyan)} [servers|script] lists all the scripts and/or server under your account"
21
+ puts " #{"generate".foreground(:cyan)} creates a new script in current_dir/name"
22
22
  puts " #{"publish".foreground(:cyan)} publishes the item on the current folder to StackFu.com"
23
23
  puts ""
24
24
  puts " For a complete guide on using StackFu from command line:"
@@ -10,6 +10,19 @@ module StackFu::Commands
10
10
  def plugin?
11
11
  File.exists?("plugin.yml")
12
12
  end
13
+
14
+ def format_error
15
+ messages = ["there were validation problems with your script.", ""]
16
+ %w(script.yml config/01-controls.yml config/02-requirements.yml config/03-executions.yml config/04-validations.yml).each do |f|
17
+ if @errors[f]
18
+ messages << "Errors in #{f.foreground(:green)}:"
19
+ messages << @errors[f].map { |e| "- #{e}" }
20
+ messages << ""
21
+ end
22
+ end
23
+
24
+ messages.flatten.join("\n")
25
+ end
13
26
 
14
27
  def default(parameters, options)
15
28
  what = :script
@@ -20,7 +33,12 @@ module StackFu::Commands
20
33
  end
21
34
 
22
35
  begin
23
- stack_spec = YAML.load(read("#{what}.yml"))
36
+ stack_spec = read_and_validate(what)
37
+
38
+ if @errors.keys.any?
39
+ error format_error
40
+ return
41
+ end
24
42
 
25
43
  %w[controls requirements executions validations].each_with_index do |item, i|
26
44
  if (yaml = read("config/0#{i+1}-#{item}.yml"))
@@ -111,7 +129,99 @@ module StackFu::Commands
111
129
  end
112
130
 
113
131
  private
132
+
133
+ def check(file, message)
134
+ return true if result = block_given? ? yield : false
135
+
136
+ (@errors[file]||=[]) << message.gsub(/'(.*)'/, '\1'.foreground(:blue).bright)
137
+ false
138
+ end
139
+
140
+ def read_and_check(yml)
141
+ begin
142
+ return YAML.load(read(yml))
143
+ rescue ArgumentError
144
+ (@errors[yml]||=[]) << "invalid YAML document. Parse error: #{$!.message}"
145
+ end
146
+ end
147
+
148
+ def read_and_validate(what)
149
+ @errors = {}
150
+
151
+ if stack_spec = read_and_check("#{what}.yml")
152
+ if check("script.yml", "the file descriptor has the wrong format") { stack_spec.is_a?(Hash) }
153
+ if check("script.yml", "missing field #{"name".try(:foreground, :blue).try(:bright)}") { stack_spec['name'] }
154
+ check("script.yml",
155
+ "invalid value for field #{"name".try(:foreground, :blue).try(:bright)}: " +
156
+ "only lower case chars, numbers and underscores are allowed") {
157
+
158
+ stack_spec['name'] =~ /^[a-z0-9_]*$/
159
+ }
160
+ end
161
+
162
+ if check("script.yml", "missing field #{"type".try(:foreground, :blue).try(:bright)}") { stack_spec['type'] }
163
+ check("script.yml", "invalid value for field #{"type".try(:foreground, :blue).try(:bright)}") { stack_spec['type'] == 'script' }
164
+ end
165
+ end
166
+ end
167
+
168
+ validate_controls
169
+ validate_requirements
170
+ validate_executions
171
+ validate_validations
172
+
173
+ stack_spec
174
+ end
175
+
176
+ def validate_spec(idx, name, item_id, checks)
177
+ file = "config/#{idx}-#{name}.yml"
178
+
179
+ return unless spec = read_and_check(file)
180
+ return unless check(file, "invalid format") {
181
+ spec.is_a?(Hash) && spec[name].is_a?(Array)
182
+ }
183
+
184
+ spec[name].each_with_index do |item, i|
185
+ checks.each do |check|
186
+ if item_id.nil? or check == item_id
187
+ check(file, "missing #{check} for #{name.singularize} #{i+1}") { item[check] }
188
+ else
189
+ check(file, "missing #{check} for #{name.singularize} #{item[item_id].try(:foreground, :blue).try(:bright)}") { item[check] }
190
+ end
191
+ end
192
+
193
+ return unless yield(item, i+1) if block_given?
194
+ end
195
+ end
196
+
197
+ def validate_controls
198
+ validate_spec '01', 'controls', 'name', ['name', 'type'] do |item, i|
199
+ check('config/01-controls.yml', "invalid type '#{item["type"]}' for control #{item["name"].try(:foreground, :blue).try(:bright)}") {
200
+ %w(Textbox Numericbox Password).include? item['type']
201
+ }
202
+ end
203
+ end
204
+
205
+ def validate_requirements
206
+ validate_spec '02', 'requirements', nil, ['type', 'data'] do |item, i|
207
+ check("config/02-requirements.yml", "invalid type #{item["type"].try(:foreground, :blue).try(:bright)} for requirement #{i}") {
208
+ %w(DirExists FileExists ExecutableExists ProcessExists RubyCanLoad RubyGem SymlinkExists).include? item['type']
209
+ }
210
+ end
211
+ end
114
212
 
213
+ def validate_executions
214
+ validate_spec '03', 'executions', 'file', ['file', 'description']
215
+ end
216
+
217
+ def validate_validations
218
+ validate_spec '04', 'validations', nil, ['type', 'data'] do |item, i|
219
+ check('config/04-validations.yml', "invalid type #{item["type"].try(:foreground, :blue).try(:bright)} for validation #{i}") {
220
+ %w(DirExists FileExists ExecutableExists ProcessExists RubyCanLoad RubyGem SymlinkExists).include? item['type']
221
+ }
222
+ end
223
+ end
224
+
115
225
  def publish(stack)
116
226
  spinner {
117
227
  stack.save
data/lib/stackfu.rb CHANGED
@@ -50,7 +50,7 @@ require "#{dir}/commands/deploy_command"
50
50
  require "#{dir}/commands/dump_command"
51
51
 
52
52
  module StackFu
53
- VERSION = '0.1.5'
53
+ VERSION = '0.1.6'
54
54
  API = "http://beta.stackfu.com"
55
55
  # API = "http://localhost:3000"
56
56
  CONFIG_FILE = "#{ENV['HOME']}/.stackfu"
data/spec/spec_helper.rb CHANGED
@@ -15,6 +15,10 @@ HighLine.track_eof = false
15
15
  # Reads out a file from the fixtures directory
16
16
 
17
17
  module StackFuHelpers
18
+ def fixture?(file)
19
+ File.exists?(File.join(File.dirname(__FILE__), "fixtures", file))
20
+ end
21
+
18
22
  def read_fixture(file)
19
23
  File.read(File.join(File.dirname(__FILE__), "fixtures", file))
20
24
  end
@@ -17,6 +17,21 @@ describe StackFu::Commands::DeployCommand do
17
17
  stdout.should =~ /Aborted./
18
18
  end
19
19
  end
20
+
21
+ context "deploying other user's scripts" do
22
+ it "queries for /user/script.json" do
23
+ prepare(:get, '/users/fcoury/mongodb.json')
24
+ prepare(:get, '/servers/webbynode.json')
25
+
26
+ when_asked " Ports: ", :answer => "80,23,22"
27
+
28
+ disagree_of "Continue with script installation?\n"
29
+
30
+ command "dep fcoury/mongodb webbynode"
31
+
32
+ stdout.should =~ /Aborted./
33
+ end
34
+ end
20
35
 
21
36
  context 'rendering controls do' do
22
37
  it "tells the user if there is another deployment running" do
@@ -41,7 +41,7 @@ describe StackFu::Commands::DumpCommand do
41
41
  stdout.should =~ /^\tcreate firewall\/executables\//
42
42
  stdout.should =~ /^\tcreate firewall\/executables\/install_ufw.sh.erb/
43
43
  stdout.should =~ /^\tcreate firewall\/executables\/configure_ufw.sh.erb/
44
- stdout.should =~ /^Script firewall dumped successfully/
44
+ stdout.should =~ /^Success: Script firewall dumped/
45
45
  end
46
46
  end
47
47
  end
@@ -2,6 +2,11 @@
2
2
  require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
3
 
4
4
  describe StackFu::Commands::GenerateCommand do
5
+ it "shown an error if no name is given" do
6
+ command "generate"
7
+ stdout.should =~ /Missing script name./
8
+ end
9
+
5
10
  it "generates the script file and folder when no executables are given" do
6
11
  expect_create :dir => "test", :file => "script.yml"
7
12
  expect_create :dir => "test/executables"
@@ -65,13 +70,13 @@ describe StackFu::Commands::GenerateCommand do
65
70
  it "raises a nice error when mkdir fails" do
66
71
  expect_create :dir => "test", :file => "script.yml", :raise => [IOError, "Error description"]
67
72
  command "generate test"
68
- stdout.should =~ /There was an error creating your script: Error description/
73
+ stdout.should =~ /Error description/
69
74
  end
70
75
 
71
76
  it "raises a nice error when mkdir fails because there is a file with same name" do
72
77
  expect_create :dir => "test", :file => "script.yml", :raise => [Errno::EEXIST, "Error description"]
73
78
  command "generate test"
74
- stdout.should =~ /There was an error creating your script: File exists - Error description/
79
+ stdout.should =~ /File exists - Error description/
75
80
  end
76
81
 
77
82
  def expect_create(opts={})
@@ -2,6 +2,278 @@
2
2
  require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
3
 
4
4
  describe StackFu::Commands::PublishCommand do
5
+
6
+ context 'validating script.yml' do
7
+ it "validates the name for invalid chars" do
8
+ setup_one 'missing', 'script.yml', "name: My Fair Scripty\ntype: script"
9
+ setup_one 'missing', 'config/01-controls.yml', ''
10
+ setup_one 'missing', 'config/02-requirements.yml', ''
11
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
12
+ setup_one 'missing', 'config/04-validations.yml', ''
13
+
14
+ command "pub"
15
+ stdout.should =~ /invalid value for field name: only lower case chars, numbers and underscores are allowed/
16
+ end
17
+
18
+
19
+ it "checks script.yml format" do
20
+ setup_fixture('invalid')
21
+ setup_one 'missing', 'config/01-controls.yml', ''
22
+ setup_one 'missing', 'config/02-requirements.yml', ''
23
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
24
+ setup_one 'missing', 'config/04-validations.yml', ''
25
+
26
+ command "pub"
27
+ stdout.should =~ /the file descriptor has the wrong format/
28
+ end
29
+
30
+ it "checks for valid YAML file" do
31
+ setup_one 'missing', 'script.yml', 'name: myscript, type: yadda'
32
+ setup_one 'missing', 'config/01-controls.yml', ''
33
+ setup_one 'missing', 'config/02-requirements.yml', ''
34
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
35
+ setup_one 'missing', 'config/04-validations.yml', ''
36
+
37
+ command "pub"
38
+ stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 21/
39
+ end
40
+
41
+ it "checks required script field 'name'" do
42
+ setup_fixture('missing')
43
+
44
+ command "pub"
45
+ stdout.should =~ /missing field name/
46
+ end
47
+
48
+ it "checks required script field 'type'" do
49
+ setup_one 'missing', 'script.yml', 'name: myscript'
50
+ setup_one 'missing', 'config/01-controls.yml', ''
51
+ setup_one 'missing', 'config/02-requirements.yml', ''
52
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
53
+ setup_one 'missing', 'config/04-validations.yml', ''
54
+
55
+ command "pub"
56
+ stdout.should =~ /missing field type/
57
+ end
58
+
59
+ it "checks content of field 'type'" do
60
+ setup_one 'missing', 'script.yml', '{name: myscript, type: yadda}'
61
+ setup_one 'missing', 'config/01-controls.yml', ''
62
+ setup_one 'missing', 'config/02-requirements.yml', ''
63
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
64
+ setup_one 'missing', 'config/04-validations.yml', ''
65
+
66
+ command "pub"
67
+ stdout.should =~ /invalid value for field type/
68
+ end
69
+ end
70
+
71
+ context 'validating 01-controls.yml' do
72
+ it "checks file format" do
73
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
74
+ setup_one 'missing', 'config/01-controls.yml', 'hey you'
75
+ setup_one 'missing', 'config/02-requirements.yml', ''
76
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
77
+ setup_one 'missing', 'config/04-validations.yml', ''
78
+
79
+ command "pub"
80
+ stdout.should =~ /invalid format/
81
+ end
82
+
83
+ it "checks for invalid YML" do
84
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
85
+ setup_one 'missing', 'config/01-controls.yml', 'name: myscript, type: yadda'
86
+ setup_one 'missing', 'config/02-requirements.yml', ''
87
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
88
+ setup_one 'missing', 'config/04-validations.yml', ''
89
+
90
+ command "pub"
91
+ stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 21/
92
+ end
93
+
94
+ it "checks for missing controls key" do
95
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
96
+ setup_one 'missing', 'config/01-controls.yml', 'other: [{name: control}]'
97
+ setup_one 'missing', 'config/02-requirements.yml', ''
98
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
99
+ setup_one 'missing', 'config/04-validations.yml', ''
100
+
101
+ command "pub"
102
+ stdout.should =~ /invalid format/
103
+ end
104
+
105
+ it "assures that controls is an array" do
106
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
107
+ setup_one 'missing', 'config/01-controls.yml', 'other: {name: control}'
108
+ setup_one 'missing', 'config/02-requirements.yml', ''
109
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
110
+ setup_one 'missing', 'config/04-validations.yml', ''
111
+
112
+ command "pub"
113
+ stdout.should =~ /invalid format/
114
+ end
115
+
116
+ it "checks for missing name" do
117
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
118
+ setup_one 'missing', 'config/01-controls.yml', 'controls: [{type: Textbox}]'
119
+ setup_one 'missing', 'config/02-requirements.yml', ''
120
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
121
+ setup_one 'missing', 'config/04-validations.yml', ''
122
+
123
+ command "pub"
124
+ stdout.should =~ /missing name for control 1/
125
+ end
126
+
127
+ it "checks for missing type" do
128
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
129
+ setup_one 'missing', 'config/01-controls.yml', 'controls: [{name: control}]'
130
+ setup_one 'missing', 'config/02-requirements.yml', ''
131
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
132
+ setup_one 'missing', 'config/04-validations.yml', ''
133
+
134
+ command "pub"
135
+ stdout.should =~ /missing type for control control/
136
+ end
137
+
138
+ it "checks for invalid type" do
139
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
140
+ setup_one 'missing', 'config/01-controls.yml', 'controls: [{name: control, type: RockOn}]'
141
+ setup_one 'missing', 'config/02-requirements.yml', ''
142
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
143
+ setup_one 'missing', 'config/04-validations.yml', ''
144
+
145
+ command "pub"
146
+ stdout.should =~ /invalid type RockOn for control control/
147
+ end
148
+ end
149
+
150
+ context 'validating 02-requirements.yml' do
151
+ it "checks file format" do
152
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
153
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
154
+ setup_one 'missing', 'config/02-requirements.yml', 'hey you'
155
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
156
+ setup_one 'missing', 'config/04-validations.yml', ''
157
+
158
+ command "pub"
159
+ stdout.should =~ /invalid format/
160
+ end
161
+
162
+ it "checks for invalid YAML" do
163
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
164
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
165
+ setup_one 'missing', 'config/02-requirements.yml', 'name: myscript, - type: yadda'
166
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
167
+ setup_one 'missing', 'config/04-validations.yml', ''
168
+
169
+ command "pub"
170
+ stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 23/
171
+ end
172
+
173
+ it "checks for missing type" do
174
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
175
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
176
+ setup_one 'missing', 'config/02-requirements.yml', "requirements:\n- {data: x, type: DirExists}\n- data: x"
177
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
178
+ setup_one 'missing', 'config/04-validations.yml', ''
179
+
180
+ command "pub"
181
+ stdout.should =~ /missing type for requirement 2/
182
+ end
183
+ end
184
+
185
+ context 'validating 03-executions.yml' do
186
+ it "checks file format" do
187
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
188
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
189
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
190
+ setup_one 'missing', 'config/03-executions.yml', 'hey you'
191
+ setup_one 'missing', 'config/04-validations.yml', ''
192
+
193
+ command "pub"
194
+ stdout.should =~ /invalid format/
195
+ end
196
+
197
+ it "checks for invalid YAML" do
198
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
199
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
200
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
201
+ setup_one 'missing', 'config/03-executions.yml', 'name: myscript, - type: yadda'
202
+ setup_one 'missing', 'config/04-validations.yml', ''
203
+
204
+ command "pub"
205
+ stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 23/
206
+ end
207
+
208
+ it "checks for missing description" do
209
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
210
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
211
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
212
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}\n- file: execution"
213
+ setup_one 'missing', 'config/04-validations.yml', ''
214
+
215
+ command "pub"
216
+ stdout.should =~ /missing description for execution execution/
217
+ end
218
+
219
+ it "checks for missing file" do
220
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
221
+ setup_one 'missing', 'config/01-controls.yml', ''
222
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
223
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}\n- description: execution"
224
+ setup_one 'missing', 'config/04-validations.yml', ''
225
+
226
+ command "pub"
227
+ stdout.should =~ /missing file for execution 2/
228
+ end
229
+ end
230
+
231
+ context 'validating 04-validations.yml' do
232
+ it "checks file format" do
233
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
234
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
235
+ setup_one 'missing', 'config/02-requirements.yml', ''
236
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
237
+ setup_one 'missing', 'config/04-validations.yml', 'hey you'
238
+
239
+ command "pub"
240
+ stdout.should =~ /invalid format/
241
+ end
242
+
243
+ it "checks for invalid YAML" do
244
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
245
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
246
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
247
+ setup_one 'missing', 'config/03-executions.yml', "executions:\n- {file: x, description: y}"
248
+ setup_one 'missing', 'config/04-validations.yml', 'name: myscript, - type: yadda'
249
+
250
+ command "pub"
251
+ stdout.should =~ /invalid YAML document. Parse error: syntax error on line 0, col 23/
252
+ end
253
+
254
+ it "checks for missing type" do
255
+ setup_one 'missing', 'script.yml', '{name: myscript, type: script}'
256
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
257
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
258
+ setup_one 'missing', 'config/03-executions.yml', ""
259
+ setup_one 'missing', 'config/04-validations.yml', "validations:\n- {data: x, type: DirExists}\n- data: x"
260
+
261
+ command "pub"
262
+ stdout.should =~ /missing type for validation 2/
263
+ end
264
+ end
265
+
266
+ it "reports all errors" do
267
+ setup_one 'missing', 'script.yml', '{name: myscript}'
268
+ setup_one 'missing', 'config/01-controls.yml', 'controls: []'
269
+ setup_one 'missing', 'config/02-requirements.yml', 'requirements: []'
270
+ setup_one 'missing', 'config/03-executions.yml', ""
271
+ setup_one 'missing', 'config/04-validations.yml', "validations:\n- {data: x, type: DirExists}\n- data: x"
272
+
273
+ command "pub"
274
+ stdout.should =~ /missing field type/
275
+ stdout.should =~ /missing type for validation 2/
276
+ end
5
277
 
6
278
  it "checks if script exists before publishing" do
7
279
  prepare(:get, '/scripts/firewall.json', '/scripts/firewall.json')
@@ -17,14 +289,32 @@ describe StackFu::Commands::PublishCommand do
17
289
  stdout.should =~ /Success/
18
290
  end
19
291
 
292
+ private
293
+
294
+ def setup_fixture(script)
295
+ setup_one script, "script.yml"
296
+ setup_one script, "config/01-controls.yml"
297
+ setup_one script, "config/02-requirements.yml"
298
+ setup_one script, "config/03-executions.yml"
299
+ setup_one script, "config/04-validations.yml"
300
+ end
301
+
302
+ def setup_one(script, expect, contents=nil)
303
+ return unless fixture?("scripts/#{script}/#{expect}")
304
+ contents ||= read_fixture("scripts/#{script}/#{expect}")
305
+
306
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with(expect).returns(contents)
307
+ end
308
+
309
+
20
310
  def setup_script(options={})
21
- StackFu::Commands::PublishCommand.any_instance.expects(:read).with("script.yml").returns(<<-EOS)
311
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("script.yml").returns(<<-EOS)
22
312
  ---
23
- type: stack
313
+ type: script
24
314
  name: #{options[:"script_name"] || "my_script"}
25
315
  description: "This will deploy my script"
26
316
  EOS
27
- StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/01-controls.yml").returns(<<-EOS)
317
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/01-controls.yml").returns(<<-EOS)
28
318
  controls:
29
319
  - name: nome
30
320
  label: Nome
@@ -33,28 +323,28 @@ controls:
33
323
  label: Idade
34
324
  type: Numericbox
35
325
  EOS
36
- StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/02-requirements.yml").returns(<<-EOS)
326
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/02-requirements.yml").returns(<<-EOS)
37
327
  requirements:
38
328
 
39
- - type: directory
329
+ - type: DirExists
40
330
  data: "/var"
41
331
  error: "You need /var folder before installing"
42
332
  EOS
43
- StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/03-executions.yml").returns(options[:scripts] || <<-EOS)
333
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/03-executions.yml").returns(options[:scripts] || <<-EOS)
44
334
  executions:
45
335
 
46
336
  - description: Echoer
47
337
  file: echoer
48
338
  EOS
49
- StackFu::Commands::PublishCommand.any_instance.expects(:read).with("config/04-validations.yml").returns(<<-EOS)
339
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("config/04-validations.yml").returns(<<-EOS)
50
340
  validations:
51
- - type: directory
341
+ - type: DirExists
52
342
  data: "/etc/apache2"
53
343
  error: Apache was not installed properly
54
344
  EOS
55
345
 
56
346
  unless options[:scripts]
57
- StackFu::Commands::PublishCommand.any_instance.expects(:read).with("executables/echoer.sh.erb").returns(<<-EOS)
347
+ StackFu::Commands::PublishCommand.any_instance.stubs(:read).with("executables/echoer.sh.erb").returns(<<-EOS)
58
348
  #
59
349
  # echoe.sh
60
350
  # Echoes a variable
data/stackfu.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{stackfu}
5
- s.version = "0.1.5"
5
+ s.version = "0.1.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Felipe Coury"]
9
- s.date = %q{2010-09-14}
9
+ s.date = %q{2010-09-16}
10
10
  s.default_executable = %q{stackfu}
11
11
  s.description = %q{StackFu Backend}
12
12
  s.email = %q{felipe@stackfu.com}
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackfu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 5
10
- version: 0.1.5
9
+ - 6
10
+ version: 0.1.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Felipe Coury
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-14 00:00:00 -03:00
18
+ date: 2010-09-16 00:00:00 -03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency