/stdhome

To get this branch, use:
bzr branch http://bzr.ed.am/stdhome

« back to all changes in this revision

Viewing changes to lib/stdhome/walker/copy_in.py

  • Committer: Tim Marston
  • Date: 2014-04-04 22:33:09 UTC
  • Revision ID: tim@ed.am-20140404223309-macifjzkiryg982n
read ~/.stdhomerc; commands set repo before run(); program performs late
initialisation of some variables; updated help

Show diffs side-by-side

added added

removed removed

19
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
21
 
22
 
from copy_base import CopyBaseWalker
 
22
import filecmp, os, shutil
 
23
from walker import Walker
23
24
import stdhome.the as the
24
 
from stdhome.file_matcher import FileMatcher
25
 
 
26
 
 
27
 
class CopyInWalker( CopyBaseWalker ):
 
25
 
 
26
 
 
27
class CopyInWalker( Walker ):
28
28
        """The copy-in walker traverses the repo, copying-in matching files from the
29
 
        home directory.
 
29
        home directory.  It will overwrite certin changes (modified files, files
 
30
        that have changed to symlinks), but barf at others.
30
31
 
31
32
        Walker source:       home dir
32
33
        Walker destination:  repo
33
34
        Walker traversing:   repo
34
35
        """
35
36
 
36
 
        def __init__( self, walk_files = None ):
37
 
                CopyBaseWalker.__init__( self )
 
37
        def __init__( self ):
38
38
                self.src_dir = the.full_home_dir
39
39
                self.dst_dir = the.repo.full_dir
40
 
                self.walk_list = walk_files if walk_files is not None else \
41
 
                                                 self.generate_walk_list()
42
 
                self.check_src_symlinks = True
43
 
 
44
 
 
45
 
        def print_op( self, rel_file, operation ):
46
 
                print "  %s %s" % ( operation, rel_file )
 
40
                self.walk_list = self.generate_walk_list( the.repo.full_dir )
 
41
 
 
42
                self.changed = list()
 
43
 
 
44
 
 
45
        def process( self, rel_file, src, dst ):
 
46
 
 
47
                # directory (in repo)
 
48
                if dst.type == 'd':
 
49
 
 
50
                        # if entity doesn't exist in home dir, delete directory in repo (and
 
51
                        # don't recurse, obviously!)
 
52
                        if src.type == '_':
 
53
                                if the.verbose > 1: print "  _>d " + rel_file
 
54
                                shutil.rmtree( dst.file )
 
55
                                return False
 
56
 
 
57
                        # if entity is a directory in home dir, copy permissions to
 
58
                        # diurectory in repo, as necessary, and recurse
 
59
                        elif src.type == 'd':
 
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 )
 
63
                                return True
 
64
 
 
65
                        # TODO: if entity is a directory symlink in the home direcotry,
 
66
                        # silently accept it if it is explicitly matched by the accept list.
 
67
                        # In which case, we'll also need to add this rel_file to a
 
68
                        # not_deployed file list so that, after this walk, we can remove it
 
69
                        # from the deployment's deploy_list.  If we don't, the directory in
 
70
                        # the repo will get copied-out.
 
71
#                       elif src.link_type == 'd' and self.accept_list.matches( rel_file ):
 
72
#                               if the.verbose > 1: print "  d@d " + rel_file
 
73
#                               return True
 
74
 
 
75
                        # TODO: serious differences between ~/ and repo (e.g., files in one
 
76
                        # that are directories in the other) should be ignored (e.g., not
 
77
                        # copied-in).  And the stuff that is ignored during copy-in should
 
78
                        # also be ignored during copy-out and must not be added to the
 
79
                        # deployment's deploy_files list.  Since these ignored files and
 
80
                        # directories are transparent to the user, they must be explicitly
 
81
                        # permitted via an "ignore list" in ~/.stdhomerc.  If these serious
 
82
                        # differences are not matched by the ignore list, an error should be
 
83
                        # shown (which will require a separate "check" walk of the repo, as
 
84
                        # is done in copy_out).
 
85
                        else:
 
86
                                self.changed.append( "%s (%s => %s)" % ( rel_file,
 
87
                                        dst.get_type_name(), src.get_type_name() ) )
 
88
                                return False
 
89
 
 
90
                # file (in repo)
 
