/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: 2016-12-13 21:40:34 UTC
  • Revision ID: tim@ed.am-20161213214034-nd5t7ztnlrjd627i
fix add command and generic filename expansion/resolution to expend to
homedir-relative filename and absolute filename based on original filename, as
specified, rather than a fully, symlink-resolved filename.  So, e.g., if ~/bob
was a symlink to ~/fred, then ~/bob/a would resolve to the relative filename
bob/a, becuase it is inside the homedir (it would resolve to fred/a otherwise)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
21
 
22
 
import filecmp, os, shutil
23
 
from walker import Walker
 
22
from copy_base import CopyBaseWalker
24
23
import stdhome.the as the
25
 
 
26
 
 
27
 
class CopyInWalker( Walker ):
 
24
from stdhome.file_matcher import FileMatcher
 
25
 
 
26
 
 
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.
 
29
        home directory.
31
30
 
32
31
        Walker source:       home dir
33
32
        Walker destination:  repo
34
33
        Walker traversing:   repo
35
34
        """
36
35
 
37
 
        def __init__( self ):
 
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 )
41
 
 
42
 
                self.changed = list()
43
 
 
44
 
 
45
 
        def process( self, rel_file, src_file, src_type, dst_file, dst_type ):
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: 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).
75
 
                        else:
76
 
                                self.changed.append( "%s (now %s)" % (
77
 
                                        rel_file, self.name_of_type( src_type ) ) )
78
 
                                return False
79
 
 
80
 
                # file (in repo)
81
 
                elif dst_type == 'f':
82
 
 
83
 
                        # if entity doesn't exist in home dir, delete file in repo
84
 
                        if src_type == '_':
85
 
                                if the.verbose > 1: print "  _>f " + rel_file
86
 
                                os.unlink( dst_file )
87
 
 
88
 
                        # if entity in home dir is a symlink, replace file in repo
89
 
                        elif src_type == 'l':
90
 
                                if the.verbose > 1: print "  l>f " + rel_file
91
 
                                os.unlink( dst_file )
92
 
                                os.symlink( os.readlink( src_file ), dst_file )
93
 
 
94
 
                        # if entity in home dir is a file, replace file in repo only if it
95
 
                        # differs
96
 
                        elif src_type == 'f':
97
 
                                if not filecmp.cmp( src_file, dst_file ):
98
 
                                        if the.verbose > 1: print "  f>f " + rel_file
99
 
                                        os.unlink( dst_file )
100
 
                                        shutil.copy( src_file, dst_file )
101
 
                                        shutil.copystat( src_file, dst_file )
102
 
                                else:
103
 
                                        if the.verbose > 1: print "  f=f " + rel_file
104
 
 
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).
115
 
                        else:
116
 
                                self.changed.append( "%s (now %s)" % (
117
 
                                        rel_file, self.name_of_type( src_type ) ) )
118
 
 
119
 
                # symlink (in repo)
120
 
                elif dst_type == 'l':
121
 
 
122
 
                        # if entity doesn't exist in home dir, delete symlink in repo
123
 
                        if src_type == '_':
124
 
                                if the.verbose > 1: print "  _>l " + rel_file
125
 
                                os.unlink( dst_file )
126
 
 
127
 
                        # if entity in home dir is a symlink, replace symlink in repo only
128
 
                        # if it differs
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 )
134
 
                                else:
135
 
                                        if the.verbose > 1: print "  l=l " + rel_file
136
 
 
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 )
143
 
 
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).
154
 
                        else:
155
 
                                self.changed.append( "%s (now %s)" % (
156
 
                                        rel_file, self.name_of_type( src_type ) ) )
157
 
                # can not recurse on a non-directory
158
 
                return False
159
 
                return False
 
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
 
43
                self.report = report
 
44
 
 
45
 
 
46
        def print_op( self, rel_file, src, op, dst ):
 
47
 
 
48
                CopyBaseWalker.print_op( self, rel_file, src, op, dst )
 
49
 
 
50
                # verbose reporting
 
51
                if the.verbose >= 2:
 
52
                        if op == '*': op = '>'
 
53
                        print "  %s%s%s %s" % ( src, op, dst, rel_file )