473,581 Members | 2,755 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Noob script needs some input: CVS PatchMaker

I needed a tool for extracting patches from CVS based on the log
messages. I.e. we mark our fixes and features with a "Bugdb XYZ"
And sometimes you need to move a fix/feature to another branch or maybe
you just want to inspect exactly what changes were related to a
specific bugdb issue.

Now I've searched hi and low for this and I now it's out there
somewhere bleeding obvious - can't imagine I'm the first to have this
thought. I just haven't been able to find it...
Well, that was an excellent opportunity to get some python practice, so
below is my first shot at the problem.

Any feedback on what would be "the pythonic way" to do this would be
much appreciated!

Usage:
cd myproject
patchmaker <regxpr>

Ouput is a diff of involved files+revs
Thank you,
/Holger
----------------------------------------------------------------------------------------------------------------------
#!/usr/bin/env python
# Copyright 2006 Holger Lindeberg Bille

import sys, re, os
import popen2

workingfile = re.compile("^Wo rking file: *(.*)$")
revision = re.compile("^re vision *(.*)$")
fileend =
re.compile("^== =============== =============== =============== =============== =============")
details = re.compile("^da te: *")
entryend = re.compile("^----------------------------")
branches = re.compile("^br anches:( *(.*);)*")

class LogEntry:
def __init__(self):
self.rev = 0
self.prevrev = 0
self.text = []

def setName(self, name):
self.name = name

def read(self, file):
done = 0
for line in file:
regx = details.search( line)
if regx:
pass
else:
if entryend.search (line):
break
else:
if fileend.search( line):
done = 1
break
else:
self.text.appen d(line.strip())
return done

def GuessPrevRev(se lf):
pass

def filter(self, filter):
found = 0
for line in self.text:
if filter.search(l ine):
found = 1
break
return found

def calcPrevRev(sel f):
# todo: get this from CVS instead of guessing
self.rev = "1.1"
self.prevrev = "1.1"
ver = self.name.split (".")
n = int(ver.pop()) - 1
while len(ver) >= 1:
if n >= 1:
ver.append(str( n))
self.prevrev = ".".join(ve r)
self.rev = self.name
break
else:
ver.pop() # throw this away
n = int(ver.pop())

def patchDump(self, file):
cmd = "cvs -q diff -u -b -r %s -r %s %s" % (self.prevrev,
self.rev, file)
# print cmd
outp, inp = popen2.popen2(c md)
for line in outp:
print line,
outp.close()
inp.close()

def dump(self):
print "------------------------------------------"
print "rev = %s" % self.name
for line in self.text:
print line
class FileLog:
def __init__(self):
self.revs = []

def setName(self, name):
self.name = name

def read(self, file):
for line in file:
regx = revision.search (line)
if regx:
rev = LogEntry()
rev.setName(reg x.group(1))
done = rev.read(file)
self.revs.appen d(rev)
if done:
break

def filter(self, filter):
found = 0
newrevs = []
for rev in self.revs:
if rev.filter(filt er):
found = 1
newrevs.append( rev)
self.revs = newrevs
return found

def calcPrevRev(sel f):
for rev in self.revs:
rev.calcPrevRev ()

def patchDump(self) :
for rev in self.revs:
rev.patchDump(s elf.name)

def dump(self):
print "File = %s" % self.name
print "No. of revs %d" % len(self.revs)
for rev in self.revs:
rev.dump()
print "============== =============== =============== ==="

class LogDB:
def __init__(self):
self.flogs = []

def read(self):
outp, inp = popen2.popen2(' cvs -q log -N')
found = 0
for line in outp:
regx = workingfile.sea rch(line)
if regx:
flog = FileLog()
flog.setName(re gx.group(1))
flog.read(outp)
self.flogs.appe nd(flog)
outp.close()
inp.close()

def filter(self, filter):
newflogs = []
for flog in self.flogs:
if flog.filter(fil ter):
newflogs.append (flog)
self.flogs = newflogs

