Index: ChangeLog
from Nicolas Pouillard <ertai(a)lrde.epita.fr>
* vcs: Remove the ruby_ex external link, use the gem package instead.
* vcs/Rakefile: Use the core_ex common rakefile.
* vcs/SPEC.yml: New. Package meta data.
* vcs/SPEC.dyn.yml: New. Package generated meta data.
* vcs/AUTHORS: New.
* vcs/NEWS: New.
* vcs/src: Rename to ...
* vcs/lib/vcs: ... this.
* vcs/lib/vcs/ask.rb: Remove, because ask is present in ruby_ex.
* vcs/lib/vcs/edit.rb: New.
* vcs/bin/vcs: Update requires, load_path, version, and some
environement variables definition.
AUTHORS | 6 +
NEWS | 3
Rakefile | 79 +--------------
SPEC.dyn.yml | 9 +
SPEC.yml | 35 +++++++
bin/vcs | 27 ++---
lib/vcs/diffstat.rb | 2
lib/vcs/edit.rb | 15 +++
lib/vcs/vcs.rb | 65 ++++++-------
src/ask.rb | 101 --------------------
src/changelog.rb | 115 -----------------------
src/conflict.rb | 21 ----
src/cvs.rb | 21 ----
src/diff.rb | 18 ---
src/diffstat.rb | 30 ------
src/last_changed_date.rb | 16 ---
src/mail.rb | 51 ----------
src/message.rb | 69 -------------
src/mycommit.rb | 86 -----------------
src/news.rb | 118 -----------------------
src/prcs.rb | 21 ----
src/revision.rb | 18 ---
src/status.rb | 17 ---
src/svn.rb | 29 -----
src/tools.rb | 22 ----
src/vcs.rb | 234 -----------------------------------------------
26 files changed, 119 insertions(+), 1109 deletions(-)
Index: vcs/lib/vcs/diffstat.rb
--- vcs/lib/vcs/diffstat.rb (revision 206)
+++ vcs/lib/vcs/diffstat.rb (working copy)
@@ -14,7 +14,7 @@
check_diffstat
data_diff = diff(*a)
cmd = @@diffstat < data_diff.output.open > [@out_path, @err_path]
- cmd.sys
+ cmd.run(@runner)
end
alias_command :ds, :diffstat
Index: vcs/bin/vcs
--- vcs/bin/vcs (revision 206)
+++ vcs/bin/vcs (working copy)
@@ -16,18 +16,11 @@
require 'optparse'
require 'set'
-begin
- REV="$Rev$".sub(/LastChangedRevision:\s+/, '').to_i
-rescue
- REV=-1
-end
-
+VCS_VERSION = '0.2.148'
VCS_PATH = Pathname.new(__FILE__).expand_path
VCS_DIR, VCS = VCS_PATH.split
-SRC = VCS_DIR + '..' + 'src'
-RUBY_EX = VCS_DIR + '..' + 'ruby_ex'
-$: << SRC.to_s
-$: << RUBY_EX.to_s
+LIB = VCS_DIR + '..' + 'lib'
+$: << LIB.to_s
dir = Pathname.pwd
while not dir.root? and not (vcs_dir = dir + 'vcs').exist?
@@ -46,14 +39,14 @@
"#{VCS}: #{progname}#{severity.downcase}: #{msg}\n"
end
-Pathname.glob("{#{SRC}/**,#{vcs_dir}}/*.rb") do |file|
+Pathname.glob("{#{LIB}/**,#{vcs_dir}}/*.rb") do |file|
LOG.debug { file.basename.to_s }
begin
- require file.basename.to_s
- rescue LoadError => ex
+ require "vcs/#{file.basename}"
+ rescue LoadError
begin
require file.to_s
- rescue
+ rescue LoadError => ex
raise ex
end
end
@@ -115,7 +108,7 @@
end
opts.on_tail('--version', 'Show version') do
- STDOUT.puts "Vcs revision: #{REV}"
+ STDOUT.puts "Vcs version: #{VCS_VERSION}"
exit
end
@@ -130,7 +123,9 @@
end
env = %w[ EMAIL FULLNAME EDITOR PAGER ]
if env.all? { |s| ENV[s] }
- env.each { |s| Kernel.const_set(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
Index: vcs/src/vcs.rb
--- vcs/src/vcs.rb (revision 206)
+++ vcs/src/vcs.rb (working copy)
@@ -1,234 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'set'
-require 'commands'
-
-# The abstract class for a Vcs wrapper.
-# Conventions:
-# example:
-# svn checkout
http://foo.bar/proj # alias
-# vcs-svn checkout
http://foo.bar/proj # wrapper
-# vcs --vcs Svn checkout
http://foo.bar/proj # manual
-#
-# checkout
-# checkout_
-# checkout!
-# checkout_!
-#
-class Vcs
-
- class Failure < Exception
- end
-
- def initialize ( aCmd )
- @cmd = aCmd.to_cmd
- @handlers = Set.new
- @runner = Commands::Runners::System.new
- @runner.subscribe_hook(:failure) do |data|
- if data.status
- LOG.error { "exit(#{data.status.exitstatus})" }
- else
- LOG.fatal { 'no exit status' }
- end
- end
- @runner.subscribe_hook(:display_command) do |cmd|
- LOG.debug { "running: #{cmd.to_sh}" }
- end
- @out, @err = STDOUT, STDERR
- end
-
- def self.add_basic_method ( meth )
- class_eval <<-end_eval
- def #{meth}! ( *args )
- run!("#{meth}", *args)
- end
- def #{meth}_! ( *args )
- run!("#{meth}", *args)
- end
- end_eval
- end
-
- @@all_commands = {}
- @@all_aliases = Set.new
-
- def self.alias_command ( m1, m2 )
- m2 = m2.to_s
- @@all_commands[m2] ||= Set.new
- @@all_commands[m2] << m1.to_s
- @@all_aliases << m1
- class_eval <<-end_eval
- def #{m1} ( *args )
- #{m2}(*args)
- end
- def #{m1}_ ( *args )
- #{m2}_(*args)
- end
- def #{m1}! ( *args )
- #{m2}!(*args)
- end
- def #{m1}_! ( *args )
- #{m2}_!(*args)
- end
- end_eval
- end
-
- attr_accessor :out, :err, :out_path, :err_path
-
- @@checkers = Set.new
-
- def run! ( *args )
- cmd = @cmd + args
- if @out_path.nil?
- cmd = cmd > [@out, @err]
- else
- cmd = cmd > [@out_path, @err_path]
- end
- cmd.run(@runner)
- end
-
- def sub_vcs
- copy = dup
- copy.out_path = TempPath.new
- copy.err_path = TempPath.new
- copy.out = copy.out_path.open('w')
- copy.err = copy.err_path.open('w')
- copy
- end
-
- def run ( *args )
- sub_vcs.run!(*args)
- end
-
- %w[ checkout delete diff status log add update commit ].each do |m|
- add_basic_method(m)
- end
-
- def method_missing ( meth, *args )
- meth = meth.to_s
- if meth =~ /^(.*)!$/
- no_bang = $1
- if respond_to? no_bang
- LOG.warn { "Unefficient method call (#{no_bang}), " +
- "prefer define methods with a `!'" }
- send(no_bang, *args).each do |line|
- puts line
- end
- else
- LOG.warn { "unknown method #{meth}" }
- run!(no_bang.sub(/_$/, ''), *args)
- end
- else
- with_bang = meth + '!'
- if respond_to? with_bang
- copy = sub_vcs
- res = copy.send(with_bang, *args)
- if res.nil?
- copy.out.close
- copy.out_path
- else
- res
- end
- else
- LOG.warn { "unknown method #{meth}" }
- run!(meth.sub(/_$/, ''), *args)
- end
- end
- end
-
- def help! ( *args )
- return help_!(*args) unless args.empty?
- @out.puts "
- |usage: #{(a)cmd.command} <subcommand> [options] [args]
- |Type '#{(a)cmd.command} help <subcommand>' for help on a specific
subcommand.
- |
- |Most subcommands take file and/or directory arguments, recursing
- |on the directories. If no arguments are supplied to such a
- |command, it recurses on the current directory (inclusive) by default.
- |
- |Available subcommands:".head_cut!
- cmds = []
- methods.each do |meth|
- next if meth =~ /_!?$/
- next unless meth =~ /^(.+)!$/
- cmd = $1
- next if cmd == 'run'
- next if @@all_aliases.include? cmd.to_sym
- cmds << cmd
- end
- cmds.sort!
- cmds.each do |cmd|
- if @@all_commands.has_key? cmd
- aliases = @@all_commands[cmd].sort.join(', ')
- @out.puts " - #{cmd} (alias #{aliases})"
- else
- @out.puts " - #{cmd}"
- end
- end
- end
-
- alias_command :ann, :blame
- alias_command :annotate, :blame
- alias_command :praise, :blame
- alias_command :co, :checkout
- alias_command :ci, :commit
- alias_command :cp, :copy
- alias_command :del, :delete
- alias_command :remove, :delete
- alias_command :rm, :delete
- alias_command :di, :diff
- alias_command :h, :help
- alias_command :ls, :list
- alias_command :mv, :move
- alias_command :rename, :move
- alias_command :ren, :move
- alias_command :pdel, :propdel
- alias_command :pd, :propdel
- alias_command :pedit, :propedit
- alias_command :pe, :propedit
- alias_command :pget, :propget
- alias_command :pg, :propget
- alias_command :plist, :proplist
- alias_command :pl, :proplist
- alias_command :pset, :propset
- alias_command :ps, :propset
- alias_command :st, :status
- alias_command :stat, :status
- alias_command :sw, :switch
- alias_command :up, :update
-
- # Cvs Alias
- alias_command :new, :add
- alias_command :rcs, :admin
- alias_command :get, :checkout
- alias_command :rlog, :log
- alias_command :patch, :rdiff
- alias_command :rfreeze, :rtag
- alias_command :freeze, :tag
-
- # Prcs Alias
- alias_command :checkin, :commit
- alias_command :populate, :add
-
- def error_handling ( meth )
- @handlers << meth
- end
-
- def call_handlers
- @handlers.each { |meth| send(meth) }
- end
-
- def self.add_conf_checker ( meth )
- @@checkers << meth
- end
-
- def call_conf_checkers
- @@checkers.each { |meth| send(meth) }
- end
-
-end # class Vcs
-
Index: vcs/src/message.rb
--- vcs/src/message.rb (revision 206)
+++ vcs/src/message.rb (working copy)
@@ -1,69 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/vcs'
-require 'vcs/changelog'
-
-class Vcs
- def diffw! ( *args )
- diff!(*args)
- end
-end
-
-class Svn
- def diffw! ( *args )
- diff! '--diff-cmd', 'diff', '-x', '-NPbuw', *args
- end
-end
-
-class Vcs
-
- @@message = Pathname.new(',message')
-
- def print_body ( file, options )
- LOG.warn "Creating a new `#{file}' file"
- file.open('w') do |f|
- f.puts options.to_yaml
- f.puts '---'
- f.puts
- f.print message.read
- end
- end
- private :print_body
-
- def message ( *args )
- error_handling :message_failed
-
- unless @@message.exist?
- cl = mkchangelog(*args)
- TempPath.new('message') do |tmp|
- tmp.open('w') do |f|
- f.puts 'Index: ChangeLog'
- f.print cl.read.sub(/^\d+-\d+-\d+/, 'from')
- f.puts
- f.print diffstat(*args).read
- f.puts
- diffw_from_status(*args).each_line do |line|
- f.print line if line !~ /^=+$/
- end
- end
- tmp.mv(@@message)
- end
- end
- @@message.open('r')
- end
-
- alias_command :msg, :message
-
- def message_failed
- if @@message.exist?
- LOG.info "#{@@message}: Contains the generated message"
- LOG.info ' (the ChangeLog entry, the diffstat, the diff)'
- end
- end
-
-end # class Vcs
Index: vcs/AUTHORS
--- vcs/AUTHORS (revision 0)
+++ vcs/AUTHORS (revision 0)
@@ -0,0 +1,6 @@
+---
+Vcs was written by and with the assistance of:
+
+ - Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>:
+ - Initial Design
+ - Maintenance
Index: vcs/src/tools.rb
--- vcs/src/tools.rb (revision 206)
+++ vcs/src/tools.rb (working copy)
@@ -1,22 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'yaml'
-module YAML
-
- def self.chop_header ( io )
- aStr = io.gets
- raise Exception, "First line is not valid: `#{aLine}'" unless aStr =~
/^---/
- io.each do |aLine|
- break if aLine =~ /^---/
- aStr += aLine
- end
- YAML::load(aStr)
- end
-
-end # module YAML
-
Index: vcs/src/ask.rb
--- vcs/src/ask.rb (revision 206)
+++ vcs/src/ask.rb (working copy)
@@ -1,101 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-ANSWERS = [ :y, :n ]
-ANSWER_NOT_VALID = 'Not a valid answer, please answer correctly'
-
-# `ask', ask the user to answer, to your question.
-#
-# Example:
-# ask('Commiting, are you sure', :n)
-#
-# produce => Commiting, are you sure (y/N):
-# and wait your answer.
-def ask ( aQuestion, theDefaultAnswer=:y, cin=STDIN, cout=STDOUT, cerr=STDERR )
-
- yn = case theDefaultAnswer
- when :y then ' [Y/n]: '
- when :n then ' [y/N]: '
- else raise ArgumentError, "not valid default answer
#{theDefaultAnswer}"
- end
-
- loop do
- cout.print aQuestion, yn
- cout.flush
-
- answer = cin.readline.chomp.downcase
-
- return theDefaultAnswer if answer.empty?
-
- answer = answer.to_sym
-
- return answer if ANSWERS.include? answer
-
- cerr.puts ANSWER_NOT_VALID
- cout.puts
- end
-
-end
-
-if defined? TEST_MODE or $0 == __FILE__
-
-require 'test/unit'
-class AskTest < Test::Unit::TestCase
-
- def ask_checker ( question, default, answer, ref, out, err )
- require 'stringio'
- cin, cout, cerr = StringIO.new, StringIO.new, StringIO.new
- cin.puts answer
- cin.rewind
- res = ask(question, default, cin, cout, cerr)
- cout.rewind
- cerr.rewind
- assert_equal(res, ref, 'bad return value')
- assert_equal(cout.readlines.join, out, 'bad standard output')
- assert_equal(cerr.readlines.join, err, 'bad error output')
- end
-
- def test_bad_default
- assert_raise(ArgumentError) { ask_checker('Q', :foo, '', :y, [], [])
}
- assert_nothing_raised do
- ask_checker('Q', :y, 'y', :y, 'Q [Y/n]: ', '')
- end
- assert_nothing_raised do
- ask_checker('Q', :n, 'y', :y, 'Q [y/N]: ', '')
- end
- end
-
- def test_valid_default_yes
- ask_checker('Q', :y, 'y', :y, 'Q [Y/n]: ', '')
- ask_checker('Q', :y, 'Y', :y, 'Q [Y/n]: ', '')
- ask_checker('Q', :y, 'n', :n, 'Q [Y/n]: ', '')
- ask_checker('Q', :y, 'N', :n, 'Q [Y/n]: ', '')
- ask_checker('Q', :y, '', :y, 'Q [Y/n]: ', '')
- end
-
- def test_valid_default_no
- ask_checker('Q', :n, 'y', :y, 'Q [y/N]: ', '')
- ask_checker('Q', :n, 'Y', :y, 'Q [y/N]: ', '')
- ask_checker('Q', :n, 'n', :n, 'Q [y/N]: ', '')
- ask_checker('Q', :n, 'N', :n, 'Q [y/N]: ', '')
- ask_checker('Q', :n, '', :n, 'Q [y/N]: ', '')
- end
-
- def test_invalid_answer
- ask_checker('Q', :n, "bad\ny", :y,
- "Q [y/N]: \nQ [y/N]: ", ANSWER_NOT_VALID + "\n")
- ask_checker('Q', :y, "ad\n\n", :y,
- "Q [Y/n]: \nQ [Y/n]: ", ANSWER_NOT_VALID + "\n")
- end
-
- def test_ask1
- ask_checker('Q', :y, 'y', :y, 'Q [Y/n]: ', '')
- end
-
-end # class AskTest
-
-end
Index: vcs/SPEC.dyn.yml
--- vcs/SPEC.dyn.yml (revision 0)
+++ vcs/SPEC.dyn.yml (revision 0)
@@ -0,0 +1,9 @@
+--- !ruby/object:OpenStruct
+table:
+ :url:
https://svn.lrde.epita.fr/svn/lrdetools/trunk/vcs
+ :date: "Fri, 01 Jul 2005"
+ :version: !ruby/object:Version
+ build: 148
+ major: 0
+ minor: 2
+ revision: 206
Index: vcs/src/prcs.rb
--- vcs/src/prcs.rb (revision 206)
+++ vcs/src/prcs.rb (working copy)
@@ -1,21 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/vcs'
-
-class Prcs < Vcs
-
- def initialize ( aCmd='prcs' )
- super
- end
-
- %w[ admin ].each do |m|
- add_basic_method(m)
- end
-
-end # class Prcs
-
Index: vcs/src/conflict.rb
--- vcs/src/conflict.rb (revision 206)
+++ vcs/src/conflict.rb (working copy)
@@ -1,21 +0,0 @@
-class Vcs
-
- def mk_conflicts_list
- ls = status.output.readlines.grep(/^C/).map! { |s| s[/^C\s+(.*)/, 1] }
- raise "no conflicts" if ls.empty?
- ls
- end
-
- def edit_conflicts!
- edit! mk_conflicts_list
- end
-
- def resolve_conflicts!
- conflicts = mk_conflicts_list
- question = "Resolve these conflicts: \n - #{conflicts.join("\n -
")}\n"
- if ask(question, :n, STDIN, @out, @err) == :y
- return resolved(conflicts)
- end
- end
-
-end # class Vcs
Index: vcs/SPEC.yml
--- vcs/SPEC.yml (revision 0)
+++ vcs/SPEC.yml (revision 0)
@@ -0,0 +1,35 @@
+---
+Author: Nicolas Pouillard
+License: GNU General Public License (GPL)
+Revision: '$Id$'
+
+name: vcs
+
+title: Vcs -- A wrapper over any version control system
+summary: A wrapper over any version control system
+description: |
+ Version control systems (Subversion, CVS, PRCS...), however useful, are not
+ very extensible: adding new features can be cumbersome, especially if you
+ want them for different such systems at once. Vcs provide a simple dynamic
+ hierarchy for Version Control Systems.
+homepage:
http://rubyforge.org/projects/vcs
+
+rdoc_dir: doc/html
+tags_url:
https://svn.lrde.epita.fr/svn/lrdetools/tags
+
+commit_command: ltci
+
+rdoc_files: !filelist
+ - README
+ - AUTHORS
+ - lib/vcs/**/*.rb
+
+pkg_files: !filelist
+ - lib/vcs/**/*.rb
+ - bin/**/*
+ - '[A-Z]*'
+
+executables: [ vcs, vcs-svn, vcs-cvs, vcs-prcs ]
+
+dependencies:
+ ruby_ex: ~> 0.1.3
Index: vcs/src/news.rb
--- vcs/src/news.rb (revision 206)
+++ vcs/src/news.rb (working copy)
@@ -1,118 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/tools'
-require 'vcs/message'
-
-class Vcs
-
- NEWS = Pathname.new(',news')
-
- def parse_news_options ( *args )
- require 'optparse'
- result =
- {
- :from => FULL_EMAIL,
- :groups => [],
- :server => ENV['NNTPSERVER'],
- }
- if !args.nil? and !args.empty? and args[0].is_a?(Hash)
- return result.merge!(args[0])
- end
- OptionParser.new do |opts|
- opts.separator ''
- opts.on('-g', '--group NAME', 'Choose a news group') do
|aString|
- result[:groups] << aString
- end
- opts.on('-s', '--server NAME', 'Choose a news server') do
|aString|
- result[:server] = aString
- end
- opts.on('-S', '--subject NAME', 'Choose your news subject')
do |aString|
- result[:subject] = aString.sub(/\.?$/, '.')
- end
- opts.on_tail('-h', '--help', 'Show this message') do
- puts opts
- exit
- end
- end.parse!(args)
- raise Failure, 'No news group' if result[:groups].empty?
- raise Failure, 'No news server' if result[:server].nil?
- raise Failure, 'No news subject' if result[:subject].nil?
- result
- end
- protected :parse_news_options
-
- def check_line ( anIO, aRegex )
- line = anIO.readline.chomp!
- LOG.debug('news') { "Server: #{line}" }
- unless line =~ aRegex
- LOG.error('news') { "Bad answer: #{line}" }
- @news_status = 'Error.'
- end
- end
- private :check_line
-
- #
- # Post the news.
- #
- def news! ( *args )
- error_handling :news_failed
-
- print_body(NEWS, parse_news_options(*args)) unless NEWS.exist?
-
- @news_status = 'Sent.'
- NEWS.open('r') do |file|
- opt = YAML::chop_header(file)
- server, port = opt[:server].split(/:/)
- port ||= 119
- LOG.info('news') { "Nntp Server: #{server}:#{port}" }
- if ask("Post a news, with this subject: #{opt[:subject]}\n" +
- " to #{opt[:groups].join(', ')}\n from #{opt[:from]}\n"
+
- 'Are you sure?', :y) == :n
- LOG.error('news') { 'Aborting' }
- exit
- end
- require 'socket'
- TCPSocket.open(server, port) do |f|
- check_line(f, /^200/)
- f.puts 'post'
- check_line(f, /^340/)
- f.puts "Newsgroups: #{opt[:groups].join(', ')}"
- f.puts "From: #{opt[:from]}"
- f.puts "Subject: #{opt[:subject]}"
- f.puts
- file.each do |line|
- f.print line.gsub(/^\./, ' .')
- end
- f.puts '.'
- check_line(f, /^240/)
- f.puts 'quit'
- check_line(f, /^205/)
- end
- end
- NEWS.delete
- @out.puts @news_status
- end
-
- def news_failed
- if defined? NEWS and NEWS.exist?
- LOG.info "#{NEWS}: Contains the generated news" +
- "(generated from #{@@message})"
- end
- end
-
- def news_conf_checker
- %w[ NNTPSERVER ].each do |var|
- if ENV[var].nil? or ENV[var].empty?
- LOG.error "environment variable `#{var}' not set"
- end
- end
- end
-
- add_conf_checker :news_conf_checker
-
-end # class Vcs
Index: vcs/Rakefile
--- vcs/Rakefile (revision 206)
+++ vcs/Rakefile (working copy)
@@ -1,73 +1,8 @@
-require 'rubygems'
-require 'rake'
-require 'rake/testtask'
-require 'rake/packagetask'
-require 'rake/rdoctask'
-require 'rake/gempackagetask'
-require 'rake/contrib/rubyforgepublisher'
-
-PKG_VERSION = "0.2.#{`vcs-svn rev`.chomp}"
-
-PKG_FILES = FileList[*%w"
- src/**/*.rb
- ruby_ex/**/*.rb
- bin/**/*
- doc/**/*
- [A-Z]*
-"].exclude(/\b\.svn\b|\..*\.sw[op]$|~$|README/)
-
-desc 'Default Task'
-task :default => :package
-
-desc 'Publish to RubyForge'
-task :rubyforge do
- Rake::RubyForgePublisher.new('vcs', 'ertai').upload
-end
-
-
-Rake::RDocTask.new('doc') do |rdoc|
- rdoc.title = 'Vcs -- A wrapper over any version control system'
- rdoc.template = 'kilmer'
- #rdoc.template = 'doc/jamis'
- rdoc.options << '--line-numbers' << '--inline-source'
- #rdoc.rdoc_files.add('src/vcs.rb', 'src/**/*.rb')
- rdoc.rdoc_files.add('src/**/*.rb')
- #rdoc.main =
-end
-
-
-# The Gem specification
-spec = Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = 'vcs'
- s.version = PKG_VERSION
- s.summary = 'A wrapper over any version control system'
- s.description = '
- Version control systems (Subversion, CVS, PRCS...), however useful,
- are not very extensible: adding new features can be cumbersome, especially
- if you want them for different such systems at once.
- Vcs provide a simple dynamic hierarchy for Version Control Systems.
- '
-
- s.bindir = 'bin'
- s.executables = %w[ vcs vcs-svn vcs-cvs vcs-prcs ]
- s.default_executable = 'vcs'
- s.files = PKG_FILES.to_a
- s.require_path = 'src'
- s.autorequire = 'vcs'
-
- s.has_rdoc = true
- s.author = 'Nicolas Pouillard'
- s.email = 'ertai(a)lrde.epita.fr'
- s.homepage = 'https://svn.lrde.epita.fr/svn/lrdetools/trunk/vcs/'
- s.rubyforge_project = s.name
-end
-
-# Create compressed packages
-Rake::GemPackageTask.new(spec) do |p|
- p.gem_spec = spec
- # p.need_tar = true
- # p.need_zip = true
-end
-
+# Author:: The TTK Team. -*- ruby -*-
+# Copyright:: Copyright (c) 2005 TTK team. All rights reserved.
+# License:: Ruby License
+# Revision:: $Id$
+require 'rubygems'
+require_gem 'core_ex'
+load 'core_ex/rakefile_base.rf'
Index: vcs/src/diffstat.rb
--- vcs/src/diffstat.rb (revision 206)
+++ vcs/src/diffstat.rb (working copy)
@@ -1,30 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
-# License:: GNU General Public License (GPL).
-# Revision:: $Id$
-
-require 'vcs/vcs'
-
-class Vcs
- @@diffstat = 'diffstat'.to_cmd
-
- # Use the diffstat command to
- # display statitics on your patch.
- def diffstat! ( *a )
- check_diffstat
- data_diff = diff(*a)
- cmd = @@diffstat < data_diff.output.open > [@out_path, @err_path]
- cmd.sys
- end
- alias_command :ds, :diffstat
-
- def check_diffstat
- unless `diffstat -V` =~ /diffstat version/
- raise ArgumentError, 'The `diffstat\' tool is needed by Vcs.diffstat'
- end
- end
-
- add_conf_checker :check_diffstat
-
-end # class Vcs
-
Index: vcs/lib/vcs/edit.rb
--- vcs/lib/vcs/edit.rb (revision 0)
+++ vcs/lib/vcs/edit.rb (revision 0)
@@ -0,0 +1,15 @@
+# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
+# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
+# License:: GNU General Public License (GPL).
+# Revision:: $Id$
+
+require 'vcs/vcs'
+
+class Vcs
+
+ def edit! ( *files )
+ cmd = EDITOR + files.flatten.map { |x| x.to_s } > [STDOUT, STDERR]
+ cmd.run(@runner)
+ end
+
+end # class Vcs
Property changes on: vcs/lib/vcs/edit.rb
___________________________________________________________________
Name: svn:keywords
+ Id
Index: vcs/src/svn.rb
--- vcs/src/svn.rb (revision 206)
+++ vcs/src/svn.rb (working copy)
@@ -1,29 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/vcs'
-require 'vcs/tools'
-
-CL = Pathname.new('ChangeLog')
-ADD_CL = Pathname.new(',ChangeLog')
-TMP_CL = Pathname.new(',,ChangeLog')
-
-class Svn < Vcs
-
- class Failure < Vcs::Failure
- end
-
- def initialize ( aCmd='svn' )
- super
- end
-
- %w[ blame cat cleanup copy export import list log merge mkdir move propedit
- switch resolved revert info propdel propget proplist propset ].each do |m|
- add_basic_method(m)
- end
-
-end # class Svn
Index: vcs/NEWS
--- vcs/NEWS (revision 0)
+++ vcs/NEWS (revision 0)
@@ -0,0 +1,3 @@
+New in 0.3 ...:
+ * help
+ * full stream based
Index: vcs/src/revision.rb
--- vcs/src/revision.rb (revision 206)
+++ vcs/src/revision.rb (working copy)
@@ -1,18 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/svn'
-
-class Svn
-
- def revision! ( *args )
- @out.puts info.read[/^Revision:\s+(\d+)/, 1]
- end
-
- alias_command :rev, :revision
-
-end # class Svn
Index: vcs/src/changelog.rb
--- vcs/src/changelog.rb (revision 206)
+++ vcs/src/changelog.rb (working copy)
@@ -1,115 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
-# License:: GNU General Public License (GPL).
-# Revision:: $Id: header 98 2004-09-29 12:07:43Z ertai $
-
-require 'vcs/vcs'
-require 'vcs/svn'
-
-class Svn
-
- @@file_st =
- {
- 'A' => 'New',
- 'D' => 'Remove',
- }
- @@file_st.default = ''
-
- @@prop_st =
- {
- 'M' => 'Changed property'
- }
-
- def mkchangelog_from_status ( *args )
- result = []
- from_status(*args) do |line, file_st, prop_st, copy_st, file|
- next if file_st =~ /[?X]/
- next if file == 'ChangeLog'
- ls = []
- ls << @@file_st[file_st] if @@file_st.has_key? file_st
- ls << @@prop_st[prop_st].downcase if @@prop_st.has_key? prop_st
- result << [file, ls.join(', ')]
- end
- raise Failure, 'No changes, so no ChangeLog entry.' if result.empty?
- result
- end
- private :mkchangelog_from_status
-
-end # class Svn
-
-
-class Vcs
-
- class MustBeFilled < Exception
- attr_reader :file
- def initialize ( file )
- @file = file
- super("You must fill this file: `#{file.to_s}'")
- end
- end
-
- def mkchangelog! ( *args )
- error_handling :changelog_failed
-
- cl = ADD_CL
-
- if cl.exist?
- f = cl.open('r')
- if f.readline !~ /^===/
- f.rewind
- return f
- end
- f.close
- else
- cl_add = mkchangelog_from_status(*args)
- LOG.warn "Creating a new `#{cl}' file"
- cl.open('w') do |f|
- f.puts '=== Fill this file correctly and remove this line ==='
- f.puts Time.now.strftime("%Y-%m-%d #{FULL_EMAIL}")
- f.puts
- cl_add.each do |file, str|
- f.puts "\t* #{file}: #{str}."
- end
- end
- end
-
- raise MustBeFilled, cl
- end
-
- def concat_changelog! ( *args )
- error_handling :changelog_failed
-
- unless CL.exist?
- raise Failure, "No `#{CL}', you are probably not in a valid
directory."
- end
-
- if cl = mkchangelog(*args)
-
- unless TMP_CL.exist?
- LOG.info "Moving `#{CL}' to `#{TMP_CL}' ..."
- CL.rename(TMP_CL)
- end
-
- CL.open('w') do |file|
- LOG.info "Prepending `#{ADD_CL}' to `#{CL}' ..."
- file.print cl.read
- file.puts
- file.print TMP_CL.read
- end
-
- end
- end
-
- def changelog_failed
- if TMP_CL.exist?
- LOG.info "Restoring `#{CL}' from `#{TMP_CL}' ..."
- TMP_CL.rename(CL)
- end
- LOG.info "#{ADD_CL}: Contains your ChangeLog entry" if ADD_CL.exist?
- end
-
- alias_command :mkcl, :mkchangelog
- alias_command :ctcl, :concat_changelog
-
-end # class Vcs
-
Index: vcs/src/status.rb
--- vcs/src/status.rb (revision 206)
+++ vcs/src/status.rb (working copy)
@@ -1,17 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
-# License:: GNU General Public License (GPL).
-# Revision:: $Id$
-
-class Svn
-
- def from_status ( *args, &block )
- status(*args).output.each_line do |line|
- next unless line =~ /^.{5} /
- m = /^(.)(.).(.).\s*(.*)$/.match(line)
- block[*m.to_a]
- end
- end
- protected :from_status
-
-end # class Svn
Index: vcs/src/last_changed_date.rb
--- vcs/src/last_changed_date.rb (revision 206)
+++ vcs/src/last_changed_date.rb (working copy)
@@ -1,16 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
-# License:: GNU General Public License (GPL).
-# $Id$
-
-require 'vcs/svn'
-
-class Svn
-
- def last_changed_date! ( *args )
- @out.puts info.read[/^Last Changed Date:.*?\(([^)]*)\).*$/, 1]
- end
-
- alias_command :date, :last_changed_date
-
-end # class Svn
Index: vcs/src/diff.rb
--- vcs/src/diff.rb (revision 206)
+++ vcs/src/diff.rb (working copy)
@@ -1,18 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
-# License:: GNU General Public License (GPL).
-# Revision:: $Id$
-
-class Svn
-
- def diffw_from_status! ( *args )
- files = Set.new
- from_status(*args) do |line, file_st, prop_st, cpy, file|
- next if file_st =~ /[?X]/
- next if file == 'ChangeLog'
- files << Pathname.new(file)
- end
- diffw!(*files.delete_if { |f| f.directory? })
- end
-
-end # class Svn
Index: vcs/src/mycommit.rb
--- vcs/src/mycommit.rb (revision 206)
+++ vcs/src/mycommit.rb (working copy)
@@ -1,86 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/vcs'
-require 'ask'
-
-class Vcs
-
- COMMITED = Pathname.new(',commited')
-
- def common_commit! ( *args, &block )
-
- opts, args = args.partition { |a| a =~ /^-/ }
-
- update!
-
- unless COMMITED.exist?
-
- begin
- mkchangelog(*args)
- rescue MustBeFilled => ex
- edit! ex.file
- end
-
- message(*args)
-
- edit! @@message
-
- if ask('Committing, are you sure?', :y) == :n
- commit_failed
- end
-
- concat_changelog!(*args)
-
- #pager! diff
- #pager! status
-
- args << 'ChangeLog' unless args.grep(/^[^-]/).empty?
-
- if commit!('-F', ADD_CL, *(opts + args))
- ADD_CL.rename(COMMITED)
- TMP_CL.delete if TMP_CL.exist?
- else
- commit_failed
- end
-
- update!
-
- else
-
- message(*args)
- edit! @@message
-
- end
-
-
- rev = revision.read.to_i
-
- block.call(rev) if block_given?
-
- LOG.info 'Deleting junk files...'
- TMP_CL.delete if TMP_CL.exist?
- ADD_CL.delete if ADD_CL.exist?
- COMMITED.delete if COMMITED.exist?
- messages = Pathname.new(',messages')
- messages.mkpath unless messages.directory?
- message_rev = messages + "#{@@message}.#{rev}"
- LOG.info "Moving `#{@@message}' to `#{message_rev}'..."
- @@message.rename(message_rev)
- LOG.info "You can remove `#{message_rev}' if everything is ok."
-
- end
- alias_command :cci, :common_commit
-
- def commit_failed
- LOG.info "#{COMMITED}: Contains your ChangeLog entry" if COMMITED.exist?
- LOG.error 'Aborting'
- LOG.info 'You can rerun the same command to continue the commit'
- raise 'Commit failed'
- end
-
-end # class Vcs
Index: vcs/src/cvs.rb
--- vcs/src/cvs.rb (revision 206)
+++ vcs/src/cvs.rb (working copy)
@@ -1,21 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# 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 $
-
-require 'vcs/vcs'
-
-class Cvs < Vcs
-
- def initialize ( aCmd='cvs' )
- super
- end
-
- %w[ rdiff rtag tag ].each do |m|
- add_basic_method(m)
- end
-
-end # class Cvs
-
Index: vcs/lib/vcs/vcs.rb
--- vcs/lib/vcs/vcs.rb (revision 206)
+++ vcs/lib/vcs/vcs.rb (working copy)
@@ -29,16 +29,16 @@
@cmd = aCmd.to_cmd
@handlers = Set.new
@runner = Commands::Runners::System.new
+ @strict_runner = Commands::Runners::System.new.raise_on_failures
+
+ display_hook = lambda { |cmd| LOG.debug { "running: #{cmd.to_sh}" } }
+
@runner.subscribe_hook(:failure) do |data|
- if data.status
- LOG.error { "exit(#{data.status.exitstatus})" }
- else
- LOG.fatal { 'no exit status' }
- end
- end
- @runner.subscribe_hook(:display_command) do |cmd|
- LOG.debug { "running: #{cmd.to_sh}" }
+ exit((data.status)? data.status.exitstatus : 1)
end
+ @runner.subscribe_hook(:display_command, &display_hook)
+ @strict_runner.subscribe_hook(:display_command, &display_hook)
+
@out, @err = STDOUT, STDERR
end
@@ -85,10 +85,15 @@
cmd = @cmd + args
if @out_path.nil?
cmd = cmd > [@out, @err]
+ if @out == STDOUT
+ cmd.run(@runner)
+ else
+ cmd.run(@strict_runner)
+ end
else
cmd = cmd > [@out_path, @err_path]
+ cmd.run(@strict_runner)
end
- cmd.run(@runner)
end
def sub_vcs
@@ -104,7 +109,16 @@
sub_vcs.run!(*args)
end
- %w[ checkout delete diff status log add update commit ].each do |m|
+ def run_missing! ( name, orig, *args )
+ if name =~ /^(.*)_$/
+ run!($1, *args)
+ else
+ LOG.warn { "unknown method #{orig}" }
+ run!(name, *args)
+ end
+ end
+
+ %w[ checkout help delete diff status log add update commit ].each do |m|
add_basic_method(m)
end
@@ -112,31 +126,16 @@
meth = meth.to_s
if meth =~ /^(.*)!$/
no_bang = $1
- if respond_to? no_bang
- LOG.warn { "Unefficient method call (#{no_bang}), " +
- "prefer define methods with a `!'" }
- send(no_bang, *args).each do |line|
- puts line
- end
- else
- LOG.warn { "unknown method #{meth}" }
- run!(no_bang.sub(/_$/, ''), *args)
- end
+ super unless respond_to? no_bang
+ run_missing!(no_bang, meth, *args)
else
with_bang = meth + '!'
- if respond_to? with_bang
+ return run_missing!(meth, meth, *args) unless respond_to? with_bang
copy = sub_vcs
res = copy.send(with_bang, *args)
- if res.nil?
+ return res unless res.nil?
copy.out.close
copy.out_path
- else
- res
- end
- else
- LOG.warn { "unknown method #{meth}" }
- run!(meth.sub(/_$/, ''), *args)
- end
end
end
Index: vcs/src/mail.rb
--- vcs/src/mail.rb (revision 206)
+++ vcs/src/mail.rb (working copy)
@@ -1,51 +0,0 @@
-# Author:: Nicolas Pouillard <ertai(a)lrde.epita.fr>fr>.
-# Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
-# License:: GNU General Public License (GPL).
-# Revision:: $Id: header 98 2004-09-29 12:07:43Z ertai $
-
-require 'vcs/vcs'
-require 'sendmail'
-
-class Vcs
-
- MAIL = Sendmail::MAIL_FILE
- MAILER = Sendmail.new
- DEFAULT_OPTIONS = %w[ --ask --sign --mime ]
-
- #
- # Mail.
- #
- def mail! ( *args )
- error_handling :mail_failed
- unless MAIL.exist?
- print_body(MAIL, MAILER.parse_mail_options(*(DEFAULT_OPTIONS + args)))
- end
- MAILER.sendmail
- MAIL.delete
- @out.puts 'Mail: Sent.'
- end
-
- def mail_failed
- if defined? MAIL and MAIL.exist?
- LOG.info "#{MAIL}: Contains the generated mail " +
- "(generated from #{@@message})"
- end
- end
-
- def mail_conf_checker
- %w[ EMAIL FULLNAME SMTPSERVER ].each do |var|
- if ENV[var].nil? or ENV[var].empty?
- LOG.error "environment variable `#{var}' not set"
- end
- end
- unless `gpg --version` =~ /^gpg \(GnuPG\)/
- LOG.error 'command not found: gpg'
- end
- unless File.exist?("#{ENV['HOME']}/.gnupg/secring.gpg")
- LOG.error 'no private key: in your ~/.gnupg'
- end
- end
-
- add_conf_checker :mail_conf_checker
-
-end # class Vcs