Skip to content
This repository
Browse code

Initial Commit

Initial commit - only contains newgem scaffolding.
  • Loading branch information...
commit 2732bbe213db899bf19aa5e372d9cc2d33b0cfff 0 parents
Mat Brown authored
4 History.txt
... ... @@ -0,0 +1,4 @@
  1 +== 0.0.1 2008-10-13
  2 +
  3 +* 1 major enhancement:
  4 + * Initial release
24 Manifest.txt
... ... @@ -0,0 +1,24 @@
  1 +History.txt
  2 +Manifest.txt
  3 +PostInstall.txt
  4 +README.rdoc
  5 +Rakefile
  6 +config/hoe.rb
  7 +config/requirements.rb
  8 +lib/sunspot.rb
  9 +lib/sunspot/version.rb
  10 +script/console
  11 +script/destroy
  12 +script/generate
  13 +script/txt2html
  14 +setup.rb
  15 +tasks/deployment.rake
  16 +tasks/environment.rake
  17 +tasks/website.rake
  18 +test/test_helper.rb
  19 +test/test_sunspot.rb
  20 +website/index.html
  21 +website/index.txt
  22 +website/javascripts/rounded_corners_lite.inc.js
  23 +website/stylesheets/screen.css
  24 +website/template.html.erb
7 PostInstall.txt
... ... @@ -0,0 +1,7 @@
  1 +
  2 +For more information on sunspot, see http://sunspot.rubyforge.org
  3 +
  4 +NOTE: Change this information in PostInstall.txt
  5 +You can also delete it if you don't want it.
  6 +
  7 +
48 README.rdoc
Source Rendered
... ... @@ -0,0 +1,48 @@
  1 += sunspot
  2 +
  3 +* FIX (url)
  4 +
  5 +== DESCRIPTION:
  6 +
  7 +FIX (describe your package)
  8 +
  9 +== FEATURES/PROBLEMS:
  10 +
  11 +* FIX (list of features or problems)
  12 +
  13 +== SYNOPSIS:
  14 +
  15 + FIX (code sample of usage)
  16 +
  17 +== REQUIREMENTS:
  18 +
  19 +* FIX (list of requirements)
  20 +
  21 +== INSTALL:
  22 +
  23 +* FIX (sudo gem install, anything else)
  24 +
  25 +== LICENSE:
  26 +
  27 +(The MIT License)
  28 +
  29 +Copyright (c) 2008 Mat Brown
  30 +
  31 +Permission is hereby granted, free of charge, to any person obtaining
  32 +a copy of this software and associated documentation files (the
  33 +'Software'), to deal in the Software without restriction, including
  34 +without limitation the rights to use, copy, modify, merge, publish,
  35 +distribute, sublicense, and/or sell copies of the Software, and to
  36 +permit persons to whom the Software is furnished to do so, subject to
  37 +the following conditions:
  38 +
  39 +The above copyright notice and this permission notice shall be
  40 +included in all copies or substantial portions of the Software.
  41 +
  42 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  43 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  44 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  45 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  46 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  47 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  48 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4 Rakefile
... ... @@ -0,0 +1,4 @@
  1 +require 'config/requirements'
  2 +require 'config/hoe' # setup Hoe + all gem configuration
  3 +
  4 +Dir['tasks/**/*.rake'].each { |rake| load rake }
73 config/hoe.rb
... ... @@ -0,0 +1,73 @@
  1 +require 'sunspot/version'
  2 +
  3 +AUTHOR = 'Mat Brown' # can also be an array of Authors
  4 +EMAIL = "mat@patch.com"
  5 +DESCRIPTION = "description of gem"
  6 +GEM_NAME = 'sunspot' # what ppl will type to install your gem
  7 +RUBYFORGE_PROJECT = 'sunspot' # The unix name for your project
  8 +HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
  9 +DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
  10 +EXTRA_DEPENDENCIES = [
  11 +# ['activesupport', '>= 1.3.1']
  12 +] # An array of rubygem dependencies [name, version]
  13 +
  14 +@config_file = "~/.rubyforge/user-config.yml"
  15 +@config = nil
  16 +RUBYFORGE_USERNAME = "unknown"
  17 +def rubyforge_username
  18 + unless @config
  19 + begin
  20 + @config = YAML.load(File.read(File.expand_path(@config_file)))
  21 + rescue
  22 + puts <<-EOS
  23 +ERROR: No rubyforge config file found: #{@config_file}
  24 +Run 'rubyforge setup' to prepare your env for access to Rubyforge
  25 + - See http://newgem.rubyforge.org/rubyforge.html for more details
  26 + EOS
  27 + exit
  28 + end
  29 + end
  30 + RUBYFORGE_USERNAME.replace @config["username"]
  31 +end
  32 +
  33 +
  34 +REV = nil
  35 +# UNCOMMENT IF REQUIRED:
  36 +# REV = YAML.load(`svn info`)['Revision']
  37 +VERS = Sunspot::VERSION::STRING + (REV ? ".#{REV}" : "")
  38 +RDOC_OPTS = ['--quiet', '--title', 'sunspot documentation',
  39 + "--opname", "index.html",
  40 + "--line-numbers",
  41 + "--main", "README",
  42 + "--inline-source"]
  43 +
  44 +class Hoe
  45 + def extra_deps
  46 + @extra_deps.reject! { |x| Array(x).first == 'hoe' }
  47 + @extra_deps
  48 + end
  49 +end
  50 +
  51 +# Generate all the Rake tasks
  52 +# Run 'rake -T' to see list of generated tasks (from gem root directory)
  53 +$hoe = Hoe.new(GEM_NAME, VERS) do |p|
  54 + p.developer(AUTHOR, EMAIL)
  55 + p.description = DESCRIPTION
  56 + p.summary = DESCRIPTION
  57 + p.url = HOMEPATH
  58 + p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
  59 + p.test_globs = ["test/**/test_*.rb"]
  60 + p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
  61 +
  62 + # == Optional
  63 + p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
  64 + #p.extra_deps = EXTRA_DEPENDENCIES
  65 +
  66 + #p.spec_extras = {} # A hash of extra values to set in the gemspec.
  67 + end
  68 +
  69 +CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
  70 +PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
  71 +$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
  72 +$hoe.rsync_args = '-av --delete --ignore-errors'
  73 +$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
