/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_base.py

  • Committer: Tim Marston
  • Date: 2016-02-13 13:20:44 UTC
  • Revision ID: tim@ed.am-20160213132044-t5zaxhdlhjyn4t1v
moved handling of --verbose to main program; manuall parse config file (because
ConfigFileParse does not support allow_no_value in python 2.6)

Show diffs side-by-side

added added

removed removed

21
21
 
22
22
import filecmp, os, shutil
23
23
from walker import Walker
24
 
from stdhome import the
25
 
from stdhome import util
 
24
import stdhome.the as the
26
25
 
27
26
 
28
27
class CopyBaseWalker( Walker ):
29
28
        """The copy-base walker traverses a walklist ruthlessly mirroring src to dst.
30
29
        It is designed to be the base class of both the copy-in and copy-out walker,
31
30
        both of which are specialisations of this purpose.  See them for more
32
 
        information.  The print_op method, derived in those classes, takes, in
33
 
        addition to the relative filename, a source file type, an operation, and a
34
 
        sestination file type.  Valid file types are f (file), l (symlink), d
35
 
        (directory) and _ (non-existant).  Valid operations are * (modify), = (skip:
36
 
        same), @ (skip: symlink substitute) and # (skip: ignored).
 
31
        information.
37
32
        """
38
33
 
39
34
 
47
42
 
48
43
                # ignore?
49
44
                if self.check_dst_ignores and the.config.ignores.matches( rel_file ):
50
 
                        self.print_op( rel_file, src.type, '#', dst.type )
 
45
                        if the.verbose >= 2:
 
46
                                self.print_op( rel_file, '%s#%s' % ( src.type, dst.type ) )
51
47
                        return True
52
48
 
53
49
                # src entity is directory
56
52
                        # if dst entity doesn't exist, create directory (no need to recurse,
57
53
                        # since we're copying the whole directory)
58
54
                        if dst.type == '_':
59
 
                                self.print_op( rel_file, 'd', '*', '_' )
 
55
                                if the.verbose >= 2: self.print_op( rel_file, 'd>_' )
60
56
                                shutil.copytree( src.file, dst.file, True )
61
57
 
62
58
                        # if dst entity is a directory, copy permissions, as required (and
63
59
                        # recurse)
64
60
                        elif dst.type == 'd':
65
 
                                if os.stat( src.file ).st_mode != os.stat( dst.file ).st_mode:
66
 
                                        self.print_op( rel_file, 'd', '*', 'd' )
67
 
                                        shutil.copystat( src.file, dst.file )
68
 
                                else:
69
 
                                        self.print_op( rel_file, 'd', '=', 'd' )
 
61
                                # TODO: should check permission and only do as necessary
 
62
                                if the.verbose >= 2: self.print_op( rel_file, 'd>d' )
 
63
                                shutil.copystat( src.file, dst.file )
70
64
                                return True
71
65
 
72
66
                        # if dst entity is a symlink to a directory, and this is an
73
67
                        # acceptable substitute, just recurse
74
68
                        elif self.check_dst_symlinks and dst.link_type == 'd' and \
75
69
                                        the.config.symlinks.matches( rel_file ):
76
 
                                self.print_op( rel_file, 'd', '@', 'd' )
 
70
                                if the.verbose >= 2: self.print_op( rel_file, 'd@d' )
77
71
                                return True
78
72
 
79
73
                        # if dst entity is a file or symlink in home dir, replace it with
80
74
                        # directory (no need to recurse, since we're copying the whole
81
75
                        # directory)
82
76
                        elif dst.type == 'f' or dst.type == 'l':
83
 
                                self.print_op( rel_file, 'd', '*', dst.type )
 
77
                                if the.verbose >= 2: self.print_op( rel_file, 'd>' + dst.type )
84
78
                                os.unlink( dst.file )
85
79
                                shutil.copytree( src.file, dst.file, True )
86
80
 
92
86
 
93
87
                        # if dst entity doesn't exist, copy file
94
88
                        if dst.type == '_':
95
 
                                self.print_op( rel_file, 'f', '*', '_' )
 
89
                                if the.verbose >= 2: self.print_op( rel_file, 'f>_' )
96
90
                                shutil.copy( src.file, dst.file )
97
91
                                shutil.copystat( src.file, dst.file )
98
92
 
99
93
                        # if dst entity is a file, replace it only if it differs
100
94
                        elif dst.type == 'f':
