jamie 0.1.0.alpha13 → 0.1.0.alpha14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/jamie/cli.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
+ require 'erb'
4
+ require 'ostruct'
3
5
  require 'thor'
4
6
 
5
7
  require 'jamie'
@@ -47,31 +49,18 @@ module Jamie
47
49
  exit 1
48
50
  end
49
51
 
50
- desc "init", "does the world"
52
+ desc "init", "Adds some configuration to your cookbook so Jamie can rock"
51
53
  def init
52
- create_file ".jamie.yml", default_yaml
53
- append_to_file("Rakefile", <<-RAKE.gsub(/ {8}/, '')) if init_rakefile?
54
-
55
- begin
56
- require 'jamie/rake_tasks'
57
- Jamie::RakeTasks.new
58
- rescue LoadError
59
- puts ">>>>> Jamie gem not loaded, omitting tasks" unless ENV['CI']
60
- end
61
- RAKE
62
- append_to_file("Thorfile", <<-THOR.gsub(/ {8}/, '')) if init_thorfile?
54
+ InitGenerator.new.init
55
+ end
63
56
 
64
- begin
65
- require 'jamie/thor_tasks'
66
- Jamie::ThorTasks.new
67
- rescue LoadError
68
- puts ">>>>> Jamie gem not loaded, omitting tasks" unless ENV['CI']
69
- end
70
- THOR
71
- empty_directory "test/integration/standard" if init_test_dir?
72
- append_to_gitignore(".jamie/")
73
- append_to_gitignore(".jamie.local.yml")
74
- add_plugins
57
+ desc "new_plugin [NAME]", "Generate a new Jamie Driver plugin gem project"
58
+ method_option :license, :aliases => "-l", :default => "apachev2",
59
+ :desc => "Type of license for gem (apachev2, mit, gplv3, gplv2, reserved)"
60
+ def new_plugin(name)
61
+ g = NewPluginGenerator.new
62
+ g.options = options
63
+ g.new_plugin(name)
75
64
  end
76
65
 
77
66
  private
@@ -143,6 +132,42 @@ module Jamie
143
132
  }
144
133
  ]
145
134
  end
135
+ end
136
+
137
+ # A project initialization generator, to help prepare a cookbook project for
138
+ # testing with Jamie.
139
+ class InitGenerator < Thor
140
+
141
+ include Thor::Actions
142
+
143
+ desc "init", "Adds some configuration to your cookbook so Jamie can rock"
144
+ def init
145
+ create_file ".jamie.yml", default_yaml
146
+ append_to_file("Rakefile", <<-RAKE.gsub(/ {8}/, '')) if init_rakefile?
147
+
148
+ begin
149
+ require 'jamie/rake_tasks'
150
+ Jamie::RakeTasks.new
151
+ rescue LoadError
152
+ puts ">>>>> Jamie gem not loaded, omitting tasks" unless ENV['CI']
153
+ end
154
+ RAKE
155
+ append_to_file("Thorfile", <<-THOR.gsub(/ {8}/, '')) if init_thorfile?
156
+
157
+ begin
158
+ require 'jamie/thor_tasks'
159
+ Jamie::ThorTasks.new
160
+ rescue LoadError
161
+ puts ">>>>> Jamie gem not loaded, omitting tasks" unless ENV['CI']
162
+ end
163
+ THOR
164
+ empty_directory "test/integration/standard" if init_test_dir?
165
+ append_to_gitignore(".jamie/")
166
+ append_to_gitignore(".jamie.local.yml")
167
+ add_plugins
168
+ end
169
+
170
+ private
146
171
 
147
172
  def default_yaml
148
173
  url_base = "https://opscode-vm.s3.amazonaws.com/vagrant/boxes"
@@ -259,4 +284,162 @@ module Jamie
259
284
  end
260
285
  end
261
286
  end
