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

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.
@@ -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