Changeset 267
- Timestamp:
- 03-06-07 19:42:09 (6 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
moap/command/cl.py (modified) (9 diffs)
-
moap/extern/command/command.py (modified) (1 diff)
-
moap/test/test_commands_cl.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r266 r267 1 1 2007-05-30 Thomas Vander Stichele <thomas at apestaart dot org> 2 2 3 patch by: bilboed@gmail.com3 patch by: Edward Hervey <bilboed@gmail.com> 4 4 5 5 * moap/command/cl.py (Prepare.do): -
trunk/moap/command/cl.py
r266 r267 20 20 # for matching the address out of the second part of the first line 21 21 _addressRegex = re.compile('^([^<]*)<(.*)>$') 22 23 # for matching contributors 24 _byRegex = re.compile(' by: ([^<]*)\s*.*$') 25 22 26 # for matching files changed 23 27 _fileRegex = re.compile('^\s*\* (.[^:\s\(]*).*') 24 28 29 # for matching release lines 30 _releaseRegex = re.compile(r'^=== release (.*) ===$') 31 25 32 class Entry: 26 33 """ 27 34 I represent one entry in a ChangeLog file. 28 29 @ivar text: the text of the message, without name line or 30 preceding/following newlines 31 @type text: str 32 @type date: str 33 @type name: str 34 @type address: str 35 @ivar files: list of files referenced in this ChangeLog entry 36 @type files: list of str 35 """ 36 37 class ChangeEntry(Entry): 38 """ 39 I represent one entry in a ChangeLog file. 40 41 @ivar text: the text of the message, without name line or 42 preceding/following newlines 43 @type text: str 44 @type date: str 45 @type name: str 46 @type address: str 47 @ivar files: list of files referenced in this ChangeLog entry 48 @type files: list of str 49 @ivar contributors: list of people who've contributed to this entry 50 @type contributors: str 37 51 """ 38 52 date = None … … 42 56 def __init__(self): 43 57 self.files = [] 58 self.contributors = [] 44 59 45 60 def parse(self, lines): … … 56 71 self.address = m.expand("\\2") 57 72 58 # all the other lines can contain files 73 # all the other lines can contain files or contributors 59 74 for line in lines[1:]: 60 75 m = _fileRegex.search(line) … … 62 77 fileName = m.expand("\\1") 63 78 self.files.append(fileName) 79 m = _byRegex.search(line) 80 if m: 81 # only append entries that we actually have a name for 82 name = m.expand("\\1").strip() 83 if name: 84 self.contributors.append(name) 64 85 65 86 # create the text attribute … … 71 92 self.text = "\n".join(save) + "\n" 72 93 94 class ReleaseEntry: 95 """ 96 I represent a release separator in a ChangeLog file. 97 """ 98 version = None 99 100 def parse(self, lines): 101 """ 102 @type lines: list of str 103 """ 104 # first and only line is the "release" line 105 m = _releaseRegex.search(lines[0]) 106 self.version = m.expand("\\1") 107 73 108 class ChangeLogFile(log.Loggable): 74 109 logCategory = "ChangeLog" … … 78 113 self._blocks = [] 79 114 self._entries = [] 115 self._releases = {} # map of release -> index in self._entries 80 116 handle = open(path, "r") 81 117 82 118 def parseBlock(block): 83 if block: 84 self._blocks.append(block) 85 entry = Entry() 86 entry.parse(block) 87 self._entries.append(entry) 119 if not block: 120 return 121 122 self._blocks.append(block) 123 if _nameRegex.match(block[0]): 124 entry = ChangeEntry() 125 elif _releaseRegex.match(block[0]): 126 entry = ReleaseEntry() 127 128 entry.parse(block) 129 self._entries.append(entry) 130 131 if isinstance(entry, ReleaseEntry): 132 self._releases[entry.version] = len(self._entries) - 1 133 134 return entry 88 135 89 136 block = [] 90 137 for line in handle.readlines(): 91 if _nameRegex.match(line) :92 # new entry starting, save old block138 if _nameRegex.match(line) or _releaseRegex.match(line): 139 # new entry starting, parse old block 93 140 parseBlock(block) 94 95 141 block = [] 142 96 143 block.append(line) 97 144 98 # don't forget t he last block145 # don't forget to parse the last block 99 146 parseBlock(block) 100 147 … … 109 156 """ 110 157 return self._entries[num] 158 159 def getReleaseIndex(self, release): 160 return self._releases[release] 161 111 162 112 163 class Checkin(util.LogCommand): … … 145 196 if not ret: 146 197 return 1 198 199 return 0 200 201 class Contributors(util.LogCommand): 202 usage = "contributors [path to directory or ChangeLog file]" 203 summary = "get a list of contributors since the previous release" 204 aliases = ["cont", "contrib"] 205 206 def addOptions(self): 207 self.parser.add_option('-r', '--release', 208 action="store", dest="release", 209 help="release to get contributors to") 210 211 def do(self, args): 212 path = os.getcwd() 213 if args: 214 path = os.path.abspath(args[0]) 215 216 if os.path.isdir(path): 217 filePath = os.path.join(path, 'ChangeLog') 218 else: 219 filePath = path 220 221 cl = ChangeLogFile(filePath) 222 223 names = [] 224 # find entry to start at 225 i = 0 226 if self.options.release: 227 try: 228 i = cl.getReleaseIndex(self.options.release) + 1 229 except KeyError: 230 self.stderr.write('No release %s found in %s !\n' % ( 231 self.options.release, filePath)) 232 return 3 233 234 self.debug('Release %s is entry %d' % (self.options.release, i)) 235 236 # now scan all entries from that point downwards 237 while True: 238 try: 239 entry = cl.getEntry(i) 240 except IndexError: 241 break 242 if isinstance(entry, ReleaseEntry): 243 break 244 245 if not entry.name in names: 246 self.debug("Adding name %s" % entry.name) 247 names.append(entry.name) 248 for n in entry.contributors: 249 if not n in names: 250 self.debug("Adding name %s" % n) 251 names.append(n) 252 253 i += 1 254 255 names.sort() 256 print names 257 self.stdout.write("\n".join(names) + "\n") 147 258 148 259 return 0 … … 347 458 348 459 Supported VCS systems: %s""" % ", ".join(vcs.getNames()) 349 subCommandClasses = [Checkin, Diff, Prepare]460 subCommandClasses = [Checkin, Contributors, Diff, Prepare] 350 461 aliases = ["cl", ] -
trunk/moap/extern/command/command.py
r219 r267 175 175 Parse the given arguments and act on them. 176 176 """ 177 options, args = self.parser.parse_args(argv) 178 179 ret = self.handleOptions(options) 177 print "THOMAS: parsing argv" 178 self.options, args = self.parser.parse_args(argv) 179 print "THOMAS: options %r" % self.options 180 181 # FIXME: make handleOptions not take options, since we store it 182 # in self.options now 183 ret = self.handleOptions(self.options) 180 184 if ret: 181 185 return ret -
trunk/moap/test/test_commands_cl.py
r215 r267 72 72 lines = e.text.split("\n")[:-1] 73 73 self.assertEquals(len(lines), 3) 74 75 class TestClGstPluginsBase(common.TestCase): 76 def setUp(self): 77 self.file = os.path.join(os.path.dirname(__file__), 'ChangeLog', 78 'ChangeLog.gst-plugins-base') 79 self.cl = cl.ChangeLogFile(self.file) 80 81 def testGetRelease(self): 82 e = self.cl.getEntry(0) 83 self.assertEquals(e.version, "0.10.10") 84 85 def testGetContributors(self): 86 e = self.cl.getEntry(1) 87 self.assertEquals(e.contributors, ["Michael Smith", ]) 88 89 def testContributors(self): 90 stdout = StringIO.StringIO() 91 c = cl.Contributors(stdout=stdout) 92 ret = c.parse([self.file, ]) 93 self.assertEquals(ret, 0) 94 self.assertEquals(stdout.getvalue(), "\n") 95 96 def testContributorsRelease(self): 97 stdout = StringIO.StringIO() 98 c = cl.Contributors(stdout=stdout) 99 ret = c.parse(["-r", "0.10.10", self.file, ]) 100 self.assertEquals(ret, 0) 101 self.assertEquals(stdout.getvalue(), """Michael Smith 102 Thomas Vander Stichele 103 Wim Taymans 104 """) 74 105 75 106 class TestCheckin(common.SVNTestCase):
Note: See TracChangeset
for help on using the changeset viewer.
