1#!/usr/bin/env python 2# 3# Copyright (c) 2014, Craig Rodrigues <rodrigc@FreeBSD.org> 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice unmodified, this list of conditions, and the following 11# disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27 28# Display SVN log entries for changesets which have files which were 29# Added or Deleted. 30# This script takes arguments which would normally be 31# passed to the "svn log" command. 32# 33# Examples: 34# 35# (1) Display all new changesets in stable/10 branch: 36# 37# list-new-changesets.py --stop-on-copy \ 38# svn://svn.freebsd.org/base/stable/10 39# 40# (2) Display all new changesets between r254153 and r261794 in 41# stable/9 branch: 42# 43# list-new-changesets.py -r254153:261794 \ 44# svn://svn.freebsd.org/base/stable/9 45 46from __future__ import print_function 47import os 48import subprocess 49import sys 50import xml.etree.ElementTree 51 52def print_logentry(logentry): 53 """Print an SVN log entry. 54 55 Take an SVN log entry formatted in XML, and print it out in 56 plain text. 57 """ 58 rev = logentry.attrib['revision'] 59 author = logentry.find('author').text 60 date = logentry.find('date').text 61 msg = logentry.find('msg').text 62 63 print("-" * 71) 64 print("%s | %s | %s" % (rev, author, date)) 65 print("Changed paths:") 66 for paths in logentry.findall('paths'): 67 for path in paths.findall('path'): 68 print(" %s %s" % (path.attrib['action'], path.text)) 69 70 print() 71 print(msg.encode('utf-8')) 72 73def main(args): 74 """Main function. 75 76 Take command-line arguments which would be passed to 'svn log'. 77 Prepend '-v --xml' to get verbose XML formatted output. 78 Only display entries which have Added or Deleted files. 79 """ 80 cmd = ["svn", "log", "-v", "--xml"] 81 cmd += args[1:] 82 83 print(" ".join(cmd)) 84 85 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 86 (out, err) = proc.communicate() 87 88 if proc.returncode != 0: 89 print(err) 90 sys.exit(proc.returncode) 91 92 displayed_entries = 0 93 root = xml.etree.ElementTree.fromstring(out) 94 95 for logentry in root.findall('logentry'): 96 show_logentry = False 97 98 for paths in logentry.findall('paths'): 99 for path in paths.findall('path'): 100 if path.attrib['action'] == 'A': 101 show_logentry = True 102 elif path.attrib['action'] == 'D': 103 show_logentry = True 104 105 if show_logentry == True : 106 print_logentry(logentry) 107 displayed_entries += 1 108 109 if displayed_entries == 0: 110 print("No changesets with Added or Deleted files") 111 112 if displayed_entries > 0: 113 print("-" * 71) 114 115 116if __name__ == "__main__": 117 main(sys.argv) 118