Skip to content

Commit 6b153bc

Browse files
committed
Merged in [19056], [19057], and [19058] from rjsparks@nostrum.com:\n Captured the svn hooks used after moving the repository. Fixes ietf-tools#3297.
- Legacy-Id: 19069 Note: SVN reference [19056] has been migrated to Git commit 14df71e Note: SVN reference [19057] has been migrated to Git commit cc3047e Note: SVN reference [19058] has been migrated to Git commit 52d274f
2 parents f09e90d + 52d274f commit 6b153bc

3 files changed

Lines changed: 107 additions & 188 deletions

File tree

hooks/post-commit

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
4545

4646
# Log everything for debug, otherwise use explicit logging (further down)
47-
#[ "$LOGGING" ] || LOGGING=1 { exec $0 "$@" 2>&1 | logger -p local0.info -t "commit"; }
47+
#[ "$LOGGING" ] || LOGGING=1 { exec $0 "$@" 2>&1 | logger -p user.info -t "commit"; }
4848

49-
logger -p local0.info -t "hook" "${0##*/} $*"
49+
logger -p user.info -t "hook" "${0##*/} $*"
5050

5151
repo="$1"
5252
rev="$2"
@@ -56,16 +56,16 @@ program=${0##*/}
5656
progdir=${0%/*}
5757
thishost="$(/bin/hostname)"
5858
thishost="${thishost%%.*}"
59-
svnpath="/home/svn"
60-
trac="/www/tools.ietf.org/tools/ietfdb/"
61-
svn_url="https://svn.tools.ietf.org/svn/tools/ietfdb"
62-
trac_url="https://trac.tools.ietf.org/tools/ietfdb"
59+
svnpath="/a/svn/tools/ietfdb"
60+
trac="/a/www/www6s/trac/ietfdb/"
61+
svn_url="https://svn.ietf.org/svn/tools/ietfdb"
62+
trac_url="https://trac.ietf.org/trac/ietfdb"
6363

6464
# Do a local backup
65-
relpath=${repo#$svnpath/}
66-
bckpath="$svnpath/.backup/$thishost/$relpath"
67-
[ -d $bckpath ] || mkdir -p $bckpath
68-
/usr/bin/svn-fast-backup -q $repo $bckpath
65+
#relpath=${repo#$svnpath/}
66+
#bckpath="$svnpath/.backup/$thishost/$relpath"
67+
#[ -d $bckpath ] || mkdir -p $bckpath
68+
#/usr/bin/svn-fast-backup -q $repo $bckpath
6969

7070
# Inform trac about a new changeset
7171
trac-admin $trac changeset added ietfdb $rev
@@ -75,7 +75,7 @@ comments=$(/usr/bin/svnlook log $repo -r $rev)
7575
files=$(/usr/bin/svnlook changed $repo -r $rev)
7676

7777
dirs=$(/usr/bin/svnlook dirs-changed -r$rev $repo)
78-
logger -p local0.info -t "commit" "dirs '$dirs'"
78+
logger -p user.info -t "commit" "dirs '$dirs'"
7979

8080
# Look for 'requirements.txt' above the committed change. Looking only for
8181
# filechanges, not for dirchanges, filters out commits which are just tree
@@ -84,28 +84,36 @@ branch=$($progdir/svnfind --filechange --dirpath $repo $rev "requirements.txt")
8484

8585
if [ -n "$branch" ]; then
8686
# Update trac tickets
87-
/usr/bin/python $progdir/trac-post-commit-hook -p "$trac" -r "$rev" 2>&1 | logger -t "svn post-commit" -p "user.error" -i
87+
/usr/bin/python2.7 $progdir/trac-post-commit-hook -p "$trac" -r "$rev" 2>&1 | logger -t "svn post-commit" -p "user.error" -i
8888

8989
# Notify buildbot
90-
filenames=$(/usr/bin/svnlook changed $repo -r $rev | sed -r -e 's/^ *[^ ]+ +//' -e "s|$branch/||")
90+
# filenames=$(/usr/bin/svnlook changed $repo -r $rev | sed -r -e 's/^ *[^ ]+ +//' -e "s|$branch/||")
91+
# # Notify local build master
9192
/usr/local/bin/buildbot sendchange \
92-
--master="zinfandel.tools.ietf.org:9989" --auth="ietfdb:BRiR6XcT7x3$" \
93-
--who="$committer" --repository="https://svn.tools.ietf.org/svn/tools/ietfdb/" \
94-
--vc=svn --branch="$branch" --revision=$rev --property=xproperty:xvalue \
95-
--revlink="https://trac.tools.ietf.org/tools/ietfdb/changeset/$rev" \
96-
--comments="$comments" $filenames > /dev/null
93+
# --master="zinfandel.tools.ietf.org:9989" --auth="ietfdb:BRiR6XcT7x3$" \
94+
# --who="$committer" --repository="https://svn.tools.ietf.org/svn/tools/ietfdb/" \
95+
# --vc=svn --branch="$branch" --revision=$rev \
96+
# --revlink="https://trac.tools.ietf.org/tools/ietfdb/changeset/$rev" \
97+
# --comments="$comments" $filenames > /dev/null
98+
# Notify remote build master (must use the remote buildbot binary to match version)
99+
# ssh henrik@dunkelfelder.tools.ietf.org /usr/local/bin/buildbot sendchange \
100+
# --master="dunkelfelder.tools.ietf.org:9989" --auth="ietfdb:BRiR6XcT7x3$" \
101+
# --who="$committer" --repository="https://svn.tools.ietf.org/svn/tools/ietfdb/" \
102+
# --vc=svn --branch="$branch" --revision=$rev \
103+
# --revlink="https://trac.tools.ietf.org/tools/ietfdb/changeset/$rev" \
104+
# --comments="$comments" $filenames > /dev/null
97105

98106
fi
99107

100108

101109
# Log the commit
102-
logger -p local0.info -t "commit" "$relpath r$rev $committer"
103-
logger -p local0.info -t "commit" "branch: $branch"
110+
logger -p user.info -t "commit" "$relpath r$rev $committer"
111+
logger -p user.info -t "commit" "branch: $branch"
104112

105113
# Notify committers
106114

107115
if [[ $comments =~ ready.(for|to).merge ]]; then
108-
mail $(< $progdir/notify-email.txt) -s "[svnhook] Svn commit ready for merge: $relpath | $committer: ${comments:0:42}..." <<-EOF | logger -p local0.info -t "ready for merge email"
116+
mail $(< $progdir/notify-email.txt) -s "[svnhook] Svn commit ready for merge: $relpath | $committer: ${comments:0:42}..." <<-EOF | logger -p user.info -t "ready for merge email"
109117
110118
$committer has a commit ready for merge:
111119
$relpath/$branch [$rev]:
@@ -123,7 +131,7 @@ if [[ $comments =~ ready.(for|to).merge ]]; then
123131

124132
else
125133

126-
mail $(< $progdir/notify-email.txt) -s "[svnhook] Svn commit to $relpath | $committer: ${comments:0:42}..." <<-EOF | logger -p local0.info -t "commit email"
134+
mail $(< $progdir/notify-email.txt) -s "[svnhook] Svn commit to $relpath | $committer: ${comments:0:42}..." <<-EOF | logger -p user.info -t "commit email"
127135
128136
$committer has made a new SVN commit in
129137
$relpath/$branch [$rev]:

hooks/pre-commit

Lines changed: 69 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,69 @@
1-
#!/usr/bin/env python
2-
3-
"""
4-
An SVN pre-commit hook which requires that commits either are marked as
5-
whitespace cleanup commits, and contain no non-whitespace changes, or
6-
leave whitespace alone on lines without code changes.
7-
"""
8-
9-
import os
10-
import sys
11-
import difflib
12-
#import debug
13-
from pysvn import Client, Transaction
14-
15-
prog = os.path.basename(sys.argv[0])
16-
17-
def die(msg):
18-
sys.stderr.write("\n%s: Error: %s\n" % (prog, msg))
19-
sys.exit(1)
20-
21-
if len(sys.argv) <= 1:
22-
die("Expected arguments: REPOSITORY TRANSACTION, found none")
23-
24-
if len(sys.argv) <= 2:
25-
die( "Expected arguments: REPOSITORY TRANSACTION, found only '%s'" % sys.argv[1])
26-
27-
repo = sys.argv[1]
28-
txname = sys.argv[2]
29-
tx = Transaction(repo, txname)
30-
client = Client()
31-
32-
is_whitespace_cleanup = "whitespace cleanup" in tx.revpropget("svn:log").lower()
33-
34-
def normalize(s):
35-
return s.rstrip().expandtabs()
36-
37-
def normalize_sequence(seq):
38-
o = []
39-
for l in seq:
40-
o.append(normalize(l))
41-
return o
42-
43-
def normalize_file_end(seq):
44-
while True and seq:
45-
if seq[-1].strip() == "":
46-
del seq[-1]
47-
else:
48-
break
49-
return seq
50-
51-
def count(gen):
52-
return sum(1 for _ in gen)
53-
54-
# Function with side effects. Acts on global varaibles
55-
def inc_ab(flag):
56-
global a, b
57-
if flag == ' ':
58-
a += 1; b += 1
59-
elif flag == '-':
60-
a += 1
61-
elif flag == '+':
62-
b += 1
63-
elif flag == '?':
64-
pass
65-
else:
66-
raise ValueError("Unexpected ndiff mark: '%s' in: %s" % (flag, plain_diff[i]))
67-
68-
def get_chunks(unidiff):
69-
if not unidiff:
70-
return [], []
71-
chunks = []
72-
chunk = []
73-
intro = unidiff[0:2]
74-
for line in unidiff[2:]:
75-
if line.startswith("@@"):
76-
if chunk:
77-
chunks.append(chunk)
78-
chunk = [line]
79-
else:
80-
chunk.append(line)
81-
chunks.append(chunk)
82-
return intro, chunks
83-
84-
changes = tx.changed()
85-
issues = {}
86-
context = 3
87-
for path in changes:
88-
action, kind, mod, propmod = changes[path]
89-
90-
# Don't try to diff added or deleted files, on ly changed text files
91-
if not (mod and action == "R"):
92-
continue
93-
94-
# Don't try do diff binary files
95-
mimetype = tx.propget("svn:mime-type", path)
96-
if mimetype and not mimetype.startswith("text/"):
97-
continue
98-
99-
new = tx.cat(path).splitlines()
100-
old = client.cat("file://"+os.path.join(repo,path)).splitlines()
101-
102-
# Added trailing space can mess up the comparison -- eliminate it
103-
new = normalize_file_end(new)
104-
old = normalize_file_end(old)
105-
106-
plain_diff = list(difflib.unified_diff(old, new, "%s (repository)"%path, "%s (commit)"%path, lineterm="" ))
107-
old = normalize_sequence(old)
108-
new = normalize_sequence(new)
109-
white_diff = list(difflib.unified_diff(old, new, "%s (repository)"%path, "%s (commit)"%path, lineterm=""))
110-
111-
plain_count = len(plain_diff)
112-
white_count = len(white_diff)
113-
114-
# for i in range(len(white_diff)):
115-
# sys.stderr.write("%-80s | %-80s\n" % (normalize(plain_diff[i][:80]), normalize(white_diff[i][:80])))
116-
if white_count != plain_count and not is_whitespace_cleanup:
117-
intro, plain_chunks = get_chunks(plain_diff)
118-
intro, white_chunks = get_chunks(white_diff)
119-
deletes = []
120-
for chunk in white_chunks:
121-
for i in range(len(plain_chunks)):
122-
if chunk == plain_chunks[i]:
123-
deletes += [i]
124-
deletes.reverse()
125-
for i in deletes:
126-
del plain_chunks[i]
127-
issue = intro
128-
for chunk in plain_chunks:
129-
issue += chunk
130-
if len(plain_chunks) > 1:
131-
are = "are"; s = "s"; an = ""
132-
else:
133-
are = "is"; s = ""; an = "an "
134-
issues[path] = issue
135-
if white_count != 0 and is_whitespace_cleanup:
136-
intro, white_chunks = get_chunks(white_diff)
137-
if len(white_chunks) > 1:
138-
are = "are"; s = "s"; an = ""
139-
else:
140-
are = "is"; s = ""; an = "an "
141-
issues[path] = white_diff
142-
143-
if issues:
144-
if is_whitespace_cleanup:
145-
die("It looks as if there are non-whitespace changes in\n"
146-
"this commit, but it was marked as a whitespace cleanup commit.\n\n"
147-
"Here %s the diff chunk%s with unexpected change%s:\n\n%s\n\n"
148-
"Declining the commit due to a mix of code and spaces-only changes. Please\n"
149-
"avoid mixing whitespace-only changes with code changes. See details above." %
150-
(are, s, s, '\n\n'.join([ '\n'.join(issues[path]) for path in issues ]))
151-
)
152-
153-
else:
154-
die("It looks as if there are spaces-only changes in this\n"
155-
"commit, but it was not marked as a whitespace cleanup commit.\n\n"
156-
"Here %s the diff chunk%s with unexpected change%s:\n\n%s\n\n"
157-
"Declining the commit due to a mix of code and spaces-only changes. Please\n"
158-
"avoid mixing whitespace-only changes with code changes. See details above." %
159-
(are, s, s, '\n\n'.join([ '\n'.join(issues[path]) for path in issues ]))
160-
)
161-
162-
sys.exit(0)
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
#
20+
#
21+
# $Id$
22+
#
23+
# Prevents some SHA-1 collisions to be commited
24+
# Test fo the 320 byte prefix found on https://shattered.io/
25+
# If the files are committed in the same transaction, svnlook
26+
# will error out itself due to the apparent corruption in the
27+
# candidate revision
28+
29+
REPOS="$1"
30+
TXN="$2"
31+
SVNLOOK=/usr/bin/svnlook
32+
YEAR=$(date +%Y)
33+
34+
$SVNLOOK changed -t "$TXN" "$REPOS"
35+
if [ $? -ne 0 ]; then
36+
echo "svnlook failed, possible SHA-1 collision" >&2
37+
exit 2
38+
fi
39+
40+
FILES=$($SVNLOOK changed -t "$TXN" "$REPOS" | grep -Ev '^D ' | /usr/bin/awk '{print $2}')
41+
for FILE in $FILES; do
42+
if [ -f $FILE ]; then
43+
# Check against known sha-1 collision attack. Someone committing 2 different files with this
44+
# known hash collision could otherwise break the repository.
45+
PREFIX=$($SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | head -c320 | /usr/bin/sha1sum | cut -c-40)
46+
if [ "$PREFIX" = 'f92d74e3874587aaf443d1db961d4e26dde13e9c' ]; then
47+
echo "known SHA-1 collision rejected" >&2
48+
exit 3
49+
fi
50+
51+
# Verify copyright year
52+
if [[ $FILE == */ietf/*.py || -s $FILE ]]; then
53+
$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | head -n 3 | grep -q "Copyright .*IETF Trust .*$YEAR.*" || {
54+
echo "
55+
Bad or missing copyright note in $FILE.
56+
Expected 'Copyright The IETF Trust ... $YEAR, All Rights Reserved',
57+
(or similar) at the start of the file.
58+
59+
For bulk correction of copyright statements, try bin/check-copyright with
60+
patching:
61+
62+
\$ bin/check-copyright -p \$(svn st | cut -c 9- | grep '\.py\$' ) | patch -p0
63+
64+
" >&2
65+
exit 3
66+
}
67+
fi
68+
fi
69+
done

hooks/trac-post-commit-hook

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ from datetime import datetime
7979
from optparse import OptionParser, OptionGroup
8080
import syslog
8181

82-
syslog.openlog("post-commit-trac", syslog.LOG_PID, syslog.LOG_LOCAL0)
82+
syslog.openlog("post-commit-trac", syslog.LOG_PID, syslog.LOG_USER)
8383
log = syslog.syslog
8484

8585
parser = OptionParser()
@@ -94,6 +94,7 @@ parser.add_option('-p', '--project', dest='project',
9494
parser.add_option('-r', '--revision', dest='rev',
9595
help='Repository revision number.')
9696
parser.add_option('-a', '--action', dest='action', default=None, help='The action to take on a ticket (default: none)')
97+
parser.add_option('-R', '--repository-name', dest='repo_name', default=None, help='Which repository to look in, if the trac instance has multiple repositories')
9798

9899
group = OptionGroup(parser, "DEPRECATED OPTIONS")
99100
group.add_option('-u', '--user', dest='user',
@@ -123,8 +124,8 @@ from trac.versioncontrol.api import NoSuchChangeset
123124

124125
ticket_prefix = '(?:#|(?:ticket|issue|bug)s?[: ]?#?)'
125126
ticket_reference = ticket_prefix + '[0-9]+'
126-
action_pattern = "(?:(?i)(?:fix(?: for)?|fixes|close|closes|addresses|references|refs|re|relates to|related to|see|described in))"
127-
ticket_command = (r'(?P<action>%s).?(?P<ticket>%s(?:(?:[, &]*|[ ]?and[ ]?)%s)*)' % (action_pattern, ticket_reference, ticket_reference))
127+
action_pattern = "(?:(?i)(?:fix(?: for| to)?|fixes|fixed|close|closes|completes|addresses|references|refs|re|relates to|related to|see|described in))"
128+
ticket_command = (r'(?P<action>%s).?(?P<ticket>%s(?:(?:[, &]*|[, ]+and[ ]?)%s)*)' % (action_pattern, ticket_reference, ticket_reference))
128129

129130
if options.envelope:
130131
ticket_command = r'\%s%s\%s' % (options.envelope[0], ticket_command,
@@ -148,9 +149,12 @@ class CommitHook:
148149

149150
_supported_cmds = {'fix': '_cmdClose',
150151
'fix for': '_cmdClose',
152+
'fix to': '_cmdClose',
151153
'fixes': '_cmdClose',
154+
'fixed': '_cmdClose',
152155
'close': '_cmdClose',
153156
'closes': '_cmdClose',
157+
'completes': '_cmdClose',
154158

155159
'addresses': '_cmdRefs',
156160
'described in': '_cmdRefs',
@@ -165,7 +169,7 @@ class CommitHook:
165169
def __init__(self, project=options.project, author=options.user,
166170
rev=options.rev, url=options.url):
167171
self.env = open_environment(project)
168-
repos = self.env.get_repository()
172+
repos = self.env.get_repository(options.repo_name)
169173
repos.sync()
170174

171175
# Instead of bothering with the encoding, we'll use unicode data

0 commit comments

Comments
 (0)