15 config/requirements.rb
... ... @@ -0,0 +1,15 @@
  1 +require 'fileutils'
  2 +include FileUtils
  3 +
  4 +require 'rubygems'
  5 +%w[rake hoe newgem rubigen].each do |req_gem|
  6 + begin
  7 + require req_gem
  8 + rescue LoadError
  9 + puts "This Rakefile requires the '#{req_gem}' RubyGem."
  10 + puts "Installation: gem install #{req_gem} -y"
  11 + exit
  12 + end
  13 +end
  14 +
  15 +$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
6 lib/sunspot.rb
... ... @@ -0,0 +1,6 @@
  1 +$:.unshift(File.dirname(__FILE__)) unless
  2 + $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
  3 +
  4 +module Sunspot
  5 +
  6 +end
10 lib/sunspot/version.rb
... ... @@ -0,0 +1,10 @@
  1 +module Sunspot
  2 + module VERSION #:nodoc:
  3 + MAJOR = 0
  4 + MINOR = 0
  5 + TINY = 1
  6 +
  7 + STRING = [MAJOR, MINOR, TINY].join('.')
  8 + self
  9 + end
  10 +end
10 script/console
... ... @@ -0,0 +1,10 @@
  1 +#!/usr/bin/env ruby
  2 +# File: script/console
  3 +irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
  4 +
  5 +libs = " -r irb/completion"
  6 +# Perhaps use a console_lib to store any extra methods I may want available in the cosole
  7 +# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
  8 +libs << " -r #{File.dirname(__FILE__) + '/../lib/sunspot.rb'}"
  9 +puts "Loading sunspot gem"
  10 +exec "#{irb} #{libs} --simple-prompt"
14 script/destroy
... ... @@ -0,0 +1,14 @@
  1 +#!/usr/bin/env ruby
  2 +APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
  3 +
  4 +begin
  5 + require 'rubigen'
  6 +rescue LoadError
  7 + require 'rubygems'
  8 + require 'rubigen'
  9 +end
  10 +require 'rubigen/scripts/destroy'
  11 +
  12 +ARGV.shift if ['--help', '-h'].include?(ARGV[0])
  13 +RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
  14 +RubiGen::Scripts::Destroy.new.run(ARGV)
14 script/generate
... ... @@ -0,0 +1,14 @@
  1 +#!/usr/bin/env ruby
  2 +APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
  3 +
  4 +begin
  5 + require 'rubigen'
  6 +rescue LoadError
  7 + require 'rubygems'
  8 + require 'rubigen'
  9 +end
  10 +require 'rubigen/scripts/generate'
  11 +
  12 +ARGV.shift if ['--help', '-h'].include?(ARGV[0])
  13 +RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
  14 +RubiGen::Scripts::Generate.new.run(ARGV)
