media/webrtc/trunk/build/util/lastchange.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #!/usr/bin/env python
     2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
     3 # Use of this source code is governed by a BSD-style license that can be
     4 # found in the LICENSE file.
     6 """
     7 lastchange.py -- Chromium revision fetching utility.
     8 """
    10 import re
    11 import optparse
    12 import os
    13 import subprocess
    14 import sys
    16 _GIT_SVN_ID_REGEX = re.compile(r'.*git-svn-id:\s*([^@]*)@([0-9]+)', re.DOTALL)
    18 class VersionInfo(object):
    19   def __init__(self, url, revision):
    20     self.url = url
    21     self.revision = revision
    24 def FetchSVNRevision(directory, svn_url_regex):
    25   """
    26   Fetch the Subversion branch and revision for a given directory.
    28   Errors are swallowed.
    30   Returns:
    31     A VersionInfo object or None on error.
    32   """
    33   try:
    34     proc = subprocess.Popen(['svn', 'info'],
    35                             stdout=subprocess.PIPE,
    36                             stderr=subprocess.PIPE,
    37                             cwd=directory,
    38                             shell=(sys.platform=='win32'))
    39   except OSError:
    40     # command is apparently either not installed or not executable.
    41     return None
    42   if not proc:
    43     return None
    45   attrs = {}
    46   for line in proc.stdout:
    47     line = line.strip()
    48     if not line:
    49       continue
    50     key, val = line.split(': ', 1)
    51     attrs[key] = val
    53   try:
    54     match = svn_url_regex.search(attrs['URL'])
    55     if match:
    56       url = match.group(2)
    57     else:
    58       url = ''
    59     revision = attrs['Revision']
    60   except KeyError:
    61     return None
    63   return VersionInfo(url, revision)
    66 def RunGitCommand(directory, command):
    67   """
    68   Launches git subcommand.
    70   Errors are swallowed.
    72   Returns:
    73     A process object or None.
    74   """
    75   command = ['git'] + command
    76   # Force shell usage under cygwin. This is a workaround for
    77   # mysterious loss of cwd while invoking cygwin's git.
    78   # We can't just pass shell=True to Popen, as under win32 this will
    79   # cause CMD to be used, while we explicitly want a cygwin shell.
    80   if sys.platform == 'cygwin':
    81     command = ['sh', '-c', ' '.join(command)]
    82   try:
    83     proc = subprocess.Popen(command,
    84                             stdout=subprocess.PIPE,
    85                             stderr=subprocess.PIPE,
    86                             cwd=directory,
    87                             shell=(sys.platform=='win32'))
    88     return proc
    89   except OSError:
    90     return None
    93 def FetchGitRevision(directory):
    94   """
    95   Fetch the Git hash for a given directory.
    97   Errors are swallowed.
    99   Returns:
   100     A VersionInfo object or None on error.
   101   """
   102   proc = RunGitCommand(directory, ['rev-parse', 'HEAD'])
   103   if proc:
   104     output = proc.communicate()[0].strip()
   105     if proc.returncode == 0 and output:
   106       return VersionInfo('git', output[:7])
   107   return None
   110 def FetchGitSVNURLAndRevision(directory, svn_url_regex):
   111   """
   112   Fetch the Subversion URL and revision through Git.
   114   Errors are swallowed.
   116   Returns:
   117     A tuple containing the Subversion URL and revision.
   118   """
   119   proc = RunGitCommand(directory, ['log', '-1',
   120                                    '--grep=git-svn-id', '--format=%b'])
   121   if proc:
   122     output = proc.communicate()[0].strip()
   123     if proc.returncode == 0 and output:
   124       # Extract the latest SVN revision and the SVN URL.
   125       # The target line is the last "git-svn-id: ..." line like this:
   126       # git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85528 0039d316....
   127       match = _GIT_SVN_ID_REGEX.search(output)
   128       if match:
   129         revision = match.group(2)
   130         url_match = svn_url_regex.search(match.group(1))
   131         if url_match:
   132           url = url_match.group(2)
   133         else:
   134           url = ''
   135         return url, revision
   136   return None, None
   139 def FetchGitSVNRevision(directory, svn_url_regex):
   140   """
   141   Fetch the Git-SVN identifier for the local tree.
   143   Errors are swallowed.
   144   """
   145   url, revision = FetchGitSVNURLAndRevision(directory, svn_url_regex)
   146   if url and revision:
   147     return VersionInfo(url, revision)
   148   return None
   151 def FetchVersionInfo(default_lastchange, directory=None,
   152                      directory_regex_prior_to_src_url='chrome|svn'):
   153   """
   154   Returns the last change (in the form of a branch, revision tuple),
   155   from some appropriate revision control system.
   156   """
   157   svn_url_regex = re.compile(
   158       r'.*/(' + directory_regex_prior_to_src_url + r')(/.*)')
   160   version_info = (FetchSVNRevision(directory, svn_url_regex) or
   161                   FetchGitSVNRevision(directory, svn_url_regex) or
   162                   FetchGitRevision(directory))
   163   if not version_info:
   164     if default_lastchange and os.path.exists(default_lastchange):
   165       revision = open(default_lastchange, 'r').read().strip()
   166       version_info = VersionInfo(None, revision)
   167     else:
   168       version_info = VersionInfo(None, None)
   169   return version_info
   172 def WriteIfChanged(file_name, contents):
   173   """
   174   Writes the specified contents to the specified file_name
   175   iff the contents are different than the current contents.
   176   """
   177   try:
   178     old_contents = open(file_name, 'r').read()
   179   except EnvironmentError:
   180     pass
   181   else:
   182     if contents == old_contents:
   183       return
   184     os.unlink(file_name)
   185   open(file_name, 'w').write(contents)
   188 def main(argv=None):
   189   if argv is None:
   190     argv = sys.argv
   192   parser = optparse.OptionParser(usage="lastchange.py [options]")
   193   parser.add_option("-d", "--default-lastchange", metavar="FILE",
   194                     help="default last change input FILE")
   195   parser.add_option("-o", "--output", metavar="FILE",
   196                     help="write last change to FILE")
   197   parser.add_option("--revision-only", action='store_true',
   198                     help="just print the SVN revision number")
   199   opts, args = parser.parse_args(argv[1:])
   201   out_file = opts.output
   203   while len(args) and out_file is None:
   204     if out_file is None:
   205       out_file = args.pop(0)
   206   if args:
   207     sys.stderr.write('Unexpected arguments: %r\n\n' % args)
   208     parser.print_help()
   209     sys.exit(2)
   211   version_info = FetchVersionInfo(opts.default_lastchange,
   212       os.path.dirname(sys.argv[0]))
   214   if version_info.revision == None:
   215     version_info.revision = '0'
   217   if opts.revision_only:
   218     print version_info.revision
   219   else:
   220     contents = "LASTCHANGE=%s\n" % version_info.revision
   221     if out_file:
   222       WriteIfChanged(out_file, contents)
   223     else:
   224       sys.stdout.write(contents)
   226   return 0
   229 if __name__ == '__main__':
   230   sys.exit(main())

mercurial