3 # Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
4 # Install utility. Based on the original installation script for rdoc by the
5 # Pragmatic Programmers.
7 # This program is free software. It may be redistributed and/or modified under
8 # the terms of the GPL version 2 (or later) or the Ruby licence.
12 # In most cases, if you have a typical project layout, you will need to do
13 # absolutely nothing to make this work for you. This layout is:
15 # bin/ # executable files -- "commands"
16 # lib/ # the source of the library
19 # The default behaviour:
20 # 1) Run all unit test files (ending in .rb) found in all directories under
22 # 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
23 # all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
24 # 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
25 # and all .rb files in lib/. This is disabled by default on Win32.
26 # 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
27 # if a corresponding batch file (.bat or .cmd) exists in the bin directory,
28 # it will be copied over as well. Otherwise, a batch file (always .bat) will
29 # be created to run the specified command.
30 # 5) Install all library files ending in .rb from lib/ into Ruby's
31 # site_lib/version directory.
38 require 'ftools' # apparently on some system ftools doesn't get loaded
46 puts "Missing rdoc; skipping documentation"
50 PREREQS = %w{openssl facter xmlrpc/client xmlrpc/server cgi}
52 InstallOptions = OpenStruct.new
55 g = list.map { |i| Dir.glob(i) }
58 g.reject! { |e| e =~ /\.svn/ }
62 # Set these values to what you want installed.
63 sbins = glob(%w{sbin/*})
64 bins = glob(%w{bin/*})
65 rdoc = glob(%w{bin/* sbin/* lib/**/*.rb README README-library CHANGELOG TODO Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
66 ri = glob(%w(bin/*.rb sbin/* lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
67 libs = glob(%w{lib/**/*.rb lib/**/*.py})
68 tests = glob(%w{tests/**/*.rb})
70 def do_bins(bins, target, strip = 's?bin/')
72 obf = bf.gsub(/#{strip}/, '')
73 install_binfile(bf, obf, target)
77 def do_libs(libs, strip = 'lib/')
79 olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
80 op = File.dirname(olf)
81 File.makedirs(op, true)
83 File.install(lf, olf, 0755, true)
87 # Verify that all of the prereqs are installed
93 puts "Could not load %s; cannot install" % pre
100 # Prepare the file installation.
102 def prepare_installation
103 # Only try to do docs if we're sure they have rdoc
105 InstallOptions.rdoc = true
106 if RUBY_PLATFORM == "i386-mswin32"
107 InstallOptions.ri = false
109 InstallOptions.ri = true
112 InstallOptions.rdoc = false
113 InstallOptions.ri = false
115 InstallOptions.tests = true
117 ARGV.options do |opts|
118 opts.banner = "Usage: #{File.basename($0)} [options]"
120 opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
121 InstallOptions.rdoc = onrdoc
123 opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
124 InstallOptions.ri = onri
126 opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
127 InstallOptions.tests = ontest
129 opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
130 InstallOptions.rdoc = false
131 InstallOptions.ri = false
132 InstallOptions.tests = false
134 opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
135 InstallOptions.rdoc = true
136 InstallOptions.ri = true
137 InstallOptions.tests = true
140 opts.on_tail('--help', "Shows this help text.") do
148 tmpdirs = [".", ENV['TMP'], ENV['TEMP'], "/tmp", "/var/tmp"]
150 version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
151 libdir = File.join(Config::CONFIG["libdir"], "ruby", version)
153 sitelibdir = Config::CONFIG["sitelibdir"]
155 sitelibdir = $:.find { |x| x =~ /site_ruby/ }
157 sitelibdir = File.join(libdir, "site_ruby")
158 elsif sitelibdir !~ Regexp.quote(version)
159 sitelibdir = File.join(sitelibdir, version)
163 if (destdir = ENV['DESTDIR'])
164 bindir = "#{destdir}#{Config::CONFIG['bindir']}"
165 sbindir = "#{destdir}#{Config::CONFIG['sbindir']}"
166 sitelibdir = "#{destdir}#{sitelibdir}"
169 FileUtils.makedirs(bindir)
170 FileUtils.makedirs(sbindir)
171 FileUtils.makedirs(sitelibdir)
173 bindir = Config::CONFIG['bindir']
174 sbindir = Config::CONFIG['sbindir']
175 tmpdirs << Config::CONFIG['bindir']
178 InstallOptions.tmp_dirs = tmpdirs.compact
179 InstallOptions.site_dir = sitelibdir
180 InstallOptions.bin_dir = bindir
181 InstallOptions.sbin_dir = sbindir
182 InstallOptions.lib_dir = libdir
186 # Build the rdoc documentation. Also, try to build the RI documentation.
188 def build_rdoc(files)
189 return unless $haverdoc
192 r.document(["--main", "README", "--title",
193 "Puppet -- Site Configuration Management", "--line-numbers"] + files)
194 rescue RDoc::RDocError => e
195 $stderr.puts e.message
196 rescue Exception => e
197 $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
202 return unless $haverdoc
205 #ri.document(["--ri-site", "--merge"] + files)
206 ri.document(["--ri-site"] + files)
207 rescue RDoc::RDocError => e
208 $stderr.puts e.message
209 rescue Exception => e
210 $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
211 $stderr.puts "Continuing with install..."
215 def run_tests(test_list)
217 require 'test/unit/ui/console/testrunner'
219 test_list.each do |test|
220 next if File.directory?(test)
225 ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
226 tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
227 tests.delete_if { |o| o == Test::Unit::TestCase }
229 tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
232 puts "Missing testrunner library; skipping tests"
237 # Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
238 # to insert a #! line; on a Unix install, the command is named as expected
239 # (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
240 # windows, we add an '.rb' extension and let file associations do their stuff.
241 def install_binfile(from, op_file, target)
243 InstallOptions.tmp_dirs.each do |t|
244 if File.directory?(t) and File.writable?(t)
250 fail "Cannot find a temporary directory" unless tmp_dir
251 tmp_file = File.join(tmp_dir, '_tmp')
252 ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
254 File.open(from) do |ip|
255 File.open(tmp_file, "w") do |op|
256 ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
258 contents = ip.readlines
259 if contents[0] =~ /^#!/
262 op.write contents.join()
266 if Config::CONFIG["target_os"] =~ /win/io and Config::CONFIG["target_os"] !~ /darwin/io
267 installed_wrapper = false
269 if File.exists?("#{from}.bat")
270 FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
271 installed_wrapper = true
274 if File.exists?("#{from}.cmd")
275 FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
276 installed_wrapper = true
279 if not installed_wrapper
280 tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
281 cwn = File.join(Config::CONFIG['bindir'], op_file)
282 cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
284 File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
285 FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
287 File.unlink(tmp_file2)
288 installed_wrapper = true
291 FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
292 File.unlink(tmp_file)
297 if "%OS%"=="Windows_NT" goto WinNT
298 <ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
301 <ruby> -x "<command>" %*
309 run_tests(tests) if InstallOptions.tests
310 #build_rdoc(rdoc) if InstallOptions.rdoc
311 #build_ri(ri) if InstallOptions.ri
312 do_bins(sbins, InstallOptions.sbin_dir)
313 do_bins(bins, InstallOptions.bin_dir)