287
+
288
+ # A generator to create a new Jamie driver plugin.
289
+ class NewPluginGenerator < Thor
290
+
291
+ include Thor::Actions
292
+
293
+ desc "new_plugin [NAME]", "Generate a new Jamie Driver plugin gem project"
294
+ method_option :license, :aliases => "-l", :default => "apachev2",
295
+ :desc => "Type of license for gem (apachev2, mit, gplv3, gplv2, reserved)"
296
+ def new_plugin(plugin_name)
297
+ if ! run("command -v bundle", :verbose => false)
298
+ die "Bundler must be installed and on your PATH: `gem install bundler'"
299
+ end
300
+
301
+ @plugin_name = plugin_name
302
+ @gem_name = "jamie-#{plugin_name}"
303
+ @gemspec = "#{gem_name}.gemspec"
304
+ @klass_name = Util.to_camel_case(plugin_name)
305
+ @constant = Util.to_snake_case(plugin_name).upcase
306
+ @license = options[:license]
307
+ @author = %x{git config user.name}.chomp
308
+ @email = %x{git config user.email}.chomp
309
+ @year = Time.now.year
310
+
311
+ create_plugin
312
+ end
313
+
314
+ private
315
+
316
+ attr_reader :plugin_name, :gem_name, :gemspec, :klass_name,
317
+ :constant, :license, :author, :email, :year
318
+
319
+ def create_plugin
320
+ run("bundle gem #{gem_name}") unless File.directory?(gem_name)
321
+
322
+ inside(gem_name) do
323
+ update_gemspec
324
+ update_gemfile
325
+ update_rakefile
326
+ create_src_files
327
+ cleanup
328
+ create_license
329
+ add_git_files
330
+ end
331
+ end
332
+
333
+ def update_gemspec
334
+ gsub_file(gemspec, %r{require '#{gem_name}/version'},
335
+ %{require 'jamie/driver/#{plugin_name}_version.rb'})
336
+ gsub_file(gemspec, %r{Jamie::#{klass_name}::VERSION},
337
+ %{Jamie::Driver::#{constant}_VERSION})
338
+ gsub_file(gemspec, %r{(gem\.executables\s*) =.*$},
339
+ '\1 = []')
340
+ gsub_file(gemspec, %r{(gem\.description\s*) =.*$},
341
+ '\1 = "' + "Jamie::Driver::#{klass_name} - " +
342
+ "A Jamie Driver for #{klass_name}\"")
343
+ gsub_file(gemspec, %r{(gem\.summary\s*) =.*$},
344
+ '\1 = gem.description')
345
+ gsub_file(gemspec, %r{(gem\.homepage\s*) =.*$},
346
+ '\1 = "https://github.com/jamie-ci/' +
347
+ "#{gem_name}/\"")
348
+ insert_into_file(gemspec,
349
+ "\n gem.add_dependency 'jamie'\n", :before => "end\n")
350
+ insert_into_file(gemspec,
351
+ "\n gem.add_development_dependency 'cane'\n", :before => "end\n")
352
+ insert_into_file(gemspec,
353
+ " gem.add_development_dependency 'tailor'\n", :before => "end\n")
354
+ end
355
+
356
+ def update_gemfile
357
+ append_to_file("Gemfile", "\ngroup :test do\n gem 'rake'\nend\n")
358
+ end
359
+
360
+ def update_rakefile
361
+ append_to_file("Rakefile", <<-RAKEFILE.gsub(/^ {8}/, ''))
362
+ require 'cane/rake_task'
363
+ require 'tailor/rake_task'
364
+
365
+ desc "Run cane to check quality metrics"
366
+ Cane::RakeTask.new
367
+
368
+ Tailor::RakeTask.new
369
+
370
+ task :default => [ :cane, :tailor ]
371
+ RAKEFILE
372
+ end
373
+
374
+ def create_src_files
375
+ license_comments = rendered_license.gsub(/^/, '# ').gsub(/\s+$/, '')
376
+
377
+ empty_directory("lib/jamie/driver")
378
+ create_template("plugin/version.rb",
379
+ "lib/jamie/driver/#{plugin_name}_version.rb",
380
+ :klass_name => klass_name, :constant => constant,
381
+ :license => license_comments)
382
+ create_template("plugin/driver.rb",
383
+ "lib/jamie/driver/#{plugin_name}.rb",
384
+ :klass_name => klass_name, :license => license_comments)
385
+ end
386
+
387
+ def rendered_license
388
+ TemplateRenderer.render("plugin/license_#{license}",
389
+ :author => author, :email => email, :year => year)
390
+ end
391
+
392
+ def create_license
393
+ dest_file = case license
394
+ when "mit" then "LICENSE.txt"
395
+ when "apachev2", "reserved" then "LICENSE"
396
+ when "gplv2", "gplv3" then "COPYING"
397
+ else
398
+ raise ArgumentError, "No such license #{license}"
399
+ end
400
+
401
+ create_file(dest_file, rendered_license)
402
+ end
403
+
404
+ def cleanup
405
+ %W(LICENSE.txt lib/#{gem_name}/version.rb lib/#{gem_name}.rb).each do |f|
406
+ run("git rm -f #{f}") if File.exists?(f)
407
+ end
408
+ remove_dir("lib/#{gem_name}")
409
+ end
410
+
411
+ def add_git_files
412
+ run("git add .")
413
+ end
414
+
415
+ def create_template(template, destination, data = {})
416
+ create_file(destination, TemplateRenderer.render(template, data))
417
+ end
418
+
419
+ # Renders an ERB template with a hash of template variables.
420
+ class TemplateRenderer < OpenStruct
421
+
422
+ def self.render(template, data = {})
423
+ renderer = new(template, data)
424
+ yield renderer if block_given?
425
+ renderer.render
426
+ end
427
+
428
+ def initialize(template, data = {})
429
+ super()
430
+ data[:template] = template
431
+ data.each { |key, value| send("#{key}=", value) }
432
+ end
433
+
434
+ def render
435
+ ERB.new(IO.read(template_file)).result(binding)
436
+ end
437
+
438
+ private
439
+
440
+ def template_file
441
+ Jamie.source_root.join("templates", "#{template}.erb").to_s
442
+ end
443
+ end
444
+ end
262
445
  end
@@ -1,7 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
- require 'mixlib/shellout'
4
-
5
3
  require 'jamie'
6
4
 
7
5
  module Jamie
data/lib/jamie/vagrant.rb CHANGED
@@ -47,6 +47,7 @@ module Jamie
47
47
  chef.run_list = instance.run_list
48
48
  chef.json = instance.attributes
49
49
  chef.data_bags_path = instance.suite.data_bags_path
50
+ chef.roles_path = instance.suite.roles_path
50
51
  end
51
52
  end
52
53
  end
data/lib/jamie/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Jamie
4
4
 
5
- VERSION = "0.1.0.alpha13"
5
+ VERSION = "0.1.0.alpha14"
6
6
  end
data/lib/jamie.rb CHANGED
@@ -18,6 +18,13 @@ require 'jamie/version'
18
18
 
19
19
  module Jamie
20
20
 
21
+ # Returns the root path of the Jamie gem source code.
22
+ #
23
+ # @return [Pathname] root path of gem
24
+ def self.source_root
25
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
26
+ end
27
+
21
28
  # Base configuration class for Jamie. This class exposes configuration such
22
29
  # as the location of the Jamie YAML file, instances, log_levels, etc.
23
30
  class Config
@@ -122,7 +129,12 @@ module Jamie
122
129
 
123
130
  def new_suite(hash)
124
131
  data_bags_path = calculate_data_bags_path(hash['name'])
125
- Suite.new(hash.rmerge({ 'data_bags_path' => data_bags_path }))
132
+ roles_path = calculate_roles_path(hash['name'])
133
+ path_hash = {
134
+ 'data_bags_path' => data_bags_path,
135
+ 'roles_path' => roles_path
136
+ }
137
+ Suite.new(hash.rmerge(path_hash))
126
138
  end
127
139
 
128
140
  def new_platform(hash)
@@ -159,14 +171,33 @@ module Jamie
159
171
  default_driver_config.rmerge(common_driver_config.rmerge(platform_config))
160
172
  end
161
173
 
174
+ def calculate_roles_path(suite_name)
175
+ suite_roles_path = File.join(test_base_path, suite_name, "roles")
176
+ common_roles_path = File.join(test_base_path, "roles")
177
+ top_level_roles_path = File.join(Dir.pwd, "roles")
178
+
179
+ if File.directory?(suite_roles_path)
180
+ suite_roles_path
181
+ elsif File.directory?(common_roles_path)
182
+ common_roles_path
183
+ elsif File.directory?(top_level_roles_path)
184
+ top_level_roles_path
185
+ else
186
+ nil
187
+ end
188
+ end
189
+
162
190
  def calculate_data_bags_path(suite_name)
163
191
  suite_data_bags_path = File.join(test_base_path, suite_name, "data_bags")
164
192
  common_data_bags_path = File.join(test_base_path, "data_bags")
193
+ top_level_data_bags_path = File.join(Dir.pwd, "data_bags")
165
194
 
166
195
  if File.directory?(suite_data_bags_path)
167
196
  suite_data_bags_path
168
197
  elsif File.directory?(common_data_bags_path)
169
198
  common_data_bags_path
199
+ elsif File.directory?(top_level_data_bags_path)
200
+ top_level_data_bags_path
170
201
  else
171
202
  nil
172
203
  end
@@ -198,6 +229,10 @@ module Jamie
198
229
  # not exist
199
230
  attr_reader :data_bags_path
200
231
 
232
+ # @return [String] local path to the suite's roles, or nil if one does
233
+ # not exist
234
+ attr_reader :roles_path
235
+
201
236
  # Constructs a new suite.
202
237
  #
203
238
  # @param [Hash] options configuration for a new suite
@@ -213,6 +248,7 @@ module Jamie
213
248
  @run_list = options['run_list']
214
249
  @attributes = options['attributes'] || Hash.new
215
250
  @data_bags_path = options['data_bags_path']
251
+ @roles_path = options['roles_path']
216
252
  end
217
253
 
218
254
  private
@@ -887,6 +923,7 @@ module Jamie
887
923
  upload_solo_rb scp
888
924
  upload_cookbooks scp
889
925
  upload_data_bags scp if instance.suite.data_bags_path
926
+ upload_roles scp if instance.suite.roles_path
890
927
  end
891
928
  end
892
929
 
@@ -926,6 +963,16 @@ module Jamie
926
963
  end
927
964
  end
928
965
 
966
+ def upload_roles(scp)
967
+ roles_dir = instance.suite.roles_path
968
+ scp.upload!(roles_dir, "#{chef_home}/roles",
969
+ :recursive => true
970
+ ) do |ch, name, sent, total|
971
+ file = name.sub(%r{^#{roles_dir}/}, '')
972
+ puts " #{file}: #{sent}/#{total}"
973
+ end
974
+ end
975
+
929
976
  def solo_rb_contents
930
977
  solo = []
931
978
  solo << %{node_name "#{instance.name}"}
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ <%= license %>
4
+
5
+ require 'jamie'
6
+
7
+ module Jamie
8
+
9
+ module Driver
10
+
11
+ # <%= klass_name %> driver for Jamie.
12
+ class <%= klass_name %> < Jamie::Driver::SSHBase
13
+
14
+ def perform_create(instance, state)
15
+ end
16
+
17
+ def perform_destroy(instance, state)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ Author:: <%= author %> (<<%= email %>>)
2
+
3
+ Copyright (C) <%= year %>, <%= author %>
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
@@ -0,0 +1,18 @@
1
+ Author:: <%= author %> (<<%= email %>>)
2
+
3
+ Copyright (C) <%= year %> <%= author %>
4
+
5
+ This program is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU General Public License
7
+ as published by the Free Software Foundation; either version 2
8
+ of the License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
+ Boston, MA 02110-1301, USA.
@@ -0,0 +1,16 @@
1
+ Author:: <%= author %> (<<%= email %>>)
2
+
3
+ Copyright (C) <%= year %> <%= author %>
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,22 @@
1
+ Author:: <%= author %> (<<%= email %>>)
2
+
3
+ Copyright (c) <%= year %>, <%= author %>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,5 @@
1
+ Author:: <%= author %> (<<%= email %>>)
2
+
3
+ Copyright (C) <%= year %>, <%= author %>
4
+
5
+ All rights reserved - Do Not Redistribute
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ <%= license %>
4
+
5
+ module Jamie
6
+
7
+ module Driver
8
+
9
+ # Version string for <%= klass_name %> Jamie driver
10
+ <%= constant %>_VERSION = "0.1.0"
11
+ end
12
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jamie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha13
4
+ version: 0.1.0.alpha14
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-20 00:00:00.000000000 Z
12
+ date: 2012-12-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -180,6 +180,13 @@ files:
180
180
  - lib/jamie/vagrant.rb
181
181
  - lib/jamie/version.rb
182
182
  - lib/vendor/hash_recursive_merge.rb
183
+ - templates/plugin/driver.rb.erb
184
+ - templates/plugin/license_apachev2.erb
185
+ - templates/plugin/license_gplv2.erb
186
+ - templates/plugin/license_gplv3.erb
187
+ - templates/plugin/license_mit.erb
188
+ - templates/plugin/license_reserved.erb
189
+ - templates/plugin/version.rb.erb
183
190
  homepage: ''
184
191
  licenses: []
185
192
  post_install_message:
@@ -194,7 +201,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
201
  version: '0'
195
202
  segments:
196
203
  - 0
197
- hash: -1363591312854279086
204
+ hash: 168460114090032110
198
205
  required_rubygems_version: !ruby/object:Gem::Requirement
199
206
  none: false
200
207
  requirements: