19
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
import filecmp, os, shutil
23
from walker import Walker
23
from copy_base import CopyBaseWalker
24
24
import stdhome.the as the
27
class CopyOutWalker( Walker ):
25
from stdhome.file_matcher import FileMatcher
28
class CopyOutWalker( CopyBaseWalker ):
28
29
"""The copy-out walker traverses the repo, copying its content to the home
29
directory. It is run *after* checking for conflicts that might occur during
30
copy-out, so any conflicts that exist can be assumed to be unimportant and
31
disposable. In other words, this will happily overwrite stuff in the home
32
directory, without regard to its content.
30
directory. During an update, it is run *after* checking for conflicts that
31
might occur during copy-out, so any conflicts that exist can be assumed to
32
be unimportant and disposable. In other words, this will happily overwrite
33
stuff in the home directory, without regard to its content.
34
35
Walker source: repo
35
36
Walker destination: home dir
37
38
that no longer exists in the repo
40
def __init__( self, updated_files = None ):
41
def __init__( self, walk_files = None ):
42
CopyBaseWalker.__init__( self )
41
43
self.src_dir = the.repo.full_dir
42
44
self.dst_dir = the.full_home_dir
43
self.walk_list = updated_files if updated_files is not None else \
44
self.generate_walk_list( the.repo.full_dir )
47
def process( self, rel_file, src_file, src_type, dst_file, dst_type ):
52
# if entity doesn't exist in home dir, create directory (no need to
53
# recurse, since we're copying the whole directory)
55
if the.verbose > 1: print " _<d " + rel_file
57
shutil.copystat( src_file, dst_file )
60
# if entity is a file or symlink in home dir, replace it with
61
# directory (no need to recurse, since we're copying the whole
63
elif dst_type == 'f' or dst_type == 'l':
64
if the.verbose > 1: print " %s<d %s" % ( dst_type, rel_file )
67
shutil.copystat( src_file, dst_file )
70
# if entity is a directory in home dir, copy permissions, as
71
# required (and recurse)
73
# TODO: should check permission and only do as necessary
74
if the.verbose > 1: print " d<d " + rel_file
75
shutil.copystat( src_file, dst_file )
79
raise NotImplementedError()
84
# if entity doesn't exist in home dir, copy file
86
if the.verbose > 1: print " _<f " + rel_file
87
shutil.copy( src_file, dst_file )
88
shutil.copystat( src_file, dst_file )
90
# if entity is a symlink in home dir, replace it with file
92
if the.verbose > 1: print " l<f " + rel_file
94
shutil.copy( src_file, dst_file )
95
shutil.copystat( src_file, dst_file )
97
# if entity is a file in home dir, replace it only if it differs
99
if not filecmp.cmp( src_file, dst_file ):
100
if the.verbose > 1: print " f<f " + rel_file
101
os.unlink( dst_file )
102
shutil.copy( src_file, dst_file )
103
shutil.copystat( src_file, dst_file )
105
if the.verbose > 1: print " f=f " + rel_file
107
# if entity is a directory in home dir, replace it with file
108
elif dst_type == 'd':
109
if the.verbose > 1: print " d<f " + rel_file
110
shutil.rmtree( dst_file )
111
shutil.copy( src_file, dst_file )
112
shutil.copystat( src_file, dst_file )
115
raise NotImplementedError()
120
# if entity doesn't exist in home dir, copy symlink
122
if the.verbose > 1: print " _<l " + rel_file
123
os.symlink( os.readlink( src_file ), dst_file )
125
# if entity is a symlink in home dir, replace it only if it differs
126
elif dst_type == 'l':
127
if os.readlink( src_file ) != os.readlink( dst_file ):
128
if the.verbose > 1: print " l<l " + rel_file
129
os.unlink( dst_file )
130
os.symlink( os.readlink( src_file ), dst_file )
132
if the.verbose > 1: print " l=l " + rel_file
134
# if entity is a file in home dir, replace it with file
135
elif dst_type == 'f':
136
if the.verbose > 1: print " f<l " + rel_file
137
os.unlink( dst_file )
138
os.symlink( os.readlink( src_file ), dst_file )
140
# if entity is a directory in home dir, replace it with file
141
elif dst_type == 'd':
142
if the.verbose > 1: print " d<l " + rel_file
143
shutil.rmtree( dst_file )
144
os.symlink( os.readlink( src_file ), dst_file )
147
raise NotImplementedError()
152
# if entity doesn't exist in home dir, we're good
156
# if entity is a file or symlink in home dir, delete it
157
if dst_type == 'f' or dst_type == 'l':
158
if the.verbose > 1: print " %s<_ %s" % ( dst_type, rel_file )
159
os.unlink( dst_file )
161
# if entity is a directory in home dir, delete it
162
elif dst_type == 'd':
163
if the.verbose > 1: print " d<_ " + rel_file
164
shutil.rmtree( dst_file )
167
raise NotImplementedError()
169
# non-directories can not be recursed in to
45
self.walk_list = walk_files if walk_files is not None else \
46
self.generate_walk_list()
47
self.check_dst_symlinks = True
48
self.check_dst_ignores = True
51
def print_op( self, rel_file, operation ):
52
operation = re.sub( r'(.)(.)(.)', r'\3\2\1', operation )
53
operation = re.sub( r'\>', r'<', operation )
54
print " %s %s" % ( operation, rel_file )