19
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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
29
31
def __init__( self ):
31
# initialise the file list
33
if not os.path.exists( the.repo.expanded_dir ):
32
self.load_deployment_state()
33
self.conflicts_checked = False
36
def load_deployment_state( self ):
38
# list of files that were copied-in (or at least given the opportunity
39
# to be) and updated through the vcs update. This means that, while
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.
46
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
53
if not os.path.exists( the.repo.full_dir ): return
55
# if no file list exists, we're done
56
file = os.path.join( the.full_mddir, "deploy.%s" % the.repo.name )
57
if not os.path.isfile( file ):
61
if the.verbose: print "loading deployment state"
63
state = json.loads( f.read() )
65
# unpack deployment state
66
self.deploy_files = state['deploy_files'];
67
self.updated_files = state['updated_files'];
70
def save_deployment_state( self ):
71
if the.verbose: print "saving deployment state"
73
# create metadata directory, as necessary
74
if not os.path.isdir( the.full_mddir ):
75
os.mkdir( the.full_mddir )
77
# pack deployment state
79
'deploy_files': self.deploy_files,
80
'updated_files': self.updated_files,
84
file = os.path.join( the.full_mddir, "deploy.%s" % the.repo.name )
86
f.write( json.dumps( state ) );
89
def remove_deployment_state( self ):
92
file = os.path.join( the.full_mddir, "deploy.%s" % the.repo.name )
93
if( os.path.isfile( file ) ):
96
if the.verbose: print "removing deployment state"
100
def is_ongoing( self ):
101
return False if self.deploy_files is None else True
104
def check_ongoing( self, ongoing = True ):
106
if self.deploy_files is None:
107
raise self.DeploymentOngoing( False )
38
assert False # not implemented
41
def load_file_list( self ):
43
# if no file list, don't load one
109
if self.deploy_files is not None:
110
raise self.DeploymentOngoing( True )
50
113
def copy_in( self ):
52
115
# check we don't already have a file list
53
if self.file_list is not None:
54
raise the.FatalError( 'deployment in progress; ' + \
55
'see "%s resolve --help" for information' % the.program.name )
57
assert False # not implemented
116
self.check_ongoing( False )
118
# if the repo doesn't exist, we have an empty file list
119
if not os.path.exists( the.repo.full_dir ):
120
self.deploy_files = list()
123
if the.verbose: print "importing files..."
124
walker = CopyInWalker()
126
if( walker.changed ):
127
raise self.CopyInConflicts( walker.changed )
128
self.deploy_files = walker.walk_list
131
self.save_deployment_state()
134
def get_conflicts( self, updated_files = None ):
136
# check we have a file list
137
self.check_ongoing( True )
140
if updated_files is not None:
141
self.updated_files = updated_files
142
self.save_deployment_state()
144
# check for deployment conflicts
145
walker = ConflictWalker( self.deploy_files, self.updated_files )
148
self.conflicts_checked = True
149
return walker.changed
60
152
def copy_out( self ):
61
if self.pre_copy_out_list is None:
64
print "deploying files"
67
for ( repodir, directories, files ) in os.walk( the.repo.expanded_dir ):
68
assert path[ : len( the.repo.expanded_dir ) ] == \
70
relative_path = path[ len( the.repo.expanded_dir ) : ]
71
fsdir = the.expanded_fsdir + relative_path
76
for dir in directories:
77
if os.path.exists( fsdir + dir ) and \
78
not os.path.isdir( fsdir + dir ):
82
# if exists in repo as directory and also in fs as non-directory
83
if os.path.isdir( the.repo.expnaded_dir + relative_path +
154
# check we have a file list
155
self.check_ongoing( True )
157
# check that deployment conflicts have been checked-for
158
if not self.conflicts_checked:
159
raise RuntimeError('logic error: deployment conflicts unchecked' )
162
if the.verbose: print "exporting files..."
163
walker = CopyOutWalker( self.updated_files )
167
self.remove_deployment_state()
170
class DeploymentOngoing( the.program.FatalError ):
172
def __init__( self, ongoing ):
174
self.msg = "there is an ongoing deployment"
176
self.msg = "there is no ongoing deployment"
179
class CopyInConflicts( the.program.FatalError ):
181
def __init__( self, conflicts ):
182
self.conflicts = conflicts