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 )