📄 dirdiff.py
字号:
#! /usr/bin/env python################################################################################ ## Copyright 2005 University of Cambridge Computer Laboratory. ## ## This file is part of Nprobe. ## ## Nprobe is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## Nprobe is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Nprobe; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ################################################################################################################################################################ ## ## Check two directories for diffing files, display differences## #### ############################################################################ ############################################################################ from string import *from sys import argvimport getoptimport osimport sysfrom stat import *from os.path import basename, dirname, join, isfile, isdir, islink, realpath, \ commonprefix, normpathfrom sys import exitimport popen2import refrom dirwalk import walk, resolve_path################################################################################ ## Turn off some tedious warnings#### ############################################################################from warnings import filterwarnings# tempnam security riskfilterwarnings('ignore', 'tempnam is a potential security risk to your program') ##############################################################################DEFAULT_FIRSTDIR = '/usr/groups/nprobe/jch1003/www/swig/grunge'DEFAULT_SECDIR = '/usr/groups/nprobe/jch1003/www/swig_dev/grunge'UNWANTED_SUFFIXES = ['pyc', 'so', 'ps', 'o']UNWANTED_TAILS = ['~', '#']DIFF = '/usr/bin/diff'PFIND = '/homes/jch1003/bin/python/pfind' ##############################################################################def unwanted_suff(f): if f[-1] in UNWANTED_TAILS: return 1 parts = f.split('.') if len(parts) > 1 and parts[-1] in UNWANTED_SUFFIXES: #print parts return 1 return 0 ##############################################################################def lsdir(dir, ferr): present = {} try: for f in os.listdir(dir): file = join(dir, f) try: mode = os.stat(file)[ST_MODE] except OSError, s: print s ferr.append((file, 'stat', str(s))) continue if S_ISDIR(mode): continue if unwanted_suff(file): continue #print f present[f] = 1 except OSError, s: ferr.append((dir, 'ls', s)) return present #############################################################################def do_diff(f, dir1, dir2, debug, context): def detailed_report(diffcmd, o, e): print 'Running', diffcmd diffs = o.readlines() if diffs: raw_input('See it...') print 'Diffs' for l in diffs: print l.strip() else: print 'Same' errs = e.readlines() if errs: print 'Error: ' for err in errs: print err.strip() raw_input('Next...') def printlines(b): for l in b: print l.strip() def eprintlines(b): for l in b: eprint(l.strip()) def escape_respecials(l): specials = '\.^$*+?{}[]()|' for c in specials: l = l.replace(c, '\%s' % (c)) return l def get_tmpf(): tmpfnm = os.tempnam('\tmp', 'dirrdif.') try: tmpf = open(tmpfnm, 'w') return (tmpf, tmpfnm) except IOError, s: sys.stderr.write('dirdiff: error opening temp file: %s\n' % (str(s))) sys.exit(1) def run_pfind(ccmd): #print 'running ', ccmd o, i, e = popen2.popen3(ccmd) cont = o.readlines() errs = e.readlines() printlines(cont) if errs: print 'Pfind produced the following errors:' printlines(errs) def do_pfind(which, files, diffs): file = files[which-1] symbol = ['<', '>'][which-1] lines = [l[1:-1] for l in diffs if l[0] == symbol] if not lines: print 'No differing lines in', file return tmpf, tmpfnm = get_tmpf() for l in lines: if len(l.rstrip()): tmpf.write('^' + '\s*' + escape_respecials(l.lstrip()) + '$\n') tmpf.close() ccmd = '%s -f%s %s' % (PFIND, tmpfnm, file) run_pfind(ccmd) os.unlink(tmpfnm) def do_lpfind(which, files, diffs): file = files[which-1] goff = (which-1)*4 #print 'goff', goff whichop = ['d', 'a'][which-1] #print whichop linesre = re.compile('^(\d+)(,(\d+))?([acd])(\d+)(,(\d+))?') tmpf, tmpfnm = get_tmpf() for l in diffs: m = linesre.match(l) if m: #print l gg = m.groups() #print gg op = gg[3] if op == 'c' or op == whichop: if gg[goff]: tmpf.write(gg[goff]) #print gg[goff], if gg[goff+2]: tmpf.write('-' + gg[goff+2]) #print '-' + gg[goff+2] tmpf.write('\n') #print else: print 'Failed to understand diff line \'%s\'' % (l) tmpf.close() ccmd = 'pfind -l%s %s' % (tmpfnm, file) run_pfind(ccmd) os.unlink(tmpfnm) def diffdiffs(diffs): diffd = {} diffdiffs = [] for d in diffs: if d[0] == '>': diffd[d[1:]] = d for d in diffs: if d[0] == '<': if diffd.has_key(d[1:]): diffd[d[1:]] = None else: diffd[d[1:]] = d return [d for d in diffd.values() if d] # # Main Fn starts here # print 'Diffing %s' % (f), first = join(dir1, f) second = join(dir2, f) diffcmd = '%s -B \'%s\' \'%s\'' % (DIFF, first, second) o, i, e = popen2.popen3(diffcmd) if debug: detailed_report(diffcmd, o, e) else: diffs = o.readlines() errs = e.readlines() if errs: print print 'Error running %s: ' % (diffcmd) printlines(errs) sys.exit(1) if diffs: print ' - differences exist' if context and f[-3:] == '.py': menustr = ' <SPC> to see diffs\n 1 to see context 1 - diff lines only\n 11 to see context 1 with matching lines\n111 to see context 1 with matching lines but common lines removed\n2/22/222/ for context 2\n <RET> to continue\n..?' nulstr = '..?' askstr = menustr while 1: ans = raw_input(askstr) if ans == '': break elif ans == ' ': printlines(diffs) askstr = menustr elif ans == '11' or ans == '22': do_pfind(int(ans[-1]), [first, second], diffs) askstr = menustr elif ans == '111' or ans == '222': do_pfind(int(ans[-1]), [first, second], diffdiffs(diffs)) askstr = menustr elif ans == '1' or ans == '2': do_lpfind(int(ans), [first, second], diffs) askstr = menustr else: askstr = nulstr continue elif context: while 1: ans = raw_input('<SPC><RET> to continue <RET> to see diffs ..?') if ans == '': printlines(diffs) break elif ans == ' ':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -