Review Board

beta

Correct post-review error messages when run outside of a checkout directory, when Mercurial is not installed

Updated 9 months, 2 weeks ago

Marc Hedlund Reviewers
reviewboard
None Review Board SVN
Currently, if you call post-review outside of a checkout directory (somewhere that no SCM info is available), and you do not have Mercurial installed, you will see this error (using a bash shell):

Failed to execute command: hg root
/bin/sh: hg: command not found

That's not a very helpful or clear error message.  This patch causes the following error message to appear instead:

The current directory does not contain a checkout from a
supported source code repository.

That's much more clear and is a correct statement of the problem.

It looks like the Mercurial code was only tested on machines where Mercurial is installed.  I think the code as written would work fine in that case -- but, not all of us have it installed.
I don't have Mercurial installed (hence this patch), but I have tested that post-review still works outside of a source controlled directory (giving a valid error), and inside of a Subversion checkout directory.

Diff revision 3 (Latest)

1 2 3
1 2 3

  1. /trunk/reviewboard/contrib/tools/post-review: 5 changes [ 1 2 3 4 5 ]
/trunk/reviewboard/contrib/tools/post-review
Revision 1243 New Change
356
    """
356
    """
357
    A wrapper around the svn Subversion tool that fetches repository
357
    A wrapper around the svn Subversion tool that fetches repository
358
    information and generates compatible diffs.
358
    information and generates compatible diffs.
359
    """
359
    """
360
    def get_repository_info(self):
360
    def get_repository_info(self):
361
        if not check_install('svn help'):
362
            return None
363
        
361
        data = execute('svn info', ignore_errors=True)
364
        data = execute('svn info', ignore_errors=True)
362
365
363
        m = re.search(r'^Repository Root: (.+)$', data, re.M)
366
        m = re.search(r'^Repository Root: (.+)$', data, re.M)
364
        if not m:
367
        if not m:
365
            return None
368
            return None
415
    """
418
    """
416
    A wrapper around the p4 Perforce tool that fetches repository information
419
    A wrapper around the p4 Perforce tool that fetches repository information
417
    and generates compatible diffs.
420
    and generates compatible diffs.
418
    """
421
    """
419
    def get_repository_info(self):
422
    def get_repository_info(self):
423
        if not check_install('p4 help'):
424
            return None
425
        
420
        data = execute('p4 info', ignore_errors=True)
426
        data = execute('p4 info', ignore_errors=True)
421
427
422
        m = re.search(r'^Server address: (.+)$', data, re.M)
428
        m = re.search(r'^Server address: (.+)$', data, re.M)
423
        if not m:
429
        if not m:
424
            return None
430
            return None
652
    """
658
    """
653
    A wrapper around the hg Mercurial tool that fetches repository
659
    A wrapper around the hg Mercurial tool that fetches repository
654
    information and generates compatible diffs.
660
    information and generates compatible diffs.
655
    """
661
    """
656
    def get_repository_info(self):
662
    def get_repository_info(self):
663
        if not check_install('hg --help'):
664
            return None
665
        
657
        data = execute('hg root', ignore_errors=True)
666
        data = execute('hg root', ignore_errors=True)
658
        if data.startswith('abort:'):
667
        if data.startswith('abort:'):
659
            # hg aborted => no mercurial repository here.
668
            # hg aborted => no mercurial repository here.
660
            return None
669
            return None
661
670
701
    A wrapper around git that fetches repository information and generates
710
    A wrapper around git that fetches repository information and generates
702
    compatible diffs. This will attempt to generate a diff suitable for the
711
    compatible diffs. This will attempt to generate a diff suitable for the
703
    remote repository, whether git, SVN or Perforce.
712
    remote repository, whether git, SVN or Perforce.
704
    """
713
    """
705
    def get_repository_info(self):
714
    def get_repository_info(self):
715
        if not check_install('git --help'):
716
            return None
717
        
706
        git_dir = execute('git rev-parse --git-dir', ignore_errors=True).strip()
718
        git_dir = execute('git rev-parse --git-dir', ignore_errors=True).strip()
707
719
708
        if git_dir.startswith("fatal:") or not os.path.isdir(git_dir):
720
        if git_dir.startswith("fatal:") or not os.path.isdir(git_dir):
709
            return None
721
            return None
710
722
839
    fd, tmpfile = mkstemp()
851
    fd, tmpfile = mkstemp()
840
    os.close(fd)
852
    os.close(fd)
841
    tempfiles.append(tmpfile)
853
    tempfiles.append(tmpfile)
842
    return tmpfile
854
    return tmpfile
843
855
856
def check_install(command):
857
    """
858
    Try executing an external command and return a boolean indicating whether
859
    that command is installed or not.  The 'command' argument should be something
860
    that executes quickly, without hitting the network (for instance, 'svn help'
861
    or 'git --version').
862
    """
863
    try:
864
        p = subprocess.Popen(command.split(' '),
865
                             stdin=subprocess.PIPE,
866
                             stdout=subprocess.PIPE,
867
                             stderr=subprocess.PIPE)
868
        return True
869
    except OSError:
870
        return False
844
871
845
def execute(command, split_lines=False, ignore_errors=False, extra_ignore_errors=()):
872
def execute(command, split_lines=False, ignore_errors=False, extra_ignore_errors=()):
846
    """
873
    """
847
    Utility function to execute a command and return the output.
874
    Utility function to execute a command and return the output.
848
    """
875
    """
  1. /trunk/reviewboard/contrib/tools/post-review: 5 changes [ 1 2 3 4 5 ]