multi_ruby_runner 1.0.0 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 292bf31accd916a0752d0ec0092c16b409141735
4
- data.tar.gz: b79c7dccb5560b865beb18e8ca516d421aaee77d
3
+ metadata.gz: 5c7ae88ea7e74814b50a117afb6f0e9d59989544
4
+ data.tar.gz: 3fbde0fa5cf8d984166f428a33ceb95b2de2355e
5
5
  SHA512:
6
- metadata.gz: d69b5cc1d575c513b435320672eb52a07d0caec396f536593b9ac9187dc83cea08580596e5b277b4996ad884628d8b7d272d7d8845f5a92cd992c21f686ec177
7
- data.tar.gz: 27e0a0134144d19c3018cf3e11f61d39ad8df788d55e738369281c42d034a7eaeb1df5932704cc56f3e0e47770599762823fe51a7f5182bd90ee18a04ef4ce94
6
+ metadata.gz: f0557fcf48a607f2d3fca67e9ae7faa659d0e0495c20cd18825849b5328a875f74967b1662515032c3156d33fc18c983f8f6ab5d1150eab1e23989b975442623
7
+ data.tar.gz: 84d428a261c85b818ca34e46b71e72081a70a767ee6a325d8ce5ed0b7626edd32fb2b8875753eb8a488ad9f64ee919f03984219ed3264a7ba85bde8821d5ef3f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### 1.0.1
2
+
3
+ * Added rbenv support
4
+ * Improved process spawning
5
+
1
6
  # 1.0.0
2
7
 
3
8
  Initial release
@@ -1,3 +1,3 @@
1
1
  class MultiRubyRunner
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -4,33 +4,34 @@ class MultiRubyRunner
4
4
  # Represents the [rbenv](https://github.com/rbenv/rbenv) ruby version manager.
5
5
  class Rbenv < VersionManager
6
6
 
7
- # Returns the string to be executed in shell to activate self in a shell.
8
- # @return [String]
9
- def activation_string
10
- %(eval "$(rbenv init -)")
7
+ # See MultiRubyRunner#execute_command_in_directory
8
+ # @return [Hash]
9
+ # {
10
+ # entire_command: includes shell invocation,
11
+ # ruby version manager activation and command
12
+ # blocking: Boolean
13
+ # environment_overrides: {}
14
+ # }
15
+ def compute_process_args(command_string, directory, options)
16
+ shell_command_string = [
17
+ "cd #{ directory }", # cd into the directory containing .ruby-version file
18
+ command_string, # execute command
19
+ ].join('; ')
20
+ # For rbenv we just have to reset RBENV_VERSION and override RBENV_DIR
21
+ # to get the ruby environment specified in `.ruby-version` in directory.
22
+ {
23
+ entire_command: [
24
+ options[:shell_invocation],
25
+ shell_command_string,
26
+ ].join(' '),
27
+ blocking: options[:blocking],
28
+ environment_overrides: {
29
+ 'RBENV_VERSION' => nil,
30
+ 'RBENV_DIR' => directory,
31
+ },
32
+ }
11
33
  end
12
34
 
13
- # This is what `rbenv init -` returns:
14
-
15
- # export PATH="/home/deploy/.rbenv/shims:${PATH}"
16
- # export RBENV_SHELL=bash
17
- # source '/home/deploy/.rbenv/libexec/../completions/rbenv.bash'
18
- # command rbenv rehash 2>/dev/null
19
- # rbenv() {
20
- # local command
21
- # command="$1"
22
- # if [ "$#" -gt 0 ]; then
23
- # shift
24
- # fi
25
-
26
- # case "$command" in
27
- # rehash|shell)
28
- # eval "$(rbenv "sh-$command" "$@")";;
29
- # *)
30
- # command rbenv "$command" "$@";;
31
- # esac
32
- # }
33
-
34
35
  end
35
36
 
36
37
  end
@@ -4,13 +4,41 @@ class MultiRubyRunner
4
4
  # Represents the [rvm](https://rvm.io/) ruby version manager.
5
5
  class Rvm < VersionManager
