55502f40dc8b7c769880b10874abc9d0

This is designed to start an 'svn log' command and reformat the output so that I can just see revision, author and comment on one line. For example with svn log I get the following:
>svn log -l 2 http://svn.collab.net/repos/svn/trunk/
------------------------------------------------------------------------
r37792 | joeswatosh | 2009-05-22 07:10:21 +0100 (Fri, 22 May 2009) | 3 lines

Just can't stay away

* COMMITTERS (joeswatosh): revert r36491 make myself active again.
------------------------------------------------------------------------
r37791 | ebswift | 2009-05-22 06:17:32 +0100 (Fri, 22 May 2009) | 4 lines

* /packages/windows-WiX/BuildSubversion/CommonBinaryFiles.wxi
Fixed installed icon for the help file (NOTE, this is hard-coded,
but won't be easily forgotten because if it is missing an error
will be generated)
------------------------------------------------------------------------

With this tool I get:
>svnl.py -l 2 http://svn.collab.net/repos/svn/trunk/
r37792 | joeswatosh | Just can't stay away
r37791 | ebswift | * /packages/windows-WiX/BuildSubversion/CommonBinaryFiles.wxi

I have also defaulted the path to top/src.
I am a complete python newbie so am very interested in what I could have done better.

Thanks!

#!/usr/bin/python

# show svn log as a summary with revision, username and comment on one line
# with no extra lines
import getopt
import subprocess
import sys

# Start bulding the command line
cmd = ["svn", "log"]

# pass selected options straight through to svn log
opts, args = getopt.getopt(sys.argv[1:],"l:", ["limit"]) 
for opt, arg in opts:
  cmd.append(opt + " " + arg);

# Add path if given, default to top/src
if len(args) > 0:
  path = args[0]
else:
  path = "top/src"
cmd.append(path)

output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
lines = output.splitlines()

# Parse the output and reformat
sep = "------------------------------------------------------------------------"
for i in xrange(len(lines)):
  line = lines[i]
  if line == sep and i+3 <= len(lines):
    info = lines[i+1]
    comment = lines[i+3]
    bar1 = info.find("|")
    bar2 = info.find("|", bar1+1)
    output = info[:bar2+2] + comment
    print output

Refactorings

No refactoring yet !

55502f40dc8b7c769880b10874abc9d0

daniop.myopenid.com

May 22, 2009, May 22, 2009 13:31, permalink

No rating. Login to rate!

I just discovered how to get the subprocess output a line at a time which works much better e.g. for piping through grep.
Hopefully there is a better way in python than the rather poor state handling I have used.

#!/usr/bin/python

# show svn log as a summary with revision, username and comment on one line
# with no extra lines
import getopt
import subprocess
import sys

# Start bulding the command line
cmd = ["svn", "log"]

# pass selected options straight through to svn log
opts, args = getopt.getopt(sys.argv[1:],"l:", ["limit"]) 
for opt, arg in opts:
  cmd.append(opt + " " + arg);

# Add path if given, otherwise default to top/src
if len(args) > 0:
  path = args[0]
else:
  path = "top/src"
cmd.append(path)

# Send the svn log command, parsing and reformatting the output
sepLine = "------------------------------------------------------------------------"
# states that the parser could be in, in the order in which they appear in the input
SEP, INFO, BLANK, COMMENT = range(4)
first = SEP
last = COMMENT

svnlog = subprocess.Popen(cmd, stdout=subprocess.PIPE)
state = first
for line in svnlog.stdout.xreadlines():
  if line.startswith(sepLine):
    output = ""
    state = SEP # reset state in case a separator line is found out of expected order
  elif state == INFO:
    bar1 = line.find("|")
    bar2 = line.find("|", bar1+1)
    output = line[:bar2+2]
  elif state == COMMENT:
    output = output + line.strip()
    print output
    
  if (state < last):
    state = state + 1
  else:
    state = first # done - wait for the start again
Bbcac97b68f9e9cabd25a3f0f0bdbe49

Hugh Brown

June 4, 2009, June 04, 2009 19:55, permalink

No rating. Login to rate!
#!/usr/bin/python

# show svn log as a summary with revision, username and comment on one line
# with no extra lines
import getopt
import subprocess
import sys

# Add path if given, otherwise default to top/src
path = (args[0] if len(args) > 0 else "top/src")

# pass selected options straight through to svn log
opts, args = getopt.getopt(sys.argv[1:],"l:", ["limit"]) 

# Start bulding the command line
cmd = ["svn", "log"] + [(opt + " " + arg) for opt, arg in opts] + [path]

# Send the svn log command, parsing and reformatting the output
sepLine = "------------------------------------------------------------------------"
# states that the parser could be in, in the order in which they appear in the input
SEP, INFO, BLANK, COMMENT = range(4)
first, last = SEP, COMMENT

