]> git.pld-linux.org Git - packages/cvsspam.git/blob - cvsspam-branch.diff
77e85d6b5afecb5b348fb2c7d15c10e9e247ea0c
[packages/cvsspam.git] / cvsspam-branch.diff
1 --- cvsspam-0.2.12/CREDITS      2005-07-11 18:53:29.000000000 +0300
2 +++ cvsspam/CREDITS     2006-12-21 11:44:26.837358000 +0200
3 @@ -29,3 +29,10 @@
4    Elan Ruusamäe
5    Steve Fox
6    Christopher Petro
7 +  Robin Getz
8 +  Glen Starrett
9 +  Jonathan Rafkind
10 +  Ryan Dlugosz
11 +  Steve Woodcock
12 +  Andy Selle
13 +  Charles Duffy
14 --- cvsspam-0.2.12/collect_diffs.rb     2005-07-11 18:53:29.000000000 +0300
15 +++ cvsspam/collect_diffs.rb    2006-12-21 11:44:26.827358000 +0200
16 @@ -27,6 +27,13 @@
17  $dirtemplate = "#cvsspam.#{Process.getpgrp}.#{Process.uid}"
18  
19  def find_data_dir
20 +  if $from_address
21 +    safe_from = make_fromaddr_safe_for_filename($from_address)
22 +    Dir["#{$tmpdir}/#{$dirtemplate}.#{safe_from}-*"].each do |dir|
23 +      stat = File.stat(dir)
24 +      return dir if stat.owned?
25 +    end
26 +  end
27    Dir["#{$tmpdir}/#{$dirtemplate}-*"].each do |dir|
28      stat = File.stat(dir)
29      return dir if stat.owned?
30 @@ -35,6 +42,14 @@
31  end
32  
33  
34 +# transform any special / unexpected characters appearing in the argument to
35 +# --from so that they will not cause problems if the value is inserted into
36 +# a file or directory name
37 +def make_fromaddr_safe_for_filename(addr)
38 +  addr.gsub(/[^a-zA-Z0-1.,_-]/, "_")
39 +end
40 +
41 +
42  def blah(msg)
43    if $debug
44      $stderr.puts "collect_diffs.rb: #{msg}"
45 @@ -129,7 +144,14 @@
46    changes = Array.new
47    i = 0
48    while i < cvs_info.length
49 -    changes << ChangeInfo.new(cvs_info[i], cvs_info[i+=1], cvs_info[i+=1])
50 +    change_file = cvs_info[i]
51 +    # It's been reported,
52 +    # http://lists.badgers-in-foil.co.uk/pipermail/cvsspam-devel/2005-September/000380.html
53 +    # that sometimes the second revision number that CVS gives us contains a
54 +    # trailing newline character, so we strip ws from these values before use,
55 +    change_from = cvs_info[i+=1].strip
56 +    change_to = cvs_info[i+=1].strip
57 +    changes << ChangeInfo.new(change_file, change_from, change_to)
58      i+=1
59    end
60    return changes
61 @@ -222,6 +244,7 @@
62  
63        diff_cmd = Array.new << $cvs_prog << "-nq" << "diff" << "-Nu"
64        diff_cmd << "-kk" if $diff_ignore_keywords
65 +      diff_cmd << "-b" if $diff_ignore_whitespace
66  
67        if change.isAddition
68          file.write "#A "
69 @@ -333,9 +356,11 @@
70  end
71  
72  $config = nil
73 +$from_address = nil
74  $cvs_prog = "cvs"
75  $debug = false
76  $diff_ignore_keywords = false
77 +$diff_ignore_whitespace = false
78  $task_keywords = []
79  
80  unless ENV.has_key?('CVSROOT')
81 @@ -387,6 +412,7 @@
82    end
83    $config = arg if opt=="--config"
84    $debug = true if opt == "--debug"
85 +  $from_address = arg if opt == "--from"
86  end
87  
88  blah("CVSROOT is #{ENV['CVSROOT']}")
89 --- cvsspam-0.2.12/cvsspam-doc.xml      2005-07-11 18:53:29.000000000 +0300
90 +++ cvsspam/cvsspam-doc.xml     2006-12-21 11:44:26.837358000 +0200
91 @@ -452,6 +452,23 @@
92  </screen></informalexample>
93        </para>
94    </section>
95 +
96 +  <section>
97 +    <title>RT</title>
98 +
99 +    <para>For Gforge, when a CVS log comment contains text like <userinput>Fix
100 +    for Bug [#123]</userinput>, or <userinput>Task [T456] ...</userinput>, the
101 +    text "[#123]" or "[T456]" will become a hyper-link to that Gforge page in
102 +    the generated email.  The format [#<replaceable>nnn</replaceable>] and
103 +    [T<replaceable>nnn</replaceable>] is taken from the existing plugin for
104 +    Gforge called cvstracker.</para>
105 +
106 +    <para>To enable, give your Gforge's URL in CVSspam's configuration file:
107 +<informalexample><screen>$gforgeBugURL = "http://gforge.org/tracker/index.php?func=detail&amp;aid=%s"
108 +$gforgeTaskURL = "http://gforge.org/pm/task.php?func=detailtask&amp;project_task_id=%s"</screen></informalexample>
109 +    The marker %s tells CVSspam where in the URL to put the bugId from the
110 +    log message.</para>
111 +  </section>
112  </section>
113  
114  <section><title>CVS Web Frontends</title>
115 --- cvsspam-0.2.12/cvsspam.conf 2005-07-11 18:53:30.000000000 +0300
116 +++ cvsspam/cvsspam.conf        2006-12-21 11:44:26.827358000 +0200
117 @@ -34,11 +34,19 @@
118  #
119  #     When $jiraURL is given, text of the form 'project-1234' will be linked
120  #   to this issue in JIRA.
121 +#
122 +#     When $xplannerStoryURL, $xplannerIterationURL and $xplannerProjectURL are
123 +#   given, text of the form XS1234 will be linked to XPlanner stories; text of
124 +#   the form XI1234 will be linked to XPlanner iterations; and text of the form
125 +#   XP1234 will be linked to XPlanner projects.
126  
127  #$bugzillaURL = "http://bugzilla.mozilla.org/show_bug.cgi?id=%s"
128  
129  #$jiraURL = "http://jira.atlassian.com/secure/ViewIssue.jspa?key=%s"
130  
131 +#$xplannerStoryURL = "http://www.example.com/xplanner/do/view/userstory?oid=%s"
132 +#$xplannerIterationURL = "http://www.example.com/xplanner/do/view/iteration?oid=%s"
133 +#$xplannerProjectURL = "http://www.example.com/xplanner/do/view/project?oid=%s"
134  
135  # Link to Wiki systems
136  # 
137 @@ -119,12 +127,21 @@
138  # cvsdiff keyword ignoring                  (Default: show changes in keywords)
139  #
140  #     Changes in CVS keywords can be distracting.  For instance, the
141 -#   $Revision$ keyword will change on each commit.  Set this value to true
142 +#   $Revision$ keyword will change on each commit.  Set this value to true
143  #   to exclude changes in keyword fields (adds the -kk option to cvs diff).
144  
145  #$diff_ignore_keywords = true
146  
147  
148 +# cvsdiff whitespace ignoring               (Default: show whitespace-only changes)
149 +#
150 +#   Whitespace-only changes can distract from the rest of a diff. Set this
151 +#   value to true to exclude changes in the amount of whitespace (adds the -b
152 +#   option to cvs diff).
153 +
154 +$diff_ignore_whitespace = true
155 +
156 +
157  # $no_removed_file_diff and $no_added_file_diff
158  #
159  #     Set both these options, and emails will only include diffs for files
160 @@ -177,3 +194,13 @@
161  #   them happy, you can say $files_in_subject = true here.
162  
163  #$files_in_subject = false
164 +
165 +
166 +
167 +# Email size limit                                        (Default: around 2MB)
168 +#
169 +#     When large changes are committed, large CVSspam emails can result.  Here
170 +#   you can set the size of email that CVSspam is not allowed to append any
171 +#   more diffs onto.  Specify the number of bytes.
172 +
173 +#$mail_size_limit = 2097152
174 --- cvsspam-0.2.12/cvsspam.rb   2005-07-11 18:53:29.000000000 +0300
175 +++ cvsspam/cvsspam.rb  2006-12-21 17:36:44.342608880 +0200
176 @@ -20,6 +20,7 @@
177  
178  $version = "0.2.12"
179  
180 +require 'time'
181  
182  $maxSubjectLength = 200
183  $maxLinesPerDiff = 1000
184 @@ -35,10 +36,6 @@
185    a<b ? a : b
186  end
187  
188 -# NB must ensure the time is UTC
189 -# (the Ruby Time object's strftime() doesn't supply a numeric timezone)
190 -DATE_HEADER_FORMAT = "%a, %d %b %Y %H:%M:%S +0000"
191 -
192  # Perform (possibly) multiple global substitutions on a string.
193  # the regexps given as keys must not use capturing subexpressions '(...)'
194  class MultiSub
195 @@ -116,6 +113,8 @@
196    UNDERSCORE = chr("_")
197    SPACE = chr(" ")
198    TAB = chr("\t")
199 +  HOOK = chr("?")
200 +  EQUALS = chr("=")
201  
202    # encode a header value according to the RFC-2047 quoted-printable spec,
203    # allowing non-ASCII characters to appear in header values, and wrapping
204 @@ -137,7 +136,7 @@
205    # return a string representing the given character-code in quoted-printable
206    # format
207    def quoted_encode_char(b)
208 -    if b>126 || b==UNDERSCORE || b==TAB
209 +    if b>126 || b==UNDERSCORE || b==TAB || b==HOOK || b==EQUALS
210        sprintf("=%02x", b)
211      elsif b == SPACE
212        "_"
213 @@ -388,6 +387,7 @@
214  class FileEntry
215    def initialize(path)
216      @path = path
217 +    @fromVer = @toVer = nil
218      @lineAdditions = @lineRemovals = 0
219      @repository = Repository.get(path)
220      @repository.merge_common_prefix(basedir())
221 @@ -533,6 +533,14 @@
222  # TODO: consolidate these into a nicer framework,
223  mailSub = proc { |match| "<a href=\"mailto:#{match}\">#{match}</a>" }
224  urlSub = proc { |match| "<a href=\"#{match}\">#{match}</a>" }
225 +gforgeTaskSub = proc { |match|
226 +  match =~ /([0-9]+)/
227 +  "<a href=\"#{$gforgeTaskURL.sub(/%s/, $1)}\">#{match}</a>"
228 +}
229 +gforgeBugSub = proc { |match|
230 +  match =~ /([0-9]+)/
231 +  "<a href=\"#{$gforgeBugURL.sub(/%s/, $1)}\">#{match}</a>"
232 +}
233  bugzillaSub = proc { |match|
234    match =~ /([0-9]+)/
235    "<a href=\"#{$bugzillaURL.sub(/%s/, $1)}\">#{match}</a>"
236 @@ -544,11 +552,27 @@
237    match =~ /([0-9]+)/
238    "<a href=\"#{$ticketURL.sub(/%s/, $1)}\">#{match}</a>"
239  }
240 +issueSub = proc { |match|
241 +  match =~ /([0-9]+)/
242 +  "<a href=\"#{$issueURL.sub(/%s/, $1)}\">#{match}</a>"
243 +}
244  wikiSub = proc { |match| 
245 -  match =~ /\[\[(.*)\]\]/
246 +  match =~ /\[\[(.*?)\]\]/
247    raw = $1
248    "<a href=\"#{$wikiURL.sub(/%s/, urlEncode(raw))}\">[[#{raw}]]</a>"
249  }
250 +xplannerIterationSub = proc { |match|
251 +  match =~ /([0-9]+)/
252 +  "<a href=\"#{$xplannerIterationURL.sub(/%s/, $1)}\">#{match}</a>"
253 +}
254 +xplannerProjectSub = proc { |match|
255 +  match =~ /([0-9]+)/
256 +  "<a href=\"#{$xplannerProjectURL.sub(/%s/, $1)}\">#{match}</a>"
257 +}
258 +xplannerStorySub = proc { |match|
259 +  match =~ /([0-9]+)/
260 +  "<a href=\"#{$xplannerStoryURL.sub(/%s/, $1)}\">#{match}</a>"
261 +}
262  commentSubstitutions = {
263                 '(?:mailto:)?[\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+\b' => mailSub,
264                 '\b(?:http|https|ftp):[^ \t\n<>"]+[\w/]' => urlSub
265 @@ -670,6 +694,12 @@
266    def diff(file)
267      '-&gt;'
268    end
269 +
270 +  # may be overridden by subclasses that are able to make a hyperlink to a
271 +  # history log for a file
272 +  def log(file)
273 +    ''
274 +  end
275  end
276  
277  # Superclass for objects that can link to CVS frontends on the web (ViewCVS,
278 @@ -710,6 +740,14 @@
279      "<a href=\"#{diff_url(file)}\">#{super(file)}</a>"
280    end
281  
282 +  def log(file)
283 +    link = log_url(file)
284 +    if link
285 +      return "<span id=\"info\">(<a href=\"#{link}\">log</a>)</span>"
286 +    end
287 +    return nil
288 +  end
289 +
290   protected
291    def add_repo(url)
292      if @repository_name
293 @@ -722,6 +760,10 @@
294        url
295      end
296    end
297 +
298 +  def log_url(file)
299 +    nil
300 +  end
301  end
302  
303  # Link to ViewCVS
304 @@ -745,6 +787,15 @@
305    def diff_url(file)
306      add_repo("#{@base_url}#{urlEncode(file.path)}.diff?r1=#{file.fromVer}&amp;r2=#{file.toVer}")
307    end
308 +
309 +  def log_url(file)
310 +    if file.toVer
311 +      log_anchor = "#rev#{file.toVer}"
312 +    else
313 +      log_anchor = ""
314 +    end
315 +    add_repo("#{@base_url}#{urlEncode(file.path)}#{log_anchor}")
316 +  end
317  end
318  
319  # Link to Chora, from the Horde framework
320 @@ -767,9 +818,9 @@
321  class CVSwebFrontend < WebFrontend
322    def path_url(path, tag)
323      if tag == nil
324 -      add_repo(@base_url + urlEncode(path))
325 +      add_repo(@base_url + urlEncode(path) + "/")
326      else
327 -      add_repo("#{@base_url}#{urlEncode(path)}?only_with_tag=#{urlEncode(tag)}")
328 +      add_repo("#{@base_url}#{urlEncode(path)}/?only_with_tag=#{urlEncode(tag)}")
329      end
330    end
331  
332 @@ -780,6 +831,17 @@
333    def diff_url(file)
334      add_repo("#{@base_url}#{urlEncode(file.path)}.diff?r1=text&amp;tr1=#{file.fromVer}&amp;r2=text&amp;tr2=#{file.toVer}&amp;f=h")
335    end
336 +
337 +  protected
338 +
339 +  def log_url(file)
340 +    if file.toVer
341 +      log_anchor = "#rev#{file.toVer}"
342 +    else
343 +      log_anchor = ""
344 +    end
345 +    add_repo("#{@base_url}#{urlEncode(file.path)}#{log_anchor}")
346 +  end
347  end
348  
349  
350 @@ -958,7 +1020,7 @@
351      end
352      shift(nil)
353      if @truncatedLineCount>0
354 -      println("<strong class=\"error\" title=\"#{@truncatedLineCount} lines truncated at column #{$maxDiffLineLength}\">[Note: Some over-long lines of diff output only partialy shown]</strong>")
355 +      println("<strong class=\"error\" title=\"#{@truncatedLineCount} lines truncated at column #{$maxDiffLineLength}\">[Note: Some over-long lines of diff output only partially shown]</strong>")
356      end
357    end
358  
359 @@ -1247,10 +1309,16 @@
360  $no_diff = false
361  $task_keywords = ['TODO', 'FIXME']
362  $bugzillaURL = nil
363 +$gforgeBugURL = nil
364 +$gforgeTaskURL = nil
365  $wikiURL = nil
366  $jiraURL = nil
367  $ticketURL = nil
368 +$issueURL = nil
369  $viewcvsURL = nil
370 +$xplannerIterationURL = nil
371 +$xplannerProjectURL = nil
372 +$xplannerStoryURL = nil
373  $choraURL = nil
374  $cvswebURL = nil
375  $from_address = nil
376 @@ -1261,6 +1329,7 @@
377  # 2MiB limit on attached diffs,
378  $mail_size_limit = 1024 * 1024 * 2
379  $arg_charset = nil
380 +$cvsroot_email_header = false
381  
382  require 'getoptlong'
383  
384 @@ -1353,7 +1422,13 @@
385  
386  
387  if $bugzillaURL != nil
388 -  commentSubstitutions['\b[Bb][Uu][Gg]\s*#?[0-9]+'] = bugzillaSub
389 +  commentSubstitutions['\b[Bb]([Uu][Gg])?\s*[#:]?\s*\[?[0-9]+\]?'] = bugzillaSub
390 +end
391 +if $gforgeBugURL != nil
392 +  commentSubstitutions['\B\[#[0-9]+\]'] = gforgeBugSub
393 +end
394 +if $gforgeTaskURL != nil
395 +  commentSubstitutions['\B\[[Tt][0-9]+\]'] = gforgeTaskSub
396  end
397  if $jiraURL != nil
398    commentSubstitutions['\b[a-zA-Z]+-[0-9]+\b'] = jiraSub
399 @@ -1361,9 +1436,21 @@
400  if $ticketURL != nil
401    commentSubstitutions['\b[Tt][Ii][Cc][Kk][Ee][Tt]\s*#?[0-9]+\b'] = ticketSub
402  end
403 +if $issueURL != nil
404 +  commentSubstitutions['\b[Ii][Ss][Ss][Uu][Ee]\s*#?[0-9]+\b'] = issueSub
405 +end
406  if $wikiURL != nil
407    commentSubstitutions['\[\[.+\]\]'] = wikiSub
408  end
409 +if $xplannerIterationURL != nil
410 +  commentSubstitutions['\bXI\[?[0-9]+\]?'] = xplannerIterationSub
411 +end
412 +if $xplannerProjectURL != nil
413 +  commentSubstitutions['\bXP\[?[0-9]+\]?'] = xplannerProjectSub
414 +end
415 +if $xplannerStoryURL != nil
416 +  commentSubstitutions['\bXS\[?[0-9]+\]?'] = xplannerStorySub
417 +end
418  $commentEncoder = MultiSub.new(commentSubstitutions)
419  
420  
421 @@ -1546,11 +1633,14 @@
422      elsif file.removal?
423        name = "<span id=\"removed\">#{name}</span>"
424      end
425 +    mail.print("<td>")
426      if file.has_diff?
427 -      mail.print("<td><tt>#{prefix}<a href=\"#file#{file_count}\">#{name}</a></tt></td>")
428 +      mail.print("<tt>#{prefix}<a href=\"#file#{file_count}\">#{name}</a></tt>")
429      else
430 -      mail.print("<td><tt>#{prefix}#{name}</tt></td>")
431 +      mail.print("<tt>#{prefix}#{name}</tt>")
432      end
433 +    mail.print(" #{$frontend.log(file)}")
434 +    mail.print("</td>")
435      if file.isEmpty
436        mail.print("<td colspan=\"2\" align=\"center\"><small id=\"info\">[empty]</small></td>")
437      elsif file.isBinary
438 @@ -1686,6 +1776,8 @@
439  # sensible header formatting, and for ensuring that the body is seperated
440  # from the message headers by a blank line (as it is required to be).
441  class MailContext
442 +  ENCODE_HEADERS = ["Subject", "X-CVSspam-Module-Path"]
443 +
444    def initialize(io)
445      @done_headers = false
446      @io = io
447 @@ -1695,8 +1787,8 @@
448    # called
449    def header(name, value)
450      raise "headers already commited" if @done_headers
451 -    if name == "Subject"
452 -      $encoder.encode_header(@io, "Subject", value)
453 +    if ENCODE_HEADERS.include?(name)
454 +      $encoder.encode_header(@io, name, value)
455      else
456        @io.puts("#{name}: #{value}")
457      end
458 @@ -1769,7 +1861,7 @@
459        ctx.header("To", recipients.map{|addr| addr.encoded}.join(','))
460        blah("Mail From: <#{from}>")
461        ctx.header("From", from.encoded) if from
462 -      ctx.header("Date", Time.now.utc.strftime(DATE_HEADER_FORMAT))
463 +      ctx.header("Date", Time.now.rfc2822)
464        yield ctx
465      end
466    end
467 @@ -1800,10 +1892,10 @@
468    return unless $fileEntries.length == 1
469    file = $fileEntries[0]
470    name = zap_header_special_chars(file.path)
471 -  unless file.fromVer == "NONE"
472 +  if file.fromVer
473      mail.header("References", make_msg_id("#{name}.#{file.fromVer}", $hostname))
474    end
475 -  unless file.toVer == "NONE"
476 +  if file.toVer
477      mail.header("Message-ID", make_msg_id("#{name}.#{file.toVer}", $hostname))
478    end
479  end
480 @@ -1834,6 +1926,14 @@
481      end
482    end
483    mail.header("X-Mailer", "CVSspam #{$version} <http://www.badgers-in-foil.co.uk/projects/cvsspam/>")
484 +  if $cvsroot_email_header
485 +    mod = '/'
486 +    if Repository.count == 1
487 +      rep = Repository.array.first
488 +      mod << rep.common_prefix
489 +    end
490 +    mail.header("X-CVSspam-Module-Path", mod)
491 +  end
492  
493    mail.body do |body|
494      make_html_email(body)
495 --- cvsspam-0.2.12/record_lastdir.rb    2005-07-11 18:53:29.000000000 +0300
496 +++ cvsspam/record_lastdir.rb   2006-12-21 11:44:26.827358000 +0200
497 @@ -4,7 +4,6 @@
498  #   http://www.badgers-in-foil.co.uk/projects/cvsspam/
499  # Copyright (c) David Holroyd
500  
501 -$repositorydir = ARGV.shift
502  
503  $tmpdir = ENV["TMPDIR"] || "/tmp"
504  
505 @@ -19,6 +18,36 @@
506    nil
507  end
508  
509 +
510 +# transform any special / unexpected characters appearing in the argument to
511 +# --from so that they will not cause problems if the value is inserted into
512 +# a file or directory name
513 +def make_fromaddr_safe_for_filename(addr)
514 +  addr.gsub(/[^a-zA-Z0-1.,_-]/, "_")
515 +end
516 +
517 +# Option processing doesn't use GetoptLong (for the moment) bacause arguments
518 +# given to this script by CVS include the names of committed files.  It
519 +# seems quite possible that one of those file names could begin with a '-'
520 +# and therefore be treated by GetoptLong as a value which requires processing.
521 +# This would probably result in an error.
522 +#
523 +# [That could be worked around by placing a '--' option (which tells GetoptLong
524 +# to stop processing option arguments) at the very end of the arguments to
525 +# record_lastdir.rb in commitinfo, but that's very easily forgotten, and isn't
526 +# really backwards compatable with the behaviour of older CVSspam releases.]
527 +if ARGV.first == "--from"
528 +  # we could, of course, be tricked, if the first committed file in the list
529 +  # happened to be named '--from' :S
530 +
531 +  # drop the "--from"
532 +  ARGV.shift
533 +  # and use the value which was given following the option,
534 +  $dirtemplate << "." << make_fromaddr_safe_for_filename(ARGV.shift)
535 +end
536 +
537 +$repositorydir = ARGV.shift
538 +
539  $datadir = find_data_dir()
540  
541  if $datadir==nil
This page took 0.053571 seconds and 2 git commands to generate.