sous_chef 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -2,5 +2,99 @@
2
2
 
3
3
  Chef's prep-cook
4
4
 
5
+ == Description
6
+
5
7
  Create bash scripts with chef-like syntax
6
8
 
9
+ == Example
10
+
11
+ Given this code:
12
+
13
+ config = {:dir => '/home'}
14
+
15
+ SousChef.prep(:verbose, :shebang) do
16
+ halt_on_failed_command
17
+
18
+ log do
19
+ stdout "/root/stdout.log"
20
+ stderr "/root/stderr.log"
21
+ end
22
+
23
+ file "/etc/config.yml" do
24
+ content config.to_yaml
25
+ mode 0600
26
+ end
27
+
28
+ execute 'rvm' do
29
+ creates "/usr/local/rvm/scripts/rvm"
30
+ command "gem install rvm && rvm-install"
31
+ end
32
+
33
+ execute "source rvm" do
34
+ command <<-EOS
35
+ RUBYOPT=""
36
+ source /usr/local/rvm/scripts/rvm
37
+ EOS
38
+ end
39
+
40
+ gemfile config[:dir] do
41
+ source "http://gemcutter.org/"
42
+
43
+ gem 'chef'
44
+ gem 'dbi', '0.4.3'
45
+ gem 'dbd-mysql', '0.4.3'
46
+ gem 'open4', '0.9.6'
47
+ end
48
+
49
+ execute 'install bundler' do
50
+ command "gem install bundler --no-ri --no-rdoc"
51
+ end
52
+
53
+ execute 'bundle gems' do
54
+ cwd config[:dir]
55
+ command "gem bundle"
56
+ end
57
+ end
58
+
59
+ the return value will be:
60
+
61
+ #!/bin/bash
62
+
63
+ # halt on failed command
64
+ set -e
65
+
66
+ exec 1>/root/stdout.log 2>/root/stderr.log
67
+
68
+ # /etc/config.yml
69
+ if ! test -e /etc/config.yml; then
70
+ echo '---
71
+ :dir: /home
72
+ ' > /etc/config.yml
73
+ fi
74
+ chmod 0600 /etc/config.yml
75
+
76
+ # rvm
77
+ if ! test -e /usr/local/rvm/scripts/rvm; then
78
+ gem install rvm && rvm-install
79
+ fi
80
+
81
+ # source rvm
82
+ RUBYOPT=""
83
+ source /usr/local/rvm/scripts/rvm
84
+
85
+ # /home
86
+ if ! test -e /home/Gemfile; then
87
+ echo 'source "http://gemcutter.org/"
88
+
89
+ gem "chef"
90
+ gem "dbd-mysql", "0.4.3"
91
+ gem "dbi", "0.4.3"
92
+ gem "open4", "0.9.6"' > /home/Gemfile
93
+ fi
94
+
95
+ # install bundler
96
+ gem install bundler --no-ri --no-rdoc
97
+
98
+ # bundle gems
99
+ cd /home
100
+ gem bundle
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :major: 0
3
2
  :minor: 0
