diff --git a/bin/vim-ruby-install.rb b/bin/vim-ruby-install.rb index 5586df65..10a15dd5 100755 --- a/bin/vim-ruby-install.rb +++ b/bin/vim-ruby-install.rb @@ -12,7 +12,7 @@ # require 'rbconfig' -include Config +include RbConfig require 'fileutils' require 'optparse' require 'pathname' @@ -32,13 +32,13 @@ syntax/ruby.vim } +# +# Miscellaneous functions in the user's environment. +# +class Env # - # Miscellaneous functions in the user's environment. + # Returns :UNIX or :WINDOWS, according to CONFIG['host_os'] and $options[:windows]. # -class Env - # - # Returns :UNIX or :WINDOWS, according to CONFIG['host_os'] and $options[:windows]. - # def Env.determine_target_os os = CONFIG['host_os'] if os =~ /mswin/ or $options[:windows] @@ -48,16 +48,16 @@ def Env.determine_target_os end end - # - # Returns the path to the directory where the vim configuration files will be copied from. - # The first preference is the directory above this script. If that fails, we look for the - # RubyGems package 'vim-ruby'. Failing that, we return +nil+. - # + # + # Returns the path to the directory where the vim configuration files will be copied from. + # The first preference is the directory above this script. If that fails, we look for the + # RubyGems package 'vim-ruby'. Failing that, we return +nil+. + # def Env.determine_source_directory - # 1. Try the directory above this installation script. + # 1. Try the directory above this installation script. vim_ruby_source_dir = File.expand_path(File.join(File.dirname($0), '..')) return vim_ruby_source_dir if _valid_vim_ruby_dir(vim_ruby_source_dir) - # 2. Try the gem 'vim-ruby'. + # 2. Try the gem 'vim-ruby'. begin require 'rubygems' raise "Need RubyGems 0.8+" if Gem::RubyGemsPackageVersion < '0.8' @@ -72,25 +72,25 @@ def Env.determine_source_directory return nil end - # Returns the Vim installation directory ($VIM). - # TODO: print warning if vim command not in PATH or appropriate key not in registry? + # Returns the Vim installation directory ($VIM). + # TODO: print warning if vim command not in PATH or appropriate key not in registry? def Env.determine_vim_dir installation_dir = ENV['VIM'] || case Env.determine_target_os when :UNIX - IO.popen('vim --version 2>/dev/null') do |version| - dir = version.read[/fall-back for \$VIM: "(.*)"/, 1] - end + IO.popen('vim --version 2>/dev/null') do |version| + dir = version.read[/fall-back for \$VIM: "(.*)"/, 1] + end when :WINDOWS - begin - require 'win32/registry' - Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Vim\Gvim') do |reg| - path = reg['path', Win32::Registry::REG_SZ] - dir = path.sub(/\\vim\d\d\\gvim.exe/i, '') - end - rescue Win32::Registry::Error - nil - end + begin + require 'win32/registry' + Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Vim\Gvim') do |reg| + path = reg['path', Win32::Registry::REG_SZ] + dir = path.sub(/\\vim\d\d\\gvim.exe/i, '') + end + rescue Win32::Registry::Error + nil + end end return installation_dir end @@ -99,7 +99,7 @@ def Env.determine_home_dir home_dir = ENV['HOME'] || case Env.determine_target_os when :WINDOWS - ENV['HOMEDRIVE'] + ENV['HOMEPATH'] if ENV['HOMEDRIVE'] and ENV['HOMEPATH'] + ENV['HOMEDRIVE'] + ENV['HOMEPATH'] if ENV['HOMEDRIVE'] and ENV['HOMEPATH'] end return home_dir end @@ -120,12 +120,12 @@ def Env._valid_vim_ruby_dir(dir) end # class Env - # - # A FileWriter writes files with pre-selected line endings and permissions. - # - # writer = FileWriter.new(:UNIX, 0664) - # writer.copy(source, target) - # +# +# A FileWriter writes files with pre-selected line endings and permissions. +# +# writer = FileWriter.new(:UNIX, 0664) +# writer.copy(source, target) +# class FileWriter LINE_ENDINGS = { :UNIX => "\n", :WINDOWS => "\r\n" } @@ -136,22 +136,25 @@ def initialize(ending, file_permissions=0644, directory_permissions=0755) :dir => directory_permissions } end - # Source and target paths assumed to be Pathname objects. Copy the source to the target, - # ensuring the right line endings. + + # Source and target paths assumed to be Pathname objects. Copy the source to the target, + # ensuring the right line endings. def copy(source_path, target_path) _ensure_directory_exists(target_path) target_path.open('wb', @permissions[:file]) do |io| lines = source_path.read.split("\n") lines.each do |line| - io.write(line.chomp + @ending) + io.write(line.chomp + @ending) end end puts "#{source_path.to_s.ljust(25)} -> #{target_path}" end - # Create the given directory with the correct directory permissions. + + # Create the given directory with the correct directory permissions. def mkpath(directory) FileUtils.mkdir_p(directory.to_s, :mode => @permissions[:dir], :verbose => true) end + def _ensure_directory_exists(path) dir = path.dirname unless dir.directory? @@ -162,41 +165,42 @@ def _ensure_directory_exists(path) end end # class FileWriter - - # - # Represents the target base directory for installs. Handles writing the files through a - # given FileWriter. - # +# +# Represents the target base directory for installs. Handles writing the files through a +# given FileWriter. +# class TargetDirectory def self.finder TargetDirectory::Finder.new end + def initialize(directory, writer) @directory = Pathname.new(directory) @writer = writer # FileWriter end + # Copies the given relative path from the current directory to the target. def copy(path) source_path = Pathname.new(path) target_path = @directory + path @writer.copy(source_path, target_path) end + def [](path) @directory + path end + def path @directory end end # class TargetDirectory - - # - # Represents the target directory. Can find candidates, based on the operating system and - # user options; but is ultimately created with one in mind. - # +# +# Represents the target directory. Can find candidates, based on the operating system and +# user options; but is ultimately created with one in mind. +# class TargetDirectory::Finder - - # Guides the user through a selection process, ending in a chosen directory. + # Guides the user through a selection process, ending in a chosen directory. def find_target_directory # 1. Was a directory specified using the --directory option? if option_dir = $options[:target_dir] @@ -207,13 +211,13 @@ def find_target_directory puts puts "Possible Vim installation directories:" dirs.each_with_index do |dir, idx| - puts " #{idx+1}) #{dir}" + puts " #{idx+1}) #{dir}" end puts r = Env.ask_user "Please select one (or anything else to specify another directory): " if (1..dirs.size).include? r.to_i - chosen_directory = dirs[r.to_i - 1] - return chosen_directory + chosen_directory = dirs[r.to_i - 1] + return chosen_directory end end # 3. We didn't find any, or the user wants to enter another. @@ -228,8 +232,8 @@ def find_target_directory private - # Return an array of _potential_ directories (i.e. they exist). Take the options into - # account. + # Return an array of _potential_ directories (i.e. they exist). Take the options into + # account. def _potential_directories dirs = [] dirs << _vim_user_dir @@ -237,32 +241,29 @@ def _potential_directories return dirs.compact.map { |dir| File.expand_path(dir) } end - # Return the Vim system preferences directory + # Return the Vim system preferences directory def _vim_system_dir vim_dir = Env.determine_vim_dir system_dir = vim_dir + "/vimfiles" if vim_dir return system_dir end - # Return the Vim user preferences directory + # Return the Vim user preferences directory def _vim_user_dir platform_dir = { :UNIX => "/.vim", :WINDOWS => "/vimfiles" } home_dir = Env.determine_home_dir user_dir = home_dir + platform_dir[Env.determine_target_os] if home_dir return user_dir end - end # class TargetDirectory::Finder - - # - # VimRubyInstaller is the class that copies the files from the source directory to the target - # directory, both of which are provided. - # +# +# VimRubyInstaller is the class that copies the files from the source directory to the target +# directory, both of which are provided. +# class VimRubyInstaller - - # +source+ and +target+ are the base directories from and to which the configuration files - # will be copied. Both are strings. + # +source+ and +target+ are the base directories from and to which the configuration files + # will be copied. Both are strings. def initialize(source, target) unless FileTest.directory?(source) raise "Automatically determined source directory ('#{source}') doesn't exist" @@ -275,26 +276,26 @@ def initialize(source, target) @target_dir = TargetDirectory.new(target, file_writer) end - # Since we know the source and target directories, all we have to do is copy the files - # across. If the --backup option was specified or the target file is - # _newer_ than the source file, we make a backup of it and report that to - # the user. + # Since we know the source and target directories, all we have to do is copy the files + # across. If the --backup option was specified or the target file is + # _newer_ than the source file, we make a backup of it and report that to + # the user. def install backupdir = BackupDir.new("./vim-ruby-backup.#{Process.pid}") Dir.chdir(@source_dir) do SOURCE_FILES.each do |path| - source_path = Pathname.new(path) - target_path = @target_dir[path] - # FIXME: Backup everything for now - if $options[:backup] and target_path.file? - backupdir.backup(@target_dir, path) - elsif target_path.file? and target_path.mtime > source_path.mtime - # We're going to overwrite a newer file; back it up, unless they're the same. - unless _same_contents?(target_path, source_path) - backupdir.backup(@target_dir, path) - end - end - @target_dir.copy(path) + source_path = Pathname.new(path) + target_path = @target_dir[path] + # FIXME: Backup everything for now + if $options[:backup] and target_path.file? + backupdir.backup(@target_dir, path) + elsif target_path.file? and target_path.mtime > source_path.mtime + # We're going to overwrite a newer file; back it up, unless they're the same. + unless _same_contents?(target_path, source_path) + backupdir.backup(@target_dir, path) + end + end + @target_dir.copy(path) end end backups = backupdir.contents @@ -302,7 +303,7 @@ def install puts puts "The following backups were made:" backups.each do |path| - puts " * #{path}" + puts " * #{path}" end puts puts "These backups are located in this directory: #{backupdir.path}" @@ -311,19 +312,20 @@ def install private - # Test two files for equality of contents, ignoring line endings. + # Test two files for equality of contents, ignoring line endings. def _same_contents?(p1, p2) contents1 = p1.read.split("\n").map { |line| line.chomp } contents2 = p2.read.split("\n").map { |line| line.chomp } contents1 == contents2 end - # A directory for holding backups of configuration files. + # A directory for holding backups of configuration files. class BackupDir def initialize(path) @base = Pathname.new(path).expand_path end - # Copy basedir/path to @path/path. + + # Copy basedir/path to @path/path. def backup(basedir, path) @base.mkpath unless @base.directory? source = basedir.path + path @@ -331,55 +333,56 @@ def backup(basedir, path) target.dirname.mkpath FileUtils.cp(source.to_s, target.dirname.to_s, :verbose => true) end + def [](path) @base + path end + def contents return [] unless @base.directory? results = [] Dir.chdir(@base) do - Pathname.new('.').find do |path| - results << path if path.file? - end + Pathname.new('.').find do |path| + results << path if path.file? + end end results end + def path @base end end # class VimRubyInstaller::BackupDir - end # class VimRubyInstaller - # - # * * * M A I N * * * - # +# +# * * * M A I N * * * +# begin - $options = { :backup => false, :target_dir => nil, - :windows => false + :windows => false } op = OptionParser.new do |p| p.banner = %{ vim-ruby-install.rb: Install the vim-ruby configuration files - About: - * Detects the Vim user and system-wide preferences directories - * User to confirm before proceeding - * User may specify other directory - * Takes config files from current directory or from vim-ruby gem - * Writes files with correct permissions and line endings + About: + * Detects the Vim user and system-wide preferences directories + * User to confirm before proceeding + * User may specify other directory + * Takes config files from current directory or from vim-ruby gem + * Writes files with correct permissions and line endings - Usage: - direct: ruby bin/vim-ruby-install.rb [options] - gem: vim-ruby-install.rb [options] + Usage: + direct: ruby bin/vim-ruby-install.rb [options] + gem: vim-ruby-install.rb [options] - Options: - }.gsub(/^ /, '') + Options: + }.gsub(/^ /, '') p.on('-b', '--backup', 'Backup existing runtime files') do |value| $options[:backup] = value end @@ -394,22 +397,22 @@ def path exit end p.on_tail %{ - Notes: + Notes: - * "Direct" usage means unpacking a vim-ruby tarball and running this - program from the vim-ruby directory. + * "Direct" usage means unpacking a vim-ruby tarball and running this + program from the vim-ruby directory. - * The convenient alternative is to use RubyGems: - gem install vim-ruby - vim-ruby-install.rb + * The convenient alternative is to use RubyGems: + gem install vim-ruby + vim-ruby-install.rb - * The --windows option is designed for forcing an install into the - Windows (gvim) configuration directory; useful when running from - Cygwin or MinGW. + * The --windows option is designed for forcing an install into the + Windows (gvim) configuration directory; useful when running from + Cygwin or MinGW. - * This installer is quite new (2004-09-20). Please report bugs to - gsinclair@soyabean.com.au. - }.gsub(/^ /, '') + * This installer is quite new (2004-09-20). Please report bugs to + gsinclair@soyabean.com.au. + }.gsub(/^ /, '') end op.parse!(ARGV)