busser 0.1.1 → 0.2.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.2.0 / 2013-03-31
2
+
3
+ ### New features
4
+
5
+ * Add dummy runner internal plugin and skip on plugin install commands. ([@fnichol][])
6
+ * Add postinstall feature to runner plugins & add dummy runner plugin. ([@fnichol][])
7
+ * Move cucumber steps into lib/ for use by plugin authors. ([@fnichol][])
8
+
9
+
1
10
  ## 0.1.1 / 2013-03-29
2
11
 
3
12
  ### New features
@@ -8,10 +17,10 @@
8
17
 
9
18
  * Support installing plugins from local .gem files. ([@fnichol][])
10
19
 
20
+
11
21
  ## 0.1.0 / 2013-03-28
12
22
 
13
23
  * Initial release
14
24
 
15
- [@fnichol]: https://github.com/fnichol
16
25
  <!--- The following link definition list is generated by PimpMyChangelog --->
17
26
  [@fnichol]: https://github.com/fnichol
@@ -4,23 +4,37 @@ Feature: Plugin install command
4
4
  I want the ability to install test runner plugins
5
5
 
6
6
  Background:
7
- Given a sandboxed GEM_HOME directory named "busser-plugin"
7
+ Given a non bundler environment
8
+ And a sandboxed GEM_HOME directory named "busser-plugin-gem-home"
8
9
 
9
10
  Scenario: Installing a missing plugin
10
- When I run `busser plugin install rack`
11
- Then the output should contain "Plugin rack installed"
11
+ When I run `busser plugin install busser-bash`
12
+ Then the output should contain "Plugin bash installed"
12
13
  And the exit status should be 0
13
- And a gem named "rack" is installed
14
+ And a gem named "busser-bash" is installed
14
15
 
15
16
  Scenario: Installing a missing plugin with a version
16
- When I run `busser plugin install rack@1.2.8`
17
- Then the output should contain "Plugin rack@1.2.8 installed (version 1.2.8)"
17
+ When I run `busser plugin install busser-bash@0.1.0`
18
+ Then the output should contain "Plugin bash installed (version 0.1.0)"
18
19
  And the exit status should be 0
19
- And a gem named "rack" is installed with version "1.2.8"
20
+ And a gem named "busser-bash" is installed with version "0.1.0"
20
21
 
21
22
  Scenario: Installing a specfic newer version of an existing plugin
22
- When I successfully run `busser plugin install rack@1.2.8`
23
- And I run `busser plugin install rack@1.3.10`
24
- Then the output should contain "Plugin rack@1.3.10 installed (version 1.3.10)"
23
+ When I successfully run `busser plugin install busser-bash@0.1.0`
24
+ And I run `busser plugin install busser-bash@0.1.1`
25
+ Then the output should contain "Plugin bash installed (version 0.1.1)"
25
26
  And the exit status should be 0
26
- And a gem named "rack" is installed with version "1.3.10"
27
+ And a gem named "busser-bash" is installed with version "0.1.1"
28
+
29
+ Scenario: Installing an internal plugin
30
+ When I run `busser plugin install dummy`
31
+ Then the output should contain "Plugin dummy already installed"
32
+ And the exit status should be 0
33
+
34
+ Scenario: Forcing postinstall script for an internal plugin
35
+ When I successfully run `busser plugin install dummy --force-postinstall`
36
+ Then a directory named "dummy" should exist
37
+ And the file "dummy/foobar.txt" should contain exactly:
38
+ """
39
+ The Dummy Driver.
40
+ """
@@ -1,11 +1,12 @@
1
1
  require 'simplecov'
2
2
  require 'aruba/cucumber'
3
3
 
4
+ require 'busser/cucumber'
5
+
4
6
  SimpleCov.command_name "features"
5
7
 
6
8
  Before do
7
9
  @aruba_timeout_seconds = 10
8
- @busser_root_dirs = []
9
10
  end
10
11
 
11
12
  After do |s|
@@ -13,28 +14,4 @@ After do |s|
13
14
  # This is useful to inspect the 'tmp/aruba' directory before any other
14
15
  # steps are executed and clear it out.
