Hi Christian,
I started out with a post-commit hook using a file:// URL, but I couldn't
get that to work. It's been a while since I worked on it, but I was
working with it that way today, and if I recall correctly, I never managed
to get past the "Unable to find a Review Board server for this source code
tree" error. Since this is running as a hook, I can't use a reviewboardrc
file. I might have to look at that some more. If there really is a better
way of getting that to work, it would explain why no one has needed to
modify the rbtools subversion interface. I've attached a sanitized version
of my hook. My modifications to svn.py were really simplistic (in other
words, sloppy). I just went through and, for each svn command like this:
diff_cmd = ['svn', 'diff', '--diff-cmd=diff', '--notice-ancestry']
I added the hard-coded username and password:
diff_cmd = ['svn', 'diff', '--non-interactive','--username=MYUSERNAME',
'--password=MYPASSWORD', '--diff-cmd=diff', '--notice-ancestry']
I can send you the whole thing if you think it would make a difference,
but I just did that same thing for svn info, etc.
Thanks,
Michelle
On Wednesday, July 2, 2014 3:03:35 PM UTC-4, Christian Hammond wrote:
>
> Hi MIchelle,
>
> I can’t really say, to be honest. I want to get a better sense of your
> setup, though.
>
> This hook is a script living on the SVN server, right? Given that it’s
> local to there, is there a reason it can’t use a file:// URL to reach its
> SVN repo?
>
> Can I see the hook and the modifications?
>
> Christian
>
> --
> Christian Hammond - [email protected] <javascript:>
> Review Board - http://www.reviewboard.org
> Beanbag, Inc. - http://www.beanbaginc.com
>
> On July 2, 2014 at 11:50:58 AM, Michelle Avery ([email protected]
> <javascript:>) wrote:
>
> Hi,
>
> I set up an instance of reviewboard a few weeks ago as a quick proof of
> concept for my company. At the time, I ran into a problem getting my
> subversion post-commit hook to work. Our repository allows no anonymous
> access, so the svn info, log, etc. calls issued by rbtools were hanging
> waiting for a password that rbtools didn't seem to give me a way to supply.
> From this
> <https://groups.google.com/d/topic/reviewboard/xDoWsUyHpBg/discussion>
> mailing
> list post, it seemed that this was actually a limitation. Since I was just
> trying out reviewboard at the time, I just modified rbtools/clients/svn.py
> to supply the credentials with those calls. However, now that I'm setting
> up what will be a production instance, I'm more concerned about doing
> things properly, and it seems odd to me that, in the two years since that
> post, no one has modified rbtools to allow those parameters. Can someone
> please confirm whether this is an uncommon requirement, or I'm just totally
> wrong and there actually is a better way of doing this?
>
> Thanks,
>
> Michelle
> --
> Get the Review Board Power Pack at http://www.reviewboard.org/powerpack/
> ---
> Sign up for Review Board hosting at RBCommons: https://rbcommons.com/
> ---
> Happy user? Let us know at http://www.reviewboard.org/users/
> ---
> You received this message because you are subscribed to the Google Groups
> "reviewboard" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected] <javascript:>.
> For more options, visit https://groups.google.com/d/optout.
>
>
--
Get the Review Board Power Pack at http://www.reviewboard.org/powerpack/
---
Sign up for Review Board hosting at RBCommons: https://rbcommons.com/
---
Happy user? Let us know at http://www.reviewboard.org/users/
---
You received this message because you are subscribed to the Google Groups
"reviewboard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
#!/usr/bin/env python
#
# svn-hook-postcommit-review
# This script should be invoked from the subversion post-commit hook like this:
#
# REPOS="$1"
# REV="$2"
# /usr/bin/python /some/path/svn-hook-postcommit-review "$REPOS" "$REV" || exit
1
#
# Searches the commit message for text in the form of:
# publish review - publishes a review request
# draft review - creates a draft review request
#
# The space before 'review' may be ommitted.
#
# The log message is interpreted for review request parameters:
# summary = up to first period+space, first new-line, or 250 chars
# description = entire log message
# existing review updated if log message includes 'update review:[0-9]+'
# bugs added to review if log message includes commands as defined in
# supported_ticket_cmds
#
# By default, the review request is created out of a diff between the current
# revision (M) and the previous revision (M-1).
#
# To create a diff that spans multiple revisions, include
# 'after revision:[0-9]+' in the log message.
#
# To limit the diff to changes in a certain path (e.g. a branch), include
# 'base path:"<path>"' in the log message. The path must be relative to
# the root of the repository and be surrounded by single or double quotes.
#
# An example commit message is:
#
# Changed blah and foo to do this or that. Publish review ticket:1
# update review:2 after revision:3 base path:'internal/trunk/style'.
#
# This would update the existing review 2 with a diff of changes to files under
# the style directory between this commit and revision 3. It would place
# the entire log message in the review summary and description, and put
# bug id 1 in the bugs field.
#
# This script may only be run from outside a working copy.
#
#
# User configurable variables
#
# Path to rbt script
POSTREVIEW_PATH = "/usr/local/bin/"
# Username and password for Review Board user that will be connecting
# to create all review requests. This user must have 'submit as'
# privileges, since it will submit requests in the name of svn committers.
USERNAME = '<my username here>'
PASSWORD = '<my password here>'
# If true, runs rbt in debug mode and outputs its diff
DEBUG = False
#
# end user configurable variables
#
import sys
import os
import subprocess
import re
import svn.fs
import svn.core
import svn.repos
# list of trac commands from trac-post-commit-hook.py.
# numbers following these commands will be added to the bugs
# field of the review request.
supported_ticket_cmds = {'review': '_cmdReview',
'publishreview': '_cmdReview',
'publish review': '_cmdReview',
'draftreview': '_cmdReview',
'draft review': '_cmdReview'}
ticket_prefix = '(?:#|(?:ticket|issue|bug)[: ]?)'
ticket_reference = ticket_prefix + '[0-9]+'
ticket_command = (r'(?P<action>[A-Za-z]*).?'
'(?P<ticket>%s(?:(?:[, &]*|[ ]?and[ ]?)%s)*)' %
(ticket_reference, ticket_reference))
def execute(command, env=None, ignore_errors=False):
"""
Utility function to execute a command and return the output.
Derived from Review Board's rbt script.
"""
if env:
env.update(os.environ)
else:
env = os.environ
p = subprocess.Popen(command,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
shell = False,
close_fds = sys.platform.startswith('win'),
universal_newlines = True,
env = env)
data = p.stdout.read()
rc = p.wait()
if rc and not ignore_errors:
sys.stderr.write('Failed to execute command: %s\n%s\n' % (command,
data))
sys.exit(1)
return data
def main():
if len(sys.argv) != 3:
sys.stderr.write('Usage: %s <repos> <rev>\n' % sys.argv[0])
sys.exit(1)
repos = sys.argv[1]
rev = sys.argv[2]
# verify that rev parameter is an int
try:
int(rev)
except ValueError:
sys.stderr.write("Parameter <rev> must be an int, was given %s\n" % rev)
sys.exit(1)
# get the svn file system object
fs_ptr = svn.repos.svn_repos_fs(svn.repos.svn_repos_open(
svn.core.svn_path_canonicalize(repos)))
# get the log message
log = svn.fs.svn_fs_revision_prop(fs_ptr, int(rev),
svn.core.SVN_PROP_REVISION_LOG)
# error if log message is blank
if len(log.strip()) < 1:
sys.stderr.write("Log message is empty, no review request created\n")
sys.exit(1)
# get the author
author = svn.fs.svn_fs_revision_prop(fs_ptr, int(rev),
svn.core.SVN_PROP_REVISION_AUTHOR)
# error if author is blank
if len(author.strip()) < 1:
sys.stderr.write("Author is blank, no review request created\n")
sys.exit(1)
# check whether to create a review, based on presence of word
# 'review' with prefix
review = r'(?:publish|draft)(?: )?review'
if not re.search(review, log, re.M | re.I):
print 'No review requested'
sys.exit(0)
# check for update to existing review
m = re.search(r'update(?: )?review:([0-9]+)', log, re.M | re.I)
if m:
reviewid = '--review-request-id=' + m.group(1)
else:
reviewid = ''
# check whether to publish or leave review as draft
if re.search(r'draft(?: )?review', log, re.M | re.I):
publish = ''
else:
publish = '-p'
# get previous revision number -- either 1 prior, or
# user-specified number
m = re.search(r'after(?: )?revision:([0-9]+)', log, re.M | re.I)
if m:
prevrev = m.group(1)
else:
prevrev = int(rev) - 1
# check for an explicitly-provided base path (must be contained
# within quotes)
m = re.search(r'base ?path:[\'"]([^\'"]+)[\'"]', log, re.M | re.I)
if m:
base_path = m.group(1)
else:
base_path = ''
# get bug numbers referenced in this log message
ticket_command_re = re.compile(ticket_command)
ticket_re = re.compile(ticket_prefix + '([0-9]+)')
ticket_ids = []
ticket_cmd_groups = ticket_command_re.findall(log)
for cmd, tkts in ticket_cmd_groups:
funcname = supported_ticket_cmds.get(cmd.lower(), '')
if funcname:
for tkt_id in ticket_re.findall(tkts):
ticket_ids.append(tkt_id)
if ticket_ids:
bugs = '--bugs-closed=' + ','.join(ticket_ids)
else:
bugs = ''
# summary is log up to first period+space / first new line / first 250 chars
# (whichever comes first)
summary = '--summary=' + log[:250].splitlines().pop(0).split('. ').pop(0)
# other parameters for postreview
repository_url = '--repository-url=http://my.server.com/repo'
password = '--password=' + PASSWORD
username = '--username=' + USERNAME
description = "--description=(In [%s]) %s" % (rev, log)
submitas = '--submit-as=' + author
revision = '%s:%s' % (prevrev, rev)
# common arguments
args = [repository_url, username, password, publish,
submitas, revision, base_path, reviewid]
# filter out any potentially blank args, which will confuse rbt
args = [i for i in args if len(i) > 1]
# if not updating an existing review, add extra arguments
if len(reviewid) == 0:
args += [summary, description, bugs]
if DEBUG:
args += ['-d', '--output-diff']
print [os.path.join(POSTREVIEW_PATH, 'rbt'), 'post'] + args
# Run Review Board rbt script
data = execute([os.path.join(POSTREVIEW_PATH, 'rbt'), 'post'] + args,
env = {'LANG': 'en_US.UTF-8'})
if DEBUG:
print data
if __name__ == '__main__':
main()