91
                elif dst.type == 'f':
 
92
 
 
93
                        # if entity doesn't exist in home dir, delete file in repo
 
94
                        if src.type == '_':
 
95
                                if the.verbose > 1: print "  _>f " + rel_file
 
96
                                os.unlink( dst.file )
 
97
 
 
98
                        # if entity in home dir is a symlink, replace file in repo
 
99
                        elif src.type == 'l':
 
100
                                if the.verbose > 1: print "  l>f " + rel_file
 
101
                                os.unlink( dst.file )
 
102
                                os.symlink( os.readlink( src.file ), dst.file )
 
103
 
 
104
                        # if entity in home dir is a file, replace file in repo only if it
 
105
                        # differs
 
106
                        elif src.type == 'f':
 
107
                                if not filecmp.cmp( src.file, dst.file ):
 
108
                                        if the.verbose > 1: print "  f>f " + rel_file
 
109
                                        os.unlink( dst.file )
 
110
                                        shutil.copy( src.file, dst.file )
 
111
                                        shutil.copystat( src.file, dst.file )
 
112
                                else:
 
113
                                        if the.verbose > 1: print "  f=f " + rel_file
 
114
 
 
115
                        # TODO: serious differences between ~/ and repo (e.g., files in one
 
116
                        # that are directories in the other) should be ignored (e.g., not
 
117
                        # copied-in).  And the stuff that is ignored during copy-in should
 
118
                        # also be ignored during copy-out and must not be added to the
 
119
                        # deployment's deploy_files list.  Since these ignored files and
 
120
                        # directories are transparent to the user, they must be explicitly
 
121
                        # permitted via an "ignore list" in ~/.stdhomerc.  If these serious
 
122
                        # differences are not matched by the ignore list, an error should be
 
123
                        # show (which will require a separate "check" walk of the repo, as
 
124
                        # is done in copy_out).
 
125
                        else:
 
126
                                self.changed.append( "%s (%s => %s)" % ( rel_file,
 
127
                                        dst.get_type_name(), src.get_type_name() ) )
 
128
 
 
129
                # symlink (in repo)
 
130
                elif dst.type == 'l':
 
131
 
 
132
                        # if entity doesn't exist in home dir, delete symlink in repo
 
133
                        if src.type == '_':
 
134
                                if the.verbose > 1: print "  _>l " + rel_file
 
135
                                os.unlink( dst.file )
 
136
 
 
137
                        # if entity in home dir is a symlink, replace symlink in repo only
 
138
                        # if it differs
 
139
                        elif src.type == 'l':
 
140
                                if os.readlink( src.file ) != os.readlink( dst.file ):
 
141
                                        if the.verbose > 1: print "  l>l " + rel_file
 
142
                                        os.unlink( dst.file )
 
143
                                        os.symlink( os.readlink( src.file ), dst.file )
 
144
                                else:
 
145
                                        if the.verbose > 1: print "  l=l " + rel_file
 
146
 
 
147
                        # if entity in home dir is a file, replace symlink in repo
 
148
                        elif src.type == 'f':
 
149
                                if the.verbose > 1: print "  f>l " + rel_file
 
150
                                os.unlink( dst.file )
 
151
                                shutil.copy( src.file, dst.file )
 
152
                                shutil.copystat( src.file, dst.file )
 
153
 
 
154
                        # TODO: serious differences between ~/ and repo (e.g., files in one
 
155
                        # that are directories in the other) should be ignored (e.g., not
 
156
                        # copied-in).  And the stuff that is ignored during copy-in should
 
157
                        # also be ignored during copy-out and must not be added to the
 
158
                        # deployment's deploy_files list.  Since these ignored files and
 
159
                        # directories are transparent to the user, they must be explicitly
 
160
                        # permitted via an "ignore list" in ~/.stdhomerc.  If these serious
 
161
                        # differences are not matched by the ignore list, an error should be
 
162
                        # show (which will require a separate "check" walk of the repo, as
 
163
                        # is done in copy_out).
 
164
                        else:
 
165
                                self.changed.append( "%s (%s => %s)" % ( rel_file,
 
166
                                        dst.get_type_name(). src.get_type_name() ) )
 
167
 
 
168
                # can not recurse on a non-directory
 
169
                return False