15
16
  Cucumber.wants_to_quit = true if s.failed?
16
-
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
-
23
- @busser_root_dirs.each { |dir| FileUtils.rm_rf(dir) }
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
17
  end
@@ -32,6 +32,8 @@ module Busser
32
32
 
33
33
  register Busser::Command::PluginInstall, "install",
34
34
  "install PLUGIN [PLUGIN ...]", "Installs one or more plugins"
35
+ tasks["install"].options = Busser::Command::PluginInstall.class_options
36
+
35
37
  register Busser::Command::PluginList, "list",
36
38
  "list", "Lists installed plugins"
37
39
  end
@@ -31,6 +31,9 @@ module Busser
31
31
 
32
32
  argument :plugins, :type => :array
33
33
 
34
+ class_option :force_postinstall, :type => :boolean, :default => false,
35
+ :desc => "Run the plugin's postinstall if it is already installed"
36
+
34
37
  def install_all
35
38
  silence_gem_ui!
36
39
  plugins.each { |plugin| install(plugin) }
@@ -39,21 +42,50 @@ module Busser
39
42
  private
40
43
 
41
44
  def install(plugin)
42
- install_gem(plugin)
45
+ gem_name, version = plugin.split("@")
46
+ name = gem_name.sub(/^busser-/, '')
47
+
48
+ if options[:force_postinstall] || install_gem(gem_name, version, name)
49
+ load_plugin(name)
50
+ run_postinstall(name)
51
+ end
43
52
  end
44
53
 
45
- def install_gem(plugin)
46
- name, version = plugin.split("@")
47
- install_arg = name =~ /\.gem$/ ? name : new_dep(name, version)
54
+ def install_gem(gem, version, name)
55
+ install_arg = gem =~ /\.gem$/ ? gem : new_dep(gem, version)
48
56
 
49
- if gem_installed?(name, version)
50
- info "#{plugin} plugin already installed"
57
+ if internal_plugin?(name) || gem_installed?(gem, version)
58
+ info "Plugin #{name} already installed"
59
+
60
+ return false
51
61
  else
52
- spec = dep_installer.install(install_arg).first
53
- info "Plugin #{plugin} installed (version #{spec.version})"
62
+ spec = dep_installer.install(install_arg).find do |spec|
63
+ spec.name == gem
64
+ end
65
+ Gem.clear_paths
66
+ info "Plugin #{name} installed (version #{spec.version})"
67
+
68
+ return true
69
+ end
70
+ end
71
+
72
+ def load_plugin(name)
73
+ Busser::Plugin.require!(Busser::Plugin.runner_plugin(name))
74
+ end
75
+
76
+ def run_postinstall(name)
77
+ klass = Busser::Plugin.runner_class(::Thor::Util.camel_case(name))
78
+ if klass.respond_to?(:run_postinstall)
79
+ banner "Running postinstall for #{name} plugin"
80
+ klass.run_postinstall
54
81
  end
55
82
  end
56
83
 
84
+ def internal_plugin?(name)
85
+ spec = Busser::Plugin.gem_from_path(Busser::Plugin.runner_plugin(name))
86
+ spec && spec.name == "busser"
87
+ end
88
+
57
89
  def gem_installed?(name, version)
58
90
  installed = Array(Gem::Specification.find_all_by_name(name, version))
59
91
  version = latest_version(name) if version.nil?
@@ -34,6 +34,7 @@ module Busser
34
34
  def perform
35
35
  Busser::Plugin.runner_plugins(plugins).each do |runner_path|
36
36
  runner = File.basename(runner_path)
37
+ next if skip_runner?(runner)
37
38
  klass = ::Thor::Util.camel_case(runner)
38
39
 
39
40
  banner "Running #{runner} test suite"
@@ -41,6 +42,12 @@ module Busser
41
42
  invoke Busser::Plugin.runner_class(klass)
42
43
  end
43
44
  end
45
+
46
+ private
47
+
48
+ def skip_runner?(runner)
49
+ runner == "dummy" && ! Array(plugins).include?("dummy")
50
+ end
44
51
  end
45
52
  end
46
53
  end
