#!/usr/bin/env ruby # Author:: Nicolas Pouillard . # Copyright:: Copyright (c) 2004 LRDE. All rights reserved. # License:: GNU General Public License (GPL). # $LastChangedBy: ertai $ # $Id: header 98 2004-09-29 12:07:43Z ertai $ # vcs: The version control system wrapper. # # Vcs is a wrapper over any version control system. require 'pathname' require 'logger' require 'optparse' require 'set' VCS_VERSION = '0.3.0' VCS_PATH = Pathname.new(__FILE__).expand_path VCS_DIR, VCS = VCS_PATH.split LIB = VCS_DIR + '..' + 'lib' $: << LIB.to_s dir = Pathname.pwd while not dir.root? and not (vcs_dir = dir + 'vcs').exist? dir = dir + '..' end $: << vcs_dir LOG = Logger.new(STDOUT) if severity = ENV['VCS_SEVERITY'] LOG.level = Logger.const_get(severity.upcase) else LOG.level = Logger::INFO end def LOG.format_message(severity, timestamp, msg, progname) progname += ': ' unless progname.nil? or progname.empty? "#{VCS}: #{progname}#{severity.downcase}: #{msg}\n" end Pathname.glob("{#{LIB}/**,#{vcs_dir}}/*.rb") do |file| LOG.debug { file.basename.to_s } begin require "vcs/#{file.basename}" rescue LoadError begin require file.to_s rescue LoadError => ex raise ex end end end ALL_VCS_NAMES = [] ALL_VCS_BY_NAME = {} ObjectSpace.each_object(Class) do |aClass| if aClass != Vcs and aClass.ancestors.include? Vcs name = aClass.to_s.to_sym ALL_VCS_NAMES << name ALL_VCS_BY_NAME[name] = aClass end end OPTIONS = {} OPTS = OptionParser.new do |opts| opts.banner = "Usage: #{VCS} [options] *" opts.separator '' opts.on('-c', '--vcs TYPE', ALL_VCS_NAMES, 'Set your vcs') do |aVcs| OPTIONS[:vcs_type] = aVcs end opts.on('-l', '--vcs-list', 'List all vcs') do |aVcs| STDERR.puts 'Vcs list:' ALL_VCS_NAMES.each { |n| STDERR.puts " - #{n}" } exit end opts.on('--mk-alias', 'Put the result of this command in your .zshrc or .bashrc') do ALL_VCS_NAMES.each do |n| n = n.to_s.downcase if VCS_PATH.executable? puts "alias #{n}=#{VCS_PATH}-#{n} ;" else puts "alias #{n}=vcs-#{n} ;" end end exit end opts.on('-C', '--[no-]check', 'Check your vcs configuration') do |check| if check Vcs.new('vcs').call_conf_checkers exit end end opts.on('-d', '--debug LEVEL', 'Set debug level') do |severity| LOG.level = Logger.const_get(severity.upcase) end opts.on_tail('-h', '--help', 'Show this message') do |test| STDERR.puts OPTS STDERR.puts "\n\nReport bugs to ." exit end opts.on_tail('--version', 'Show version') do STDOUT.puts "Vcs version: #{VCS_VERSION}" exit end end ENV['LC_ALL'] = 'C' if ENV.has_key? 'FULLNAME' FULLNAME = ENV['FULLNAME'] else require 'etc' ENV['FULLNAME'] = (Etc.getpwnam ENV['USER']).gecos LOG.warn "Need FULLNAME in the environement (default: #{ENV['FULLNAME']})" end env = %w[ EMAIL FULLNAME EDITOR PAGER ] if env.all? { |s| ENV[s] } EDITOR = ENV['EDITOR'].to_cmd PAGER = ENV['PAGER'].to_cmd EMAIL = ENV['EMAIL'] else env.each { |s| LOG.error "Need #{s} in the environement" unless ENV[s] } exit end FULL_EMAIL = "#{FULLNAME} <#{EMAIL}>" def main vcs = nil begin OPTS.parse!(ARGV) unless OPTIONS.has_key? :vcs_type STDERR.puts OPTS STDERR.puts "\nSpecify at least a Vcs type, or use a wrapped command\n" + 'like svn, cvs, prcs in the vcs bin directory.' exit end vcs = ALL_VCS_BY_NAME[OPTIONS[:vcs_type]].new if ARGV.empty? meth = :help! else meth = ARGV.shift.sub(/([^!])$/, '\1!') end vcs.send(meth, *ARGV) rescue Exception vcs.call_handlers unless vcs.nil? LOG.debug { raise } LOG.error $!.to_s.sub(/\.$/, '') unless $!.to_s == 'exit' end end main()