mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Consolidate a bunch of CVS or RCS logs read from stdin.
This commit is contained in:
		
							parent
							
								
									c4d6c4d950
								
							
						
					
					
						commit
						6f0cf7ee20
					
				
					 1 changed files with 124 additions and 0 deletions
				
			
		
							
								
								
									
										124
									
								
								Tools/scripts/logmerge.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										124
									
								
								Tools/scripts/logmerge.py
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,124 @@
 | 
				
			||||||
 | 
					#! /usr/bin/env python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""Consolidate a bunch of CVS or RCS logs read from stdin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Input should be the output of a CVS or RCS logging command, e.g.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cvs log -rrelease14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					which dumps all log messages from release1.4 upwards (assuming that
 | 
				
			||||||
 | 
					release 1.4 was tagged with tag 'release14').
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This collects all the revision records and outputs them sorted by date
 | 
				
			||||||
 | 
					rather than by file, collapsing duplicate revision record, i.e.,
 | 
				
			||||||
 | 
					records with the same message for different files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The -t option causes it to truncate (discard) the last revision log
 | 
				
			||||||
 | 
					entry; this is useful when using something like the above cvs log
 | 
				
			||||||
 | 
					command, which shows the revisions including the given tag, while you
 | 
				
			||||||
 | 
					probably want everything *since* that tag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					XXX This code was created by reverse engineering CVS 1.9 and RCS 5.7.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os, sys, getopt, string, re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sep1 = '='*77 + '\n'			# file separator
 | 
				
			||||||
 | 
					sep2 = '-'*28 + '\n'			# revision separator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    """Main program"""
 | 
				
			||||||
 | 
					    truncate_last = 0
 | 
				
			||||||
 | 
					    opts, args = getopt.getopt(sys.argv[1:], "-t")
 | 
				
			||||||
 | 
					    for o, a in opts:
 | 
				
			||||||
 | 
						if o == '-t':
 | 
				
			||||||
 | 
						    truncate_last = 1
 | 
				
			||||||
 | 
					    database = []
 | 
				
			||||||
 | 
					    while 1:
 | 
				
			||||||
 | 
						chunk = read_chunk(sys.stdin)
 | 
				
			||||||
 | 
						if not chunk:
 | 
				
			||||||
 | 
						    break
 | 
				
			||||||
 | 
						records = digest_chunk(chunk)
 | 
				
			||||||
 | 
						if truncate_last:
 | 
				
			||||||
 | 
						    del records[-1]
 | 
				
			||||||
 | 
						database[len(database):] = records
 | 
				
			||||||
 | 
					    database.sort()
 | 
				
			||||||
 | 
					    database.reverse()
 | 
				
			||||||
 | 
					    format_output(database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_chunk(fp):
 | 
				
			||||||
 | 
					    """Read a chunk -- data for one file, ending with sep1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Split the chunk in parts separated by sep2.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    chunk = []
 | 
				
			||||||
 | 
					    lines = []
 | 
				
			||||||
 | 
					    while 1:
 | 
				
			||||||
 | 
						line = fp.readline()
 | 
				
			||||||
 | 
						if not line:
 | 
				
			||||||
 | 
						    break
 | 
				
			||||||
 | 
						if line == sep1:
 | 
				
			||||||
 | 
						    if lines:
 | 
				
			||||||
 | 
							chunk.append(lines)
 | 
				
			||||||
 | 
						    break
 | 
				
			||||||
 | 
						if line == sep2:
 | 
				
			||||||
 | 
						    if lines:
 | 
				
			||||||
 | 
							chunk.append(lines)
 | 
				
			||||||
 | 
							lines = []
 | 
				
			||||||
 | 
						else:
 | 
				
			||||||
 | 
						    lines.append(line)
 | 
				
			||||||
 | 
					    return chunk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def digest_chunk(chunk):
 | 
				
			||||||
 | 
					    """Digest a chunk -- extrach working file name and revisions"""
 | 
				
			||||||
 | 
					    lines = chunk[0]
 | 
				
			||||||
 | 
					    key = 'Working file:'
 | 
				
			||||||
 | 
					    keylen = len(key)
 | 
				
			||||||
 | 
					    for line in lines:
 | 
				
			||||||
 | 
						if line[:keylen] == key:
 | 
				
			||||||
 | 
						    working_file = string.strip(line[keylen:])
 | 
				
			||||||
 | 
						    break
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
						working_file = None
 | 
				
			||||||
 | 
					    records = []
 | 
				
			||||||
 | 
					    for lines in chunk[1:]:
 | 
				
			||||||
 | 
						revline = lines[0]
 | 
				
			||||||
 | 
						dateline = lines[1]
 | 
				
			||||||
 | 
						text = lines[2:]
 | 
				
			||||||
 | 
						words = string.split(dateline)
 | 
				
			||||||
 | 
						if len(words) >= 3 and words[0] == 'date:':
 | 
				
			||||||
 | 
						    dateword = words[1]
 | 
				
			||||||
 | 
						    timeword = words[2]
 | 
				
			||||||
 | 
						    if timeword[-1:] == ';':
 | 
				
			||||||
 | 
							timeword = timeword[:-1]
 | 
				
			||||||
 | 
						    date = dateword + ' ' + timeword
 | 
				
			||||||
 | 
						else:
 | 
				
			||||||
 | 
						    date = None
 | 
				
			||||||
 | 
						    text.insert(0, revline)
 | 
				
			||||||
 | 
						words = string.split(revline)
 | 
				
			||||||
 | 
						if len(words) >= 2 and words[0] == 'revision':
 | 
				
			||||||
 | 
						    rev = words[1]
 | 
				
			||||||
 | 
						else:
 | 
				
			||||||
 | 
						    rev = None
 | 
				
			||||||
 | 
						    text.insert(0, revline)
 | 
				
			||||||
 | 
						records.append((date, working_file, rev, text))
 | 
				
			||||||
 | 
					    return records
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					def format_output(database):
 | 
				
			||||||
 | 
					    prevtext = None
 | 
				
			||||||
 | 
					    prev = []
 | 
				
			||||||
 | 
					    database.append((None, None, None, None)) # Sentinel
 | 
				
			||||||
 | 
					    for (date, working_file, rev, text) in database:
 | 
				
			||||||
 | 
						if text != prevtext:
 | 
				
			||||||
 | 
						    if prev:
 | 
				
			||||||
 | 
							print sep2,
 | 
				
			||||||
 | 
							for (date, working_file, rev) in prev:
 | 
				
			||||||
 | 
							    print date, working_file
 | 
				
			||||||
 | 
							sys.stdout.writelines(prevtext)
 | 
				
			||||||
 | 
						    prev = []
 | 
				
			||||||
 | 
						prev.append((date, working_file, rev))
 | 
				
			||||||
 | 
						prevtext = text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue