19
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
import filecmp, os, shutil
23
from walker import Walker
22
from copy_base import CopyBaseWalker
24
23
import stdhome.the as the
27
class CopyInWalker( Walker ):
24
from stdhome.file_matcher import FileMatcher
27
class CopyInWalker( CopyBaseWalker ):
28
28
"""The copy-in walker traverses the repo, copying-in matching files from the
29
home directory. It will overwrite certin changes (modified files, files
30
that have changed to symlinks), but barf at others.
32
31
Walker source: home dir
33
32
Walker destination: repo
34
33
Walker traversing: repo
36
def __init__( self, walk_files = None, report = False ):
37
CopyBaseWalker.__init__( self )
38
38
self.src_dir = the.full_home_dir
39
39
self.dst_dir = the.repo.full_dir
40
self.walk_list = self.generate_walk_list( the.repo.full_dir )
45
def process( self, rel_file, src_file, src_type, dst_file, dst_type ):
50
# if entity doesn't exist in home dir, delete directory in repo (and
51
# don't recurse, obviously!)
53
if the.verbose > 1: print " _>d " + rel_file
54
shutil.rmtree( dst_file )
57
# if entity is a directory in home dir, copy permissions to
58
# diurectory in repo, as necessary, and recurse
60
# TODO: should check permissions and only do as necessary
61
if the.verbose > 1: print " d>d " + rel_file
62
shutil.copystat( src_file, dst_file )
65
# TODO: serious differences in between ~/ and repo (e.g., files in
66
# one that are directories in the other) should be ignored (e.g.,
67
# not copied-in). And the stuff that is ignored during copy-in
68
# should also be ignored during copy-out and must not be added to
69
# the deploy_files list. Since these ignored files/directories are
70
# transparent to the user, they should have to explicitly permit
71
# them via an ignore file (e.g., ~/.stdhome/.ignore, akin to bzr's
72
# .bzrignore file). If these serious differences are not matched by
73
# the ignore file, an error should show (which will requie a
74
# separate "check" walk of the repo, as is done in copy_out).
76
self.changed.append( "%s (now %s)" % (
77
rel_file, self.name_of_type( src_type ) ) )
83
# if entity doesn't exist in home dir, delete file in repo
85
if the.verbose > 1: print " _>f " + rel_file
88
# if entity in home dir is a symlink, replace file in repo
90
if the.verbose > 1: print " l>f " + rel_file
92
os.symlink( os.readlink( src_file ), dst_file )
94
# if entity in home dir is a file, replace file in repo only if it
97
if not filecmp.cmp( src_file, dst_file ):
98
if the.verbose > 1: print " f>f " + rel_file
100
shutil.copy( src_file, dst_file )
101
shutil.copystat( src_file, dst_file )
103
if the.verbose > 1: print " f=f " + rel_file
105
# TODO: serious differences in between ~/ and repo (e.g., files in
106
# one that are directories in the other) should be ignored (e.g.,
107
# not copied-in). And the stuff that is ignored during copy-in
108
# should also be ignored during copy-out and must not be added to
109
# the deploy_files list. Since these ignored files/directories are
110
# transparent to the user, they should have to explicitly permit
111
# them via an ignore file (e.g., ~/.stdhome/.ignore, akin to bzr's
112
# .bzrignore file). If these serious differences are not matched by
113
# the ignore file, an error should show (which will requie a
114
# separate "check" walk of the repo, as is done in copy_out).
116
self.changed.append( "%s (now %s)" % (
117
rel_file, self.name_of_type( src_type ) ) )
120
elif dst_type == 'l':
122
# if entity doesn't exist in home dir, delete symlink in repo
124
if the.verbose > 1: print " _>l " + rel_file
125
os.unlink( dst_file )
127
# if entity in home dir is a symlink, replace symlink in repo only
129
elif src_type == 'l':
130
if os.readlink( src_file ) != os.readlink( dst_file ):
131
if the.verbose > 1: print " l>l " + rel_file
132
os.unlink( dst_file )
133
os.symlink( os.readlink( src_file ), dst_file )
135
if the.verbose > 1: print " l=l " + rel_file
137
# if entity in home dir is a file, replace symlink in repo
138
elif src_type == 'f':
139
if the.verbose > 1: print " f>l " + rel_file
140
os.unlink( dst_file )
141
shutil.copy( src_file, dst_file )
142
shutil.copystat( src_file, dst_file )
144
# TODO: serious differences in between ~/ and repo (e.g., files in
145
# one that are directories in the other) should be ignored (e.g.,
146
# not copied-in). And the stuff that is ignored during copy-in
147
# should also be ignored during copy-out and must not be added to
148
# the deploy_files list. Since these ignored files/directories are
149
# transparent to the user, they should have to explicitly permit
150
# them via an ignore file (e.g., ~/.stdhome/.ignore, akin to bzr's
151
# .bzrignore file). If these serious differences are not matched by
152
# the ignore file, an error should show (which will requie a
153
# separate "check" walk of the repo, as is done in copy_out).
155
self.changed.append( "%s (now %s)" % (
156
rel_file, self.name_of_type( src_type ) ) )
157
# can not recurse on a non-directory
40
self.walk_list = walk_files if walk_files is not None else \
41
self.generate_walk_list( the.repo.full_dir )
42
self.check_src_symlinks = True
46
def print_op( self, rel_file, src, op, dst ):
48
CopyBaseWalker.print_op( self, rel_file, src, op, dst )
52
if op == '*': op = '>'
53
print " %s%s%s %s" % ( src, op, dst, rel_file )