101
95
                                if not filecmp.cmp( src.file, dst.file ):
102
 
                                        self.print_op( rel_file, 'f', '*', 'f' )
 
96
                                        if the.verbose >= 2: self.print_op( rel_file, 'f>f' )
103
97
                                        os.unlink( dst.file )
104
98
                                        shutil.copy( src.file, dst.file )
105
99
                                        shutil.copystat( src.file, dst.file )
106
100
                                else:
107
 
                                        self.print_op( rel_file, 'f', '=', 'f' )
 
101
                                        if the.verbose >= 2: self.print_op( rel_file, 'f=f' )
108
102
 
109
103
                        # if dst entity is a directory, replace it with file
110
104
                        elif dst.type == 'd':
111
 
                                self.print_op( rel_file, 'f', '*', 'd' )
 
105
                                if the.verbose >= 2: self.print_op( rel_file, 'f>d' )
112
106
                                shutil.rmtree( dst.file )
113
107
                                shutil.copy( src.file, dst.file )
114
108
                                shutil.copystat( src.file, dst.file )
115
109
 
116
110
                        # if dst entity is a symlink, replace it with file
117
111
                        elif dst.type == 'l':
118
 
                                self.print_op( rel_file, 'f', '*', 'l' )
 
112
                                if the.verbose >= 2: self.print_op( rel_file, 'f>l' )
119
113
                                os.unlink( dst.file )
120
114
                                shutil.copy( src.file, dst.file )
121
115
                                shutil.copystat( src.file, dst.file )
128
122
 
129
123
                        # if dst entity doesn't exist, copy symlink
130
124
                        if dst.type == '_':
131
 
                                self.print_op( rel_file, 'l', '*', '_' )
 
125
                                if the.verbose >= 2: self.print_op( rel_file, 'l>_' )
132
126
                                os.symlink( os.readlink( src.file ), dst.file )
133
127
 
134
128
                        # if dst entity is a symlink, replace it only if it differs
135
129
                        elif dst.type == 'l':
136
130
                                if os.readlink( src.file ) != os.readlink( dst.file ):
137
 
                                        self.print_op( rel_file, 'l', '*', 'l' )
 
131
                                        if the.verbose >= 2: self.print_op( rel_file, 'l>l' )
138
132
                                        os.unlink( dst.file )
139
133
                                        os.symlink( os.readlink( src.file ), dst.file )
140
134
                                else:
141
 
                                        self.print_op( rel_file, 'l', '=', 'l' )
 
135
                                        if the.verbose >= 2: self.print_op( rel_file, 'l=l' )
142
136
 
143
137
                        # if dst entity is a file, replace it with symlink
144
138
                        elif dst.type == 'f':
145
 
                                self.print_op( rel_file, 'l', '*', 'f' )
 
139
                                if the.verbose >= 2: self.print_op( rel_file, 'l>f' )
146
140
                                os.unlink( dst.file )
147
141
                                os.symlink( os.readlink( src.file ), dst.file )
148
142
 
153
147
                                # acceptable substitute, just recurse
154
148
                                if self.check_src_symlinks and src.link_type == 'd' and \
155
149
                                                the.config.symlinks.matches( rel_file ):
156
 
                                        self.print_op( rel_file, 'd', '@', 'd' )
 
150
                                        if the.verbose >= 2: self.print_op( rel_file, 'd@d' )
157
151
                                        return True
158
152
 
159
153
                                # else replace it with a symlink
160
 
                                self.print_op( rel_file, 'l', '*', 'd' )
 
154
                                if the.verbose >= 2: self.print_op( rel_file, 'l>d' )
161
155
                                shutil.rmtree( dst.file )
162
156
                                os.symlink( os.readlink( src.file ), dst.file )
163
157
 
173
167
 
174
168
                        # if dst entity is a file or symlink, delete it
175
169
                        elif dst.type == 'f' or dst.type == 'l':
176
 
                                self.print_op( rel_file, '_', '*', dst.type )
 
170
                                if the.verbose >= 2: self.print_op( rel_file, '_>' + dst.type )
177
171
                                os.unlink( dst.file )
178
172
 
179
173
                        # if dst entity is a directory, delete it
180
174
                        elif dst.type == 'd':
181
 
                                self.print_op( rel_file, '_', '*', 'd' )
 
175
                                if the.verbose >= 2: self.print_op( rel_file, '_>d' )
182
176
                                shutil.rmtree( dst.file )
183
177
 
184
178
                        else: