SOURCES: cvsspam-svnspam-branch.diff - update fropm svn

glen glen at pld-linux.org
Thu Mar 5 00:23:38 CET 2009


Author: glen                         Date: Wed Mar  4 23:23:38 2009 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- update fropm svn

---- Files affected:
SOURCES:
   cvsspam-svnspam-branch.diff (1.4 -> 1.5) 

---- Diffs:

================================================================
Index: SOURCES/cvsspam-svnspam-branch.diff
diff -u SOURCES/cvsspam-svnspam-branch.diff:1.4 SOURCES/cvsspam-svnspam-branch.diff:1.5
--- SOURCES/cvsspam-svnspam-branch.diff:1.4	Thu Mar  5 00:09:03 2009
+++ SOURCES/cvsspam-svnspam-branch.diff	Thu Mar  5 00:23:33 2009
@@ -1,91 +1,418 @@
---- cvsspam-svn/svn_cvsspam.rb	2009-03-04 23:47:04.364552847 +0200
-+++ svn/svn_cvsspam.rb	2009-03-05 00:54:18.266649054 +0200
-@@ -18,8 +18,9 @@
- # to your cvssppam.conf
- 
- 
--$version = "0.2.11"
-+$version = "0.2.12"
- 
-+require 'time'
- 
- $maxSubjectLength = 200
- $maxLinesPerDiff = 1000
-@@ -35,10 +36,6 @@
-   a<b ? a : b
- end
- 
--# NB must ensure the time is UTC
--# (the Ruby Time object's strftime() doesn't supply a numeric timezone)
--DATE_HEADER_FORMAT = "%a, %d %b %Y %H:%M:%S +0000"
--
- # Perform (possibly) multiple global substitutions on a string.
- # the regexps given as keys must not use capturing subexpressions '(...)'
- class MultiSub
-@@ -48,7 +45,7 @@
-     @mash = Array.new
-     expr = nil
-     hash.each do |key,val|
--      if expr == nil ; expr="(" else expr<<"|(" end
-+      if expr == nil ; expr="(" else expr << "|(" end
-       expr << key << ")"
-       @mash << val
-     end
-@@ -116,6 +113,8 @@
-   UNDERSCORE = chr("_")
-   SPACE = chr(" ")
-   TAB = chr("\t")
-+  HOOK = chr("?")
-+  EQUALS = chr("=")
- 
-   # encode a header value according to the RFC-2047 quoted-printable spec,
-   # allowing non-ASCII characters to appear in header values, and wrapping
-@@ -137,8 +136,8 @@
-   # return a string representing the given character-code in quoted-printable
-   # format
-   def quoted_encode_char(b)
--    if b>126 || b==UNDERSCORE || b==TAB
--      sprintf("=%02x", b)
-+    if b>126 || b==UNDERSCORE || b==TAB || b==HOOK || b==EQUALS
-+      sprintf("=%02X", b)
-     elsif b == SPACE
-       "_"
-     else
-@@ -163,8 +162,9 @@
- 
-   # gives a string starting "=?", and including a charset specification, that
-   # marks the start of a quoted-printable character sequence
--  def marker_start_quoted
--    "=?#{@charset}?#{@encoding}?"
-+  def marker_start_quoted(charset=nil)
-+    charset = @charset if charset.nil?
-+    "=?#{charset}?#{@encoding}?"
-   end
- 
-   # test to see of the given string contains non-ASCII characters
-@@ -339,8 +339,11 @@
- 
-   # gets the Repository object for the first component of the given path
-   def Repository.get(name)
--    name =~ /^[^\/]+/
--    name = $&
-+    # Leading './' is ignored (for peeps who have done 'cvs checkout .')
-+    # Trailing '/' ensures no match for files in root (we just want dirs)
-+    name =~ /^(?:\.\/)?([^\/]+)\//  
-+    name = $1
-+    name = "/" if name.nil?  # file at top-level?  fake up a name for repo
-     rep = @@repositories[name]
-     if rep.nil?
-       rep =  Repository.new(name)
-@@ -385,6 +388,7 @@
- class FileEntry
-   def initialize(path)
-     @path = path
-+    @fromVer = @toVer = nil
-     @lineAdditions = @lineRemovals = 0
-     @repository = Repository.get(path)
-     @repository.merge_common_prefix(basedir())
-@@ -394,7 +398,7 @@
+--- svn_post_commit_hook.rb	(.../trunk)	(revision 0)
++++ svn_post_commit_hook.rb	(.../branches/svn_support)	(revision 265)
+@@ -0,0 +1,409 @@
++#!/usr/bin/ruby -w
++
++$svnlook_exe = "svnlook"  # default assumes the program is in $PATH
++
++def usage(msg)
++  $stderr.puts(msg)
++  exit(1)
++end
++
++def blah(msg)
++  if $debug
++    $stderr.puts "svn_post_commit_hook.rb: #{msg}"
++  end
++end
++
++$tmpdir = ENV["TMPDIR"] || "/tmp"
++$dirtemplate = "#svnspam.#{Process.getpgrp}.#{Process.uid}"
++# arguments to pass though to 'cvsspam.rb'
++$passthrough_args = []
++
++def make_data_dir
++  dir = "#{$tmpdir}/#{$dirtemplate}-#{rand(99999999)}"
++  Dir.mkdir(dir, 0700)
++  dir
++end
++
++def init
++  $datadir = make_data_dir
++
++  # set PWD so that svnlook can create its .svnlook directory
++  Dir.chdir($datadir)
++end
++
++def cleanup
++  unless $debug
++	  File.unlink("#{$datadir}/logfile")
++	  Dir.rmdir($datadir)
++  end
++end
++
++def send_email
++  cmd = File.dirname($0) + "/cvsspam.rb"
++  unless system(cmd,"--svn","#{$datadir}/logfile", *$passthrough_args)
++    fail "problem running '#{cmd}'"
++  end
++end
++
++# Like IO.popen, but accepts multiple arguments like Kernel.exec
++# (So no need to escape shell metacharacters)
++def safer_popen(*args)
++  IO.popen("-") do |pipe|
++    if pipe==nil
++      exec(*args)
++    else
++      yield pipe
++    end
++  end
++end
++
++
++# Process the command-line arguments in the given list
++def process_args
++  require 'getoptlong'
++
++  opts = GetoptLong.new(
++    [ "--to",     "-t", GetoptLong::REQUIRED_ARGUMENT ],
++    [ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
++    [ "--debug",  "-d", GetoptLong::NO_ARGUMENT ],
++    [ "--from",   "-u", GetoptLong::REQUIRED_ARGUMENT ],
++    [ "--charset",      GetoptLong::REQUIRED_ARGUMENT ]
++  )
++
++  opts.each do |opt, arg|
++    if ["--to", "--config", "--from", "--charset"].include?(opt)
++      $passthrough_args << opt << arg
++    end
++    if ["--debug"].include?(opt)
++      $passthrough_args << opt
++    end
++    $config = arg if opt=="--config"
++    $debug = true if opt == "--debug"
++  end
++
++  $repository = ARGV[0]
++  $revision = ARGV[1]
++
++  unless $revision =~ /^\d+$/
++    usage("revision must be an integer: #{revision.inspect}")
++  end
++  $revision = $revision.to_i
++
++  unless FileTest.directory?($repository)
++    usage("no such directory: #{$repository.inspect}")
++  end
++  $repository =~ /([^\/]+$)/ 
++  $shortrepo = $1
++end
++
++# runs the given svnlook subcommand
++def svnlook(cmd, revision, *args)
++  rev = revision.to_s
++  safer_popen($svnlook_exe, cmd, $repository, "-r", rev, *args) do |io|
++    yield io
++  end
++end
++
++class Change
++  def initialize(filechange, propchange, path)
++    @filechange = filechange
++    @propchange = propchange
++    @path = path
++  end
++
++  attr_accessor :filechange, :propchange, :path
++
++  def property_change?
++    @propchange != " "
++  end
++
++  def file_change?
++    @filechange != "_"
++  end
++
++  def addition?
++    @filechange == "A"
++  end
++
++  def deletion?
++    @filechange == "D"
++  end
++end
++
++
++
++# Line-oriented access to an underlying IO object.  Remembers 'current' line
++# for lookahead during parsing.
++class LineReader
++  def initialize(io)
++    @io = io
++  end
++
++  def current
++    @line
++  end
++
++  def next_line
++    (@line = @io.gets) != nil
++  end
++
++  def assert_current(re)
++    raise "unexpected #{current.inspect}" unless @line =~ re
++    $~
++  end
++
++  def assert_next(re=nil)
++    raise "unexpected end of text" unless next_line
++    unless re.nil?
++      raise "unexpected #{current.inspect}" unless @line =~ re
++    end
++    $~
++  end
++end
++
++
++def read_modified_diff(out, lines, path)
++  lines.assert_next(/^=+$/)
++  lines.assert_next
++  if lines.current =~ /\(Binary files differ\)/
++    process_modified_binary_diff(out, lines, path)
++  else
++    process_modified_text_diff(out, lines, path)
++  end
++end
++
++
++def process_modified_binary_diff(out, lines, path)
++  prev_rev= $revision-1
++  next_rev= $revision
++  out.puts "#V #{prev_rev},#{next_rev}"
++  out.puts "#M #{$shortrepo}/#{path}"
++  out.puts "#U diff x x"
++  out.puts "#U Binary files x and y differ"
++end
++
++
++def process_modified_text_diff(out, lines, path)
++  m = lines.assert_current(/^---.*\(rev (\d+)\)$/)
++  prev_rev = m[1].to_i
++  diff1 = lines.current
++  m = lines.assert_next(/^\+\+\+.*\(rev (\d+)\)$/)
++  next_rev = m[1].to_i
++  diff2 = lines.current
++  out.puts "#V #{prev_rev},#{next_rev}"
++  out.puts "#M #{$shortrepo}/#{path}"
++  out.puts "#U #{diff1}"
++  out.puts "#U #{diff2}"
++  while lines.next_line && lines.current =~ /^[-\+ @\\]/
++    out.puts "#U #{lines.current}"
++  end
++end
++
++def read_added_diff(out, lines, path)
++  lines.assert_next(/^=+$/)
++  lines.assert_next
++  if lines.current =~ /\(Binary files differ\)/
++    process_added_binary_diff(out, lines, path)
++  else
++    process_added_text_diff(out, lines, path)
++  end
++end
++
++def process_added_binary_diff(out, lines, path)
++  next_rev= $revision
++  out.puts "#V NONE,#{next_rev}"
++  out.puts "#A #{$shortrepo}/#{path}"
++  out.puts "#U diff x x"
++  out.puts "#U Binary file x added"
++end
++
++def process_added_text_diff(out, lines, path)
++  m = lines.assert_current(/^---.*\(rev (\d+)\)$/)
++  prev_rev = m[1].to_i
++  diff1 = lines.current
++  m = lines.assert_next(/^\+\+\+.*\(rev (\d+)\)$/)
++  next_rev = m[1].to_i
++  diff2 = lines.current
++  out.puts "#V NONE,#{next_rev}"
++  out.puts "#A #{$shortrepo}/#{path}"
++  out.puts "#U #{diff1}"
++  out.puts "#U #{diff2}"
++  while lines.next_line && lines.current =~ /^[-\+ @\\]/
++    out.puts "#U #{lines.current}"
++  end
++end
++
++def read_deleted_diff(out, lines, path)
++  lines.assert_next(/^=+$/)
++  m = lines.assert_next(/^---.*\(rev (\d+)\)$/)
++  prev_rev = m[1].to_i
++  diff1 = lines.current
++  m = lines.assert_next(/^\+\+\+.*\(rev (\d+)\)$/)
++  next_rev = m[1].to_i
++  diff2 = lines.current
++  out.puts "#V #{prev_rev},NONE"
++  out.puts "#R #{$shortrepo}/#{path}"
++  out.puts "#U #{diff1}"
++  out.puts "#U #{diff2}"
++  while lines.next_line && lines.current =~ /^[-\+ @\\]/
++    out.puts "#U #{lines.current}"
++  end
++end
++
++def read_property_lines(path, prop_name, revision)
++  lines = []
++  svnlook("propget", revision, prop_name, path) do |io|
++    io.each_line do |line|
++      lines << line.chomp
++    end
++  end
++  lines
++end
++
++def assert_prop_match(a, b)
++  if !b.nil? && a != b
++    raise "property mismatch: #{a.inspect}!=#{b.inspect}"
++  end
++end
++
++# We need to read the property change from the output of svnlook, but have
++# a difficulty in that there's no unambiguous delimiter marking the end of
++# a potentially multi-line property value.  Therefore, we do a seperate
++# svn propget on the given file to get the value of the property on its own,
++# and then use that value as a guide as to how much data to read from the
++# svnlook output.
++def munch_prop_text(path, prop_name, revision, lines, line0)
++  prop = read_property_lines(path, prop_name, revision)
++  if prop.empty?
++    assert_prop_match(line0, "")
++    return
++  end
++  assert_prop_match(line0, prop.shift)
++  prop.each do |prop_line|
++    lines.assert_next
++    assert_prop_match(lines.current.chomp, prop_line)
++  end
++end
++
++def read_properties_changed(out, lines, path)
++  prev_rev= $revision-1
++  next_rev= $revision
++  lines.assert_next(/^_+$/)
++  return unless lines.next_line
++  out.puts "#V #{prev_rev},#{next_rev}"
++  out.puts "#P #{$shortrepo}/#{path}"
++# The first three get consumed and not highlighted
++  out.puts "#U "
++  out.puts "#U Property changes:"
++  out.puts "#U "
++  while true
++    break unless lines.current =~ /^Name: (.+)$/
++    prop_name = $1
++    m = lines.assert_next(/^   ([-+]) (.*)/)
++    op = m[1]
++    line0 = m[2]
++    if op == "-"
++      munch_prop_text(path, prop_name, $revision-1, lines, line0)
++      if lines.next_line && lines.current =~ /^   \+ (.*)/
++	munch_prop_text(path, prop_name, $revision, lines, $1)
++	lines.next_line
++      end
++    else  # op == "+"
++      munch_prop_text(path, prop_name, $revision, lines, line0)
++      lines.next_line
++    end
++    out.puts "#U #{m[1]} #{prop_name}:#{m[2]}"
++  end
++  out.puts "#U "
++end
++
++def handle_copy(out, lines, path, from_ref, from_file)
++  prev_rev= $revision-1
++  next_rev= $revision
++  out.puts "#V #{$shortrepo}/#{from_file}:#{prev_rev},#{next_rev}"
++  out.puts "#C #{$shortrepo}/#{path}"
++  if lines.next_line && lines.current =~ /^=+$/
++    m = lines.assert_next(/^---.*\(rev (\d+)\)$/)
++    prev_rev = m[1].to_i
++    diff1 = lines.current
++    m = lines.assert_next(/^\+\+\+.*\(rev (\d+)\)$/)
++    next_rev = m[1].to_i
++    diff2 = lines.current
++    out.puts "#U #{diff1}"
++    out.puts "#U #{diff2}"
++    while lines.next_line && lines.current =~ /^[-\+ @\\]/
++      out.puts "#U #{lines.current}"
++    end
++  else
++    out.puts "#U "
++    out.puts "#U Copied from #{$shortrepo}/#{from_file}:#{from_ref}"
++    out.puts "#U "
++  end
++end
++
++def svnlook_author
++  svnlook("author", $revision) do |io|
++    return io.readline.chomp
++  end
++  nil
++end
++
++def find_author
++  return if $passthrough_args.include?("--from")
++  author = svnlook_author
++  if author
++    blah("Author from svnlook: '#{author}'")
++    $passthrough_args << "--from" << author
++  end
++end
++
++def process_svnlook_log(file)
++  svnlook("log", $revision) do |io|
++    io.each_line do |line|
++      file.puts("#> #{line}")
++    end
++  end
++end
++
++def process_svnlook_diff(file)
++  svnlook("diff", $revision) do |io|
++    lines = LineReader.new(io)
++    while lines.next_line
++      if lines.current =~ /^Modified:\s+(.*)/
++	read_modified_diff(file, lines, $1)
++      elsif lines.current =~ /^Added:\s+(.*)/
++	read_added_diff(file, lines, $1)
++      elsif lines.current =~ /^Copied:\s+(.*) \(from rev (\d+), (.*)\)$/
++	handle_copy(file, lines, $1, $2, $3)
++      elsif lines.current =~ /^Deleted:\s+(.*)/
++	read_deleted_diff(file, lines, $1)
++      elsif lines.current =~ /^Property changes on:\s+(.*)/
++	read_properties_changed(file, lines, $1)
++      elsif lines.current == "\n"
++	# ignore
++      else
++	raise "unable to parse line #{lines.current.inspect}"
++      end
++    end
++  end
++end
++
++def process_commit()
++  File.open("#{$datadir}/logfile", File::WRONLY|File::CREAT) do |file|
++    process_svnlook_log(file)
++    process_svnlook_diff(file)
++  end
++end
++
++
++def main
++  init()
++  process_args()
++  find_author()
++  process_commit()
++  send_email()
++  cleanup()
++end
++
++
++main
+--- cvsspam.rb	(.../trunk)	(revision 265)
++++ cvsspam.rb	(.../branches/svn_support)	(revision 265)
+@@ -398,7 +398,7 @@
  
    # the full path and filename within the repository
    attr_accessor :path
@@ -94,25 +421,7 @@
    attr_accessor :type
    # records number of 'addition' lines in diff output, once counted
    attr_accessor :lineAdditions
-@@ -412,7 +416,7 @@
-   # works out the filename part of #path
-   def file
-     @path =~ /.*\/(.*)/
--    $1 || @path
-+    $1
-   end
- 
-   # set the branch on which this change was committed, and add it to the list
-@@ -430,7 +434,7 @@
-   # works out the directory part of #path
-   def basedir
-     @path =~ /(.*)\/.*/
--    $1 || "/"
-+    $1
-   end
- 
-   # gives the Repository object this file was automatically associated with
-@@ -449,16 +453,27 @@
+@@ -453,17 +453,28 @@
    def removal?
      @type == "R"
    end
@@ -137,171 +446,12 @@
 +  def modifiedprops?
 +    @type == "P"
 +  end
-+
  
++
    # passing true, this object remembers that a diff will appear in the email,
    # passing false, this object remembers that no diff will appear in the email.
-@@ -530,6 +545,14 @@
- # TODO: consolidate these into a nicer framework,
- mailSub = proc { |match| "<a href=\"mailto:#{match}\">#{match}</a>" }
- urlSub = proc { |match| "<a href=\"#{match}\">#{match}</a>" }
-+gforgeTaskSub = proc { |match|
-+  match =~ /([0-9]+)/
-+  "<a href=\"#{$gforgeTaskURL.sub(/%s/, $1)}\">#{match}</a>"
-+}
-+gforgeBugSub = proc { |match|
-+  match =~ /([0-9]+)/
-+  "<a href=\"#{$gforgeBugURL.sub(/%s/, $1)}\">#{match}</a>"
-+}
- bugzillaSub = proc { |match|
-   match =~ /([0-9]+)/
-   "<a href=\"#{$bugzillaURL.sub(/%s/, $1)}\">#{match}</a>"
-@@ -541,9 +564,31 @@
-   match =~ /([0-9]+)/
-   "<a href=\"#{$ticketURL.sub(/%s/, $1)}\">#{match}</a>"
- }
-+issueSub = proc { |match|
-+  match =~ /([0-9]+)/
-+  "<a href=\"#{$issueURL.sub(/%s/, $1)}\">#{match}</a>"
-+}
-+wikiSub = proc { |match| 
-+  match =~ /\[\[(.*?)\]\]/
-+  raw = $1
-+  "<a href=\"#{$wikiURL.sub(/%s/, urlEncode(raw))}\">[[#{raw}]]</a>"
-+}
-+xplannerIterationSub = proc { |match|
-+  match =~ /([0-9]+)/
-+  "<a href=\"#{$xplannerIterationURL.sub(/%s/, $1)}\">#{match}</a>"
-+}
-+xplannerProjectSub = proc { |match|
-+  match =~ /([0-9]+)/
-+  "<a href=\"#{$xplannerProjectURL.sub(/%s/, $1)}\">#{match}</a>"
-+}
-+xplannerStorySub = proc { |match|
-+  match =~ /([0-9]+)/
-+  "<a href=\"#{$xplannerStoryURL.sub(/%s/, $1)}\">#{match}</a>"
-+}
- commentSubstitutions = {
- 		'(?:mailto:)?[\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+\b' => mailSub,
--		'\b(?:http|https|ftp):[^ \t\n<>"]+[\w/]' => urlSub}
-+		'\b(?:http|https|ftp):[^ \t\n<>"]+[\w/]' => urlSub
-+		}
- 
- # outputs commit log comment text supplied by LogReader as preformatted HTML
- class CommentHandler < LineConsumer
-@@ -661,6 +706,12 @@
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/SOURCES/cvsspam-svnspam-branch.diff?r1=1.4&r2=1.5&f=u



More information about the pld-cvs-commit mailing list