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

  • Committer: Tim Marston
  • Date: 2014-02-26 19:10:31 UTC
  • Revision ID: tim@ed.am-20140226191031-elcqy5j09h2syn2j
moved copy-in, copy-out and deployment conflict checking to a set of "walkers";
bzr vcs back-end now parses affected files during update; deployment state now
includes affected files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# copy_in.py
 
1
# copy_in_walker.py
2
2
#
3
3
# Copyright (C) 2013 to 2014 Tim Marston <tim@edm.am>
4
4
#
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, report = False ):
37
 
                CopyBaseWalker.__init__( self )
38
 
                self.src_dir = the.full_home_dir
 
37
        def __init__( self ):
 
38
                self.src_dir = the.full_fsdir
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( 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 )
 
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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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