svnlog = subprocess.Popen(cmd, stdout=subprocess.PIPE)
state = first
for line in svnlog.stdout.xreadlines():
  if line.startswith(sepLine):
    output = ""
    state = SEP # reset state in case a separator line is found out of expected order
  elif state == INFO:
    bar1 = line.find("|")
    bar2 = line.find("|", bar1+1)
    output = line[:bar2+2]
  elif state == COMMENT:
    output += line.strip()
    print output

  state = (state + 1 if (state < last) else first)
Bbcac97b68f9e9cabd25a3f0f0bdbe49

Hugh Brown

June 4, 2009, June 04, 2009 20:07, permalink

No rating. Login to rate!

Couple of problems with the last code.

Lifted the code to eliminate state transitions that daniop wrote.

#!/usr/bin/python

# show svn log as a summary with revision, username and comment on one line
# with no extra lines
from getopt import getopt
from subprocess import Popen, PIPE
from sys import argv

# pass selected options straight through to svn log
opts, args = getopt(argv[1:],"l:", ["limit"]) 

# Add path if given, otherwise default to top/src
path = (args[0] if len(args) > 0 else "top/src")

# Start bulding the command line
cmd = ["svn", "log"] + [(opt + " " + arg) for opt, arg in opts] + [path]

svnlog = Popen(cmd, stdout=PIPE)
lines = output.splitlines()

# Parse the output and reformat
sep = "-" * 72
for i, line in enumerate(lines):
  if line == sep and i+3 <= len(lines):
    info, comment = lines[i+1], lines[i+3]
    bar1 = info.find("|")
    bar2 = info.find("|", bar1+1)
    print info[:bar2+2] + comment
Bbcac97b68f9e9cabd25a3f0f0bdbe49

Hugh Brown

June 4, 2009, June 04, 2009 20:08, permalink

1 rating. Login to rate!

One more time.

#!/usr/bin/python

# show svn log as a summary with revision, username and comment on one line
# with no extra lines
from getopt import getopt
from subprocess import Popen, PIPE
from sys import argv

# pass selected options straight through to svn log
opts, args = getopt(argv[1:],"l:", ["limit"]) 

# Add path if given, otherwise default to top/src
path = (args[0] if len(args) > 0 else "top/src")

# Start bulding the command line
cmd = ["svn", "log"] + [(opt + " " + arg) for opt, arg in opts] + [path]

svnlog = Popen(cmd, stdout=PIPE)
lines = svnlog.splitlines()

# Parse the output and reformat
sep = "-" * 72
for i, line in enumerate(lines):
  if line == sep and i+3 <= len(lines):
    info, comment = lines[i+1], lines[i+3]
    bar1 = info.find("|")
    bar2 = info.find("|", bar1+1)
    print info[:bar2+2] + comment
D41d8cd98f00b204e9800998ecf8427e

markus

September 29, 2009, September 29, 2009 17:42, permalink

No rating. Login to rate!
#!/usr/bin/python

# show svn log as a summary with revision, username and comment on one line
# with no extra lines

import sys 
from getopt import getopt
from subprocess import Popen, PIPE
from xml.dom import minidom

# pass selected options straight through to svn log
opts, args = getopt(sys.argv[1:],"l:", ["limit"]) 

# Add path if given, otherwise default to top/src
path = (args[0] if len(args) > 0 else "top/src")

# Start bulding the command line
cmd = ["svn", "log", "--xml"] + [(opt + " " + arg) for opt, arg in opts] + [path]

svnlog = Popen(cmd, stdout=PIPE).communicate()[0]
doc = minidom.parseString(svnlog)
for entry in doc.getElementsByTagName('logentry'):
    rev = entry.getAttribute('revision')
    author = entry.getElementsByTagName('author')[0].firstChild.data
    msg = entry.getElementsByTagName('msg')[0].firstChild.data
    print 'r%s | %s | %s' % (rev, author, msg,)
17a547c8fa25d4d610c9c881e1a63b15

gunstiges hotel

February 25, 2010, February 25, 2010 12:16, permalink

No rating. Login to rate!

Train Danger,capable used express turn pleasure official brief case neck when map end ready follow population academic intention policy drive vision edge rely photograph separate demand favour mechanism relation arise property most employ partner scientific lot signal domestic commission grant better provision forget appeal investment citizen somewhat sound range all feeling complex extremely population factory improvement play suggest feel background action understand until unfortunately corporate begin literature present quite example forget inside stuff achieve credit whom face anybody pleasure them upper goal discuss doctor fresh week environmental relatively

Train Danger,capable used express turn pleasure official brief case neck when map end ready follow population academic intention policy drive vision edge rely photograph separate demand favour mechanism relation arise property most employ partner scientific lot signal domestic commission grant better provision forget appeal investment citizen somewhat sound range all feeling complex extremely population factory improvement play suggest feel background action understand until unfortunately corporate begin literature present quite example forget inside stuff achieve credit whom face anybody pleasure them upper goal discuss doctor fresh week environmental relatively

Your refactoring





Format Copy from initial code

or Cancel