Review Board

beta

Add support for finding SVN repository to post-review

Updated 1 week, 5 days ago

Michael Plump Reviewers
trunk reviewboard
451
None Review Board SVN
The patch resolves the problem described in this thread:
http://groups.google.com/group/reviewboard/browse_thread/thread/c9027e1c73cb0c86

Specifically, users can have many different URLs for the same subversion repository, none of which may match the URL that Review Board uses.  There may be differences in hostnames (is it "svn" or "svn.scm" or "svn.scm.example.com") or even more drastic changes in URLs.  For example, a user could have the repository NFS mounted, in which case she'd have a URL like "file:///mnt/svn/repos/").

This patch uses the JSON "get repository info" API (committed as r1263).  If the local repository is Subversion, we loop through each repository on the server.  First we try to find one that has the same UUID.  If we get that, we check to make sure our local checkout's directory is somewhere beneath the repository URL specified on the server.  If it is, we calculate the new base_path for our diff which is relative to the server's URL and send that up with our diff.

This magic won't work if the server uses DOS '\' delimited paths, but it won't be any worse in that case either... it will just revert to the old behaviour.  And I think that is probably a rare use case anyway (most people will use 'http' URLs).
I posted many review drafts with varying local repository URLs and server URLs.
Posted 9 months ago (April 7th, 2008, 1:20 a.m.)

   

  
Loading diff fragment...
None of the other errors here had trailing periods, so I removed this one for consistency.
Posted 8 months, 4 weeks ago (April 15th, 2008, 3:03 a.m.)

   

  
  1. Christian Hammond 4 months, 2 weeks ago (August 27th, 2008, 2:46 a.m.)
    Pinging on this review.
  2. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:42 p.m.)
    I'll attach an updated review that addresses these comments in a second. Thanks.
  3. Christopher Orr 1 month ago (December 8th, 2008, 10:13 a.m.)
    I can see an updated patch (r2 on the diff page), but don't see any mention of it below.  Doesn't notification of new diffs normally show up on this page?
    
    Anyway, not much to add aside from saying this patch works nicely for me.  Very useful.
Loading diff fragment...
Can you add a comment describing this function a bit? It's a little weird looking how it may return a new RepositoryInfo or itself, and this should be documented.
  1. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:31 p.m.)
    Done. Let me know if it makes sense. (There's also a comment on the function it overrides in RepositoryInfo.)
Loading diff fragment...
Should probably use isinstanceof().
  1. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:39 p.m.)
    The repository objects are just dicts that come back from the server (JSON objects), not actual useful python classes. So type(repository) is 'dict' and type(repository['tool']) is 'unicode'.
  2. Christian Hammond 1 month, 3 weeks ago (November 13th, 2008, 2:12 a.m.)
    My mistake, I was thinking wrong when I wrote this.
Loading diff fragment...
We'll need to coordinate a little with the change in /r/451/ as that's going to need this repository base path as well.
  1. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:32 p.m.)
    I looked at that review, but didn't entirely understand what you meant. So I cheerfully ignored this.
  2. Christian Hammond 1 month, 3 weeks ago (November 13th, 2008, 2:14 a.m.)
    I don't know what I meant back then either. *shrug* :) Perhaps I got the number wrong.
Loading diff fragment...
What you really want is to do something like:

common_path = os.path.commonprefix([root, path])

if common_path == path:
    return "/"
else:
    return path[len(common_path):]


If you have, say, a base path of: "/svn/foo" and a path of "/svn/foo/trunk/abc", common_path will be "/svn/foo". Your resulting path would then be "/trunk/abc"

If the common prefix is the same as the whole path, then "/".
  1. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:34 p.m.)
    Wow, yeah, I was happy to read about that... it would be a lot of reduced code. But os.path.commonprefix is broken to the point of uselessness. From the docs: "Note that this may return invalid paths because it works a character at a time."
    
    In particular, it doesn't work with empty path elements:
    >>> os.path.commonprefix(['/svn//foo/bar', '/svn/foo'])
    '/svn/'
    
    and even worse, it doesn't actually compare path elements, just characters:
    >>> os.path.commonprefix(['/svn/foobar/hello', '/svn/foo'])
    '/svn/foo'
    
  2. Christian Hammond 1 month, 3 weeks ago (November 13th, 2008, 2:15 a.m.)
    Yeah that's pretty bad. *sigh*
    
    The first case could be fixed through some path normalization, but the second is just stupid.
Loading diff fragment...
No need for the else, due to the return.
  1. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:40 p.m.)
    Good point.
Loading diff fragment...
Could just put m.group(1) in the parameter list directly.
  1. Michael Plump 2 months, 1 week ago (October 26th, 2008, 3:41 p.m.)
    Done.
Posted 2 weeks, 3 days ago (December 21st, 2008, 1:30 p.m.)
Just a few trivial changes left.
Loading diff fragment...
I'd prefer this written as "rsp = e.args[0]"
Loading diff fragment...
Sentence casing please.
Loading diff fragment...
I think you can compare lists directly:

if rootdirs != pathdirs:
    return None
Loading diff fragment...
Sentence casing, please.
Loading diff fragment...
Sentence casing, please.
Review request changed
Updated 2 weeks, 3 days ago (December 22nd, 2008, 1:47 a.m.)
Just the few changes requested by David.
Ship it!
Posted 1 week, 5 days ago (December 26th, 2008, 11:50 p.m.)
Looks good now. Committed to SVN as r1642. Thanks!!