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

  • Committer: Tim Marston
  • Date: 2014-01-05 11:51:35 UTC
  • Revision ID: tim@ed.am-20140105115135-6ses87ggwyjrxzfj
added global objects (the.repo, the.program), deployment object and implemented
init command

Show diffs side-by-side

added added

removed removed

1
 
# copy_out.py
2
 
#
3
 
# Copyright (C) 2013 to 2014 Tim Marston <tim@edm.am>
4
 
#
5
 
# This file is part of stdhome (hereafter referred to as "this program").
6
 
# See http://ed.am/dev/stdhome for more information.
7
 
#
8
 
# This program is free software: you can redistribute it and/or modify
9
 
# it under the terms of the GNU General Public License as published by
10
 
# the Free Software Foundation, either version 3 of the License, or
11
 
# (at your option) any later version.
12
 
#
13
 
# This program is distributed in the hope that it will be useful,
14
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
# GNU General Public License for more details.
17
 
#
18
 
# You should have received a copy of the GNU General Public License
19
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 
 
21
 
 
22
 
import filecmp, os, shutil
23
 
from walker import Walker
24
 
import stdhome.the as the
25
 
 
26
 
 
27
 
class CopyOutWalker( Walker ):
28
 
        """The copy-out walker traverses the repo, copying its content to the home
29
 
        directory.  It is run *after* checking for conflicts that might occur during
30
 
        copy-out, so any conflicts that exist can be assumed to be unimportant and
31
 
        disposable.  In other words, this will happily overwrite stuff in the home
32
 
        directory, without regard to its content.
33
 
 
34
 
        Walker source:       repo
35
 
        Walker destination:  home dir
36
 
        Walker traversing:   repo (or a provided file list, which may include stuff
37
 
                                                        that no longer exists in the repo
38
 
        """
39
 
 
40
 
        def __init__( self, updated_files = None ):
41
 
                self.src_dir = the.repo.full_dir
42
 
                self.dst_dir = the.full_home_dir
43
 
                self.walk_list = updated_files if updated_files is not None else \
44
 
                                                 self.generate_walk_list( the.repo.full_dir )
45
 
 
46
 
                self.accept_symlinks = list()
47
 
 
48
 
 
49
 
        def process( self, rel_file, src, dst ):
50
 
 
51
 
                # directory (in repo)
52
 
                if src.type == 'd':
53
 
 
54
 
                        # if entity doesn't exist in home dir, create directory (no need to
55
 
                        # recurse, since we're copying the whole directory)
56
 
                        if dst.type == '_':
57
 
                                if the.verbose > 1: print "  _<d " + rel_file
58
 
                                os.mkdir( dst.file )
59
 
                                shutil.copystat( src.file, dst.file )
60
 
                                return False
61
 
 
62
 
                        # if entity is a directory in home dir, copy permissions, as
63
 
                        # required (and recurse)
64
 
                        elif dst.type == 'd':
65
 
                                # TODO: should check permission and only do as necessary
66
 
                                if the.verbose > 1: print "  d<d " + rel_file
67
 
                                shutil.copystat( src.file, dst.file )
68
 
                                return True
69
 
 
70
 
                        # TODO: if entity is a symlink to a directory, and this is
71
 
                        # acceptable, just recurse
72
 
#                       elif dst.link_type == 'd' and self.accept_list.match( rel_file ):
73
 
#                               if the.verbose > 1: print "  d@=d " + rel_file
74
 
#                               return True
75
 
 
76
 
                        # if entity is a file or symlink in home dir, replace it with
77
 
                        # directory (no need to recurse, since we're copying the whole
78
 
                        # directory)
79
 
                        elif dst.type == 'f' or dst.type == 'l':
80
 
                                if the.verbose > 1: print "  %s<d %s" % ( dst.type, rel_file )
81
 
                                os.unlink( dst.file )
82
 
                                os.mkdir( dst.file )
83
 
                                shutil.copystat( src.file, dst.file )
84
 
                                return False
85
 
 
86
 
                        else:
87
 
                                raise NotImplementedError()
88
 
 
89
 
                # file (in repo)
90
 
                if src.type == 'f':
