19
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
23
from copy_base import CopyBaseWalker
22
import filecmp, os, shutil
23
from walker import Walker
24
24
import stdhome.the as the
25
from stdhome.file_matcher import FileMatcher
28
class CopyOutWalker( CopyBaseWalker ):
27
class CopyOutWalker( Walker ):
29
28
"""The copy-out walker traverses the repo, copying its content to the home
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.
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.
35
34
Walker source: repo
36
35
Walker destination: home dir
38
37
that no longer exists in the repo
41
def __init__( self, walk_files = None, quiet = False ):
42
CopyBaseWalker.__init__( self )
40
def __init__( self, updated_files = None ):
43
41
self.src_dir = the.repo.full_dir
44
42
self.dst_dir = the.full_home_dir
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
52
def print_op( self, rel_file, src, op, dst ):
55
if not self.quiet and the.verbose < 2 and op == '*':
57
print " N %s" % ( rel_file )
59
print " D %s" % ( rel_file )
61
print " M %s" % ( rel_file )
63
print " K %s" % ( rel_file )
67
if op == '*': op = '<'
68
print " %s%s%s %s" % ( src, op, dst, rel_file )
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