6
6
 
7
- # Returns the string to be executed in shell to activate self in a shell.
7
+ # See MultiRubyRunner#execute_command_in_directory
8
+ # @return [Hash]
9
+ # {
10
+ # entire_command: includes shell invocation,
11
+ # ruby version manager activation and command
12
+ # blocking: Boolean
13
+ # environment_overrides: {}
14
+ # }
15
+ def compute_process_args(command_string, directory, options)
16
+ {
17
+ entire_command: [
18
+ options[:shell_invocation],
19
+ %('#{ shell_command_string(command_string, directory) }')
20
+ ].join(' '),
21
+ blocking: options[:blocking],
22
+ environment_overrides: {},
23
+ }
24
+ end
25
+
26
+ # Returns the command string to be passed to the shell
27
+ def shell_command_string(command_string, directory)
28
+ [
29
+ activation_string, # activate rvm
30
+ "cd #{ directory }", # cd into the directory containing .ruby-version file
31
+ command_string, # execute command
32
+ ].join('; ')
33
+ end
34
+
35
+ # Returns the string to be executed in shell to activate rvm in a shell.
8
36
  # @return [String]
9
37
  def activation_string
10
38
  # Given the @ruby_executable_path, we can compute the rvm script path
11
39
  # that needs to be sourced:
12
- # /Users/uname/.rvm/rubies/ruby-2.2.3/bin/ruby
13
- # ~/.rvm/scripts/rvm
40
+ # /Users/username/.rvm/rubies/ruby-2.2.3/bin/ruby
41
+ # ~/.rvm/scripts/rvm
14
42
  script_path = @ruby_executable_path.match(
15
43
  /^.+(#{ Regexp.escape("/.rvm/") })(?=rubies)/
16
44
  )[0]
@@ -22,8 +22,8 @@ class MultiRubyRunner
22
22
  @ruby_executable_path = ruby_executable_path
23
23
  end
24
24
 
25
- def activation_string
26
- raise "Implement #activation_string in subclasses!"
25
+ def compute_process_args(command_string, directory, options)
26
+ raise "Implement #compute_process_args in subclasses!"
27
27
  end
28
28
 
29
29
  end
@@ -1,7 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  require "multi_ruby_runner/version"
4
- require 'multi_ruby_runner'
5
4
  require 'multi_ruby_runner/version_manager'
6
5
  require 'multi_ruby_runner/version_manager/none'
7
6
  require 'multi_ruby_runner/version_manager/rbenv'
@@ -13,45 +12,29 @@ class MultiRubyRunner
13
12
  def initialize
14
13
  end
15
14
 
16
- # Executes a blocking command in a directory.
17
- # Command will be executed in the ruby environment specified in .ruby-version
18
- # file in the directory.
19
- # Example command:
20
- # `/bin/bash -c 'source /Users/johund/.rvm/scripts/rvm; cd /Users/johund/development/vgr-table-export; ruby -v'`
21
- # @param command_string [String] the command to run in directory
22
- # @param directory [String] the dir containing the ".ruby-version" file and the ruby project to run
15
+ # Executes a command in a directory. Command will be executed in the
16
+ # ruby environment specified in `.ruby-version` file in `directory`.
17
+ # Returns stdout in the blocking form and pid of child process in the
18
+ # non-blocking form.
19
+ #
20
+ # @param command_string [String] the shell command to run in directory
21
+ # @param directory [String] the dir containing the ".ruby-version" file
23
22
  # @param options [Hash, optional]
24
23
  # @option options [String, optional] shell_invocation what shell to use, defaults to bash
25
24
  # @option options [Boolean, optional] blocking, defaults to true.
26
- # @return [String] STDOUT output
25
+ # @return [String, Integer, Nil] STDOUT output when blocking, pid when non-blocking.
27
26
  def execute_command_in_directory(command_string, directory, options = {})
28
27
  shell_path = ENV['SHELL'] || '/bin/bash'
29
28
  options = {
30
29
  blocking: true,
31
30
  shell_invocation: "#{ shell_path } -c",
32
31
  }.merge(options)
33
- shell_command_string = [
34
- ruby_version_manager.activation_string, # e.g., "source ~/.rvm/scripts/rvm"
35
- "cd #{ directory }",
36
- command_string
37
- ].join('; ')
38
- entire_command = "#{ options[:shell_invocation] } '#{ shell_command_string }'"
39
-
40
- # Bundler.with_clean_env avoids spilling over of any bundler environment
41
- # e.g., BUNDLE_BIN_PATH, BUNDLE_GEMFILE, and RUBYOPT
42
- if options[:blocking]
43
- # Wait for command to complete
44
- Bundler.with_clean_env do
45
- `#{ entire_command }`
46
- end
47
- else
48
- # Fork new process, execute command there and return immediately to caller.
49
- fork do
50
- Bundler.with_clean_env do
51
- `#{ entire_command }`
52
- end
53
- end
54
- end
32
+ process_args = ruby_version_manager.compute_process_args(
33
+ command_string,
34
+ directory,
35
+ options
36
+ )
37
+ execute_command(process_args)
55
38
  end
56
39
 
57
40
  # Returns the ruby version manager used
@@ -60,4 +43,52 @@ class MultiRubyRunner
60
43
  VersionManager.detect
61
44
  end
62
45
 
46
+ protected
47
+
48
+ # @param process_args [Hash]
49
+ # {
50
+ # entire_command: includes shell invocation,
51
+ # ruby version manager activation and command
52
+ # blocking: Boolean
53
+ # environment_overrides: {}
54
+ # }
55
+ def execute_command(process_args)
56
+ if process_args[:blocking]
57
+ # Wait for command to complete
58
+ execute_blocking_command(process_args)
59
+ else
60
+ # Spawn new process, execute command there and return immediately to caller.
61
+ execute_non_blocking_command(process_args)
62
+ end
63
+ end
64
+
65
+ def execute_blocking_command(process_args)
66
+ stdout_str = stderr_str = status = nil
67
+ Bundler.with_clean_env do
68
+ stdout_str, stderr_str, status = Open3.capture3(
69
+ process_args[:environment_overrides],
70
+ process_args[:entire_command]
71
+ )
72
+ end
73
+ if 0 == status
74
+ # return stdout
75
+ stdout_str
76
+ else
77
+ # Raise exception
78
+ raise "Command failed with status #{ status.inspect }. stderr: #{ stderr_str }"
79
+ end
80
+ end
81
+
82
+ def execute_non_blocking_command(process_args)
83
+ pid = nil
84
+ Bundler.with_clean_env do
85
+ pid = Process.spawn(
86
+ process_args[:environment_overrides],
87
+ process_args[:entire_command]
88
+ )
89
+ end
90
+ Process.detach(pid) # Avoid zombie process
91
+ pid # return spawned process' pid
92
+ end
93
+
63
94
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Jo Hund"]
10
10
  spec.email = ["jhund@clearcove.ca"]
11
11
  spec.summary = %q{Execute Ruby code in different Ruby environments.}
12
- spec.description = %q{This gem lets you for example call JRuby code from MRI. It relies on rbenv or RVM to manage the Ruby runtime environment.}
12
+ spec.description = %q{Execute Ruby code in different Ruby environments. This gem lets you for example call JRuby code from MRI. It relies on rbenv or RVM to manage the Ruby runtime environment.}
13
13
  spec.homepage = "https://github.com/jhund/multi_ruby_runner"
14
14
  spec.license = "MIT"
15
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_ruby_runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jo Hund
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-16 00:00:00.000000000 Z
11
+ date: 2016-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,8 +52,9 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: This gem lets you for example call JRuby code from MRI. It relies on
56
- rbenv or RVM to manage the Ruby runtime environment.
55
+ description: Execute Ruby code in different Ruby environments. This gem lets you for
56
+ example call JRuby code from MRI. It relies on rbenv or RVM to manage the Ruby runtime
57
+ environment.
57
58
  email:
58
59
  - jhund@clearcove.ca
59
60
  executables: []