vagrant-exec 0.2.1 → 0.3.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/README.md CHANGED
@@ -11,7 +11,7 @@ You will probably use the plugin if you don't want to SSH into the box to execut
11
11
  Example
12
12
  -------
13
13
 
14
- ```shell
14
+ ```bash
15
15
  ➜ vagrant exec pwd
16
16
  /vagrant
17
17
  ```
@@ -19,49 +19,67 @@ Example
19
19
  Installation
20
20
  ------------
21
21
 
22
- ```shell
22
+ ```bash
23
23
  ➜ vagrant plugin install vagrant-exec
24
24
  ```
25
25
 
26
26
  Configuration
27
27
  -------------
28
28
 
29
- ### Custom folder
29
+ ### Custom root
30
30
 
31
31
  The root directory can be configured using Vagrantfile.
32
32
 
33
33
  ```ruby
34
34
  Vagrant.configure('2') do |config|
35
35
  config.vm.box = 'precise32'
36
- config.exec.folder = '/custom'
36
+ config.exec.root = '/custom'
37
37
  end
38
38
  ```
39
39
 
40
- ```shell
40
+ ```bash
41
41
  ➜ vagrant exec pwd
42
42
  # is the same as
43
43
  ➜ vagrant ssh -c "cd /custom && bundle exec pwd"
44
44
  ```
45
45
 
46
- ### Bundler
46
+ ### Prepend with
47
47
 
48
- You can enable bundler to prepend each command with `bundle exec`. Note that it won't be done for commands starting with `bundle` (e.g. `bundle install`).
48
+ You can tell `vagrant-exec` to prepend all the commands with custom string.
49
49
 
50
50
  ```ruby
51
51
  Vagrant.configure('2') do |config|
52
52
  config.vm.box = 'precise32'
53
- config.exec.bundler = true
53
+ config.exec.prepend_with 'bundle exec'
54
54
  end
55
55
  ```
56
56
 
57
- ```shell
57
+ ```bash
58
58
  ➜ vagrant exec pwd
59
59
  # is the same as
60
60
  ➜ vagrant ssh -c "cd /vagrant && bundle exec pwd"
61
+ ```
62
+
63
+ You can also limit prepend to specific commands and combine them.
64
+
65
+ ```ruby
66
+ Vagrant.configure('2') do |config|
67
+ config.vm.box = 'precise32'
68
+ config.exec.prepend_with 'bundle exec', :only => %w(rails rspec cucumber)
69
+ config.exec.prepend_with 'rvmsudo', :only => %w(gem)
70
+ end
71
+ ```
72
+
73
+ ```bash
74
+ ➜ vagrant exec rails c
75
+ # is the same as
76
+ ➜ vagrant ssh -c "cd /vagrant && bundle exec rails c"
77
+ ```
61
78
 
62
- ➜ vagrant exec bundle install
79
+ ```bash
80
+ ➜ vagrant exec gem install bundler
63
81
  # is the same as
64
- ➜ vagrant ssh -c "cd /vagrant && bundle install"
82
+ ➜ vagrant ssh -c "cd /vagrant && rvmsudo gem install bundler"
65
83
  ```
66
84
 
67
85
  ### Environment variables
@@ -76,7 +94,7 @@ Vagrant.configure('2') do |config|
76
94
  end
77
95
  ```
78
96
 
79
- ```shell
97
+ ```bash
80
98
  ➜ vagrant exec pwd
81
99
  # is the same as
82
100
  ➜ vagrant ssh -c "cd /vagrant && export RAILS_ENV=test && export RAILS_ROOT=/vagrant && pwd"
@@ -87,22 +105,27 @@ Acceptance tests
87
105
 
88
106
  Before running features, you'll need to bootstrap box.
89
107
 
90
- ```shell
108
+ ```bash
91
109
  ➜ bundle exec rake features:bootstrap
92
110
  ```
93
111
 
94
112
  To run features, execute the following rake task.
95
113
 
96
- ```shell
114
+ ```bash
97
115
  ➜ bundle exec rake features:run
98
116
  ```
99
117
 
100
118
  After you're done, remove Vagrant box.
101
119
 
102
- ```shell
120
+ ```bash
103
121
  ➜ bundle exec rake features:cleanup
104
122
  ```
105
123
 
