kb 1.0.0.alpha.0 → 1.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
+ - 2.0.0
4
5
  - 1.9.3
5
6
  - 1.9.2
6
7
  - ruby-head
@@ -0,0 +1,26 @@
1
+ Feature: Plugin install command
2
+ In order to let user test they way they want to test
3
+ As a user of kb
4
+ I want the ability to install test runner plugins
5
+
6
+ Background:
7
+ Given a sandboxed GEM_HOME directory named "kb-plugin"
8
+
9
+ Scenario: Installing a missing plugin
10
+ When I run `kb plugin install rack`
11
+ Then the output should contain "Plugin rack installed"
12
+ And the exit status should be 0
13
+ And a gem named "rack" is installed
14
+
15
+ Scenario: Installing a missing plugin with a version
16
+ When I run `kb plugin install rack@1.2.8`
17
+ Then the output should contain "Plugin rack@1.2.8 installed (version 1.2.8)"
18
+ And the exit status should be 0
19
+ And a gem named "rack" is installed with version "1.2.8"
20
+
21
+ Scenario: Installing a specfic newer version of an existing plugin
22
+ When I successfully run `kb plugin install rack@1.2.8`
23
+ And I run `kb plugin install rack@1.3.10`
24
+ Then the output should contain "Plugin rack@1.3.10 installed (version 1.3.10)"
25
+ And the exit status should be 0
26
+ And a gem named "rack" is installed with version "1.3.10"
@@ -1,10 +1,15 @@
1
1
  require 'tmpdir'
2
+ require 'pathname'
2
3
 
3
4
  Given(/^a KB_ROOT of "(.*?)"$/) do |kb_root|
5
+ backup_envvar('KB_ROOT')
6
+
4
7
  ENV['KB_ROOT'] = kb_root
5
8
  end
6
9
 
7
10
  Given(/^a test KB_ROOT directory named "(.*?)"$/) do |name|
11
+ backup_envvar('KB_ROOT')
12
+
8
13
  kb_root = Pathname.new(Dir.mktmpdir(name))
9
14
  (kb_root + "suites").mkpath
10
15
  ENV['KB_ROOT'] = kb_root.to_s
@@ -19,7 +24,33 @@ Given(/^a suite directory named "(.*?)"$/) do |name|
19
24
  FileUtils.mkdir_p(File.join(ENV['KB_ROOT'], "suites", name))
20
25
  end
21
26
 
27
+ Given(/^a sandboxed GEM_HOME directory named "(.*?)"$/) do |name|
28
+ backup_envvar('GEM_HOME')
29
+ backup_envvar('GEM_PATH')
30
+
31
+ gem_home = Pathname.new(Dir.mktmpdir(name))
32
+ ENV['GEM_HOME'] = gem_home.to_s
33
+ ENV['GEM_PATH'] = [gem_home.to_s, ENV['GEM_PATH']].join(':')
34
+ @kb_root_dirs << gem_home
35
+ end
36
+
22
37
  Then(/^the suite directory named "(.*?)" should not exist$/) do |name|
23
38
  directory = File.join(ENV['KB_ROOT'], "suites", name)
24
39
  check_directory_presence([directory], false)
25
40
  end
41
+
42
+ Then(/^a gem named "(.*?)" is installed with version "(.*?)"$/) do |name, version|
43
+ unbundlerize do
44
+ run_simple(unescape("gem list #{name} --version #{version} -i"), true, nil)
45
+ end
46
+ end
47
+
48
+ Then(/^a gem named "(.*?)" is installed$/) do |name|
49
+ unbundlerize do
50
+ run_simple(unescape("gem list #{name} -i"), true, nil)
51
+ end
52
+ end
53
+
54
+ Then(/^pry me$/) do
55
+ require 'pry' ; binding.pry
56
+ end
@@ -4,7 +4,7 @@ require 'aruba/cucumber'
4
4
  SimpleCov.command_name "features"
5
5
 
6
6
  Before do
