-
Notifications
You must be signed in to change notification settings - Fork 1
/
cvs_utils.py
163 lines (145 loc) · 5.92 KB
/
cvs_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
'''
Utilities for cvs repos'''
import os
import re
import sys
import subprocess
import fileinput
from repo_defaults import *
def cvsPathExists( cvsPath, revision=None, debug=False ):
try:
if revision:
repoCmd = [ 'cvs', 'ls', '%s@%s' % ( cvsPath, revision) ]
else:
repoCmd = [ 'cvs', 'ls', cvsPath ]
if debug:
print("cvsPathExists check_output: %s" % ' '.join( repoCmd ))
contents = subprocess.check_output( repoCmd, stderr = subprocess.STDOUT, text=True )
# No need to check contents
# If no exception, the path exists
return True
except RuntimeError:
return False
except subprocess.CalledProcessError:
return False
def cvsGetRemoteTags( packageName, verbose=False ):
p1 = subprocess.Popen(['cvs', '-Q', 'rlog', '-h', packageName], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['awk', '-F"[.:]"', '/^\t/&&$(NF-1)!=0{print $1}'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
plaintags = set()
for line in output.split('\n'):
line = line.strip()
parts = line.split()
if len(parts) < 1:
continue
plaintags.add(parts[0].split(":")[0])
tags = sorted(plaintags)
if verbose:
print("cvsGetRemoteTags: Found %d tags in %s" % ( len(tags), packageName ))
return tags
def cvsGetWorkingBranch( debug=False ):
'''See if the current directory is the top of an cvs working directory.
Returns a 3-tuple of [ url, branch, tag ], [ None, None, None ] on error.
For a valid cvs working dir, url must be a valid string, branch is typically
the last component of the working dir path. tag is either None or the same
as branch if path matches the cvs tags naming scheme.'''
repo_url = None
repo_branch = None
repo_tag = None
try:
repoCmd = [ 'cvs', 'info', '.' ]
statusInfo = subprocess.check_output( repoCmd, stderr=subprocess.STDOUT, text=True )
statusLines = statusInfo.splitlines()
for line in statusLines:
if line is None:
break
if line.startswith( "URL:" ):
repo_url = line.split()[1]
repo_tag = None
( parent_dir, repo_branch ) = os.path.split( repo_url )
while parent_dir:
( parent_dir, dir_name ) = os.path.split( parent_dir )
if dir_name == 'tags':
repo_tag = repo_branch
break
break
except OSError as e:
if debug:
print(e)
pass
except subprocess.CalledProcessError as e:
if debug:
print(e)
pass
return ( repo_url, repo_branch, repo_tag )
def cvsFindPackageRelease( packageSpec, tag, debug = False, verbose = False ):
(repo_url, repo_path, repo_tag) = (None, None, None)
if verbose:
print("cvsFindPackageRelease: Need to find packageSpec=%s, tag=%s" % (packageSpec, tag))
if verbose:
if repo_url:
print("cvsFindPackageRelease found %s/%s: url=%s, repo_path=%s, tag=%s" % (packageSpec, tag, repo_url, repo_path, repo_tag))
else:
print("cvsFindPackageRelease Error: Cannot find %s/%s" % (packageSpec, tag))
return (repo_url, repo_path, repo_tag)
def parseCVSModulesTxt( cvsRepoRoot=None, verbose=False ):
'''Parse the CVS modules file and return a dict of packageName -> location'''
package2Location = {}
if cvsRepoRoot is not None:
os.environ['CVSROOT'] = cvsRepoRoot
if 'CVSROOT' not in os.environ:
if not os.path.exists( DEF_CVS_ROOT ):
# CVS root not accessible. Carry on quietly.
return package2Location
os.environ['CVSROOT'] = DEF_CVS_ROOT
cvsModulesTxtFile = os.path.join( os.environ['CVSROOT'], 'CVSROOT', 'modules')
if not os.path.exists(cvsModulesTxtFile):
if verbose:
print("CVS modules file not accessible: Unable to load CVS module list.")
return package2Location
with open(cvsModulesTxtFile, 'r') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if not line:
continue
if line.startswith('#'):
continue
# Spear CVS repo uses these CVS module features
# Example: If CVSROOT/modules contains
# foo path/to/foo &bar
# bar -d subDir/bar path/to/bar
# Then:
# % cvs co foo
# is equivalent to
# % cvs co path/to/foo MAIN_TRUNK
# % cd MAIN_TRUNK
# % cvs co path/to/bar subDir/bar
# See if a directory path is specified
dirPath = "."
dirPathRegExp = re.compile( r"-d (\S+)" )
dirPathMatch = dirPathRegExp.search( line )
if dirPathMatch:
dirPath = dirPathMatch.group(1)
line = line.replace( dirPathMatch.group(0), "" )
# See if any submodules are specified
subModules = []
subModuleRegExp = re.compile( r"&(\S+)" )
while True:
subModuleMatch = subModuleRegExp.search( line )
if not subModuleMatch:
break
subModules.append( subModuleMatch.group(1) )
line = line.replace( subModuleMatch.group(0), "" )
# We should have at most 2 whitespace separated parts left: packageName packageLocation
parts = line.split()
if(len(parts) < 2):
if verbose:
print("Error parsing ", cvsModulesTxtFile, "Cannot break", line, "into columns with enough fields using spaces/tabs")
continue
packageName = parts[0]
packageLocation = parts[1]
package2Location[packageName] = packageLocation
# Note: could return ( package2Location, dirPath, subModules ) if we intended to do something w/ dirPath or subModules
return package2Location