def calcPrevRev(sel f):
for flog in self.flogs:
flog.calcPrevRe v()

def patchDump(self) :
for flog in self.flogs:
flog.patchDump( )

def dump(self):
print "Starting dump"
print "============== =============== =============== ==="
for flog in self.flogs:
flog.dump()

if len(sys.argv) != 2:
sys.stderr.writ e("wrong number of args")
sys.exit()
a = sys.argv[1]
a.encode('latin-1')
#print "arg = %s" % a
db = LogDB()
db.read()
#db.dump()
myfilter = re.compile(a)
db.filter(myfil ter)
#db.dump()
db.calcPrevRev( )
db.patchDump()

Jun 16 '06 #1
2 1237
On 16/06/2006 7:28 PM, Holger wrote:
Well, that was an excellent opportunity to get some python practice, so
below is my first shot at the problem.

Any feedback on what would be "the pythonic way" to do this would be
much appreciated!
#!/usr/bin/env python
# Copyright 2006 Holger Lindeberg Bille

import sys, re, os
import popen2

workingfile = re.compile("^Wo rking file: *(.*)$")
revision = re.compile("^re vision *(.*)$")
fileend =
re.compile("^== =============== =============== =============== =============== =============")
details = re.compile("^da te: *")
entryend = re.compile("^----------------------------")
branches = re.compile("^br anches:( *(.*);)*")

class LogEntry:
def __init__(self):
self.rev = 0
self.prevrev = 0
self.text = []

def setName(self, name):
self.name = name

def read(self, file):
done = 0
for line in file:
regx = details.search( line)
if regx:
pass
else:
if entryend.search (line):
break
else:
if fileend.search( line):
done = 1
break
else:
self.text.appen d(line.strip())
return done
IMHO that flight of geese heading equatorwards for winter is not Xic for
any language X. Compare with:
| def read(self, file):
| done = 0
| for line in file:
| regx = details.search( line)
| if regx:
| pass
| elif entryend.search (line):
| break
| elif fileend.search( line):
| done = 1
| break
| else:
| self.text.appen d(line.strip())
| return done

2nd comment: Make a habit of NOT using the names of built-ins like
"file" for your own names. Pretend they are reserved words. Doesn't
matter in this case, but will save you grief some day soon.

3rd comment: Read the section in the re manual that explains the
difference between search and match. Searching for "^foo" will give the
same results as using match() with "foo" or the redundantly anchored
"^foo". However some regex engines when presented with
re.search("^foo ", "x" * 10000)
will note that there is no joy at offset 0, there is no point (given the
anchor "^") of looking at offset 1, and return almost immediately.
Others (cough, cough) will check at offset 1, 2, ...
Ponder these results:

python -mtimeit -s"import re;rx=re.compil e('^foo');txt=' x'*10000"
"rx.match(t xt)"
100000 loops, best of 3: 1.2 usec per loop

python -mtimeit -s"import re;rx=re.compil e('foo');txt='x '*10000" "
rx.search(txt)"
10000 loops, best of 3: 19.8 usec per loop

python -mtimeit -s"import re;rx=re.compil e('^foo');txt=' x'*10000"
"rx.search(txt) "
1000 loops, best of 3: 201 usec per loop

4th comment: what you have called "regx" is a match object. "mobj" might
be a better choice. The term "regex" is applied to a pattern, or
sometimes to the compiled re object.
def GuessPrevRev(se lf):
pass

def filter(self, filter):
Ugh. THREE filters: the built-in, the argument, and the method.
In any case, this method doesn't perform a filtering operation, and the
arg is not a filter, it's an re pattern. Suggestion:
def anyLinesMatch(s elf, pattern):
found = 0
for line in self.text:
if filter.search(l ine):
found = 1
break
return found
[snip]
class FileLog:
def __init__(self):
self.revs = []
[snip]
def filter(self, filter):
found = 0
newrevs = []
for rev in self.revs:
if rev.filter(filt er):
Waahhh! The filter count has now hit 4.
found = 1
newrevs.append( rev)
self.revs = newrevs
return found
[snip]