7
- @aruba_timeout_seconds = 5
7
+ @aruba_timeout_seconds = 10
8
8
  @kb_root_dirs = []
9
9
  end
10
10
 
@@ -14,6 +14,27 @@ After do |s|
14
14
  # steps are executed and clear it out.
15
15
  Cucumber.wants_to_quit = true if s.failed?
16
16
 
17
- ENV['KB_ROOT'] = ENV.delete('_CUKE_KB_ROOT') if ENV['_CUKE_KB_ROOT']
17
+ # Restore environment variables to their original settings, if they have
18
+ # been saved off
19
+ ENV.keys.select { |key| key =~ /^_CUKE_/ }.each do |backup_key|
20
+ ENV[backup_key.sub(/^_CUKE_/, '')] = ENV.delete(backup_key)
21
+ end
22
+
18
23
  @kb_root_dirs.each { |dir| FileUtils.rm_rf(dir) }
19
24
  end
25
+
26
+ def backup_envvar(key)
27
+ ENV["_CUKE_#{key}"] = ENV[key]
28
+ end
29
+
30
+ def restore_envvar(key)
31
+ ENV[key] = ENV.delete("_CUKE_#{key}")
32
+ end
33
+
34
+ def unbundlerize
35
+ keys = %w[BUNDLER_EDITOR BUNDLE_BIN_PATH BUNDLE_GEMFILE RUBYOPT]
36
+
37
+ keys.each { |key| backup_envvar(key) ; ENV.delete(key) }
38
+ yield
39
+ keys.each { |key| restore_envvar(key) }
40
+ end
@@ -17,7 +17,9 @@
17
17
  # limitations under the License.
18
18
 
19
19
  require 'kb/thor'
20
+ require 'kb/command/plugin'
20
21
  require 'kb/command/suite'
22
+ require 'kb/command/test'
21
23
 
22
24
  module KB
23
25
 
@@ -27,7 +29,11 @@ module KB
27
29
  #
28
30
  class CLI < Thor::Base
29
31
 
32
+ register KB::Command::Plugin, "plugin",
33
+ "plugin SUBCOMMAND", "Plugin subcommands"
30
34
  register KB::Command::Suite, "suite",
31
35
  "suite SUBCOMMAND", "Suite subcommands"
36
+ register KB::Command::Test, "test",
37
+ "test [PLUGIN ...]", "Runs test suites"
32
38
  end
33
39
  end
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'kb/thor'
20
+ require 'kb/command/plugin_install'
21
+ require 'kb/command/plugin_list'
22
+
23
+ module KB
24
+
25
+ module Command
26
+
27
+ # Plugin commands.
28
+ #
29
+ # @author Fletcher Nichol <fnichol@nichol.ca>
30
+ #
31
+ class Plugin < KB::Thor::Base
32
+
33
+ register KB::Command::PluginInstall, "install",
34
+ "install PLUGIN [PLUGIN ...]", "Installs one or more plugins"
35
+ register KB::Command::PluginList, "list",
36
+ "list", "Lists installed plugins"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,95 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'rubygems/dependency_installer'
20
+ require 'kb/thor'
21
+
22
+ module KB
23
+
24
+ module Command
25
+
26
+ # Plugin install command.
27
+ #
28
+ # @author Fletcher Nichol <fnichol@nichol.ca>
29
+ #
30
+ class PluginInstall < KB::Thor::BaseGroup
31
+
32
+ argument :plugins, :type => :array
33
+
34
+ def install_all
35
+ silence_gem_ui!
36
+ plugins.each { |plugin| install(plugin) }
37
+ end
38
+
39
+ private
40
+
41
+ def install(plugin)
42
+ install_gem(plugin)
43
+ end
44
+
45
+ def install_gem(plugin)
46
+ name, version = plugin.split("@")
47
+
48
+ if gem_installed?(name, version)
49
+ info "#{plugin} plugin already installed"
50
+ else
51
+ spec = dep_installer.install(new_dep(name, version)).first
52
+ info "Plugin #{plugin} installed (version #{spec.version})"
53
+ end
54
+ end
55
+
56
+ def gem_installed?(name, version)
57
+ installed = Array(Gem::Specification.find_all_by_name(name, version))
58
+ version = latest_version(name) if version.nil?
59
+
60
+ installed.find { |spec| spec.version.to_s == version }
61
+ end
62
+
63
+ def latest_version(name)
64
+ available_gems = dep_installer.find_gems_with_sources(new_dep(name))
65
+
66
+ spec, source = if available_gems.respond_to?(:last)
67
+ # DependencyInstaller sorts the results such that the last one is
68
+ # always the one it considers best.
69
+ spec_with_source = available_gems.last
70
+ spec_with_source && spec_with_source
71
+ else
72
+ # Rubygems 2.0 returns a Gem::Available set, which is a
73
+ # collection of AvailableSet::Tuple structs
74
+ available_gems.pick_best!
75
+ best_gem = available_gems.set.first
76
+ best_gem && [best_gem.spec, best_gem.source]
77
+ end
78
+
79
+ spec && spec.version && spec.version.to_s
80
+ end
81
+
82
+ def silence_gem_ui!
83
+ Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
84
+ end
85
+
86
+ def dep_installer
87
+ Gem::DependencyInstaller.new
88
+ end
89
+
90
+ def new_dep(name, version = nil)
91
+ Gem::Dependency.new(name, version)
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,50 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'kb/plugin'
20
+ require 'kb/thor'
21
+
22
+ module KB
23
+
24
+ module Command
25
+
26
+ # Plugin list command.
27
+ #
28
+ # @author Fletcher Nichol <fnichol@nichol.ca>
29
+ #
30
+ class PluginList < KB::Thor::BaseGroup
31
+
32
+ def list
33
+ if plugin_data.empty?
34
+ say "No plugins installed yet"
35
+ else
36
+ print_table([["Plugin", "Version"]] + plugin_data)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def plugin_data
43
+ @plugin_data ||= KB::Plugin.runner_plugins.map do |path|
44
+ spec = KB::Plugin.gem_from_path(path)
45
+ [File.basename(path), (spec && spec.version)]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,46 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'kb/thor'
20
+ require 'kb/plugin'
21
+
22
+ module KB
23
+
24
+ module Command
25
+
26
+ # Test command.
27
+ #
28
+ # @author Fletcher Nichol <fnichol@nichol.ca>
29
+ #
30
+ class Test < KB::Thor::BaseGroup
31
+
32
+ argument :plugins, :type => :array, :required => false
33
+
34
+ def perform
35
+ KB::Plugin.runner_plugins(plugins).each do |runner_path|
36
+ runner = File.basename(runner_path)
37
+ klass = ::Thor::Util.camel_case(runner)
38
+
39
+ banner "Running #{runner} test suite"
40
+ KB::Plugin.require!(runner_path)
41
+ invoke KB::Plugin.runner_class(klass)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,63 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ module KB
20
+
21
+ module RunnerPlugin
22
+ end
23
+
24
+ module Plugin
25
+
26
+ module_function
27
+
28
+ def runner_plugins(plugin_names = nil)
29
+ if plugin_names
30
+ Array(plugin_names).map { |plugin| "kb/runner_plugin/#{plugin}" }
31
+ else
32
+ all_runner_plugins
33
+ end
34
+ end
35
+
36
+ def all_runner_plugins
37
+ Gem.find_files('kb/runner_plugin/*.rb').map do |file|
38
+ "kb/runner_plugin/#{File.basename(file).sub(/\.rb$/, '')}"
39
+ end
40
+ end
41
+
42
+ def require!(plugin_path)
43
+ require plugin_path
44
+ rescue LoadError => e
45
+ die "Could not load #{plugin_path} (#{e.class}: #{e.message})"
46
+ end
47
+
48
+ def runner_class(klass)
49
+ KB::RunnerPlugin.const_get(klass)
50
+ end
51
+
52
+ def gem_from_path(plugin_path)
53
+ local_gem_path = "#{File.expand_path(plugin_path, $LOAD_PATH.first)}"
54
+ local_gemspec = File.join(File.dirname($LOAD_PATH.first), "kb.gemspec")
55
+
56
+ if ! Dir.glob("#{local_gem_path}#{Gem.suffix_pattern}").empty?
57
+ Gem::Specification.load(File.expand_path(local_gemspec))
58
+ else
59
+ Gem::Specification.find_by_path(plugin_path)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require 'kb/thor'
20
+
21
+ module KB
22
+
23
+ module RunnerPlugin
24
+
25
+ # Base class for all test runner plugins.
26
+ #
27
+ # @author Fletcher Nichol <fnichol@nichol.ca>
28
+ #
29
+ class Base < KB::Thor::BaseGroup
30
+ end
31
+ end
32
+ end
@@ -33,6 +33,7 @@ module KB
33
33
 
