"""A class to build directory diff tools on."""
"""Directory comparison class."""
# Properties that caller may change before calling self.run():
self
.hide
= [os
.curdir
, os
.pardir
] # Names never to be shown
self
.ignore
= ['RCS', 'tags'] # Names ignored in comparison
"""Compare everything except common subdirectories."""
self
.a_list
= filter(dircache
.listdir(self
.a
), self
.hide
)
self
.b_list
= filter(dircache
.listdir(self
.b
), self
.hide
)
"""Compute common names."""
"""Distinguish files, directories, funnies."""
a_path
= os
.path
.join(self
.a
, x
)
b_path
= os
.path
.join(self
.b
, x
)
a_stat
= statcache
.stat(a_path
)
# print 'Can\'t stat', a_path, ':', why[1]
b_stat
= statcache
.stat(b_path
)
# print 'Can\'t stat', b_path, ':', why[1]
a_type
= S_IFMT(a_stat
[ST_MODE
])
b_type
= S_IFMT(b_stat
[ST_MODE
])
self
.common_funny
.append(x
)
self
.common_dirs
.append(x
)
self
.common_files
.append(x
)
self
.common_funny
.append(x
)
self
.common_funny
.append(x
)
"""Find out differences between common files."""
xx
= cmpfiles(self
.a
, self
.b
, self
.common_files
)
self
.same_files
, self
.diff_files
, self
.funny_files
= xx
"""Find out differences between common subdirectories.
A new dircmp object is created for each common subdirectory,
these are stored in a dictionary indexed by filename.
The hide and ignore properties are inherited from the parent."""
for x
in self
.common_dirs
:
a_x
= os
.path
.join(self
.a
, x
)
b_x
= os
.path
.join(self
.b
, x
)
self
.subdirs
[x
] = newdd
= dircmp().new(a_x
, b_x
)
newdd
.ignore
= self
.ignore
def phase4_closure(self
):
"""Recursively call phase4() on subdirectories."""
for x
in self
.subdirs
.keys():
self
.subdirs
[x
].phase4_closure()
"""Print a report on the differences between a and b."""
# Assume that phases 1 to 3 have been executed
# Output format is purposely lousy
print 'diff', self
.a
, self
.b
print 'Only in', self
.a
, ':', self
.a_only
print 'Only in', self
.b
, ':', self
.b_only
print 'Identical files :', self
.same_files
print 'Differing files :', self
.diff_files
print 'Trouble with common files :', self
.funny_files
print 'Common subdirectories :', self
.common_dirs
print 'Common funny cases :', self
.common_funny
def report_closure(self
):
"""Print reports on self and on subdirs.
If phase 4 hasn't been done, no subdir reports are printed."""
return # No subdirectories computed
for x
in self
.subdirs
.keys():
self
.subdirs
[x
].report_closure()
def report_phase4_closure(self
):
"""Report and do phase 4 recursively."""
for x
in self
.subdirs
.keys():
self
.subdirs
[x
].report_phase4_closure()
def cmpfiles(a
, b
, common
):
"""Compare common files in two directories.
- files that compare equal
- files that compare different
- funny cases (can't stat etc.)"""
res
[cmp(os
.path
.join(a
, x
), os
.path
.join(b
, x
))].append(x
)
2 for funny cases (can't stat, etc.)"""
if cmpcache
.cmp(a
, b
): return 0
"""Return a copy with items that occur in skip removed."""
if item
not in skip
: result
.append(item
)
"""Demonstration and testing."""
options
, args
= getopt
.getopt(sys
.argv
[1:], 'r')
raise getopt
.error
, 'need exactly two args'
dd
= dircmp().new(args
[0], args
[1])
if ('-r', '') in options
:
dd
.report_phase4_closure()
if __name__
== "__main__":