vagrant-exec 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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