stackfu 0.1.5 → 0.1.6

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/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