ruby-virtualenv 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +32 -63
- data/Rakefile +8 -0
- data/lib/sandbox/cli.rb +9 -13
- data/lib/sandbox/errors.rb +2 -2
- data/lib/sandbox/installer.rb +46 -72
- data/lib/sandbox/templates/activate.erb +2 -16
- data/lib/sandbox/version.rb +1 -1
- data/ruby-virtualenv.gemspec +1 -1
- data/spec/sandbox/cli_spec.rb +114 -116
- data/spec/sandbox/errors_spec.rb +5 -9
- data/spec/sandbox/installer_spec.rb +131 -133
- data/spec/sandbox/output_spec.rb +39 -39
- data/spec/sandbox_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +6 -12
- data/features/development.feature +0 -13
- data/features/steps/common.rb +0 -174
- data/features/steps/env.rb +0 -10
data/README.md
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
* http://github.com/nkryptic/sandbox
|
5
|
-
|
6
|
-
DESCRIPTION:
|
7
|
-
------------
|
1
|
+
Ruby Virtualenv
|
2
|
+
===============
|
8
3
|
|
9
4
|
Inspired by Python's [virtualenv](http://pypi.python.org/pypi/virtualenv)
|
10
5
|
project, Ruby-Virtualenv is a utility to create sandboxed Ruby/Rubygems
|
@@ -31,90 +26,64 @@ When you want to leave the environment:
|
|
31
26
|
|
32
27
|
$ deactivate
|
33
28
|
|
34
|
-
|
35
|
-
|
29
|
+
Notes
|
30
|
+
-----
|
36
31
|
|
37
32
|
* It creates an environment that has its own installation directory for Gems.
|
38
33
|
* It doesn't share gems with other sandbox environments.
|
39
34
|
* It (optionally) doesn't use the globally installed gems either.
|
40
35
|
* It will use a local to the sandbox .gemrc file
|
41
36
|
|
42
|
-
|
43
|
-
|
37
|
+
Install
|
38
|
+
-------
|
44
39
|
|
45
|
-
|
46
|
-
temporarily to the sandbox directory. Other environment variables are
|
47
|
-
set to enable this funtionality, so if you may experience odd behavior.
|
48
|
-
Everything should be reset when you deactivate the sandbox.
|
40
|
+
$ gem install ruby-virtualenv
|
49
41
|
|
50
|
-
|
51
|
-
|
42
|
+
Usage
|
43
|
+
-----
|
52
44
|
|
53
45
|
Create a new virtualenv (verbose output by default):
|
54
46
|
|
55
47
|
$ ruby-virtualenv ~/.ruby-virtualenvs/my-new-sandbox
|
56
|
-
creating new sandbox in
|
48
|
+
creating new sandbox in ~/.ruby-virtualenvs/my-new-sandbox
|
57
49
|
installing activation script
|
58
50
|
installing .gemrc
|
59
51
|
installing gems:
|
60
52
|
nothing to do
|
61
53
|
|
62
|
-
Create a new sandbox with no output:
|
63
|
-
|
64
|
-
$ ruby-virtualenv ~/.ruby-virtualenvs/my-new-sandbox -q
|
65
|
-
|
66
54
|
Create a new sandbox with specific gems:
|
67
55
|
|
68
56
|
$ ruby-virtualenv ~/.ruby-virtualenvs/my-new-sandbox -g rake,rails
|
69
|
-
creating new sandbox in
|
57
|
+
creating new sandbox in ~/.ruby-virtualenvs/my-new-sandbox
|
70
58
|
installing activation script
|
71
59
|
installing .gemrc
|
72
60
|
installing gems:
|
73
61
|
gem: rake
|
74
62
|
gem: rails
|
75
63
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
I hope to expand the full version branch to allow for installing both
|
80
|
-
rubygems and ruby as part of the sandbox. This would enable experimentation
|
81
|
-
with different versions of both and exclude the requirement on needing
|
82
|
-
rubygems in the first place.
|
83
|
-
|
84
|
-
REQUIREMENTS:
|
85
|
-
-------------
|
86
|
-
|
87
|
-
* ruby
|
88
|
-
* rubygems
|
89
|
-
|
90
|
-
INSTALL:
|
91
|
-
--------
|
92
|
-
|
93
|
-
$ gem install ruby-virtualenv
|
94
|
-
|
95
|
-
LICENSE:
|
96
|
-
--------
|
64
|
+
License
|
65
|
+
-------
|
97
66
|
|
98
|
-
(The MIT License)
|
67
|
+
(The MIT License)
|
99
68
|
|
100
|
-
Copyright (c) 2011 Francesc Esplugas
|
101
|
-
Copyright (c) 2008 Jacob Radford
|
69
|
+
Copyright (c) 2011 Francesc Esplugas
|
70
|
+
Copyright (c) 2008 Jacob Radford
|
102
71
|
|
103
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
104
|
-
a copy of this software and associated documentation files (the
|
105
|
-
'Software'), to deal in the Software without restriction, including
|
106
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
107
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
108
|
-
permit persons to whom the Software is furnished to do so, subject to
|
109
|
-
the following conditions:
|
72
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
73
|
+
a copy of this software and associated documentation files (the
|
74
|
+
'Software'), to deal in the Software without restriction, including
|
75
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
76
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
77
|
+
permit persons to whom the Software is furnished to do so, subject to
|
78
|
+
the following conditions:
|
110
79
|
|
111
|
-
The above copyright notice and this permission notice shall be
|
112
|
-
included in all copies or substantial portions of the Software.
|
80
|
+
The above copyright notice and this permission notice shall be
|
81
|
+
included in all copies or substantial portions of the Software.
|
113
82
|
|
114
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
115
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
116
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
117
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
118
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
119
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
120
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
83
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
84
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
85
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
86
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
87
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
88
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
89
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
data/lib/sandbox/cli.rb
CHANGED
@@ -41,7 +41,7 @@ module Sandbox
|
|
41
41
|
tell_unless_really_quiet(error.message)
|
42
42
|
when StandardError #, Timeout::Error
|
43
43
|
tell_unless_really_quiet("Error: #{error.message}")
|
44
|
-
tell_when_really_verbose(error.backtrace.collect { |bt| " #{bt}" }.join(
|
44
|
+
tell_when_really_verbose(error.backtrace.collect { |bt| " #{bt}" }.join("\n")) if error.backtrace
|
45
45
|
when Interrupt
|
46
46
|
tell_unless_really_quiet("Interrupted")
|
47
47
|
else
|
@@ -52,9 +52,6 @@ module Sandbox
|
|
52
52
|
end
|
53
53
|
## END CLASS METHODS
|
54
54
|
|
55
|
-
## PUBLIC INSTANCE METHODS
|
56
|
-
public
|
57
|
-
|
58
55
|
# The options for this execution.
|
59
56
|
attr_reader :options
|
60
57
|
|
@@ -69,12 +66,12 @@ module Sandbox
|
|
69
66
|
targets = options.delete(:args)
|
70
67
|
|
71
68
|
if targets.size < 1
|
72
|
-
raise Sandbox::Error.new('
|
69
|
+
raise Sandbox::Error.new('No target specified. See `ruby-virtualenv -h` for assistance.')
|
73
70
|
elsif targets.size > 1
|
74
|
-
raise Sandbox::Error.new('
|
71
|
+
raise Sandbox::Error.new('Multiple targets specified. See `ruby-virtualenv -h` for assistance.')
|
75
72
|
end
|
76
73
|
|
77
|
-
options[
|
74
|
+
options[:target] = targets[0]
|
78
75
|
|
79
76
|
Sandbox::Installer.new(options).populate
|
80
77
|
end
|
@@ -85,7 +82,7 @@ module Sandbox
|
|
85
82
|
# * determine command name to lookup in CommandManager
|
86
83
|
# * load command and have it process any add't options
|
87
84
|
# * catches exceptions for unknown switches or commands
|
88
|
-
def parse_args!(
|
85
|
+
def parse_args!(args)
|
89
86
|
options[:original_args] = args.dup
|
90
87
|
parser.parse!(args)
|
91
88
|
rescue OptionParser::ParseError => ex
|
@@ -114,9 +111,9 @@ module Sandbox
|
|
114
111
|
o.on('-n', '--no-gems', 'Do not install any gems after virtualenv is created.') { @options[:gems] = [] }
|
115
112
|
o.on('-q', '--quiet', 'Show less output. (multiple allowed)') { |f| Sandbox.decrease_verbosity }
|
116
113
|
o.on('-v', '--verbose', 'Show more output. (multiple allowed)') { |f| Sandbox.increase_verbosity }
|
117
|
-
o.on_tail('-h', '--help', 'Show this help message and exit.') { tell_unless_really_quiet(
|
118
|
-
o.on_tail('-H', '--long-help', 'Show the full description about the program.') { tell_unless_really_quiet(
|
119
|
-
o.on_tail('-V', '--version', 'Display the program version and exit.'
|
114
|
+
o.on_tail('-h', '--help', 'Show this help message and exit.') { tell_unless_really_quiet(o); exit }
|
115
|
+
o.on_tail('-H', '--long-help', 'Show the full description about the program.') { tell_unless_really_quiet(long_help); exit }
|
116
|
+
o.on_tail('-V', '--version', 'Display the program version and exit.') { tell_unless_really_quiet(Sandbox::VERSION); exit }
|
120
117
|
o.separator ""
|
121
118
|
end
|
122
119
|
end
|
@@ -163,11 +160,10 @@ WARNINGS:
|
|
163
160
|
HELP
|
164
161
|
end
|
165
162
|
|
166
|
-
private
|
167
|
-
|
168
163
|
def raise_parse_error(reason, args=[])
|
169
164
|
raise Sandbox::ParseError.new(reason, args)
|
170
165
|
end
|
166
|
+
private :raise_parse_error
|
171
167
|
|
172
168
|
end
|
173
169
|
end
|
data/lib/sandbox/errors.rb
CHANGED
@@ -6,7 +6,7 @@ module Sandbox
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def message
|
9
|
-
out = [
|
9
|
+
out = [super]
|
10
10
|
out.concat(backtrace.collect { |bt| " #{bt}" }) if Sandbox.really_verbose?
|
11
11
|
out.join("\n")
|
12
12
|
end
|
@@ -23,7 +23,7 @@ module Sandbox
|
|
23
23
|
|
24
24
|
def initialize(reason=nil, args=[])
|
25
25
|
msg = if args.is_a?(Array) && args.size > 0
|
26
|
-
"#{reason} => #{args.join(
|
26
|
+
"#{reason} => #{args.join(' ')}"
|
27
27
|
elsif args.is_a?(String) && args.length > 0
|
28
28
|
"#{reason} => #{args}"
|
29
29
|
else
|
data/lib/sandbox/installer.rb
CHANGED
@@ -47,129 +47,103 @@ module Sandbox
|
|
47
47
|
FileUtils.mkdir_p(gembin)
|
48
48
|
|
49
49
|
bin = File.join(target, 'bin')
|
50
|
-
FileUtils.ln_s(
|
50
|
+
FileUtils.ln_s(gembin, bin)
|
51
51
|
end
|
52
52
|
|
53
53
|
def install_gemrc
|
54
54
|
filename = File.join(target, '.gemrc')
|
55
|
-
template = File.read(File.dirname(
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
File.open(filename, 'w') do |f|
|
60
|
-
f.write output
|
61
|
-
end
|
55
|
+
template = File.read(File.dirname(__FILE__) + '/templates/gemrc.erb')
|
56
|
+
output = ERB.new(template).result(binding)
|
57
|
+
File.open(filename, 'w') { |f| f.write(output) }
|
62
58
|
end
|
63
59
|
|
64
60
|
def install_scripts
|
65
61
|
filename = File.join(target, 'bin', 'activate')
|
66
|
-
template = File.read(File.dirname(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
File.open(filename, 'w') do |f|
|
71
|
-
f.write output
|
72
|
-
end
|
62
|
+
template = File.read(File.dirname(__FILE__) + '/templates/activate.erb')
|
63
|
+
output = ERB.new(template).result(binding)
|
64
|
+
File.open(filename, 'w') { |f| f.write(output) }
|
73
65
|
end
|
74
66
|
|
75
67
|
def install_gems
|
76
|
-
|
77
|
-
# return if gem.empty?
|
78
|
-
gems = options[ :gems ] || []
|
68
|
+
gems = options[:gems] || []
|
79
69
|
if gems.size == 0
|
80
|
-
tell(
|
70
|
+
tell(" nothing to install")
|
81
71
|
return
|
82
72
|
end
|
83
|
-
|
73
|
+
|
84
74
|
begin
|
85
75
|
setup_sandbox_env
|
86
76
|
gems.each do |gem|
|
87
|
-
tell_unless_really_quiet(
|
77
|
+
tell_unless_really_quiet(" gem: #{gem}")
|
88
78
|
cmd = "gem install #{gem}"
|
89
|
-
|
90
|
-
status, output = shell_out( cmd )
|
79
|
+
status, output = shell_out(cmd)
|
91
80
|
unless status
|
92
|
-
tell_unless_really_quiet(
|
81
|
+
tell_unless_really_quiet(" failed to install gem: #{gem}")
|
93
82
|
end
|
94
83
|
end
|
95
84
|
ensure
|
96
85
|
restore_sandbox_env
|
97
86
|
end
|
98
87
|
end
|
99
|
-
|
100
|
-
def shell_out(
|
101
|
-
# err_capture = Sandbox.really_verbose? '2>&1' : '2>/dev/null'
|
102
|
-
# out = `#{cmd} #{err_capture}`
|
88
|
+
|
89
|
+
def shell_out(cmd)
|
103
90
|
out = `#{cmd} 2>/dev/null`
|
104
91
|
result = $?.exitstatus == 0
|
105
|
-
[
|
92
|
+
[result, out]
|
106
93
|
end
|
107
|
-
|
94
|
+
|
108
95
|
def setup_sandbox_env
|
109
|
-
@old_env = Hash[ *ENV.select { |k,v| ['HOME','GEM_HOME','GEM_PATH'].include?(
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
ENV[ 'HOME' ] = target
|
116
|
-
ENV[ 'GEM_HOME' ] = "#{target}/rubygems"
|
117
|
-
ENV[ 'GEM_PATH' ] = "#{target}/rubygems"
|
96
|
+
@old_env = Hash[ *ENV.select { |k,v| ['HOME','GEM_HOME','GEM_PATH'].include?(k) }.flatten ]
|
97
|
+
|
98
|
+
ENV['HOME'] = target
|
99
|
+
ENV['GEM_HOME'] = "#{target}/rubygems"
|
100
|
+
ENV['GEM_PATH'] = "#{target}/rubygems"
|
118
101
|
end
|
119
|
-
|
102
|
+
|
120
103
|
def restore_sandbox_env
|
121
|
-
|
122
|
-
ENV[
|
123
|
-
ENV[
|
124
|
-
ENV[ 'GEM_PATH' ] = @old_env[ 'GEM_PATH' ]
|
104
|
+
ENV['HOME'] = @old_env['HOME']
|
105
|
+
ENV['GEM_HOME'] = @old_env['GEM_HOME']
|
106
|
+
ENV['GEM_PATH'] = @old_env['GEM_PATH']
|
125
107
|
end
|
126
|
-
|
127
|
-
def resolve_target(
|
128
|
-
|
129
|
-
|
130
|
-
if File.exists?( path )
|
108
|
+
|
109
|
+
def resolve_target(path)
|
110
|
+
path = fix_path(path)
|
111
|
+
if File.exists?(path)
|
131
112
|
raise Sandbox::Error, "target '#{path}' exists"
|
132
113
|
end
|
133
|
-
|
114
|
+
|
134
115
|
base = path
|
135
|
-
while base = File.dirname(
|
136
|
-
if check_path!(
|
116
|
+
while base = File.dirname(base)
|
117
|
+
if check_path!(base)
|
137
118
|
break
|
138
119
|
elsif base == '/'
|
139
120
|
raise "something is seriously wrong; we should never get here"
|
140
121
|
end
|
141
122
|
end
|
142
|
-
|
123
|
+
|
124
|
+
path
|
143
125
|
end
|
144
|
-
|
145
|
-
def check_path!(
|
146
|
-
if File.directory?(
|
147
|
-
if File.writable?(
|
126
|
+
|
127
|
+
def check_path!(path)
|
128
|
+
if File.directory?(path)
|
129
|
+
if File.writable?(path)
|
148
130
|
return true
|
149
131
|
else
|
150
132
|
raise Sandbox::Error, "path '#{path}' has a permission problem"
|
151
133
|
end
|
152
|
-
elsif File.exists?(
|
134
|
+
elsif File.exists?(path)
|
153
135
|
raise Sandbox::Error, "path '#{path}' is not a directory"
|
154
136
|
end
|
155
137
|
false
|
156
138
|
end
|
157
|
-
|
158
|
-
def fix_path(
|
159
|
-
unless path.index(
|
160
|
-
path = File.join(
|
139
|
+
|
140
|
+
def fix_path(path)
|
141
|
+
unless path.index('/') == 0
|
142
|
+
path = File.join(FileUtils.pwd, path)
|
161
143
|
end
|
162
144
|
path
|
163
145
|
end
|
164
146
|
|
165
|
-
## END PUBLIC INSTANCE METHODS
|
166
|
-
|
167
|
-
|
168
|
-
## PRIVATE INSTANCE METHODS
|
169
|
-
private
|
170
|
-
|
171
|
-
## END PRIVATE INSTANCE METHODS
|
172
|
-
|
173
147
|
end
|
174
|
-
|
175
|
-
end
|
148
|
+
|
149
|
+
end
|
@@ -33,18 +33,12 @@ deactivate () {
|
|
33
33
|
export PATH
|
34
34
|
fi
|
35
35
|
|
36
|
-
if [ -n "$_OLD_SANDBOX_HOME" ] ; then
|
37
|
-
HOME="$_OLD_SANDBOX_HOME"
|
38
|
-
export HOME
|
39
|
-
fi
|
40
|
-
|
41
36
|
if [ -n "$_OLD_SANDBOX_PS1" ] ; then
|
42
37
|
PS1="$_OLD_SANDBOX_PS1"
|
43
38
|
export PS1
|
44
39
|
fi
|
45
40
|
|
46
41
|
unset _OLD_SANDBOX_PATH
|
47
|
-
unset _OLD_SANDBOX_HOME
|
48
42
|
unset _OLD_SANDBOX_GEM_HOME
|
49
43
|
unset _OLD_SANDBOX_GEM_PATH
|
50
44
|
unset _OLD_SANDBOX_PS1
|
@@ -68,24 +62,16 @@ activate () {
|
|
68
62
|
_OLD_SANDBOX_GEM_HOME="$GEM_HOME"
|
69
63
|
_OLD_SANDBOX_GEM_PATH="$GEM_PATH"
|
70
64
|
_OLD_SANDBOX_PATH="$PATH"
|
71
|
-
_OLD_SANDBOX_HOME="$HOME"
|
72
65
|
_OLD_SANDBOX_PS1="$PS1"
|
73
66
|
|
74
67
|
# set the sandbox-aware states
|
75
68
|
SANDBOX_ENV="<%= target %>"
|
76
69
|
PATH="$SANDBOX_ENV/bin:$PATH"
|
77
|
-
HOME="$SANDBOX_ENV"
|
78
70
|
GEM_HOME="$SANDBOX_ENV/rubygems"
|
79
71
|
GEM_PATH="$GEM_HOME"
|
80
|
-
|
81
|
-
# special case for Aspen magic directories
|
82
|
-
# see http://www.zetadev.com/software/aspen/
|
83
|
-
PS1="[ruby-virtualenv:`basename \`dirname \"$SANDBOX_ENV\"\``] $PS1"
|
84
|
-
else
|
85
|
-
PS1="(ruby-virtualenv:`basename \"$SANDBOX_ENV\"`) $PS1"
|
86
|
-
fi
|
72
|
+
PS1="(`basename \"$SANDBOX_ENV\"`) $PS1"
|
87
73
|
|
88
|
-
export SANDBOX_ENV PATH
|
74
|
+
export SANDBOX_ENV PATH GEM_HOME GEM_PATH PS1
|
89
75
|
|
90
76
|
forget_cached_commands
|
91
77
|
|