82 script/txt2html
... ... @@ -0,0 +1,82 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +GEM_NAME = 'sunspot' # what ppl will type to install your gem
  4 +RUBYFORGE_PROJECT = 'sunspot'
  5 +
  6 +require 'rubygems'
  7 +begin
  8 + require 'newgem'
  9 + require 'rubyforge'
  10 +rescue LoadError
  11 + puts "\n\nGenerating the website requires the newgem RubyGem"
  12 + puts "Install: gem install newgem\n\n"
  13 + exit(1)
  14 +end
  15 +require 'redcloth'
  16 +require 'syntax/convertors/html'
  17 +require 'erb'
  18 +require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}/version.rb"
  19 +
  20 +version = Sunspot::VERSION::STRING
  21 +download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
  22 +
  23 +def rubyforge_project_id
  24 + RubyForge.new.configure.autoconfig["group_ids"][RUBYFORGE_PROJECT]
  25 +end
  26 +
  27 +class Fixnum
  28 + def ordinal
  29 + # teens
  30 + return 'th' if (10..19).include?(self % 100)
  31 + # others
  32 + case self % 10
  33 + when 1: return 'st'
  34 + when 2: return 'nd'
  35 + when 3: return 'rd'
  36 + else return 'th'
  37 + end
  38 + end
  39 +end
  40 +
  41 +class Time
  42 + def pretty
  43 + return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
  44 + end
  45 +end
  46 +
  47 +def convert_syntax(syntax, source)
  48 + return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
  49 +end
  50 +
  51 +if ARGV.length >= 1
  52 + src, template = ARGV
  53 + template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
  54 +else
  55 + puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
  56 + exit!
  57 +end
  58 +
  59 +template = ERB.new(File.open(template).read)
  60 +
  61 +title = nil
  62 +body = nil
  63 +File.open(src) do |fsrc|
  64 + title_text = fsrc.readline
  65 + body_text_template = fsrc.read
  66 + body_text = ERB.new(body_text_template).result(binding)
  67 + syntax_items = []
  68 + body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
  69 + ident = syntax_items.length
  70 + element, syntax, source = $1, $2, $3
  71 + syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
  72 + "syntax-temp-#{ident}"
  73 + }
  74 + title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
  75 + body = RedCloth.new(body_text).to_html
  76 + body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
  77 +end
  78 +stat = File.stat(src)
  79 +created = stat.ctime
  80 +modified = stat.mtime
  81 +
  82 +$stdout << template.result(binding)