@@ -1,3 +1,11 @@
1
+ begin
2
+ require 'aruba/cucumber'
3
+ rescue LoadError
4
+ abort "The aruba gem must be in your development dependencies"
5
+ end
6
+
7
+ require 'busser/cucumber/hooks'
8
+
1
9
  require 'tmpdir'
2
10
  require 'pathname'
3
11
 
@@ -24,6 +32,11 @@ Given(/^a suite directory named "(.*?)"$/) do |name|
24
32
  FileUtils.mkdir_p(File.join(ENV['BUSSER_ROOT'], "suites", name))
25
33
  end
26
34
 
35
+ Given(/^a file in suite "(.*?)" named "(.*?)" with:$/) do |suite, file, content|
36
+ file_name = File.join(ENV['BUSSER_ROOT'], "suites", suite, file)
37
+ write_file(file_name, content)
38
+ end
39
+
27
40
  Given(/^a sandboxed GEM_HOME directory named "(.*?)"$/) do |name|
28
41
  backup_envvar('GEM_HOME')
29
42
  backup_envvar('GEM_PATH')
@@ -34,14 +47,21 @@ Given(/^a sandboxed GEM_HOME directory named "(.*?)"$/) do |name|
34
47
  @busser_root_dirs << gem_home
35
48
  end
36
49
 
50
+ Given(/^a non bundler environment$/) do
51
+ %w[BUNDLER_EDITOR BUNDLE_BIN_PATH BUNDLE_GEMFILE RUBYOPT].each do |key|
52
+ backup_envvar(key)
53
+ ENV.delete(key)
54
+ end
55
+ end
56
+
37
57
  Then(/^the suite directory named "(.*?)" should not exist$/) do |name|
38
58
  directory = File.join(ENV['BUSSER_ROOT'], "suites", name)
39
59
  check_directory_presence([directory], false)
40
60
  end
41
61
 
42
- Then(/^a gem named "(.*?)" is installed with version "(.*?)"$/) do |name, version|
62
+ Then(/^a gem named "(.*?)" is installed with version "(.*?)"$/) do |name, ver|
43
63
  unbundlerize do
44
- run_simple(unescape("gem list #{name} --version #{version} -i"), true, nil)
64
+ run_simple(unescape("gem list #{name} --version #{ver} -i"), true, nil)
45
65
  end
46
66
  end
47
67
 
@@ -0,0 +1,31 @@
1
+ Before do
2
+ @busser_root_dirs = []
3
+ end
4
+
5
+ After do
6
+ @busser_root_dirs.each { |dir| FileUtils.rm_rf(dir) }
7
+ end
8
+
9
+ # Restore environment variables to their original settings, if they have
10
+ # been saved off
11
+ After do
12
+ ENV.keys.select { |key| key =~ /^_CUKE_/ }.each do |backup_key|
13
+ ENV[backup_key.sub(/^_CUKE_/, '')] = ENV.delete(backup_key)
14
+ end
15
+ end
16
+
17
+ def backup_envvar(key)
18
+ ENV["_CUKE_#{key}"] = ENV[key]
19
+ end
20
+
21
+ def restore_envvar(key)
22
+ ENV[key] = ENV.delete("_CUKE_#{key}")
23
+ end
24
+
25
+ def unbundlerize
26
+ keys = %w[BUNDLER_EDITOR BUNDLE_BIN_PATH BUNDLE_GEMFILE RUBYOPT]
27
+
28
+ keys.each { |key| backup_envvar(key) ; ENV.delete(key) }
29
+ yield
30
+ keys.each { |key| restore_envvar(key) }
31
+ end
data/lib/busser/plugin.rb CHANGED
@@ -25,9 +25,13 @@ module Busser
25
25
 
26
26
  module_function
27
27
 
28
+ def runner_plugin(plugin_name)
29
+ "busser/runner_plugin/#{plugin_name}"
30
+ end
31
+
28
32
  def runner_plugins(plugin_names = nil)
29
33
  if plugin_names
30
- Array(plugin_names).map { |plugin| "busser/runner_plugin/#{plugin}" }
34
+ Array(plugin_names).map { |plugin| runner_plugin(plugin) }
31
35
  else
