31
32
process() for more information.
35
37
"""Iterates over self.walk_list, calling process() for each entry in turn. For
36
38
directory entries, where process() returns False, subsequent entries in
37
39
walk_list that fall under the directory are skipped.
43
print("walking [%s]" % self.__class__.__name__)
42
46
for rel_file in self.walk_list:
44
48
# if we're skipping, skip entries in subdirectories, or turn off
52
src_file = os.path.join( self.src_dir, rel_file )
53
dst_file = os.path.join( self.dst_dir, rel_file )
55
src_type = Walker.get_file_type( src_file )
56
dst_type = Walker.get_file_type( dst_file )
58
recurse = self.process(
59
rel_file, src_file, src_type, dst_file, dst_type )
56
src = Walker.File( os.path.join( self.src_dir, rel_file ) )
57
dst = Walker.File( os.path.join( self.dst_dir, rel_file ) )
60
recurse = self.process( rel_file, src, dst )
61
62
# Set up skipping, as required. Note that we don't check to see if
62
63
# we're dealing with a directory here. We can't, because we've no
63
64
# way of knowing what to check. It could be src_type or dst_type
64
65
# (if src_dir or dst_dir was used to generate the walk list) or it
65
66
# could be neither (if the walk list came from somewhere else). But
66
# it shouldn't matter. We adding an os.pathset to the end of the
67
# filename, so it wuill only match files that are descendents of a
68
# directory with the name of this file.
69
if not recurse: skip = rel_file + os.pathsep
73
def get_file_type( full_file ):
74
"""Returns the type of a given file, at the time of calling. Types are 'd' for
75
directory, 'f' for file, 'l' for symlink, '_' for missing and '?' for
79
if not os.path.lexists( full_file ):
81
elif os.path.islink( full_file ):
83
elif os.path.isfile( full_file ):
85
elif os.path.isdir( full_file ):
92
def generate_walk_list( full_dir, rel_file = '' ):
67
# it shouldn't matter: we add a path seperateor (os.sep) to the end
68
# of the filename, so it wuill only match files that are descendents
69
# of a directory with the name of this file.
70
if not recurse: skip = rel_file + os.sep
75
def __init__( self, full_file ):
77
if not os.path.exists( self.file ):
79
elif os.path.isfile( self.file ):
81
elif os.path.isdir( self.file ):
85
if os.path.islink( self.file ):
86
self.link_type = self.type
89
self.link_type = False
91
def get_type_name( self ):
92
if self.type == 'l': return 'symlink'
93
elif self.type == 'f': return 'file'
94
elif self.type == 'd': return 'directory'
95
elif self.type == '_': return 'missing'
96
else: return 'unknown'
100
if( self.link_type ): type += '/' + self.link_type
101
return 'File( %s (%s) )' % ( self.file, type )
105
def generate_walk_list( full_dir, rel_file = '', recurse = True ):
93
106
"""Returns a list of files and directories in full_dir, specified as relative
94
107
files (relative to full_dir), breadth first.
97
111
# ignore some files
98
if rel_file in { '.bzr', '.stdhome' }: return list()
112
static_ignores = [ '.stdhome', '.stdhomerc' ] + \
113
the.repo.vcs.ignored_files
114
if rel_file in static_ignores:
100
117
full_file = os.path.join( full_dir, rel_file )
106
123
# directories are returned and recursed in to
107
124
elif os.path.isdir( full_file ):
108
125
ret = [ rel_file ] if rel_file != '' else []
109
for file in os.listdir( full_file ):
110
ret.extend( Walker.generate_walk_list(
111
full_dir, os.path.join( rel_file, file ) ) )
127
for file in os.listdir( full_file ):
128
ret.extend( Walker.generate_walk_list(
129
full_dir, os.path.join( rel_file, file ) ) )
112
130
return sorted( ret )
114
132
# other kinds are invalid
116
134
raise RuntimeError(
117
135
'unknown/exotic file: %s' % full_file )
121
def name_of_type( type ):
122
if type == 'd': return 'a directory'
123
elif type == 'f': return 'a file'
124
elif type == 'l': return 'a symlink'
125
elif type == '_': return 'missing'
126
else: return 'something exotic'