22
22
import os, re, shutil, filecmp, json
 
24
 
from walker.copy_in import CopyInWalker
 
25
 
from walker.conflict import ConflictWalker
 
26
 
from walker.copy_out import CopyOutWalker
 
 
24
from walker.copy_in_walker import CopyInWalker
 
 
25
from walker.conflict_walker import ConflictWalker
 
 
26
from walker.copy_out_walker import CopyOutWalker
 
32
31
        def __init__( self ):
 
34
 
                        raise RuntimeError( 'logic error: Deployment initialised when '
 
36
32
                self.load_deployment_state()
 
37
33
                self.conflicts_checked = False
 
40
36
        def load_deployment_state( self ):
 
41
 
                """Load any deployment state.  If one is found then a deployment will be
 
42
 
                considered to be ongoing.
 
45
38
                # list of files that were copied-in (or at least given the opportunity
 
46
39
        # to be) and updated through the vcs update.  This means that, while
 
47
 
        # there may have been conflicts during the update (which the user will
 
48
 
        # have to deal with in the repo), any conflicts arising with these files
 
49
 
        # in the home directory are no longer important and can be ignored.  In
 
50
 
        # short, this is a list of files that can safely be deployed, regardless
 
51
 
        # of the state of the home directory.
 
 
40
        # there may have been conflicts during the update (which will be dealt
 
 
41
        # with in the repo), any arising conflicts with the filesystem are now
 
 
42
        # assumed to be because of the vcs update and can be ignored (that is to
 
 
43
        # say, we no longer care about the file in the home directory).  In
 
 
44
        # short, this is a list of files that it is safe to deploy, regardless
 
 
45
        # of the state of the filesystem.
 
52
46
                self.deploy_files = None
 
54
 
                # list of files that were affected by a recent vcs update (so only these
 
55
 
                # files need to be checked for deployment conflicts or copied-out)
 
56
 
                self.affected_files = None
 
58
 
                # the revno that the repo was as prior to a recent update
 
59
 
                self.initial_revno = None
 
 
48
                # list of files that were changed by a recent vcs update (so only these
 
 
49
                # need to be checked for deployment conflicts or copied-out)
 
 
50
                self.updated_files = None
 
61
52
                # do we have a repo?
 
62
53
                if not os.path.exists( the.repo.full_dir ): return
 
 
69
60
                # read the file list
 
70
 
                if the.verbose: print "deployment state found; loading"
 
 
61
                if the.verbose: print "loading deployment state"
 
71
62
                f = open( file, 'r' )
 
72
63
                state = json.loads( f.read() )
 
74
65
                # unpack deployment state
 
75
66
                self.deploy_files = state['deploy_files'];
 
76
 
                self.initial_revno = state['initial_revno'];
 
77
 
                self.affected_files = state['affected_files'];
 
 
67
                self.updated_files = state['updated_files'];
 
80
70
        def save_deployment_state( self ):
 
81
 
                """Save the current deployment state (so there will be a deployment ongoing).
 
84
71
                if the.verbose: print "saving deployment state"
 
86
73
                # create metadata directory, as necessary
 
 
90
77
                # pack deployment state
 
92
79
                        'deploy_files': self.deploy_files,
 
93
 
                        'initial_revno': self.initial_revno,
 
94
 
                        'affected_files': self.affected_files,
 
 
80
                        'updated_files': self.updated_files,
 
 
116
100
        def is_ongoing( self ):
 
117
 
                """Is there a deployment currently ongoing?
 
120
101
                return False if self.deploy_files is None else True
 
123
104
        def check_ongoing( self, ongoing = True ):
 
124
 
                """Check that a deployment either is or is not ongoing and raise an error if
 
129
106
                        if self.deploy_files is None:
 
130
107
                                raise self.DeploymentOngoing( False )
 
 
133
110
                                raise self.DeploymentOngoing( True )
 
136
 
        def get_initial_revno( self ):
 
137
 
                """Get the initial revision identifier from the deployment state.
 
140
 
                return self.initial_revno
 
143
 
        def copy_in( self, initial_revno = None ):
 
144
 
                """Copy-in changes from the home directory to the repository.  When finished,
 
145
 
                the state of deployment is saved, meaning that a deployment is ongoing.
 
148
115
                # check we don't already have a file list
 
149
116
                self.check_ongoing( False )
 
 
160
127
                                raise self.CopyInConflicts( walker.changed )
 
161
128
                        self.deploy_files = walker.walk_list
 
163
 
                        # obtain initial revno
 
164
 
                        self.initial_revno = the.repo.vcs.get_revno()
 
167
131
                self.save_deployment_state()
 
170
 
        def get_conflicts( self, affected_files = None ):
 
171
 
                """Check to see if there are any delpoyment conflicts.  If a list of affected
 
172
 
                files is supplied, then only those files are checked (and they are also
 
173
 
                saved with the deployment state).  Otherwise, all files in the
 
174
 
                repository are checked.
 
 
134
        def get_conflicts( self, updated_files = None ):
 
177
136
                # check we have a file list
 
178
137
                self.check_ongoing( True )
 
180
139
                # set updated files
 
181
 
                if affected_files is not None:
 
182
 
                        self.affected_files = affected_files
 
 
140
                if updated_files is not None:
 
 
141
                        self.updated_files = updated_files
 
183
142
                        self.save_deployment_state()
 
185
144
                # check for deployment conflicts
 
186
 
                walker = ConflictWalker( self.deploy_files, self.affected_files )
 
 
145
                walker = ConflictWalker( self.deploy_files, self.updated_files )
 
189
148
                self.conflicts_checked = True
 
190
 
                return walker.changed + walker.obstructed
 
 
149
                return walker.changed
 
193
152
        def copy_out( self ):
 
194
 
                """Copy-out changed files frmo the repository to the home directory.  If the
 
195
 
                deployment state incudes a list of affected files, then only those fiels
 
199
154
                # check we have a file list
 
200
155
                self.check_ongoing( True )