zozo 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +18 -0
- data/README.rdoc +61 -0
- data/bin/zozo +135 -0
- data/spec/zozo_spec.rb +254 -0
- metadata +78 -0
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2010 Jeremy Evans
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
= What?
|
2
|
+
|
3
|
+
zozo is a tool that makes it easy to reduce the memory footprint of your applications by having them not load rubygems/bundler at runtime:
|
4
|
+
|
5
|
+
$ unicorn -c unicorn.conf -D
|
6
|
+
$ ps ux
|
7
|
+
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
|
8
|
+
jeremy 18226 0.0 0.5 17196 4496 ?? S 1:34PM 0:00.01 ruby: unicorn master -c unicorn.conf -D (ruby)
|
9
|
+
jeremy 8473 31.3 3.3 27180 30172 ?? S 1:34PM 0:00.62 ruby: unicorn worker[0] -c unicorn.conf -D (ruby)
|
10
|
+
|
11
|
+
$ zozo -R config.ru unicorn
|
12
|
+
$ ruby -I lib bin/unicorn -c unicorn.conf -D
|
13
|
+
$ ps ux
|
14
|
+
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
|
15
|
+
jeremy 17561 0.0 0.4 5548 3908 ?? S 1:35PM 0:00.01 ruby: unicorn master -c unicorn.conf -D (ruby)
|
16
|
+
jeremy 22626 4.2 2.0 15016 17904 ?? S 1:35PM 0:00.25 ruby: unicorn worker[0] -c unicorn.conf -D (ruby)
|
17
|
+
|
18
|
+
As you can see, the memory footprint is reduced dramatically:
|
19
|
+
|
20
|
+
master process:
|
21
|
+
VSZ: 5548/17196 => 68% reduction
|
22
|
+
RSS: 3908/4496 => 13% reduction
|
23
|
+
worker process:
|
24
|
+
VSZ: 15016/27180 => 45% reduction
|
25
|
+
RSS: 17904/30172 => 41% reduction
|
26
|
+
|
27
|
+
That's a major difference, as a 41% reduction in memory footprint means you can host 68% more workers in the same amount of memory. It also makes your applications faster. They will start faster because zozo loads all necessary library files into a single directory tree. They will run faster as there will be fewer ruby objects to check every time the garbage collector is run.
|
28
|
+
|
29
|
+
= Why?
|
30
|
+
|
31
|
+
Rubygems is a fine package distribution system, but it is not very efficient from a runtime memory standpoint. If your application uses rubygems in production, every time it starts, rubygems needs to figure out which packages to load. zozo makes it so that this is calculation is only done once, and the result is cached into a local directory.
|
32
|
+
|
33
|
+
= How?
|
34
|
+
|
35
|
+
zozo works by starting ruby and checking the current load path. It then requires all of the command line arguments given, and checks the load path again. Any new entries in the load path are checked and their contents are loaded into a local directory (lib by default). By default, zozo uses symlinks, but it can use hard links (-H) or make copies (-c) via a command line option.
|
36
|
+
|
37
|
+
In addition, new entries in the load path that end in /bin are loaded into a separate local directory (bin by default). This allows you to run them with loading rubygems via:
|
38
|
+
|
39
|
+
ruby -I lib bin/$program
|
40
|
+
|
41
|
+
zozo adds replacement rubygems.rb, ubygems.rb, and bundler.rb files to the lib directory it creates, so it works transparently if your program requires rubygems and/or bundler. If you run your program without adding the lib directory zozo creates to the load path, rubygems/bundler will be used as it was. If you run your program with the lib directory zozo creates in the load path, then rubygems/bundler will not be loaded, and it won't need to be because all other libraries your program uses will already be in the load path.
|
42
|
+
|
43
|
+
= Where?
|
44
|
+
|
45
|
+
http://github.com/jeremyevans/zozo
|
46
|
+
|
47
|
+
= Who?
|
48
|
+
|
49
|
+
Jeremy Evans / code@jeremyevans.net
|
50
|
+
|
51
|
+
= When?
|
52
|
+
|
53
|
+
Now:
|
54
|
+
|
55
|
+
sudo gem install zozo
|
56
|
+
|
57
|
+
= Does not work with Rails!
|
58
|
+
|
59
|
+
The replacement rubygems.rb and bundler.rb files only do the bare minimum. The rubygems.rb file adds Kernel#gem, and the bundler.rb file adds Bundler.setup, both of which are defined to do nothing and return nil. No other features are mocked out. This means that frameworks that rely on introspecting the running Gem/Bundler configuration (notably Rails) will not work.
|
60
|
+
|
61
|
+
This is probably fixable, and I'll accept patches that allow zozo to work with Rails, but I don't plan on working on the issue myself. As Rails uses a substantial amount of memory by itself, it benefits less from zozo than more memory friendly frameworks such as Sinatra.
|
data/bin/zozo
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# bin/zozo is currently a completely procedural program, with
|
4
|
+
# no classes or methods defined. This may change in the future
|
5
|
+
# if more extensibility is desired.
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
require 'find'
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
sep = File::SEPARATOR
|
12
|
+
lib_dir = 'lib'
|
13
|
+
bin_dir = 'bin'
|
14
|
+
ln_method = :ln_s
|
15
|
+
ln_opts = {}
|
16
|
+
loads = []
|
17
|
+
rackups = []
|
18
|
+
|
19
|
+
# Parse all command line options
|
20
|
+
opt_parser = OptionParser.new do |o|
|
21
|
+
o.banner = "zozo: Simple $LOAD_PATH management for ruby projects"
|
22
|
+
o.define_head "Usage: zozo [-l lib_dir] [-b bin_dir] [-L path] [-R ru_file] [-cfhHnv] lib"
|
23
|
+
o.separator ""
|
24
|
+
o.separator "zozo creates a directory with symbolic links to other directories"
|
25
|
+
o.separator "and files, allowing you to avoid loading rubygems and bundler when"
|
26
|
+
o.separator "running in production with a simple addition of one directory to the"
|
27
|
+
o.separator "$LOAD_PATH."
|
28
|
+
o.separator ""
|
29
|
+
o.separator "Options:"
|
30
|
+
|
31
|
+
o.on("-b", '--bin-dir LIBDIR', "Use a nonstandard bin dir (default: bin)") do |v|
|
32
|
+
bin_dir = v
|
33
|
+
end
|
34
|
+
|
35
|
+
o.on("-c", '--copy', "Copy files instead of creating symbolic links") do
|
36
|
+
ln_method = :cp
|
37
|
+
end
|
38
|
+
|
39
|
+
o.on("-f", '--force', "Force file system modifications") do
|
40
|
+
ln_opts[:force] = true
|
41
|
+
end
|
42
|
+
|
43
|
+
o.on("-h", "-?", "--help", "Show this message and exit") do
|
44
|
+
puts o
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
o.on("-H", '--hard-link', "Create hard links instead of symbolic links") do
|
49
|
+
ln_method = :ln
|
50
|
+
end
|
51
|
+
|
52
|
+
o.on("-l", '--lib-dir LIBDIR', "Use a nonstandard lib dir (default: lib)") do |v|
|
53
|
+
lib_dir = v
|
54
|
+
end
|
55
|
+
|
56
|
+
o.on("-L", '--load path', "Use load instead of require for the given argument") do |v|
|
57
|
+
loads << v
|
58
|
+
end
|
59
|
+
|
60
|
+
o.on("-n", '--noop', "Don't make any file system modifications") do
|
61
|
+
ln_opts[:noop] = true
|
62
|
+
end
|
63
|
+
|
64
|
+
o.on("-R", '--rackup ru_file', "Load the given file as a rackup file") do |v|
|
65
|
+
rackups << v
|
66
|
+
end
|
67
|
+
|
68
|
+
o.on("-v", '--verbose', "Log all file system modifications to stderr") do
|
69
|
+
ln_opts[:verbose] = true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
opt_parser.parse!
|
73
|
+
mkdir_opts = ln_opts.reject{|k,v| k == :force}
|
74
|
+
|
75
|
+
# Require/load the files specifying by the arguments, and check for new
|
76
|
+
# load path entries
|
77
|
+
start_dirs = $LOAD_PATH.dup
|
78
|
+
ENV['ZOZO'] = '1'
|
79
|
+
loads.each{|f| load f}
|
80
|
+
unless rackups.empty?
|
81
|
+
begin
|
82
|
+
require 'rack'
|
83
|
+
rescue LoadError
|
84
|
+
require 'rubygems'
|
85
|
+
require 'rack'
|
86
|
+
end
|
87
|
+
rackups.each{|f| eval("Rack::Builder.new{( " + File.read(f) + "\n )}.to_app", nil, f)}
|
88
|
+
end
|
89
|
+
ARGV.each{|f| require f}
|
90
|
+
new_dirs = ($LOAD_PATH - start_dirs).uniq
|
91
|
+
|
92
|
+
# Find all files/directories that we want to link to/create
|
93
|
+
lns = {}
|
94
|
+
bins = {}
|
95
|
+
new_dirs.each do |d|
|
96
|
+
Find.find(d) do |f|
|
97
|
+
next if f == d
|
98
|
+
p = f.sub(d, '').sub(sep, '')
|
99
|
+
h = (d =~ /#{sep}bin\z/) ? bins : lns
|
100
|
+
if File.directory?(f)
|
101
|
+
raise(StandardError, "File/directory overlap (file: #{h[p]}, directory: #{f})") if h[p].is_a?(String)
|
102
|
+
h[p] = :dir
|
103
|
+
elsif File.file?(f)
|
104
|
+
raise(StandardError, "File/directory overlap (file: #{f}, directory: #{p})") if h[p] == :dir
|
105
|
+
# Other entry comes before this one in the load path, so ignore it
|
106
|
+
h[p] ||= f
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Handle directory creation and file linking/copying
|
112
|
+
[[lib_dir, lns], [bin_dir, bins]].each do |dir, h|
|
113
|
+
FileUtils.mkdir(dir, mkdir_opts)
|
114
|
+
h.sort.each do |k, v|
|
115
|
+
p = File.join(dir, k)
|
116
|
+
if v == :dir
|
117
|
+
FileUtils.mkdir(p, mkdir_opts)
|
118
|
+
else
|
119
|
+
FileUtils.send(ln_method, v, p, ln_opts)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Create special files for rubygems and bundler
|
125
|
+
%w'rubygems.rb ubygems.rb bundler.rb'
|
126
|
+
[['rubygems.rb', "module Kernel; def gem(*args); end end"],
|
127
|
+
['ubygems.rb', "require 'rubygems'"],
|
128
|
+
['bundler.rb', "module Bundler; def self.setup(*args); end end"]
|
129
|
+
].each do |file, data|
|
130
|
+
p = File.join(lib_dir, file)
|
131
|
+
$stderr.puts("Writing #{p}") if ln_opts[:verbose]
|
132
|
+
if ln_opts[:force] || !File.exist?(p)
|
133
|
+
File.open(p, 'wb'){|f| f.puts(data)} unless ln_opts[:noop]
|
134
|
+
end
|
135
|
+
end
|
data/spec/zozo_spec.rb
ADDED
@@ -0,0 +1,254 @@
|
|
1
|
+
#!/usr/bin/env spec
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'open3'
|
5
|
+
Dir.chdir(File.dirname(File.expand_path(__FILE__)))
|
6
|
+
|
7
|
+
context "zozo" do
|
8
|
+
after do
|
9
|
+
FileUtils.rm_r('lib') if File.directory?('lib')
|
10
|
+
FileUtils.rm_r('bin') if File.directory?('bin')
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(args='test1')
|
14
|
+
`#{File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'bin', 'zozo')} #{args}`
|
15
|
+
end
|
16
|
+
|
17
|
+
def run3(args='test1', &block)
|
18
|
+
Open3.popen3("#{File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'bin', 'zozo')} #{args}", &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ino(f)
|
22
|
+
File.stat(f).ino
|
23
|
+
end
|
24
|
+
|
25
|
+
def should_be_same(f1, f2)
|
26
|
+
File.read(f1).should == File.read(f2)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should create bin and lib directories with symbolic links by default" do
|
30
|
+
run.should == ''
|
31
|
+
File.file?('lib/a').should be_true
|
32
|
+
File.symlink?('lib/a').should be_true
|
33
|
+
should_be_same('lib/a', 'test1/a')
|
34
|
+
File.directory?('lib/b').should be_true
|
35
|
+
File.file?('lib/b/c').should be_true
|
36
|
+
File.symlink?('lib/b/c').should be_true
|
37
|
+
should_be_same('lib/b/c', 'test1/b/c')
|
38
|
+
|
39
|
+
File.file?('bin/b1').should be_true
|
40
|
+
File.symlink?('bin/b1').should be_true
|
41
|
+
should_be_same('bin/b1', 'b/bin/b1')
|
42
|
+
File.directory?('bin/d').should be_true
|
43
|
+
File.file?('bin/d/b2').should be_true
|
44
|
+
File.symlink?('bin/d/b2').should be_true
|
45
|
+
should_be_same('bin/d/b2', 'b/bin/d/b2')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should print out help if -h option is used" do
|
49
|
+
run('-h').should =~ /Usage: zozo/
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should create bin and lib directories with hard links if the -H option is used" do
|
53
|
+
run('-H test1').should == ''
|
54
|
+
File.file?('lib/a').should be_true
|
55
|
+
File.symlink?('lib/a').should be_false
|
56
|
+
ino('lib/a').should == ino('test1/a')
|
57
|
+
File.directory?('lib/b').should be_true
|
58
|
+
File.file?('lib/b/c').should be_true
|
59
|
+
File.symlink?('lib/b/c').should be_false
|
60
|
+
ino('lib/b/c').should == ino('test1/b/c')
|
61
|
+
|
62
|
+
File.file?('bin/b1').should be_true
|
63
|
+
File.symlink?('bin/b1').should be_false
|
64
|
+
ino('bin/b1').should == ino('b/bin/b1')
|
65
|
+
File.directory?('bin/d').should be_true
|
66
|
+
File.file?('bin/d/b2').should be_true
|
67
|
+
File.symlink?('bin/d/b2').should be_false
|
68
|
+
ino('bin/d/b2').should == ino('b/bin/d/b2')
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should create bin and lib directories with file copies if the -c option is used" do
|
72
|
+
run('-c test1').should == ''
|
73
|
+
File.file?('lib/a').should be_true
|
74
|
+
File.symlink?('lib/a').should be_false
|
75
|
+
ino('lib/a').should_not == ino('test1/a')
|
76
|
+
should_be_same('lib/a', 'test1/a')
|
77
|
+
File.directory?('lib/b').should be_true
|
78
|
+
File.file?('lib/b/c').should be_true
|
79
|
+
File.symlink?('lib/b/c').should be_false
|
80
|
+
ino('lib/b/c').should_not == ino('test1/b/c')
|
81
|
+
should_be_same('lib/b/c', 'test1/b/c')
|
82
|
+
|
83
|
+
File.file?('bin/b1').should be_true
|
84
|
+
File.symlink?('bin/b1').should be_false
|
85
|
+
ino('bin/b1').should_not == ino('b/bin/b1')
|
86
|
+
should_be_same('bin/b1', 'b/bin/b1')
|
87
|
+
File.directory?('bin/d').should be_true
|
88
|
+
File.file?('bin/d/b2').should be_true
|
89
|
+
File.symlink?('bin/d/b2').should be_false
|
90
|
+
ino('bin/d/b2').should_not == ino('b/bin/d/b2')
|
91
|
+
should_be_same('bin/d/b2', 'b/bin/d/b2')
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should load files with load instead of require if the -L option is used" do
|
95
|
+
run3('load_test') do |si, so, se|
|
96
|
+
se.read.should =~ /no such file to load -- load_test \(LoadError\)/
|
97
|
+
so.read.should == ''
|
98
|
+
end
|
99
|
+
run('-L load_test').should == ''
|
100
|
+
File.file?('lib/a').should be_true
|
101
|
+
File.symlink?('lib/a').should be_true
|
102
|
+
should_be_same('lib/a', 'test1/a')
|
103
|
+
File.directory?('lib/b').should be_true
|
104
|
+
File.file?('lib/b/c').should be_true
|
105
|
+
File.symlink?('lib/b/c').should be_true
|
106
|
+
should_be_same('lib/b/c', 'test1/b/c')
|
107
|
+
|
108
|
+
File.file?('bin/b1').should be_true
|
109
|
+
File.symlink?('bin/b1').should be_true
|
110
|
+
should_be_same('bin/b1', 'b/bin/b1')
|
111
|
+
File.directory?('bin/d').should be_true
|
112
|
+
File.file?('bin/d/b2').should be_true
|
113
|
+
File.symlink?('bin/d/b2').should be_true
|
114
|
+
should_be_same('bin/d/b2', 'b/bin/d/b2')
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should load rackup files with Rack::Builder instead of require if the -R option is used" do
|
118
|
+
run3('test.ru') do |si, so, se|
|
119
|
+
se.read.should =~ /no such file to load -- test.ru \(LoadError\)/
|
120
|
+
so.read.should == ''
|
121
|
+
end
|
122
|
+
run('-R test.ru').should == ''
|
123
|
+
File.file?('lib/a').should be_true
|
124
|
+
File.symlink?('lib/a').should be_true
|
125
|
+
should_be_same('lib/a', 'test1/a')
|
126
|
+
File.directory?('lib/b').should be_true
|
127
|
+
File.file?('lib/b/c').should be_true
|
128
|
+
File.symlink?('lib/b/c').should be_true
|
129
|
+
should_be_same('lib/b/c', 'test1/b/c')
|
130
|
+
|
131
|
+
File.file?('bin/b1').should be_true
|
132
|
+
File.symlink?('bin/b1').should be_true
|
133
|
+
should_be_same('bin/b1', 'b/bin/b1')
|
134
|
+
File.directory?('bin/d').should be_true
|
135
|
+
File.file?('bin/d/b2').should be_true
|
136
|
+
File.symlink?('bin/d/b2').should be_true
|
137
|
+
should_be_same('bin/d/b2', 'b/bin/d/b2')
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should not make any file system modifications if -n option is used" do
|
141
|
+
run('-n test1').should == ''
|
142
|
+
File.exist?('lib').should be_false
|
143
|
+
File.exist?('bin').should be_false
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should force file system modifications over existing files if -f option is used" do
|
147
|
+
run.should == ''
|
148
|
+
run3 do |si, so, se|
|
149
|
+
se.read.should =~ %r{File exists - /data/code/zozo/spec/test1/a or lib/a \(Errno::EEXIST\)}
|
150
|
+
so.read.should == ''
|
151
|
+
end
|
152
|
+
run('-f test1').should == ''
|
153
|
+
File.file?('lib/a').should be_true
|
154
|
+
File.symlink?('lib/a').should be_true
|
155
|
+
should_be_same('lib/a', 'test1/a')
|
156
|
+
File.directory?('lib/b').should be_true
|
157
|
+
File.file?('lib/b/c').should be_true
|
158
|
+
File.symlink?('lib/b/c').should be_true
|
159
|
+
should_be_same('lib/b/c', 'test1/b/c')
|
160
|
+
|
161
|
+
File.file?('bin/b1').should be_true
|
162
|
+
File.symlink?('bin/b1').should be_true
|
163
|
+
should_be_same('bin/b1', 'b/bin/b1')
|
164
|
+
File.directory?('bin/d').should be_true
|
165
|
+
File.file?('bin/d/b2').should be_true
|
166
|
+
File.symlink?('bin/d/b2').should be_true
|
167
|
+
should_be_same('bin/d/b2', 'b/bin/d/b2')
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should log all file system modifications to stderr if -v option is used" do
|
171
|
+
run3('-v test1') do |si, so, se|
|
172
|
+
se.read.split("\n").should == ["mkdir lib", "ln -s /data/code/zozo/spec/test1/a lib/a", "mkdir lib/b", "ln -s /data/code/zozo/spec/test1/b/c lib/b/c", "mkdir bin", "ln -s /data/code/zozo/spec/b/bin/b1 bin/b1", "mkdir bin/d", "ln -s /data/code/zozo/spec/b/bin/d/b2 bin/d/b2", "Writing lib/rubygems.rb", "Writing lib/ubygems.rb", "Writing lib/bundler.rb"]
|
173
|
+
se.read.should == ''
|
174
|
+
end
|
175
|
+
File.file?('lib/a').should be_true
|
176
|
+
File.symlink?('lib/a').should be_true
|
177
|
+
should_be_same('lib/a', 'test1/a')
|
178
|
+
File.directory?('lib/b').should be_true
|
179
|
+
File.file?('lib/b/c').should be_true
|
180
|
+
File.symlink?('lib/b/c').should be_true
|
181
|
+
should_be_same('lib/b/c', 'test1/b/c')
|
182
|
+
|
183
|
+
File.file?('bin/b1').should be_true
|
184
|
+
File.symlink?('bin/b1').should be_true
|
185
|
+
should_be_same('bin/b1', 'b/bin/b1')
|
186
|
+
File.directory?('bin/d').should be_true
|
187
|
+
File.file?('bin/d/b2').should be_true
|
188
|
+
File.symlink?('bin/d/b2').should be_true
|
189
|
+
should_be_same('bin/d/b2', 'b/bin/d/b2')
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should handle rubygems' gem method correctly" do
|
193
|
+
run
|
194
|
+
`ruby -I lib test_rubygems.rb`.should == 'no_error'
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should handle requiring rubygems as ubygems" do
|
198
|
+
run
|
199
|
+
`ruby -I lib test_ubygems.rb`.should == 'no_error'
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should handle bundler's Bundler.setup method correctly" do
|
203
|
+
run
|
204
|
+
`ruby -I lib test_bundler.rb`.should == 'no_error'
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should raise an error on file/directory overlap, with directory after file" do
|
208
|
+
run3('test2') do |si, so, se|
|
209
|
+
se.read.should =~ %r{File/directory overlap \(file: .*/zozo/spec/test2/b, directory: .*/zozo/spec/test1/b\) \(StandardError\)}
|
210
|
+
so.read.should == ''
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should raise an error on file/directory overlap, with file after directory" do
|
215
|
+
run3('test3') do |si, so, se|
|
216
|
+
se.read.should =~ %r{File/directory overlap \(file: .*/zozo/spec/test2/b, directory: b\) \(StandardError\)}
|
217
|
+
so.read.should == ''
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should define ZOZO environment variable when running under zozo" do
|
222
|
+
run('test_zozo').should == 'no_error'
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context "zozo -b and -l arguments" do
|
227
|
+
after do
|
228
|
+
FileUtils.rm_r('li')
|
229
|
+
FileUtils.rm_r('bi')
|
230
|
+
end
|
231
|
+
|
232
|
+
def should_be_same(f1, f2)
|
233
|
+
File.read(f1).should == File.read(f2)
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should create bin and lib directories with given names" do
|
237
|
+
`#{File.join(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__)))), 'bin', 'zozo')} -b bi -l li test1`
|
238
|
+
File.file?('li/a').should be_true
|
239
|
+
File.symlink?('li/a').should be_true
|
240
|
+
should_be_same('li/a', 'test1/a')
|
241
|
+
File.directory?('li/b').should be_true
|
242
|
+
File.file?('li/b/c').should be_true
|
243
|
+
File.symlink?('li/b/c').should be_true
|
244
|
+
should_be_same('li/b/c', 'test1/b/c')
|
245
|
+
|
246
|
+
File.file?('bi/b1').should be_true
|
247
|
+
File.symlink?('bi/b1').should be_true
|
248
|
+
should_be_same('bi/b1', 'b/bin/b1')
|
249
|
+
File.directory?('bi/d').should be_true
|
250
|
+
File.file?('bi/d/b2').should be_true
|
251
|
+
File.symlink?('bi/d/b2').should be_true
|
252
|
+
should_be_same('bi/d/b2', 'b/bin/d/b2')
|
253
|
+
end
|
254
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zozo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jeremy Evans
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-01 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: code@jeremyevans.net
|
24
|
+
executables:
|
25
|
+
- zozo
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.rdoc
|
30
|
+
- LICENSE
|
31
|
+
- bin/zozo
|
32
|
+
files:
|
33
|
+
- README.rdoc
|
34
|
+
- LICENSE
|
35
|
+
- bin/zozo
|
36
|
+
- spec/zozo_spec.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/jeremyevans/zozo
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --quiet
|
44
|
+
- --line-numbers
|
45
|
+
- --inline-source
|
46
|
+
- --title
|
47
|
+
- "zozo: Simple $LOAD_PATH management for ruby projects"
|
48
|
+
- --main
|
49
|
+
- README.rdoc
|
50
|
+
require_paths:
|
51
|
+
- bin
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
hash: 3
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.7
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Simple $LOAD_PATH management for ruby projects
|
77
|
+
test_files:
|
78
|
+
- spec/zozo_spec.rb
|