1,585 setup.rb
... ... @@ -0,0 +1,1585 @@
  1 +#
  2 +# setup.rb
  3 +#
  4 +# Copyright (c) 2000-2005 Minero Aoki
  5 +#
  6 +# This program is free software.
  7 +# You can distribute/modify this program under the terms of
  8 +# the GNU LGPL, Lesser General Public License version 2.1.
  9 +#
  10 +
  11 +unless Enumerable.method_defined?(:map) # Ruby 1.4.6
  12 + module Enumerable
  13 + alias map collect
  14 + end
  15 +end
  16 +
  17 +unless File.respond_to?(:read) # Ruby 1.6
  18 + def File.read(fname)
  19 + open(fname) {|f|
  20 + return f.read
  21 + }
  22 + end
  23 +end
  24 +
  25 +unless Errno.const_defined?(:ENOTEMPTY) # Windows?
  26 + module Errno
  27 + class ENOTEMPTY
  28 + # We do not raise this exception, implementation is not needed.
  29 + end
  30 + end
  31 +end
  32 +
  33 +def File.binread(fname)
  34 + open(fname, 'rb') {|f|
  35 + return f.read
  36 + }
  37 +end
  38 +
  39 +# for corrupted Windows' stat(2)
  40 +def File.dir?(path)
  41 + File.directory?((path[-1,1] == '/') ? path : path + '/')
  42 +end
  43 +
  44 +
  45 +class ConfigTable
  46 +
  47 + include Enumerable
  48 +
  49 + def initialize(rbconfig)
  50 + @rbconfig = rbconfig
  51 + @items = []
  52 + @table = {}
  53 + # options
  54 + @install_prefix = nil
  55 + @config_opt = nil
  56 + @verbose = true
  57 + @no_harm = false
  58 + end
  59 +
  60 + attr_accessor :install_prefix
  61 + attr_accessor :config_opt
  62 +
  63 + attr_writer :verbose
  64 +
  65 + def verbose?
  66 + @verbose
  67 + end
  68 +
  69 + attr_writer :no_harm
  70 +
  71 + def no_harm?
  72 + @no_harm
  73 + end
  74 +
  75 + def [](key)
  76 + lookup(key).resolve(self)
  77 + end
  78 +
  79 + def []=(key, val)
  80 + lookup(key).set val
  81 + end
  82 +
  83 + def names
  84 + @items.map {|i| i.name }
  85 + end
  86 +
  87 + def each(&block)
  88 + @items.each(&block)
  89 + end
  90 +
  91 + def key?(name)
  92 + @table.key?(name)
  93 + end
  94 +
  95 + def lookup(name)
  96 + @table[name] or setup_rb_error "no such config item: #{name}"
  97 + end
  98 +
  99 + def add(item)
  100 + @items.push item
  101 + @table[item.name] = item
  102 + end
  103 +
  104 + def remove(name)
  105 + item = lookup(name)
  106 + @items.delete_if {|i| i.name == name }
  107 + @table.delete_if {|name, i| i.name == name }
  108 + item
  109 + end
  110 +
  111 + def load_script(path, inst = nil)
  112 + if File.file?(path)
  113 + MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
  114 + end
  115 + end
  116 +
  117 + def savefile
  118 + '.config'
  119 + end
  120 +
  121 + def load_savefile
  122 + begin
  123 + File.foreach(savefile()) do |line|
  124 + k, v = *line.split(/=/, 2)
  125 + self[k] = v.strip
  126 + end
  127 + rescue Errno::ENOENT
  128 + setup_rb_error $!.message + "\n#{File.basename($0)} config first"
  129 + end
  130 + end
  131 +
  132 + def save
  133 + @items.each {|i| i.value }
  134 + File.open(savefile(), 'w') {|f|
  135 + @items.each do |i|
  136 + f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
  137 + end
  138 + }
  139 + end
  140 +
  141 + def load_standard_entries
  142 + standard_entries(@rbconfig).each do |ent|
  143 + add ent
  144 + end
  145 + end
  146 +
  147 + def standard_entries(rbconfig)
  148 + c = rbconfig
  149 +
  150 + rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
  151 +
  152 + major = c['MAJOR'].to_i
  153 + minor = c['MINOR'].to_i
  154 + teeny = c['TEENY'].to_i
  155 + version = "#{major}.#{minor}"
  156 +
  157 + # ruby ver. >= 1.4.4?
  158 + newpath_p = ((major >= 2) or
  159 + ((major == 1) and
  160 + ((minor >= 5) or
  161 + ((minor == 4) and (teeny >= 4)))))
  162 +
  163 + if c['rubylibdir']
  164 + # V > 1.6.3
  165 + libruby = "#{c['prefix']}/lib/ruby"
  166 + librubyver = c['rubylibdir']
  167 + librubyverarch = c['archdir']
  168 + siteruby = c['sitedir']
  169 + siterubyver = c['sitelibdir']
  170 + siterubyverarch = c['sitearchdir']
  171 + elsif newpath_p
  172 + # 1.4.4 <= V <= 1.6.3
  173 + libruby = "#{c['prefix']}/lib/ruby"
  174 + librubyver = "#{c['prefix']}/lib/ruby/#{version}"
  175 + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
  176 + siteruby = c['sitedir']
  177 + siterubyver = "$siteruby/#{version}"
  178 + siterubyverarch = "$siterubyver/#{c['arch']}"
  179 + else
  180 + # V < 1.4.4
  181 + libruby = "#{c['prefix']}/lib/ruby"
  182 + librubyver = "#{c['prefix']}/lib/ruby/#{version}"
  183 + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
  184 + siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
  185 + siterubyver = siteruby
  186 + siterubyverarch = "$siterubyver/#{c['arch']}"
  187 + end
  188 + parameterize = lambda {|path|
  189 + path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
  190 + }
  191 +
  192 + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
  193 + makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
  194 + else
  195 + makeprog = 'make'
  196 + end
  197 +
  198 + [
  199 + ExecItem.new('installdirs', 'std/site/home',
  200 + 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
  201 + {|val, table|
  202 + case val
  203 + when 'std'
  204 + table['rbdir'] = '$librubyver'
  205 + table['sodir'] = '$librubyverarch'
  206 + when 'site'
  207 + table['rbdir'] = '$siterubyver'
  208 + table['sodir'] = '$siterubyverarch'
  209 + when 'home'
  210 + setup_rb_error '$HOME was not set' unless ENV['HOME']
  211 + table['prefix'] = ENV['HOME']
  212 + table['rbdir'] = '$libdir/ruby'
  213 + table['sodir'] = '$libdir/ruby'
  214 + end
  215 + },
  216 + PathItem.new('prefix', 'path', c['prefix'],
  217 + 'path prefix of target environment'),
  218 + PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
  219 + 'the directory for commands'),
  220 + PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
  221 + 'the directory for libraries'),
  222 + PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
  223 + 'the directory for shared data'),
  224 + PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
  225 + 'the directory for man pages'),
  226 + PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
  227 + 'the directory for system configuration files'),
  228 + PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
  229 + 'the directory for local state data'),
  230 + PathItem.new('libruby', 'path', libruby,
  231 + 'the directory for ruby libraries'),
  232 + PathItem.new('librubyver', 'path', librubyver,
  233 + 'the directory for standard ruby libraries'),
  234 + PathItem.new('librubyverarch', 'path', librubyverarch,
  235 + 'the directory for standard ruby extensions'),
  236 + PathItem.new('siteruby', 'path', siteruby,
  237 + 'the directory for version-independent aux ruby libraries'),
  238 + PathItem.new('siterubyver', 'path', siterubyver,
  239 + 'the directory for aux ruby libraries'),
  240 + PathItem.new('siterubyverarch', 'path', siterubyverarch,
  241 + 'the directory for aux ruby binaries'),
  242 + PathItem.new('rbdir', 'path', '$siterubyver',
  243 + 'the directory for ruby scripts'),
  244 + PathItem.new('sodir', 'path', '$siterubyverarch',
  245 + 'the directory for ruby extentions'),
  246 + PathItem.new('rubypath', 'path', rubypath,
  247 + 'the path to set to #! line'),
  248 + ProgramItem.new('rubyprog', 'name', rubypath,
  249 + 'the ruby program using for installation'),
  250 + ProgramItem.new('makeprog', 'name', makeprog,
  251 + 'the make program to compile ruby extentions'),
  252 + SelectItem.new('shebang', 'all/ruby/never', 'ruby',
  253 + 'shebang line (#!) editing mode'),
  254 + BoolItem.new('without-ext', 'yes/no', 'no',
  255 + 'does not compile/install ruby extentions')
  256 + ]
  257 + end
  258 + private :standard_entries
  259 +
  260 + def load_multipackage_entries
  261 + multipackage_entries().each do |ent|
  262 + add ent
  263 + end
  264 + end
  265 +
  266 + def multipackage_entries
  267 + [
  268 + PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
  269 + 'package names that you want to install'),
  270 + PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
  271 + 'package names that you do not want to install')
  272 + ]
  273 + end
  274 + private :multipackage_entries
  275 +
  276 + ALIASES = {
  277 + 'std-ruby' => 'librubyver',
  278 + 'stdruby' => 'librubyver',
  279 + 'rubylibdir' => 'librubyver',
  280 + 'archdir' => 'librubyverarch',
  281 + 'site-ruby-common' => 'siteruby', # For backward compatibility
  282 + 'site-ruby' => 'siterubyver', # For backward compatibility
  283 + 'bin-dir' => 'bindir',
  284 + 'bin-dir' => 'bindir',
  285 + 'rb-dir' => 'rbdir',
  286 + 'so-dir' => 'sodir',
  287 + 'data-dir' => 'datadir',
  288 + 'ruby-path' => 'rubypath',
  289 + 'ruby-prog' => 'rubyprog',
  290 + 'ruby' => 'rubyprog',
  291 + 'make-prog' => 'makeprog',
  292 + 'make' => 'makeprog'
  293 + }
  294 +
  295 + def fixup
  296 + ALIASES.each do |ali, name|
  297 + @table[ali] = @table[name]
  298 + end
  299 + @items.freeze
  300 + @table.freeze
  301 + @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
  302 + end
  303 +
  304 + def parse_opt(opt)
  305 + m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
  306 + m.to_a[1,2]
  307 + end
  308 +
  309 + def dllext
  310 + @rbconfig['DLEXT']
  311 + end
  312 +
  313 + def value_config?(name)
  314 + lookup(name).value?
  315 + end
  316 +
  317 + class Item
  318 + def initialize(name, template, default, desc)
  319 + @name = name.freeze
  320 + @template = template
  321 + @value = default
  322 + @default = default
  323 + @description = desc
  324 + end
  325 +
  326 + attr_reader :name
  327 + attr_reader :description
  328 +
  329 + attr_accessor :default
  330 + alias help_default default
  331 +
  332 + def help_opt
  333 + "--#{@name}=#{@template}"
  334 + end
  335 +
  336 + def value?
  337 + true
  338 + end
  339 +
  340 + def value
  341 + @value
  342 + end
  343 +
  344 + def resolve(table)
  345 + @value.gsub(%r<\$([^/]+)>) { table[$1] }
  346 + end
  347 +
  348 + def set(val)
  349 + @value = check(val)
  350 + end
  351 +
  352 + private
  353 +
  354 + def check(val)
  355 + setup_rb_error "config: --#{name} requires argument" unless val
  356 + val
  357 + end
  358 + end
  359 +
  360 + class BoolItem < Item
  361 + def config_type
  362 + 'bool'
  363 + end
  364 +
  365 + def help_opt
  366 + "--#{@name}"
  367 + end
  368 +
  369 + private
  370 +
  371 + def check(val)
  372 + return 'yes' unless val
  373 + case val
  374 + when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
  375 + when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
  376 + else
  377 + setup_rb_error "config: --#{@name} accepts only yes/no for argument"
  378 + end
  379 + end
  380 + end
  381 +
  382 + class PathItem < Item
  383 + def config_type
  384 + 'path'
  385 + end
  386 +
  387 + private
  388 +
  389 + def check(path)
  390 + setup_rb_error "config: --#{@name} requires argument" unless path
  391 + path[0,1] == '$' ? path : File.expand_path(path)
  392 + end
  393 + end
  394 +
  395 + class ProgramItem < Item
  396 + def config_type
  397 + 'program'
  398 + end
  399 + end
  400 +
  401 + class SelectItem < Item
  402 + def initialize(name, selection, default, desc)
  403 + super
  404 + @ok = selection.split('/')
  405 + end
  406 +
  407 + def config_type
  408 + 'select'
  409 + end
  410 +
  411 + private
  412 +
  413 + def check(val)
  414 + unless @ok.include?(val.strip)
  415 + setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
  416 + end
  417 + val.strip
  418 + end
  419 + end
  420 +
  421 + class ExecItem < Item
  422 + def initialize(name, selection, desc, &block)
  423 + super name, selection, nil, desc
  424 + @ok = selection.split('/')
  425 + @action = block
  426 + end
  427 +
  428 + def config_type
  429 + 'exec'
  430 + end
  431 +
  432 + def value?
  433 + false
  434 + end
  435 +
  436 + def resolve(table)
  437 + setup_rb_error "$#{name()} wrongly used as option value"
  438 + end
  439 +
  440 + undef set
  441 +
  442 + def evaluate(val, table)
  443 + v = val.strip.downcase
  444 + unless @ok.include?(v)
  445 + setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
  446 + end
  447 + @action.call v, table
  448 + end
  449 + end
  450 +
  451 + class PackageSelectionItem < Item
  452 + def initialize(name, template, default, help_default, desc)
  453 + super name, template, default, desc
  454 + @help_default = help_default
  455 + end
  456 +
  457 + attr_reader :help_default
  458 +
  459 + def config_type
  460 + 'package'
  461 + end
  462 +
  463 + private
  464 +
  465 + def check(val)
  466 + unless File.dir?("packages/#{val}")
  467 + setup_rb_error "config: no such package: #{val}"
  468 + end
  469 + val
  470 + end
  471 + end
  472 +
  473 + class MetaConfigEnvironment
  474 + def initialize(config, installer)
  475 + @config = config
  476 + @installer = installer
  477 + end
  478 +
  479 + def config_names
  480 + @config.names
  481 + end
  482 +
  483 + def config?(name)
  484 + @config.key?(name)
  485 + end
  486 +
  487 + def bool_config?(name)
  488 + @config.lookup(name).config_type == 'bool'
  489 + end
  490 +
  491 + def path_config?(name)
  492 + @config.lookup(name).config_type == 'path'
  493 + end
  494 +
  495 + def value_config?(name)
  496 + @config.lookup(name).config_type != 'exec'
  497 + end
  498 +
  499 + def add_config(item)
  500 + @config.add item
  501 + end
  502 +
  503 + def add_bool_config(name, default, desc)
  504 + @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
  505 + end
  506 +
  507 + def add_path_config(name, default, desc)
  508 + @config.add PathItem.new(name, 'path', default, desc)
  509 + end
  510 +
  511 + def set_config_default(name, default)
  512 + @config.lookup(name).default = default
  513 + end
  514 +
  515 + def remove_config(name)
  516 + @config.remove(name)
  517 + end
  518 +
  519 + # For only multipackage
  520 + def packages
  521 + raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
  522 + @installer.packages
  523 + end
  524 +
  525 + # For only multipackage
  526 + def declare_packages(list)
  527 + raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
  528 + @installer.packages = list
  529 + end
  530 + end
  531 +
  532 +end # class ConfigTable
  533 +
  534 +
  535 +# This module requires: #verbose?, #no_harm?
  536 +module FileOperations
  537 +
  538 + def mkdir_p(dirname, prefix = nil)
  539 + dirname = prefix + File.expand_path(dirname) if prefix
  540 + $stderr.puts "mkdir -p #{dirname}" if verbose?
  541 + return if no_harm?
  542 +
  543 + # Does not check '/', it's too abnormal.
  544 + dirs = File.expand_path(dirname).split(%r<(?=/)>)
  545 + if /\A[a-z]:\z/i =~ dirs[0]
  546 + disk = dirs.shift
  547 + dirs[0] = disk + dirs[0]
  548 + end
  549 + dirs.each_index do |idx|
  550 + path = dirs[0..idx].join('')
  551 + Dir.mkdir path unless File.dir?(path)
  552 + end
  553 + end
  554 +
  555 + def rm_f(path)
  556 + $stderr.puts "rm -f #{path}" if verbose?
  557 + return if no_harm?
  558 + force_remove_file path
  559 + end
  560 +
  561 + def rm_rf(path)
  562 + $stderr.puts "rm -rf #{path}" if verbose?
  563 + return if no_harm?
  564 + remove_tree path
  565 + end
  566 +
  567 + def remove_tree(path)
  568 + if File.symlink?(path)
  569 + remove_file path
  570 + elsif File.dir?(path)
  571 + remove_tree0 path
  572 + else
  573 + force_remove_file path
  574 + end
  575 + end
  576 +
  577 + def remove_tree0(path)
  578 + Dir.foreach(path) do |ent|
  579 + next if ent == '.'
  580 + next if ent == '..'
  581 + entpath = "#{path}/#{ent}"
  582 + if File.symlink?(entpath)
  583 + remove_file entpath
  584 + elsif File.dir?(entpath)
  585 + remove_tree0 entpath
  586 + else
  587 + force_remove_file entpath
  588 + end
  589 + end
  590 + begin
  591 + Dir.rmdir path
  592 + rescue Errno::ENOTEMPTY
  593 + # directory may not be empty
  594 + end
  595 + end
  596 +
  597 + def move_file(src, dest)
  598 + force_remove_file dest
  599 + begin
  600 + File.rename src, dest
  601 + rescue
  602 + File.open(dest, 'wb') {|f|
  603 + f.write File.binread(src)
  604 + }
  605 + File.chmod File.stat(src).mode, dest
  606 + File.unlink src
  607 + end
  608 + end
  609 +
  610 + def force_remove_file(path)
  611 + begin
  612 + remove_file path
  613 + rescue
  614 + end
  615 + end
  616 +
  617 + def remove_file(path)
  618 + File.chmod 0777, path
  619 + File.unlink path
  620 + end
  621 +
  622 + def install(from, dest, mode, prefix = nil)
  623 + $stderr.puts "install #{from} #{dest}" if verbose?
  624 + return if no_harm?
  625 +
  626 + realdest = prefix ? prefix + File.expand_path(dest) : dest
  627 + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
  628 + str = File.binread(from)
  629 + if diff?(str, realdest)
  630 + verbose_off {
  631 + rm_f realdest if File.exist?(realdest)
  632 + }
  633 + File.open(realdest, 'wb') {|f|
  634 + f.write str
  635 + }
  636 + File.chmod mode, realdest
  637 +
  638 + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
  639 + if prefix
  640 + f.puts realdest.sub(prefix, '')
  641 + else
  642 + f.puts realdest
  643 + end
  644 + }
  645 + end
  646 + end
  647 +
  648 + def diff?(new_content, path)
  649 + return true unless File.exist?(path)
  650 + new_content != File.binread(path)
  651 + end
  652 +
  653 + def command(*args)
  654 + $stderr.puts args.join(' ') if verbose?
  655 + system(*args) or raise RuntimeError,
  656 + "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
  657 + end
  658 +
  659 + def ruby(*args)
  660 + command config('rubyprog'), *args
  661 + end
  662 +
  663 + def make(task = nil)
  664 + command(*[config('makeprog'), task].compact)
  665 + end
  666 +
  667 + def extdir?(dir)
  668 + File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
  669 + end
  670 +
  671 + def files_of(dir)
  672 + Dir.open(dir) {|d|
  673 + return d.select {|ent| File.file?("#{dir}/#{ent}") }
  674 + }
  675 + end
  676 +
  677 + DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
  678 +
  679 + def directories_of(dir)
  680 + Dir.open(dir) {|d|
  681 + return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
  682 + }
  683 + end
  684 +
  685 +end
  686 +
  687 +
  688 +# This module requires: #srcdir_root, #objdir_root, #relpath
  689 +module HookScriptAPI
  690 +
  691 + def get_config(key)
  692 + @config[key]
  693 + end
  694 +
  695 + alias config get_config
  696 +
  697 + # obsolete: use metaconfig to change configuration
  698 + def set_config(key, val)
  699 + @config[key] = val
  700 + end
  701 +
  702 + #
  703 + # srcdir/objdir (works only in the package directory)
  704 + #
  705 +
  706 + def curr_srcdir
  707 + "#{srcdir_root()}/#{relpath()}"
  708 + end
  709 +
  710 + def curr_objdir
  711 + "#{objdir_root()}/#{relpath()}"
  712 + end
  713 +
  714 + def srcfile(path)
  715 + "#{curr_srcdir()}/#{path}"
  716 + end
  717 +
  718 + def srcexist?(path)
  719 + File.exist?(srcfile(path))
  720 + end
  721 +
  722 + def srcdirectory?(path)
  723 + File.dir?(srcfile(path))
  724 + end
  725 +
  726 + def srcfile?(path)
  727 + File.file?(srcfile(path))
  728 + end
  729 +
  730 + def srcentries(path = '.')
  731 + Dir.open("#{curr_srcdir()}/#{path}") {|d|
  732 + return d.to_a - %w(. ..)
  733 + }
  734 + end
  735 +
  736 + def srcfiles(path = '.')
  737 + srcentries(path).select {|fname|
  738 + File.file?(File.join(curr_srcdir(), path, fname))
  739 + }
  740 + end
  741 +
  742 + def srcdirectories(path = '.')
  743 + srcentries(path).select {|fname|
  744 + File.dir?(File.join(curr_srcdir(), path, fname))
  745 + }
  746 + end
  747 +
  748 +end
  749 +
  750 +
  751 +class ToplevelInstaller
  752 +
  753 + Version = '3.4.1'
  754 + Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
  755 +
  756 + TASKS = [
  757 + [ 'all', 'do config, setup, then install' ],
  758 + [ 'config', 'saves your configurations' ],
  759 + [ 'show', 'shows current configuration' ],
  760 + [ 'setup', 'compiles ruby extentions and others' ],
  761 + [ 'install', 'installs files' ],
  762 + [ 'test', 'run all tests in test/' ],
  763 + [ 'clean', "does `make clean' for each extention" ],
  764 + [ 'distclean',"does `make distclean' for each extention" ]
  765 + ]
  766 +
  767 + def ToplevelInstaller.invoke
  768 + config = ConfigTable.new(load_rbconfig())
  769 + config.load_standard_entries
  770 + config.load_multipackage_entries if multipackage?
  771 + config.fixup
  772 + klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
  773 + klass.new(File.dirname($0), config).invoke
  774 + end
  775 +
  776 + def ToplevelInstaller.multipackage?
  777 + File.dir?(File.dirname($0) + '/packages')
  778 + end
  779 +
  780 + def ToplevelInstaller.load_rbconfig
  781 + if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
  782 + ARGV.delete(arg)
  783 + load File.expand_path(arg.split(/=/, 2)[1])
  784 + $".push 'rbconfig.rb'
  785 + else
  786 + require 'rbconfig'
  787 + end
  788 + ::Config::CONFIG
  789 + end
  790 +
  791 + def initialize(ardir_root, config)
  792 + @ardir = File.expand_path(ardir_root)
  793 + @config = config
  794 + # cache
  795 + @valid_task_re = nil
  796 + end
  797 +
  798 + def config(key)
  799 + @config[key]
  800 + end
  801 +
  802 + def inspect
  803 + "#<#{self.class} #{__id__()}>"
  804 + end
  805 +
  806 + def invoke
  807 + run_metaconfigs
  808 + case task = parsearg_global()
  809 + when nil, 'all'
  810 + parsearg_config
  811 + init_installers
  812 + exec_config
  813 + exec_setup
  814 + exec_install
  815 + else
  816 + case task
  817 + when 'config', 'test'
  818 + ;
  819 + when 'clean', 'distclean'
  820 + @config.load_savefile if File.exist?(@config.savefile)
  821 + else
  822 + @config.load_savefile
  823 + end
  824 + __send__ "parsearg_#{task}"
  825 + init_installers
  826 + __send__ "exec_#{task}"
  827 + end
  828 + end
  829 +
  830 + def run_metaconfigs
  831 + @config.load_script "#{@ardir}/metaconfig"
  832 + end
  833 +
  834 + def init_installers
  835 + @installer = Installer.new(@config, @ardir, File.expand_path('.'))
  836 + end
  837 +
  838 + #
  839 + # Hook Script API bases
  840 + #
  841 +
  842 + def srcdir_root
  843 + @ardir
  844 + end
  845 +
  846 + def objdir_root
  847 + '.'
  848 + end
  849 +
  850 + def relpath
  851 + '.'
  852 + end
  853 +
  854 + #
  855 + # Option Parsing
  856 + #
  857 +
  858 + def parsearg_global
  859 + while arg = ARGV.shift
  860 + case arg
  861 + when /\A\w+\z/
  862 + setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
  863 + return arg
  864 + when '-q', '--quiet'
  865 + @config.verbose = false
  866 + when '--verbose'
  867 + @config.verbose = true
  868 + when '--help'
  869 + print_usage $stdout
  870 + exit 0
  871 + when '--version'
  872 + puts "#{File.basename($0)} version #{Version}"
  873 + exit 0
  874 + when '--copyright'
  875 + puts Copyright
  876 + exit 0
  877 + else
  878 + setup_rb_error "unknown global option '#{arg}'"
  879 + end
  880 + end
  881 + nil
  882 + end
  883 +
  884 + def valid_task?(t)
  885 + valid_task_re() =~ t
  886 + end
  887 +
  888 + def valid_task_re
  889 + @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
  890 + end
  891 +
  892 + def parsearg_no_options
  893 + unless ARGV.empty?
  894 + task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
  895 + setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
  896 + end
  897 + end
  898 +
  899 + alias parsearg_show parsearg_no_options
  900 + alias parsearg_setup parsearg_no_options
  901 + alias parsearg_test parsearg_no_options
  902 + alias parsearg_clean parsearg_no_options
  903 + alias parsearg_distclean parsearg_no_options
  904 +
  905 + def parsearg_config
  906 + evalopt = []
  907 + set = []
  908 + @config.config_opt = []
  909 + while i = ARGV.shift
  910 + if /\A--?\z/ =~ i
  911 + @config.config_opt = ARGV.dup
  912 + break
  913 + end
  914 + name, value = *@config.parse_opt(i)
  915 + if @config.value_config?(name)
  916 + @config[name] = value
  917 + else
  918 + evalopt.push [name, value]
  919 + end
  920 + set.push name
  921 + end
  922 + evalopt.each do |name, value|
  923 + @config.lookup(name).evaluate value, @config
  924 + end
  925 + # Check if configuration is valid
  926 + set.each do |n|
  927 + @config[n] if @config.value_config?(n)
  928 + end
  929 + end
  930 +
  931 + def parsearg_install
  932