34
34
  include Helpers
35
35
  include UI
36
+ include ::Thor::Actions
36
37
  end
37
38
 
38
39
  # Base class for all Thor Group subclasses which includes useful mixins.
@@ -43,6 +44,7 @@ module KB
43
44
 
44
45
  include Helpers
45
46
  include UI
47
+ include ::Thor::Actions
46
48
  end
47
49
  end
48
50
  end
@@ -33,5 +33,20 @@ module KB
33
33
  def warn(msg)
34
34
  say(">>>>>> #{msg}")
35
35
  end
36
+
37
+ def run!(cmd)
38
+ run(cmd, :capture => false, :verbose => false)
39
+
40
+ if $?.success?
41
+ true
42
+ else
43
+ die "Command [#{cmd}] exit code was #{$?.exitstatus}", $?.exitstatus
44
+ end
45
+ end
46
+
47
+ def die(msg, exitstatus = 1)
48
+ $stderr.puts(msg)
49
+ exit(exitstatus)
50
+ end
36
51
  end
37
52
  end
@@ -17,5 +17,5 @@
17
17
  # limitations under the License.
18
18
 
19
19
  module KB
20
- VERSION = "1.0.0.alpha.0"
20
+ VERSION = "1.0.0.alpha.1"
21
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha.0
4
+ version: 1.0.0.alpha.1
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: 2013-03-15 00:00:00.000000000 Z
12
+ date: 2013-03-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -254,6 +254,7 @@ files:
254
254
  - README.md
255
255
  - Rakefile
256
256
  - bin/kb
257
+ - features/plugin_install_command.feature
257
258
  - features/step_definitions/kb_root_steps.rb
258
259
  - features/suite_cleanup_command.feature
259
260
  - features/suite_path_command.feature
@@ -261,10 +262,16 @@ files:
261
262
  - kb.gemspec
262
263
  - lib/kb.rb
263
264
  - lib/kb/cli.rb
265
+ - lib/kb/command/plugin.rb
266
+ - lib/kb/command/plugin_install.rb
267
+ - lib/kb/command/plugin_list.rb
264
268
  - lib/kb/command/suite.rb
265
269
  - lib/kb/command/suite_cleanup.rb
266
270
  - lib/kb/command/suite_path.rb
271
+ - lib/kb/command/test.rb
267
272
  - lib/kb/helpers.rb
273
+ - lib/kb/plugin.rb
274
+ - lib/kb/runner_plugin.rb
268
275
  - lib/kb/thor.rb
269
276
  - lib/kb/ui.rb
270
277
  - lib/kb/version.rb
@@ -296,6 +303,7 @@ signing_key:
296
303
  specification_version: 3
297
304
  summary: Kitchen Busser - Runs tests for projects in test-kitchen
298
305
  test_files:
306
+ - features/plugin_install_command.feature
299
307
  - features/step_definitions/kb_root_steps.rb
300
308
  - features/suite_cleanup_command.feature
301
309
  - features/suite_path_command.feature