class LogDB:
def __init__(self):
self.flogs = [] [snip] def filter(self, filter):
newflogs = []
for flog in self.flogs:
if flog.filter(fil ter): See above. newflogs.append (flog)
self.flogs = newflogs

[snip]

HTH,
John
Jun 17 '06 #2

John Machin wrote:
Any feedback on what would be "the pythonic way" to do this would be
much appreciated!
--snip--
IMHO that flight of geese heading equatorwards for winter is not Xic for
any language X. Compare with:
He he, good point.
2nd comment: Make a habit of NOT using the names of built-ins like
"file" for your own names. Pretend they are reserved words. Doesn't
matter in this case, but will save you grief some day soon.

Agree.
3rd comment: Read the section in the re manual that explains the
difference between search and match. Searching for "^foo" will give the
same results as using match() with "foo" or the redundantly anchored
"^foo". However some regex engines when presented with
Good point.
4th comment: what you have called "regx" is a match object. "mobj" might
be a better choice. The term "regex" is applied to a pattern, or
sometimes to the compiled re object. ]
HTH,
John


Thank you for taking the time :-)
All points are noted.

Holger,

Jun 19 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1619
by: Rtritell | last post by:
I dont get whats wrong with this <html> <head> <title>Random Mad Lib!</title> <script language="JavaScript"> <!-- Hide
4
1227
by: areese801 | last post by:
i am using a website with a form that passes criteria to a javascript to run a query rather than just appending my criteria to parts of the URL. i need to import a bunch of records into MS access from this site. this would be very easy to do if i could just change part of the url and programatically navigate there. unfortunatly this...
17
7900
by: comp.lang.tcl | last post by:
The TCL command I am using will do a command-line action on a PHP script: set cannotRunPHP I have to do it this way as both the TCL script and the PHP script run as CLI. However, "info.php" requires user input to run; this causes the TCL script calling the PHP script to hose up and die. Is there a way I can do this so that the TCL...
1
1267
by: henry | last post by:
I'm hoping this won't be too hard with Javascript (I'm new to the language). I've got a page with a form on it (name=frm1) which has a text input (name=url). I want to be able to click a link that will open a popup that has 2 frames. The top frame (frameA) will have a button/link that, when clicked, will do 2 things: 1. Insert the URL of...
1
1623
by: islandsoul | last post by:
hey im trying to make something so it presses spacebar in game for me so i don't have to. i previously got this from somewhere else and tried to change it so it worked with the game i started playing. here is the first script '----------------- intHighNumber = 10 intLowNumber = 5 x = 0 wow="World of Warcraft"
2
3105
by: Muzzy | last post by:
Hi, I've used information on these newsgroups to build many pages. So I thought that now that I have my script working (something that I've been working on for about a week), I should post it so that it may help others. If posting this script is against the rules in this group then please accept my appologies. I developped this script so...
3
1623
by: Mr. Roper | last post by:
I'm pretty weak when it comes to Java script, hopefully someone will take mercy on my sole and explain this to me. How come on the following HTML page, when I have my first script tag commented out, my button calls my OnClick function. However if I uncomment the first script tag, I get the following error: Button1_onclick is not defined ...
6
1473
by: plemon | last post by:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Untitled Document</title> <script type="text/javascript">var v11 = + $0; var v12 = +...
6
1983
by: Paulchen | last post by:
Hello, I have found a perl script and need to "translate" this to PHP. I try to do it step by step and the first part of it is this function (the whole script is found at http://nonsense.sourceforge.net/): ### Load and parse a datafile, slurping the contents into the %pool hash sub LoadDataFile { my $file = shift; $file = SafeFile(...
0
7783
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8134
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8296
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7880
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6539
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5350
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3794
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3807
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1119
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.