124
+ Known issues
125
+ -----------------------------
126
+
127
+ `vagrant-exec` cannot properly handle `-v` in command args (it's caught somewhere before plugin), so executing `vagrant exec ruby -v` will return Vagrant version rather than Ruby. As a workaround, wrap it in quotes: `vagrant exec "ruby -v"`.
128
+
106
129
  Note on Patches/Pull Requests
107
130
  -----------------------------
108
131
 
@@ -1,49 +1,8 @@
1
- Given(/^I have default Vagrantfile$/) do
2
- vagrantfile = <<-RUBY
3
- Vagrant.require_plugin 'vagrant-exec'
4
-
5
- Vagrant.configure('2') do |config|
6
- config.vm.box = 'vagrant_exec'
7
- end
8
- RUBY
9
- step 'a file named "Vagrantfile" with:', vagrantfile
10
- end
11
-
12
-
13
- Given(/^I set vagrant-exec folder to (.+)$/) do |folder|
14
- config = <<-RUBY
15
-
16
- Vagrant.configure('2') do |config|
17
- config.exec.folder = #{folder}
18
- end
19
- RUBY
20
- step 'I append to "Vagrantfile" with:', config
21
- end
22
-
23
-
24
- Given(/^I set vagrant-exec bundler to (.+)$/) do |bundler|
25
- config = <<-RUBY
26
-
27
- Vagrant.configure('2') do |config|
28
- config.exec.bundler = #{bundler}
29
- end
30
- RUBY
31
- step 'I append to "Vagrantfile" with:', config
32
- end
33
-
34
-
35
- Given(/^I set vagrant-exec env with the following values:$/) do |table|
36
- data = table.hashes
37
- config = data.map do |hash|
38
- key, value = "#{hash['key']}", "#{hash['value']}"
39
- %(config.exec.env['#{key}'] = '#{value}')
40
- end
41
-
42
- config = <<-RUBY
43
-
44
- Vagrant.configure('2') do |config|
45
- #{config.join("\n\s\s")}
46
- end
47
- RUBY
48
- step 'I append to "Vagrantfile" with:', config
1
+ Then(/^SHH subprocess should execute command "(.+)"$/) do |command|
2
+ ssh = %w(vagrant@127.0.0.1 -p 2200 -o Compression=yes)
3
+ ssh += %w(-o DSAAuthentication=yes -o LogLevel=FATAL)
4
+ ssh += %w(-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null)
5
+ ssh += %W(-o IdentitiesOnly=yes -i #{Dir.home}/.vagrant.d/insecure_private_key)
6
+ ssh += ['-q', '-t', "bash -l -c '#{command.delete('"')} --'"]
7
+ assert_partial_output("Executing SSH in subprocess: #{ssh}", all_output)
49
8
  end
@@ -8,5 +8,5 @@ end
8
8
 
9
9
  After do
10
10
  # halt VM
11
- system "cd tmp/aruba; bundle exec vagrant halt &> /dev/null"
11
+ system 'cd tmp/aruba; bundle exec vagrant halt &> /dev/null'
12
12
  end
@@ -10,82 +10,165 @@ Feature: vagrant-exec
10
10
  Using Vagrantfile configuration
11
11
 
12
12
  Background:
13
- Given I have default Vagrantfile
13
+ Given I write to "Vagrantfile" with:
14
+ """
15
+ Vagrant.require_plugin 'vagrant-exec'
14
16
 
15
- Scenario: uses /vagrant as default folder
17
+ Vagrant.configure('2') do |config|
18
+ config.vm.box = 'vagrant_exec'
19
+ end
20
+ """
21
+
22
+ Scenario Outline: shows help correctly
23
+ Given I run `bundle exec vagrant up`
24
+ When I run `bundle exec vagrant exec <args>`
25
+ Then the output should contain "Usage: vagrant exec [options] <command>"
26
+ Examples:
27
+ | args |
28
+ | |
29
+ | -h |
30
+ | --help |
31
+ | -h pwd |
32
+ | --help pwd -h |
33
+
34
+ Scenario Outline: passes command arguments correctly
35
+ Given I run `bundle exec vagrant up`
36
+ When I run `bundle exec vagrant exec <cmd>`
37
+ Then SHH subprocess should execute command "cd /vagrant && <cmd>"
38
+ Examples:
39
+ | cmd |
40
+ | cwd . |
41
+ | cwd ~ |
42
+ | cwd -h |
43
+ | cwd --blah |
44
+ | "cwd -h blah -v blah" |
45
+
46
+ Scenario: uses /vagrant as default root
16
47
  Given I run `bundle exec vagrant up`
17
48
  When I run `bundle exec vagrant exec pwd`
18
49
  Then the exit status should be 0
19
- And the output should contain "Executing single command on remote machine: source ~/.profile && cd /vagrant && pwd"
50
+ And SHH subprocess should execute command "cd /vagrant && pwd"
51
+
52
+ Scenario: can use custom root
53
+ Given I overwrite "Vagrantfile" with:
54
+ """
55
+ Vagrant.require_plugin 'vagrant-exec'
20
56
 
21
- Scenario: can use custom folder
22
- Given I set vagrant-exec folder to "/tmp"
57
+ Vagrant.configure('2') do |config|
58
+ config.vm.box = 'vagrant_exec'
59
+ config.exec.root = '/tmp'
60
+ end
61
+ """
23
62
  And I run `bundle exec vagrant up`
24
63
  When I run `bundle exec vagrant exec pwd`
25
64
  Then the exit status should be 0
26
- And the output should contain "Executing single command on remote machine: source ~/.profile && cd /tmp && pwd"
65
+ And SHH subprocess should execute command "cd /tmp && pwd"
66
+
67
+ Scenario: raises error if root is improperly set
68
+ Given I overwrite "Vagrantfile" with:
69
+ """
70
+ Vagrant.require_plugin 'vagrant-exec'
27
71
 
28
- Scenario: raises error if folder is improperly set
29
- Given I set vagrant-exec folder to true
72
+ Vagrant.configure('2') do |config|
73
+ config.vm.box = 'vagrant_exec'
74
+ config.exec.root = true
75
+ end
76
+ """
30
77
  And I run `bundle exec vagrant up`
31
78
  Then the exit status should not be 0
32
- And the output should contain "folder should be a string"
79
+ And the output should contain "root should be a string"
33
80
 
34
- Scenario: does not use bundler by default
35
- Given I run `bundle exec vagrant up`
81
+ Scenario: can prepend all commands
82
+ Given I overwrite "Vagrantfile" with:
83
+ """
84
+ Vagrant.require_plugin 'vagrant-exec'
85
+
86
+ Vagrant.configure('2') do |config|
87
+ config.vm.box = 'vagrant_exec'
88
+ config.exec.prepend_with 'echo vagrant-exec &&'
89
+ end
90
+ """
91
+ And I run `bundle exec vagrant up`
36
92
  When I run `bundle exec vagrant exec pwd`
37
- Then the output should not contain "bundle exec"
93
+ Then the exit status should be 0
94
+ And SHH subprocess should execute command "cd /vagrant && echo vagrant-exec && pwd"
95
+
96
+ Scenario: can prepend only specific commands
97
+ Given I overwrite "Vagrantfile" with:
98
+ """
99
+ Vagrant.require_plugin 'vagrant-exec'
38
100
 
39
- # we don't have bundler in box
40
- Scenario: can use bundler
41
- Given I set vagrant-exec bundler to true
101
+ Vagrant.configure('2') do |config|
102
+ config.vm.box = 'vagrant_exec'
103
+ config.exec.prepend_with 'echo vagrant-exec &&', :only => %w(pwd echo)
104
+ end
105
+ """
42
106
  And I run `bundle exec vagrant up`
43
107
  When I run `bundle exec vagrant exec pwd`
44
- Then the exit status should not be 0
45
- And the output should contain "Executing single command on remote machine: source ~/.profile && cd /vagrant && bundle exec pwd"
108
+ Then SHH subprocess should execute command "cd /vagrant && echo vagrant-exec && pwd"
109
+ When I run `bundle exec vagrant exec echo 1`
110
+ Then SHH subprocess should execute command "cd /vagrant && echo vagrant-exec && echo 1"
111
+ When I run `bundle exec vagrant exec env`
112
+ Then SHH subprocess should execute command "cd /vagrant && env"
46
113
 
47
- Scenario: does not use bundler for bundle commands
48
- Given I set vagrant-exec bundler to true
114
+ Scenario: can use prepend multiple times
115
+ Given I overwrite "Vagrantfile" with:
116
+ """
117
+ Vagrant.require_plugin 'vagrant-exec'
118
+
119
+ Vagrant.configure('2') do |config|
120
+ config.vm.box = 'vagrant_exec'
121
+ config.exec.prepend_with 'echo vagrant-exec1 &&', :only => %w(pwd)
122
+ config.exec.prepend_with 'echo vagrant-exec2 &&', :only => %w(echo)
123
+ end
124
+ """
49
125
  And I run `bundle exec vagrant up`
50
- When I run `bundle exec vagrant exec bundle install`
51
- Then the output should contain "Executing single command on remote machine: source ~/.profile && cd /vagrant && bundle install"
126
+ When I run `bundle exec vagrant exec pwd`
127
+ Then SHH subprocess should execute command "cd /vagrant && echo vagrant-exec1 && pwd"
128
+ When I run `bundle exec vagrant exec echo 1`
129
+ Then SHH subprocess should execute command "cd /vagrant && echo vagrant-exec2 && echo 1"
52
130
 
53
- Scenario: raises error if bundler is improperly set
54
- Given I set vagrant-exec bundler to "true"
55
- When I run `bundle exec vagrant up`
131
+ Scenario: raises error if prepend command is improperly set
132
+ Given I overwrite "Vagrantfile" with:
133
+ """
134
+ Vagrant.require_plugin 'vagrant-exec'
135
+
136
+ Vagrant.configure('2') do |config|
137
+ config.vm.box = 'vagrant_exec'
138
+ config.exec.prepend_with :test
139
+ end
140
+ """
141
+ Given I set vagrant-exec prepend with :test for all commands
142
+ And I run `bundle exec vagrant up`
56
143
  Then the exit status should not be 0
57
- And the output should contain "bundler should be boolean"
144
+ And the output should contain "prepend_with command should be a string"
145
+
146
+ Scenario: raises error if prepend only is improperly set
147
+ Given I overwrite "Vagrantfile" with:
148
+ """
149
+ Vagrant.require_plugin 'vagrant-exec'
150
+
151
+ Vagrant.configure('2') do |config|
152
+ config.vm.box = 'vagrant_exec'
153
+ config.exec.prepend_with 'echo vagrant-exec1 &&', :only => 'test'
154
+ end
155
+ """
156
+ And I run `bundle exec vagrant up`
157
+ Then the exit status should not be 0
158
+ And the output should contain "prepend_with :only should be an array"
58
159
 
59
160
  Scenario: can export environment variables
60
- Given I set vagrant-exec env with the following values:
61
- | key | value |
62
- | TEST1 | true |
63
- | TEST2 | false |
161
+ Given I overwrite "Vagrantfile" with:
162
+ """
163
+ Vagrant.require_plugin 'vagrant-exec'
164
+
165
+ Vagrant.configure('2') do |config|
166
+ config.vm.box = 'vagrant_exec'
167
+ config.exec.env['TEST1'] = true
168
+ config.exec.env['TEST2'] = false
169
+ end
170
+ """
64
171
  And I run `bundle exec vagrant up`
65
172
  When I run `bundle exec vagrant exec pwd`
66
173
  Then the exit status should be 0
67
- And the output should contain "Executing single command on remote machine: source ~/.profile && cd /vagrant && export TEST1=true && export TEST2=false && pwd"
68
-
69
- Scenario Outline: shows help correctly
70
- Given I run `bundle exec vagrant up`
71
- When I run `bundle exec vagrant exec <args>`
72
- Then the output should contain "Usage: vagrant exec [options] <command>"
73
- Examples:
74
- | args |
75
- | |
76
- | -h |
77
- | --help |
78
- | -h pwd |
79
- | --help pwd -h |
80
-
81
- Scenario Outline: passes command arguments correctly
82
- Given I run `bundle exec vagrant up`
83
- When I run `bundle exec vagrant exec <cmd>`
84
- Then the output should contain "Executing single command on remote machine: source ~/.profile && cd /vagrant && <cmd>"
85
- Examples:
86
- | cmd |
87
- | cwd . |
88
- | cwd ~ |
89
- | cwd -h |
90
- | cwd --blah |
91
- | cwd -h blah -v blah |
174
+ And SHH subprocess should execute command "cd /vagrant && export TEST1=true && export TEST2=false && pwd"
@@ -2,6 +2,10 @@ module VagrantPlugins
2
2
  module Exec
3
3
  class Command < Vagrant.plugin(2, :command)
4
4
 
5
+ def self.synopsis
6
+ 'proxies command to VM synced folder root'
7
+ end
8
+
5
9
  def execute
6
10
  cmd, cmd_args = parse_args
7
11
  cmd && cmd_args or return nil
@@ -12,14 +16,14 @@ module VagrantPlugins
12
16
 
13
17
  plain = "#{cmd} " << cmd_args.join(' ')
14
18
 
15
- command = "source ~/.profile && "
16
- command << "cd #{vm.config.exec.folder} && "
19
+ command = "cd #{vm.config.exec.root} && "
17
20
  command << add_env(vm.config.exec.env)
18
- command << add_bundler(vm.config.exec.bundler, plain)
21
+ command << prepend_command(vm.config.exec.prepends, plain)
19
22
  command << plain
20
23
 
21
24
  @logger.info("Executing single command on remote machine: #{command}")
22
- env = vm.action(:ssh_run, ssh_run_command: command)
25
+ ssh_opts = { extra_args: ['-q'] } # make it quiet
26
+ env = vm.action(:ssh_run, ssh_run_command: command, ssh_opts: ssh_opts)
23
27
 
24
28
  status = env[:ssh_run_exit_status] || 0
25
29
  return status
@@ -51,20 +55,22 @@ module VagrantPlugins
51
55
  end
52
56
 
53
57
  def add_env(env)
54
- ''.tap do |command|
55
- if env.any?
56
- env.each do |key, value|
57
- command << "export #{key}=#{value} && "
58
- end
59
- end
58
+ ''.tap do |cmd|
59
+ env.each do |key, value|
60
+ cmd << "export #{key}=#{value} && "
61
+ end if env.any?
60
62
  end
61
63
  end
62
64
 
63
- def add_bundler(bundler, plain_command)
64
- ''.tap do |command|
65
- if bundler && plain_command !~ /^bundle /
66
- command << 'bundle exec '
67
- end
65
+ def prepend_command(prepends, command)
66
+ bin = command.split(' ').first
67
+ ''.tap do |cmd|
68
+ prepends.each do |prep|
69
+ if !prep[:only] || prep[:only].include?(bin)
70
+ prep = prep[:command].strip # remove trailing space
71
+ cmd << "#{prep} "
72
+ end
73
+ end if prepends.any?
68
74
  end
69
75
  end
70
76
 
@@ -3,25 +3,40 @@ module VagrantPlugins
3
3
  class Config < Vagrant.plugin(2, :config)
4
4
 
5
5
  attr_reader :env
6
- attr_accessor :bundler
7
- attr_accessor :folder
6
+ attr_accessor :root
8
7
 
9
8
  def initialize
10
- @env = {}
11
- @bundler = UNSET_VALUE
12
- @folder = UNSET_VALUE
9
+ @env = {}
10
+ @prepend_with = UNSET_VALUE
11
+ @root = UNSET_VALUE
12
+ end
13
+
14
+ def prepend_with(command, opts = {})
15
+ @prepend_with = [] if @prepend_with == UNSET_VALUE
16
+ @prepend_with << { :command => command }.merge(opts)
17
+ end
18
+
19
+ def prepends
20
+ @prepend_with
13
21
  end
14
22
 
15
23
  def validate(_)
16
- return { 'exec' => ['bundler should be boolean'] } unless [true, false].include?(@bundler)
17
- return { 'exec' => ['folder should be a string'] } unless @folder.is_a?(String)
24
+ return { 'exec' => ['root should be a string'] } unless @root.is_a?(String)
25
+ if @prepend_with.any?
26
+ if !@prepend_with.all? { |p| p[:command].is_a?(String) }
27
+ return { 'exec' => ['prepend_with command should be a string'] }
28
+ end
29
+ if !@prepend_with.all? { |p| !p[:only] || p[:only].is_a?(Array) }
30
+ return { 'exec' => ['prepend_with :only should be an array'] }
31
+ end
32
+ end
18
33
 
19
34
  {}
20
35
  end
21
36
 
22
37
  def finalize!
23
- @folder = '/vagrant' if @folder == UNSET_VALUE
24
- @bundler = false if @bundler == UNSET_VALUE
38
+ @root = '/vagrant' if @root == UNSET_VALUE
39
+ @prepend_with = [] if @prepend_with == UNSET_VALUE
25
40
  end
26
41
 
27
42
  end # Config
@@ -1,7 +1,7 @@
1
1
  module VagrantPlugins
2
2
  module Exec
3
3
 
4
- VERSION = '0.2.1'
4
+ VERSION = '0.3.0'
5
5
 
6
6
  end # Exec
7
7
  end # VagrantPlugins
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-exec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.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-12-10 00:00:00.000000000 Z
12
+ date: 2013-12-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aruba
@@ -77,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
77
  version: '0'
78
78
  segments:
79
79
  - 0
80
- hash: 657150828523853671
80
+ hash: -1851522929754547545
81
81
  required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  none: false
83
83
  requirements:
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  version: '0'
87
87
  segments:
88
88
  - 0
89
- hash: 657150828523853671
89
+ hash: -1851522929754547545
90
90
  requirements: []
91
91
  rubyforge_project:
92
92
  rubygems_version: 1.8.23