91
 
 
92
 
                        # if entity doesn't exist in home dir, copy file
93
 
                        if dst.type == '_':
94
 
                                if the.verbose > 1: print "  _<f " + rel_file
95
 
                                shutil.copy( src.file, dst.file )
96
 
                                shutil.copystat( src.file, dst.file )
97
 
 
98
 
                        # if entity is a file in home dir, replace it only if it differs
99
 
                        elif dst.type == 'f':
100
 
                                if not filecmp.cmp( src.file, dst.file ):
101
 
                                        if the.verbose > 1: print "  f<f " + rel_file
102
 
                                        os.unlink( dst.file )
103
 
                                        shutil.copy( src.file, dst.file )
104
 
                                        shutil.copystat( src.file, dst.file )
105
 
                                else:
106
 
                                        if the.verbose > 1: print "  f=f " + rel_file
107
 
 
108
 
                        # if entity is a directory in home dir, replace it with file
109
 
                        elif dst.type == 'd':
110
 
                                if the.verbose > 1: print "  d<f " + rel_file
111
 
                                shutil.rmtree( dst.file )
112
 
                                shutil.copy( src.file, dst.file )
113
 
                                shutil.copystat( src.file, dst.file )
114
 
 
115
 
                        # if entity is a symlink in home dir, replace it with file
116
 
                        elif dst.type == 'l':
117
 
                                if the.verbose > 1: print "  l<f " + rel_file
118
 
                                os.unlink( dst.file )
119
 
                                shutil.copy( src.file, dst.file )
120
 
                                shutil.copystat( src.file, dst.file )
121
 
 
122
 
                        else:
123
 
                                raise NotImplementedError()
124
 
 
125
 
                # link (in repo)
126
 
                if src.type == 'l':
127
 
 
128
 
                        # if entity doesn't exist in home dir, copy symlink
129
 
                        if dst.type == '_':
130
 
                                if the.verbose > 1: print "  _<l " + rel_file
131
 
                                os.symlink( os.readlink( src.file ), dst.file )
132
 
 
133
 
                        # if entity is a symlink in home dir, replace it only if it differs
134
 
                        elif dst.type == 'l':
135
 
                                if os.readlink( src.file ) != os.readlink( dst.file ):
136
 
                                        if the.verbose > 1: print "  l<l " + rel_file
137
 
                                        os.unlink( dst.file )
138
 
                                        os.symlink( os.readlink( src.file ), dst.file )
139
 
                                else:
140
 
                                        if the.verbose > 1: print "  l=l " + rel_file
141
 
 
142
 
                        # if entity is a file in home dir, replace it with file
143
 
                        elif dst.type == 'f':
144
 
                                if the.verbose > 1: print "  f<l " + rel_file
145
 
                                os.unlink( dst.file )
146
 
                                os.symlink( os.readlink( src.file ), dst.file )
147
 
 
148
 
                        # if entity is a directory in home dir, replace it with file
149
 
                        elif dst.type == 'd':
150
 
                                if the.verbose > 1: print "  d<l " + rel_file
151
 
                                shutil.rmtree( dst.file )
152
 
                                os.symlink( os.readlink( src.file ), dst.file )
153
 
 
154
 
                        else:
155
 
                                raise NotImplementedError()
156
 
 
157
 
                # deleted file (in repo)
158
 
                if src.type == '_':
159
 
 
160
 
                        # if entity doesn't exist in home dir, we're good
161
 
                        if dst.type == '_':
162
 
                                pass;
163
 
 
164
 
                        # if entity is a file or symlink in home dir, delete it
165
 
                        if dst.type == 'f' or dst.type == 'l':
166
 
                                if the.verbose > 1: print "  %s<_ %s" % ( dst.type, rel_file )
167
 
                                os.unlink( dst.file )
168
 
 
169
 
                        # if entity is a directory in home dir, delete it
170
 
                        elif dst.type == 'd':
171
 
                                if the.verbose > 1: print "  d<_ " + rel_file
172
 
                                shutil.rmtree( dst.file )
173
 
 
174
 
                        else:
175
 
                                raise NotImplementedError()
176
 
 
177
 
                # non-directories can not be recursed in to
178
 
                return False