4
- :patch: 1
5
-
3
+ :build:
4
+ :patch: 2
5
+ :major: 0
@@ -32,7 +32,8 @@ module SousChef
32
32
  script << %{# #{resource.name}\n} if verbose? && resource.name
33
33
  script << resource.to_script
34
34
  end
35
- lines.join("\n\n")
35
+ # add a trailing newline for consistency and vim-friendliness
36
+ lines.join("\n\n") << "\n"
36
37
  end
37
38
  end
38
39
 
@@ -98,9 +99,12 @@ module SousChef
98
99
  end
99
100
 
100
101
  def escape_string(string)
101
- # many slashes because single-quote has some sort of
102
- # special meaning in regexp replacement strings
103
- string && string.gsub(/'/, %q{\\\\'})
102
+ # bash is completely insane
103
+ # this stops the quote, immediately starts another one using
104
+ # double quotes to insert the single quote, then resumes the
105
+ # single quote again until the terminating single quote
106
+ return if string.nil?
107
+ string.gsub("'", %q{'"'"'})
104
108
  end
105
109
 
106
110
  def method_missing(meth, *args, &block)
@@ -9,6 +9,7 @@ module SousChef
9
9
 
10
10
  def to_script
11
11
  @script ||= begin
12
+ setup
12
13
  prepend %{cd #{escape_path(@cwd)}} if @cwd
13
14
  @commands = @commands.inject([]) do |result, line|
14
15
  result + line.split("\n")
@@ -7,7 +7,7 @@ module SousChef
7
7
 
8
8
  protected
9
9
  def escaped_content
10
- escape_string(content)
10
+ content#.gsub('$', '\$')
11
11
  end
12
12
 
13
13
  def create
@@ -24,9 +24,21 @@ module SousChef
24
24
  %{test -e #{escape_path(path)}}
25
25
  end
26
26
 
27
+ def heredoc
28
+ @heredoc ||= begin
29
+ candidate = "SousChefHeredoc"
30
+ candidate += "1" while content.include?(candidate)
31
+ candidate
32
+ end
33
+ end
34
+
27
35
  def create_file_command
28
36
  if content
29
- %{echo '#{escaped_content}' > #{escape_path(path)}}
37
+ lines = []
38
+ lines << "cat <<'#{heredoc}' > #{escape_path(path)}"
39
+ lines << escaped_content
40
+ lines << heredoc
41
+ lines.join("\n")
30
42
  else
31
43
  %{touch #{escape_path(path)}}
32
44
  end
@@ -7,9 +7,11 @@ if test -e /root/report.log; then
7
7
  fi
8
8
 
9
9
  if ! test -e /etc/config.yml; then
10
- echo '--- {}
10
+ cat <<'SousChefHeredoc' > /etc/config.yml
11
+ --- {}
11
12
 
12
- ' > /etc/config.yml
13
+
14
+ SousChefHeredoc
13
15
  fi
14
16
  chmod 0600 /etc/config.yml
15
17
 
@@ -23,10 +25,12 @@ source /usr/local/rvm/scripts/rvm
23
25
 
24
26
  if ! test -e /etc/profile.d/rvm.sh; then
25
27
  echo 'Setting up rvm source'
26
- echo '# rvm configuration
28
+ cat <<'SousChefHeredoc' > /etc/profile.d/rvm.sh
29
+ # rvm configuration
27
30
  RUBYOPT=""
28
31
  if [[ -s /usr/local/rvm/scripts/rvm ]] ; then source /usr/local/rvm/scripts/rvm ; fi
29
- ' > /etc/profile.d/rvm.sh
32
+
33
+ SousChefHeredoc
30
34
  fi
31
35
 
32
36
  echo 'installing ruby'
@@ -49,12 +53,14 @@ mkdir -p /home/sous_chef
49
53
  chmod 0755 /home/sous_chef
50
54
 
51
55
  if ! test -e /home/sous_chef/Gemfile; then
52
- echo 'source "http://gemcutter.org/"
56
+ cat <<'SousChefHeredoc' > /home/sous_chef/Gemfile
57
+ source "http://gemcutter.org/"
53
58
 
54
59
  gem "chef"
55
60
  gem "dbd-mysql", "0.4.3"
56
61
  gem "dbi", "0.4.3"
57
- gem "open4", "0.9.6"' > /home/sous_chef/Gemfile
62
+ gem "open4", "0.9.6"
63
+ SousChefHeredoc
58
64
  fi
59
65
 
60
66
  gem install bundler --no-ri --no-rdoc
@@ -64,9 +70,11 @@ gem bundle
64
70
 
65
71
  if ! test -e /etc/profile.d/bin-path.sh; then
66
72
  echo 'Setting up bin-path'
67
- echo '# bundled gem bin path configuration
73
+ cat <<'SousChefHeredoc' > /etc/profile.d/bin-path.sh
74
+ # bundled gem bin path configuration
68
75
  export PATH=/home/sous_chef/bin:$PATH
69
- ' > /etc/profile.d/bin-path.sh
76
+
77
+ SousChefHeredoc
70
78
  fi
71
79
 
72
80
  nohup /home/sous_chef/bin/chef --main &
data/spec/recipe_spec.rb CHANGED
@@ -16,7 +16,7 @@ describe SousChef::Recipe do
16
16
  end
17
17
 
18
18
  it "includes comments" do
19
- @recipe.to_script.should == "# run ls\nls"
19
+ @recipe.to_script.should == "# run ls\nls\n"
20
20
  end
21
21
  end
22
22
 
@@ -34,7 +34,7 @@ describe SousChef::Recipe do
34
34
  end
35
35
 
36
36
  it "includes a shebang line" do
37
- @recipe.to_script.should == "#!/bin/bash\n\nls"
37
+ @recipe.to_script.should == "#!/bin/bash\n\nls\n"
38
38
  end
39
39
  end
40
40
  end
@@ -56,7 +56,7 @@ describe SousChef::Recipe do
56
56
  end
57
57
 
58
58
  it "loads a recipe from a file" do
59
- @recipe.to_script.should == File.read(File.dirname(__FILE__) + '/fixtures/deploy_command_expected.sh').strip
59
+ @recipe.to_script.should == File.read(File.dirname(__FILE__) + '/fixtures/deploy_command_expected.sh')
60
60
  end
61
61
  end
62
62
  end
@@ -1,37 +1,21 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe SousChef::Resource::Execute do
4
- before do
5
- @execute = SousChef::Resource::Execute.new(nil, "install bundler") do
6
- command "gem install bundler"
4
+ it "formats multiline commands that are wrapped in not_if" do
5
+ execute = resource("clone sous_chef") do
6
+ command <<-EOS
7
+ git clone git://github.com/engineyard/sous_chef.git
8
+ cd sous_chef
9
+ gem bundle
10
+ EOS
11
+ not_if 'test -d sous_chef'
7
12
  end
8
- end
9
-
10
- it "has a name" do
11
- @execute.name.should == "install bundler"
12
- end
13
-
14
- it "responds to a method its context responds to" do
15
- @context = stub(:foobar => 5)
16
- @execute = SousChef::Resource::Execute.new(@context, "install bundler") do
17
- command "gem install bundler"
18
- end
19
- @execute.should respond_to(:foobar)
20
- end
21
-
22
- it "delegates missing methods to its context when it responds" do
23
- @context = stub(:foobar => 5)
24
- @execute = SousChef::Resource::Execute.new(@context, "install bundler") do
25
- command "gem install bundler"
26
- end
27
- @execute.foobar.should == 5
28
- end
29
-
30
- it "does not resource_respond_to? a method its context responds to" do
31
- @context = stub(:foobar => 5)
32
- @execute = SousChef::Resource::Execute.new(@context, "install bundler") do
33
- command "gem install bundler"
34
- end
35
- @execute.should_not be_resource_respond_to(:foobar)
13
+ execute.to_script.should == %{
14
+ if ! test -d sous_chef; then
15
+ git clone git://github.com/engineyard/sous_chef.git
16
+ cd sous_chef
17
+ gem bundle
18
+ fi
19
+ }.strip
36
20
  end
37
21
  end
@@ -35,10 +35,12 @@ describe SousChef::Resource::File do
35
35
  @file.content.should == nil
36
36
  end
37
37
 
38
- it "echos content to file" do
38
+ it "cats content to file" do
39
39
  @file.to_script.should == %{
40
40
  if ! test -e note.txt; then
41
- echo 'this is a note' > note.txt
41
+ cat <<'SousChefHeredoc' > note.txt
42
+ this is a note
43
+ SousChefHeredoc
42
44
  fi
43
45
  }.strip
44
46
  end
@@ -49,7 +51,9 @@ fi
49
51
  end
50
52
  @file.to_script.should == %q{
51
53
  if ! test -e note.txt; then
52
- echo 'this is a \'note\'' > note.txt
54
+ cat <<'SousChefHeredoc' > note.txt
55
+ this is a 'note'
56
+ SousChefHeredoc
53
57
  fi
54
58
  }.strip
55
59
  end
@@ -58,11 +62,26 @@ fi
58
62
  @file = resource("note.txt") do
59
63
  content %{export PATH=/my/bin:$PATH}
60
64
  end
61
- @file.to_script.should == %q{
65
+ @file.to_script.should == <<-EOSH.chomp
62
66
  if ! test -e note.txt; then
63
- echo 'export PATH=/my/bin:$PATH' > note.txt
67
+ cat <<'SousChefHeredoc' > note.txt
68
+ export PATH=/my/bin:$PATH
69
+ SousChefHeredoc
64
70
  fi
65
- }.strip
71
+ EOSH
72
+ end
73
+
74
+ it "changes it's heredoc if the content of the file contains the heredoc" do
75
+ @file = resource("note.txt") do
76
+ content %{SousChefHeredoc}
77
+ end
78
+ @file.to_script.should == <<-EOSH.chomp
79
+ if ! test -e note.txt; then
80
+ cat <<'SousChefHeredoc1' > note.txt
81
+ SousChefHeredoc
82
+ SousChefHeredoc1
83
+ fi
84
+ EOSH
66
85
  end
67
86
 
68
87
  it "handles newlines in the content" do
@@ -75,16 +94,18 @@ a
75
94
  NOTE
76
95
  EOS
77
96
  end
78
- @file.to_script.should == %q{
97
+ @file.to_script.should == <<-EOSH.chomp
79
98
  if ! test -e note.txt; then
80
- echo 'This
99
+ cat <<'SousChefHeredoc' > note.txt
100
+ This
81
101
  is
82
102
 
83
103
  a
84
104
  NOTE
85
- ' > note.txt
105
+
106
+ SousChefHeredoc
86
107
  fi
87
- }.strip
108
+ EOSH
88
109
  end
89
110
 
90
111
  it "outputs the path instead of the name if it exists" do
@@ -94,7 +115,9 @@ fi
94
115
  end
95
116
  @file.to_script.should == %q{
96
117
  if ! test -e /home/user/note.txt; then
97
- echo 'this is a note' > /home/user/note.txt
118
+ cat <<'SousChefHeredoc' > /home/user/note.txt
119
+ this is a note
120
+ SousChefHeredoc
98
121
  fi
99
122
  }.strip
100
123
  end
data/spec/sous_spec.rb CHANGED
@@ -8,7 +8,7 @@ describe SousChef do
8
8
  command "ls"
9
9
  end
10
10
  end
11
- script.should == "ls"
11
+ script.should == "ls\n"
12
12
  end
13
13
 
14
14
  it "concatenates multiple commands" do
@@ -18,7 +18,7 @@ describe SousChef do
18
18
  command "tar xvfz file.tgz"
19
19
  end
20
20
  end
21
- script.should == "curl -O http://www.example.com/file.tgz\ntar xvfz file.tgz"
21
+ script.should == "curl -O http://www.example.com/file.tgz\ntar xvfz file.tgz\n"
22
22
  end
23
23
 
24
24
  it "respects multiline commands" do
@@ -30,7 +30,7 @@ tar xvfz file.tgz
30
30
  CODE
31
31
  end
32
32
  end
33
- script.should == "curl -O http://www.example.com/file.tgz\ntar xvfz file.tgz"
33
+ script.should == "curl -O http://www.example.com/file.tgz\ntar xvfz file.tgz\n"
34
34
  end
35
35
 
36
36
  it "changes current working directory on cwd" do
@@ -39,7 +39,7 @@ tar xvfz file.tgz
39
39
  cwd "/home/user"
40
40
  end
41
41
  end
42
- script.should == %{cd /home/user}
42
+ script.should == "cd /home/user\n"
43
43
  end
44
44
 
45
45
  it "changes the current working directory before any commands" do
@@ -49,7 +49,7 @@ tar xvfz file.tgz
49
49
  cwd "/home/user"
50
50
  end
51
51
  end
52
- script.should == %{cd /home/user\ncp foo bar}
52
+ script.should == "cd /home/user\ncp foo bar\n"
53
53
  end
54
54
 
55
55
  it "can use a method defined within the prep block" do
@@ -62,7 +62,7 @@ tar xvfz file.tgz
62
62
  report "`date`"
63
63
  end
64
64
  end
65
- script.should == %{echo `date`}
65
+ script.should == "echo `date`\n"
66
66
  end
67
67
 
68
68
  it "scopes cwd to the correct execute block" do
@@ -76,7 +76,7 @@ tar xvfz file.tgz
76
76
  command "gem bundle"
77
77
  end
78
78
  end
79
- script.should == %{gem install bundler\n\ncd /data/projects/foo\ngem bundle}
79
+ script.should == "gem install bundler\n\ncd /data/projects/foo\ngem bundle\n"
80
80
  end
81
81
 
82
82
  it "wraps commands in an if block on not_if" do
@@ -87,12 +87,12 @@ tar xvfz file.tgz
87
87
  not_if "test -d /data/projects/foo/vendor"
88
88
  end
89
89
  end
90
- script.should == %{
90
+ script.should == <<-EOSH
91
91
  if ! test -d /data/projects/foo/vendor; then
92
92
  cd /data/projects/foo
93
93
  gem bundle
94
94
  fi
95
- }.strip
95
+ EOSH
96
96
  end
97
97
 
98
98
  it "wraps commands in an if block with test -e on creates" do
@@ -103,12 +103,12 @@ fi
103
103
  command "gem bundle"
104
104
  end
105
105
  end
106
- script.should == %{
106
+ script.should == <<-EOSH
107
107
  if ! test -e /data/projects/foo/vendor; then
108
108
  cd /data/projects/foo
109
109
  gem bundle
110
110
  fi
111
- }.strip
111
+ EOSH
112
112
  end
113
113
  end
114
114
 
@@ -120,11 +120,13 @@ fi
120
120
  content "export PATH=~/bin:$PATH"
121
121
  end
122
122
  end
123
- script.should == %{
123
+ script.should == <<-EOSH
124
124
  if ! test -e ~/.bash_profile; then
125
- echo 'export PATH=~/bin:$PATH' > ~/.bash_profile
125
+ cat <<'SousChefHeredoc' > ~/.bash_profile
126
+ export PATH=~/bin:\$PATH
127
+ SousChefHeredoc
126
128
  fi
127
- }.strip
129
+ EOSH
128
130
  end
129
131
  end
130
132
 
@@ -133,7 +135,7 @@ fi
133
135
  script = SousChef.prep do
134
136
  directory "/usr/local/bin"
135
137
  end
136
- script.should == %{mkdir -p /usr/local/bin}
138
+ script.should == "mkdir -p /usr/local/bin\n"
137
139
  end
138
140
  end
139
141
 
@@ -142,7 +144,7 @@ fi
142
144
  script = SousChef.prep do
143
145
  log "~/script.log"
144
146
  end
145
- script.should == %{exec 1>~/script.log 2>&1}
147
+ script.should == "exec 1>~/script.log 2>&1\n"
146
148
  end
147
149
 
148
150
  it "allows logging stdout only" do
@@ -151,7 +153,7 @@ fi
151
153
  stdout "stdout.log"
152
154
  end
153
155
  end
154
- script.should == %{exec 1>stdout.log}
156
+ script.should == "exec 1>stdout.log\n"
155
157
  end
156
158
 
157
159
  it "allows logging stdout and stderr" do
@@ -161,7 +163,7 @@ fi
161
163
  stderr "stderr.log"
162
164
  end
163
165
  end
164
- script.should == %{exec 1>stdout.log 2>stderr.log}
166
+ script.should == "exec 1>stdout.log 2>stderr.log\n"
165
167
  end
166
168
  end
167
169
 
@@ -170,7 +172,7 @@ fi
170
172
  script = SousChef.prep do
171
173
  halt_on_failed_command
172
174
  end
173
- script.should == %{set -e}
175
+ script.should == "set -e\n"
174
176
  end
175
177
  end
176
178
 
@@ -179,7 +181,7 @@ fi
179
181
  script = SousChef.prep do
180
182
  echo "I'm in bash!"
181
183
  end
182
- script.should == %q{echo 'I\'m in bash!'}
184
+ script.should == %{echo 'I'"'"'m in bash!'\n}
183
185
  end
184
186
 
185
187
  it "echoes from anywhere" do
@@ -189,12 +191,14 @@ fi
189
191
  content "something"
190
192
  end
191
193
  end
192
- script.should == %q{
194
+ script.should == <<-EOSH
193
195
  if ! test -e newfile.txt; then
194
- echo 'I\'m in bash!'
195
- echo 'something' > newfile.txt
196
+ echo 'I'"'"'m in bash!'
197
+ cat <<'SousChefHeredoc' > newfile.txt
198
+ something
199
+ SousChefHeredoc
196
200
  fi
197
- }.strip
201
+ EOSH
198
202
  end
199
203
  end
200
204
 
@@ -206,12 +210,14 @@ fi
206
210
  gem "rack", "1.0.0"
207
211
  end
208
212
  end
209
- script.should == %q{
213
+ script.should == <<-EOSH
210
214
  if ! test -e /data/projects/foo/Gemfile; then
211
- echo 'gem "rack", "1.0.0"
212
- gem "rails", "2.3.2"' > /data/projects/foo/Gemfile
215
+ cat <<'SousChefHeredoc' > /data/projects/foo/Gemfile
216
+ gem "rack", "1.0.0"
217
+ gem "rails", "2.3.2"
218
+ SousChefHeredoc
213
219
  fi
214
- }.strip
220
+ EOSH
215
221
  end
216
222
 
217
223
  it "can have sources" do
@@ -221,13 +227,15 @@ fi
221
227
  source 'http://gems.engineyard.com/'
222
228
  end
223
229
  end
224
- script.should == %q{
230
+ script.should == <<-EOSH
225
231
  if ! test -e /data/projects/foo/Gemfile; then
226
- echo 'source "http://gems.engineyard.com/"
232
+ cat <<'SousChefHeredoc' > /data/projects/foo/Gemfile
233
+ source "http://gems.engineyard.com/"
227
234
 
228
- gem "rails"' > /data/projects/foo/Gemfile
235
+ gem "rails"
236
+ SousChefHeredoc
229
237
  fi
230
- }.strip
238
+ EOSH
231
239
  end
232
240
  end
233
241
 
@@ -239,7 +247,7 @@ fi
239
247
  end
240
248
  end
241
249
  recipe.node = { :dir => '/home' }
242
- recipe.to_script.should == "ls /home"
250
+ recipe.to_script.should == "ls /home\n"
243
251
  end
244
252
  end
245
253
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sous_chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Emde