LSSTApplications  16.0-10-g0ee56ad+4,16.0-11-ga33d1f2+4,16.0-12-g3ef5c14+2,16.0-12-g71e5ef5+17,16.0-12-gbdf3636+2,16.0-13-g118c103+2,16.0-13-g8f68b0a+2,16.0-15-gbf5c1cb+3,16.0-16-gfd17674+2,16.0-17-g7c01f5c+2,16.0-18-g0a50484,16.0-20-ga20f992+7,16.0-21-g0e05fd4+5,16.0-21-g15e2d33+3,16.0-22-g62d8060+3,16.0-22-g847a80f+3,16.0-25-gf00d9b8,16.0-28-g3990c221+3,16.0-3-gf928089+2,16.0-32-g88a4f23+4,16.0-34-gd7987ad+2,16.0-37-gc7333cb+1,16.0-4-g10fc685+1,16.0-4-g18f3627+25,16.0-4-g5f3a788+25,16.0-5-gaf5c3d7+3,16.0-5-gcc1f4bb,16.0-6-g3b92700+3,16.0-6-g4412fcd+2,16.0-6-g7235603+3,16.0-69-g2562ce1b+1,16.0-7-g0913a87,16.0-8-g14ebd58+3,16.0-8-g2df868b,16.0-8-g4cec79c+5,16.0-8-gadf6c7a,16.0-82-g59ec2a54a,16.0-9-g5400cdc+1,16.0-9-ge6233d7+4,master-g2880f2d8cf+2,v17.0.rc1
LSSTDataManagementBasePackage
svn.py
Go to the documentation of this file.
1 #
2 # A simple python interface to svn, using os.popen
3 #
4 # If ever we want to do anything clever, we should use one of
5 # the supported svn/python packages
6 #
7 import os
8 import re
9 import sys
10 
11 
12 def isSvnFile(file):
13  """Is file under svn control?"""
14 
15  return re.search(r"is not a working copy",
16  "".join(os.popen("svn info %s 2>&1" % file).readlines())) is None
17 
18 
19 def getInfo(file="."):
20  """Return a dictionary of all the information returned by "svn info" for the specified file"""
21 
22  if not isSvnFile(file):
23  raise RuntimeError("%s is not under svn control" % file)
24 
25  infoList = os.popen("svn info %s" % file).readlines()
26 
27  info = {}
28  for line in infoList:
29  mat = re.search(r"^([^:]+)\s*:\s*(.*)", line)
30  if mat:
31  info[mat.group(1)] = mat.group(2)
32 
33  return info
34 
35 
36 def isTrunk(file="."):
37  """Is file on the trunk?"""
38 
39  info = getInfo(file)
40 
41  return re.search(r"/trunk($|/)", info["URL"]) is not None
42 
43 
44 def revision(file=None, lastChanged=False):
45  """Return file's Revision as a string; if file is None return
46  a tuple (oldestRevision, youngestRevision, flags) as reported
47  by svnversion; e.g. (4123, 4168, ("M", "S")) (oldestRevision
48  and youngestRevision may be equal)
49  """
50 
51  if file:
52  info = getInfo(file)
53 
54  if lastChanged:
55  return info["Last Changed Rev"]
56  else:
57  return info["Revision"]
58 
59  if lastChanged:
60  raise RuntimeError("lastChanged makes no sense if file is None")
61 
62  res = os.popen("svnversion . 2>&1").readline()
63 
64  if res == "exported\n":
65  raise RuntimeError("No svn revision information is available")
66 
67  versionRe = r"^(?P<oldest>\d+)(:(?P<youngest>\d+))?(?P<flags>[MS]*)"
68  mat = re.search(versionRe, res)
69  if mat:
70  matches = mat.groupdict()
71  if not matches["youngest"]:
72  matches["youngest"] = matches["oldest"]
73  # OK, we have only one revision present. Find the newest revision
74  # that actually changed anything in this product and ignore "oldest" (#522)
75  res = os.popen("svnversion --committed . 2>&1").readline()
76  mat = re.search(versionRe, res)
77  if mat:
78  matches = mat.groupdict()
79  return matches["youngest"], matches["youngest"], tuple(matches["flags"])
80 
81  return matches["oldest"], matches["youngest"], tuple(matches["flags"])
82 
83  raise RuntimeError("svnversion returned unexpected result \"%s\"" % res[:-1])
84 
85 
86 #
87 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
88 #
89 def guessVersionName(HeadURL):
90  """Guess a version name given a HeadURL"""
91 
92  if re.search(r"/trunk$", HeadURL):
93  versionName = ""
94  elif re.search(r"/branches/(.+)$", HeadURL):
95  versionName = "branch_%s+" % re.search(r"/branches/(.+)$", HeadURL).group(1)
96  elif re.search(r"/tags/(.+)$", HeadURL):
97  versionName = "%s" % re.search(r"/tags/(.*)$", HeadURL).group(1)
98 
99  return versionName # no need for a "+svnXXXX"
100  elif re.search(r"/tickets/(\d+)$", HeadURL):
101  versionName = "ticket_%s+" % re.search(r"/tickets/(\d+)$", HeadURL).group(1)
102  else:
103  print("Unable to guess versionName name from %s" % HeadURL, file=sys.stderr)
104  versionName = "unknown+"
105 
106  try: # Try to lookup the svn versionName
107  (oldest, youngest, flags) = revision()
108 
109  okVersion = True
110  if "M" in flags:
111  msg = "You are installing, but have unchecked in files"
112  okVersion = False
113  if "S" in flags:
114  msg = "You are installing, but have switched SVN URLs"
115  okVersion = False
116  if oldest != youngest:
117  msg = "You have a range of revisions in your tree (%s:%s); adopting %s" % \
118  (oldest, youngest, youngest)
119  okVersion = False
120 
121  if not okVersion:
122  raise RuntimeError("Problem with determining svn revision: %s" % msg)
123 
124  versionName += "svn" + youngest
125  except IOError:
126  return "unknown"
127 
128  return versionName
129 
130 
131 def parseVersionName(versionName):
132  """A callback that knows about the LSST convention that a tagname such as
133  ticket_374
134  means the top of ticket 374, and
135  ticket_374+svn6021
136  means revision 6021 on ticket 374. You may replace "ticket" with "branch" if you wish
137 
138  The "versionName" may actually be the directory part of a URL, and ".../(branches|tags|tickets)/tagname"
139  is also supported
140  """
141 
142  mat = re.search(r"/(branche|tag|ticket)s/(\d+(?:\.\d+)*)(?:([-+])((svn)?(\d+)))?$", versionName)
143  if not mat:
144  mat = re.search(r"/(branch|ticket)_(\d+)(?:([-+])svn(\d+))?$", versionName)
145  if mat:
146  type = mat.group(1)
147  if type == "branches":
148  type = "branch"
149  ticket = mat.group(2)
150  pm = mat.group(3) # + or -
151  revision = mat.group(4)
152  if revision:
153  revision = re.sub("^svn", "", revision)
154 
155  return (type, ticket, revision, pm)
156 
157  return (None, None, None, None)
def getInfo(file=".")
Definition: svn.py:19
def parseVersionName(versionName)
Definition: svn.py:131
def revision(file=None, lastChanged=False)
Definition: svn.py:44
def guessVersionName(HeadURL)
Definition: svn.py:89
table::Key< table::Array< int > > group
Definition: PsfexPsf.cc:359
def isSvnFile(file)
Definition: svn.py:12
def isTrunk(file=".")
Definition: svn.py:36