pairing with luke, nagios_command provider skeleton
[vinpup.git] / install.rb
blob6c418119bcbb7ff44da882958d9f0981aecd608c
1 #! /usr/bin/env ruby
2 #--
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.
10 # Usage
11 # -----
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
17 #   tests/  # unit tests
19 # The default behaviour:
20 # 1) Run all unit test files (ending in .rb) found in all directories under
21 #    tests/.
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.
33 #++
35 require 'rbconfig'
36 require 'find'
37 require 'fileutils'
38 require 'ftools' # apparently on some system ftools doesn't get loaded
39 require 'optparse'
40 require 'ostruct'
42 begin
43     require 'rdoc/rdoc'
44     $haverdoc = true
45 rescue LoadError
46     puts "Missing rdoc; skipping documentation"
47     $haverdoc = false
48 end
50 PREREQS = %w{openssl facter xmlrpc/client xmlrpc/server cgi}
52 InstallOptions = OpenStruct.new
54 def glob(list)
55     g = list.map { |i| Dir.glob(i) }
56     g.flatten!
57     g.compact!
58     g.reject! { |e| e =~ /\.svn/ }
59     g
60 end
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/')
71   bins.each do |bf|
72     obf = bf.gsub(/#{strip}/, '')
73     install_binfile(bf, obf, target)
74   end
75 end
77 def do_libs(libs, strip = 'lib/')
78   libs.each do |lf|
79     olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
80     op = File.dirname(olf)
81     File.makedirs(op, true)
82     File.chmod(0755, op)
83     File.install(lf, olf, 0755, true)
84   end
85 end
87 # Verify that all of the prereqs are installed
88 def check_prereqs
89     PREREQS.each { |pre|
90         begin
91             require pre
92         rescue LoadError
93             puts "Could not load %s; cannot install" % pre
94             exit -1
95         end
96     }
97 end
100 # Prepare the file installation.
102 def prepare_installation
103   # Only try to do docs if we're sure they have rdoc
104   if $haverdoc
105       InstallOptions.rdoc  = true
106       if RUBY_PLATFORM == "i386-mswin32"
107         InstallOptions.ri  = false
108       else
109         InstallOptions.ri  = true
110       end
111   else
112       InstallOptions.rdoc  = false
113       InstallOptions.ri  = false
114   end
115   InstallOptions.tests = true
117   ARGV.options do |opts|
118     opts.banner = "Usage: #{File.basename($0)} [options]"
119     opts.separator ""
120     opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
121       InstallOptions.rdoc = onrdoc
122     end
123     opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
124       InstallOptions.ri = onri
125     end
126     opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
127       InstallOptions.tests = ontest
128     end
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
133     end
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
138     end
139     opts.separator("")
140     opts.on_tail('--help', "Shows this help text.") do
141       $stderr.puts opts
142       exit
143     end
145     opts.parse!
146   end
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"]
154   if sitelibdir.nil?
155     sitelibdir = $:.find { |x| x =~ /site_ruby/ }
156     if sitelibdir.nil?
157       sitelibdir = File.join(libdir, "site_ruby")
158     elsif sitelibdir !~ Regexp.quote(version)
159       sitelibdir = File.join(sitelibdir, version)
160     end
161   end
163   if (destdir = ENV['DESTDIR'])
164     bindir = "#{destdir}#{Config::CONFIG['bindir']}"
165     sbindir = "#{destdir}#{Config::CONFIG['sbindir']}"
166     sitelibdir = "#{destdir}#{sitelibdir}"
167     tmpdirs << bindir
169     FileUtils.makedirs(bindir)
170     FileUtils.makedirs(sbindir)
171     FileUtils.makedirs(sitelibdir)
172   else
173     bindir = Config::CONFIG['bindir']
174     sbindir = Config::CONFIG['sbindir']
175     tmpdirs << Config::CONFIG['bindir']
176   end
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
190     begin
191         r = RDoc::RDoc.new
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}"
198     end
201 def build_ri(files)
202     return unless $haverdoc
203     begin
204         ri = RDoc::RDoc.new
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..."
212     end
215 def run_tests(test_list)
216         begin
217                 require 'test/unit/ui/console/testrunner'
218                 $:.unshift "lib"
219                 test_list.each do |test|
220                 next if File.directory?(test)
221                 require test
222                 end
224                 tests = []
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) }
230                 $:.shift
231         rescue LoadError
232                 puts "Missing testrunner library; skipping tests"
233         end
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)
242   tmp_dir = nil
243   InstallOptions.tmp_dirs.each do |t|
244     if File.directory?(t) and File.writable?(t)
245       tmp_dir = t
246       break
247     end
248   end
249   
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'])
257       op.puts "#!#{ruby}"
258       contents = ip.readlines
259       if contents[0] =~ /^#!/
260           contents.shift
261       end
262       op.write contents.join()
263     end
264   end
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
272     end
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
277     end
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
289     end
290   end
291   FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
292   File.unlink(tmp_file)
295 CMD_WRAPPER = <<-EOS
296 @echo off
297 if "%OS%"=="Windows_NT" goto WinNT
298 <ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
299 goto done
300 :WinNT
301 <ruby> -x "<command>" %*
302 goto done
303 :done
306 check_prereqs
307 prepare_installation
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)
314 do_libs(libs)