32
36
  all_runner_plugins
33
37
  end
@@ -42,7 +46,7 @@ module Busser
42
46
  def require!(plugin_path)
43
47
  require plugin_path
44
48
  rescue LoadError => e
45
- die "Could not load #{plugin_path} (#{e.class}: #{e.message})"
49
+ Busser::UI.die "Could not load #{plugin_path} (#{e.class}: #{e.message})"
46
50
  end
47
51
 
48
52
  def runner_class(klass)
@@ -27,6 +27,15 @@ module Busser
27
27
  # @author Fletcher Nichol <fnichol@nichol.ca>
28
28
  #
29
29
  class Base < Busser::Thor::BaseGroup
30
+
31
+ def self.postinstall(&block)
32
+ (class << self; self; end).send(:define_method, :run_postinstall) do
33
+ klass = Class.new(Busser::Thor::BaseGroup) do
34
+ define_method(:postinstall, &block)
35
+ end
36
+ klass.start
37
+ end
38
+ end
30
39
  end
31
40
  end
32
41
  end
@@ -0,0 +1,40 @@
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 'busser/runner_plugin'
20
+
21
+ # Dummy runner plugin for Busser.
22
+ #
23
+ # @author Fletcher Nichol <fnichol@nichol.ca>
24
+ #
25
+ class Busser::RunnerPlugin::Dummy < Busser::RunnerPlugin::Base
26
+
27
+ postinstall do
28
+ empty_directory("dummy")
29
+ create_file("dummy/foobar.txt", "The Dummy Driver.")
30
+ end
31
+
32
+ def test
33
+ banner "[dummy] Running"
34
+ if File.exists?(File.join(suite_path("dummy"), "foobar.txt"))
35
+ info "[dummy] The postinstall script has been called"
36
+ else
37
+ warn "[dummy] The postinstall script was not called"
38
+ end
39
+ end
40
+ end
data/lib/busser/ui.rb CHANGED
@@ -22,6 +22,8 @@ module Busser
22
22
 
23
23
  module UI
24
24
 
25
+ module_function
26
+
25
27
  def banner(msg)
26
28
  say("-----> #{msg}")
27
29
  end
@@ -17,5 +17,5 @@
17
17
  # limitations under the License.
18
18
 
19
19
  module Busser
20
- VERSION = "0.1.1"
20
+ VERSION = "0.2.0"
21
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: busser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
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-29 00:00:00.000000000 Z
12
+ date: 2013-03-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -260,7 +260,6 @@ files:
260
260
  - features/files/base64.txt
261
261
  - features/plugin_install_command.feature
262
262
  - features/setup_command.feature
263
- - features/step_definitions/busser_root_steps.rb
264
263
  - features/suite_cleanup_command.feature
265
264
  - features/suite_path_command.feature
266
265
  - features/support/env.rb
@@ -275,9 +274,12 @@ files:
275
274
  - lib/busser/command/suite_cleanup.rb
276
275
  - lib/busser/command/suite_path.rb
277
276
  - lib/busser/command/test.rb
277
+ - lib/busser/cucumber.rb
278
+ - lib/busser/cucumber/hooks.rb
278
279
  - lib/busser/helpers.rb
279
280
  - lib/busser/plugin.rb
280
281
  - lib/busser/runner_plugin.rb
282
+ - lib/busser/runner_plugin/dummy.rb
281
283
  - lib/busser/thor.rb
282
284
  - lib/busser/ui.rb
283
285
  - lib/busser/version.rb
@@ -304,7 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
304
306
  version: '0'
305
307
  segments:
306
308
  - 0
307
- hash: -1680018210627822446
309
+ hash: -4345973046536692272
308
310
  requirements: []
309
311
  rubyforge_project:
310
312
  rubygems_version: 1.8.24
@@ -316,7 +318,6 @@ test_files:
316
318
  - features/files/base64.txt
317
319
  - features/plugin_install_command.feature
318
320
  - features/setup_command.feature
319
- - features/step_definitions/busser_root_steps.rb
320
321
  - features/suite_cleanup_command.feature
321
322
  - features/suite_path_command.feature
322
323
  - features/support/env.rb