scripts/svn_helper.py
changeset 30 636baa95715c
child 44 9d3a0f98df34
equal deleted inserted replaced
29:64b3e323210f 30:636baa95715c
       
     1 #!/usr/bin/python2.5
       
     2 #
       
     3 # Copyright 2008 the Melange authors.
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (the "License");
       
     6 # you may not use this file except in compliance with the License.
       
     7 # You may obtain a copy of the License at
       
     8 #
       
     9 #   http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 
       
    17 """Helper functions that wrap the pysvn Python svn bindings.
       
    18 
       
    19 ls(): returns list of selected directory entries from an SVN repository
       
    20 lsDirs(): wrapper around ls() that only returns node_kind.dir entries
       
    21 lsFiles(): wrapper around ls() that only returns node_kind.files entries
       
    22 exists(): returns True if repo_path exists in the svn repository
       
    23 
       
    24 DEF_SVN_REPO: default HTTPS path to the SoC project SVN repo
       
    25 PYSVN_ALL_NODE_KINDS: all directory entry node_kinds supported by pysvn
       
    26 PYSVN_FILE_DIR_NODE_KINDS: actual file and directory node_kinds
       
    27 """
       
    28 
       
    29 __authors__ = [
       
    30   # alphabetical order by last name, please
       
    31   '"Todd Larsen" <tlarsen@google.com>',
       
    32 ]
       
    33 
       
    34 
       
    35 import pysvn
       
    36 
       
    37 
       
    38 #: default HTTPS path to the SoC project SVN repo
       
    39 DEF_SVN_REPO = 'https://soc.googlecode.com/svn/'
       
    40 
       
    41 #: all of the directory entry node_kinds supported py pysvn
       
    42 PYSVN_ALL_NODE_KINDS = set([pysvn.node_kind.none, pysvn.node_kind.dir,
       
    43                             pysvn.node_kind.file, pysvn.node_kind.unknown])
       
    44 
       
    45 #: actual file and directory node_kinds (includes dir and file, but excludes
       
    46 #: the "non-file" none and unknown)
       
    47 PYSVN_FILE_DIR_NODE_KINDS = set([pysvn.node_kind.dir, pysvn.node_kind.file])
       
    48 
       
    49 
       
    50 def ls(client, repo_path, keep_kinds=PYSVN_FILE_DIR_NODE_KINDS, **kwargs):
       
    51   """Returns a list of (possibly recursive) svn repo directory entries.
       
    52 
       
    53   Args:
       
    54     client: pysvn Client instance
       
    55     repo_path: absolute svn repository path URL, including the server and
       
    56       directory path within the repo
       
    57     keep_kinds: types of directory entries to keep in the returned list; a
       
    58       collection of pysvn.node_kind objects; default is
       
    59       PYSVN_FILE_DIR_NODE_KINDS
       
    60     **kwargs: keyword arguments passed on to Client.list(), including:
       
    61       recurse: indicates if return results should include entries from
       
    62         subdirectories of repo_path as well; default is False
       
    63 
       
    64   Returns:
       
    65     list of (Unicode, coming from pysvn) strings representing the entries
       
    66     of types indicated by keep_kinds; strings are altered to match the
       
    67     output of the actual 'svn ls' command: repo_path prefix is removed,
       
    68     directories end with the / separator.
       
    69   """
       
    70   raw_entries = client.list(repo_path, **kwargs)
       
    71   entries = []
       
    72 
       
    73   # Find shortest repos_path that is a 'dir' entry; will be prefix of all
       
    74   # other entries, since Client.list() always returns repo_path as one of
       
    75   # the entries.  It is easier and more reliable to do this search than to
       
    76   # try to manipulate repo_path into the prefix (since the user could supply
       
    77   # any number of valid, but different, formats).
       
    78   shortest_path = raw_entries[0][0].repos_path
       
    79 
       
    80   for svn_list, _ in raw_entries:
       
    81     if svn_list.kind == pysvn.node_kind.dir:
       
    82       entry_path = svn_list.repos_path
       
    83 
       
    84       if len(entry_path) < len(shortest_path):
       
    85         shortest_path = entry_path
       
    86 
       
    87   # normalize the path name of entry_prefix to include a trailing separator
       
    88   entry_prefix = shortest_path
       
    89 
       
    90   if not entry_prefix.endswith('/'):
       
    91     entry_prefix = entry_prefix + '/'
       
    92 
       
    93   for svn_list,_ in raw_entries:
       
    94     # only include requested node kinds (dir, file, etc.)
       
    95     if svn_list.kind not in keep_kinds:
       
    96       continue
       
    97 
       
    98     entry_path = svn_list.repos_path
       
    99 
       
   100     # omit the repo_path directory entry itself (simiilar to omitting '.' as
       
   101     # is done by the actual 'svn ls' command)
       
   102     if entry_path == shortest_path:
       
   103       continue
       
   104 
       
   105     # all entry_paths except for the shortest should start with that
       
   106     # shortest entry_prefix, so assert that and remove the prefix
       
   107     assert entry_path.startswith(entry_prefix)
       
   108     entry_path = entry_path[len(entry_prefix):]
       
   109 
       
   110     # normalize directory entry_paths to include a trailing separator
       
   111     if ((svn_list.kind == pysvn.node_kind.dir)
       
   112         and (not entry_path.endswith('/'))):
       
   113       entry_path = entry_path + '/'
       
   114 
       
   115     entries.append(entry_path)
       
   116 
       
   117   return entries
       
   118 
       
   119 
       
   120 def lsDirs(client, repo_path, **kwargs):
       
   121   """Wrapper around ls() that only returns node_kind.dir entries.
       
   122   """
       
   123   return ls(client, repo_path, keep_kinds=(pysvn.node_kind.dir,), **kwargs)
       
   124 
       
   125 
       
   126 def lsFiles(client, repo_path, **kwargs):
       
   127   """Wrapper around ls() that only returns node_kind.files entries.
       
   128   """
       
   129   return ls(client, repo_path, keep_kinds=(pysvn.node_kind.file,), **kwargs)
       
   130 
       
   131 
       
   132 def exists(client, repo_path):
       
   133   """Returns True if repo_path exists in the svn repository."""
       
   134   try:
       
   135     raw_entries = client.list(repo_path)
       
   136     return True
       
   137   except pysvn._pysvn.ClientError:
       
   138     # Client.list() raises an exception if the path is not present in the repo
       
   139     return False