22
22
import os, re, shutil, filecmp, json
 
24
 
from walker.copy_in_walker import CopyInWalker
 
25
 
from walker.conflict_walker import ConflictWalker
 
26
 
from walker.copy_out_walker import CopyOutWalker
 
 
24
from walker.copy_in import CopyInWalker
 
 
25
from walker.conflict import ConflictWalker
 
 
26
from walker.copy_out import CopyOutWalker
 
31
32
        def __init__( self ):
 
 
34
                        raise RuntimeError( 'logic error: Deployment initialised when '
 
32
36
                self.load_deployment_state()
 
33
37
                self.conflicts_checked = False
 
36
40
        def load_deployment_state( self ):
 
 
41
                """Load any deployment state.  If one is found then a deployment will be
 
 
42
                considered to be ongoing.
 
38
45
                # list of files that were copied-in (or at least given the opportunity
 
39
46
        # to be) and updated through the vcs update.  This means that, while
 
40
47
        # 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.
 
 
48
        # with in the repo), any conflicts arising with these files in the home
 
 
49
        # directory are no longer important and can be ignored.  In short, this
 
 
50
        # is a list of files that it is safe to deploy, regardless of their
 
 
51
        # state in the home directory.
 
46
52
                self.deploy_files = 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
 
 
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
 
52
61
                # do we have a repo?
 
53
62
                if not os.path.exists( the.repo.full_dir ): return
 
 
60
69
                # read the file list
 
61
 
                if the.verbose: print "loading deployment state"
 
 
70
                if the.verbose: print "deployment state found; loading"
 
62
71
                f = open( file, 'r' )
 
63
72
                state = json.loads( f.read() )
 
65
74
                # unpack deployment state
 
66
75
                self.deploy_files = state['deploy_files'];
 
67
 
                self.updated_files = state['updated_files'];
 
 
76
                self.initial_revno = state['initial_revno'];
 
 
77
                self.affected_files = state['affected_files'];
 
70
80
        def save_deployment_state( self ):
 
 
81
                """Save the current deployment state (so there will be a deployment ongoing).
 
71
84
                if the.verbose: print "saving deployment state"
 
73
86
                # create metadata directory, as necessary
 
 
77
90
                # pack deployment state
 
79
92
                        'deploy_files': self.deploy_files,
 
80
 
                        'updated_files': self.updated_files,
 
 
93
                        'initial_revno': self.initial_revno,
 
 
94
                        'affected_files': self.affected_files,
 
 
100
116
        def is_ongoing( self ):
 
 
117
                """Is there a deployment currently ongoing?
 
101
120
                return False if self.deploy_files is None else True
 
104
123
        def check_ongoing( self, ongoing = True ):
 
 
124
                """Check that a deployment either is or is not ongoing and raise an error if
 
106
129
                        if self.deploy_files is None:
 
107
130
                                raise self.DeploymentOngoing( False )
 
 
110
133
                                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.
 
115
148
                # check we don't already have a file list
 
116
149
                self.check_ongoing( False )
 
 
127
160
                                raise self.CopyInConflicts( walker.changed )
 
128
161
                        self.deploy_files = walker.walk_list
 
 
163
                        # obtain initial revno
 
 
164
                        self.initial_revno = the.repo.vcs.get_revno()
 
131
167
                self.save_deployment_state()
 
134
 
        def get_conflicts( self, updated_files = None ):
 
 
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.
 
136
177
                # check we have a file list
 
137
178
                self.check_ongoing( True )
 
139
180
                # set updated files
 
140
 
                if updated_files is not None:
 
141
 
                        self.updated_files = updated_files
 
 
181
                if affected_files is not None:
 
 
182
                        self.affected_files = affected_files
 
142
183
                        self.save_deployment_state()
 
144
185
                # check for deployment conflicts
 
145
 
                walker = ConflictWalker( self.deploy_files, self.updated_files )
 
 
186
                walker = ConflictWalker( self.deploy_files, self.affected_files )
 
148
189
                self.conflicts_checked = True
 
149
 
                return walker.changed
 
 
190
                return walker.changed + walker.obstructed
 
152
193
        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
 
154
199
                # check we have a file list
 
155
200
                self.check_ongoing( True )