def processImports( self ): # Import rules # # - In the case of multiple imports, duplicate data is overridden # by the successing import. This rule is implied by the iteration # order of the imports list. # # - Repositories from an imported RSpec are overriden/discarded by any # repository in the importing RSpec, if they share the same ID. IDs # are case insensitive. # # - Import instructions are not inherited/imported. An import is regarded # as obsolete once it has been processed. # for rspec in self.imports: # First let the imported rspec process its own imports. rspec.processImports() # POINT OF RECURSION # Generate repository ID record existing_repo_ids = list() for r in self.getRepositories(): existing_repo_ids.append( r.getID() ) # Add all repositories from the imported RSpec, but skip those # with IDs we already have (override). for r in rspec.getRepositories(): if r.getID() not in existing_repo_ids: self.addRepository( r ) else: infoMessage("Repository '%s' in '%s' overridden by repository '%s' in '%s'"\ %(r.getID(), rspec.rspecFileLocator.getHref(), r.getID(), self.rspecFileLocator.getHref()), 1)
def update(self): if not treesAreEqual( self.getAbsLocalPath(), self.getHref() ): print >>sys.stderr, '\n' infoMessage("Regular file repository '%s' is out of sync.\n'%s' and '%s' doesn't match. The system is unable to\nperform intelligent synchronization of non-revisioned repositories.\nDo you want to overwrite (delete and replace) the local copy '%s'\nwith the contents of the remote copy '%s'?"\ %(self.getID(), self.getAbsLocalPath(), self.getHref(), self.getAbsLocalPath(), self.getHref() ), 0) choice = raw_input( "> yes/no: " ).lower() while choice not in ['yes','no']: infoMessage("Invalid choice, try again.", 0) choice = raw_input( "> yes/no: " ).lower() if choice == 'yes': infoMessage("Updating (replacing) local copy '%s' with '%s'"\ %(self.getAbsLocalPath(), self.getHref()), 1) shutil.rmtree( self.getAbsLocalPath() ) shutil.copytree( self.getHref(), self.getAbsLocalPath() ) elif choice == 'no': infoMessage("Skipping update of repository '%s'"%self.getID(), 2) else: ctxAssert( False, "Unhandled choice" ) else: infoMessage("Repository '%s' (%s) is up to date"%(self.getID(), self.getHref()), 1)
def update(self): ctxAssert( self.isLocal(), "This method should not be called without first checking for an existing working copy." ) infoMessage("Updating RSpec repository '%s' (%s)"%(self.getID(), self.getHref()), 1) self.client.updateWorkingCopy( self.getAbsLocalPath(), self.getRSpecRevision() )
def update_to_release ( svn_client, release, contexo_root ): cur_rel = get_current_version ( contexo_root ) infoMessage("Updating " + cur_rel + " to release: " + release[0], 0) update_dir = os.path.join (contexo_root, "update" ) # # call system/pre_update.py # os.chdir (update_dir) execfile ( "pre_update.py" ) # # Svn switch to release ( would like to export here ) # shutil.rmtree ( contexo_root, ignore_errors = True ) svn_client.export( release[1], contexo_root, force=True ) # # install modules # call system/install_pymods.py # system_dir = os.path.join (contexo_root, "system" ) os.chdir (system_dir) execfile( "install_pymods.py" ) # # Perform other post update activities # call system/post_update.py # os.chdir (update_dir) execfile ( "post_update.py" )
def checkout(self): import shutil import ctx_view ctxAssert( self.isLocal() == False, "This method should not be called without first checking for an existing local copy." ) infoMessage("Checking out repository '%s' (%s) to '%s'" %(self.getID(), self.getHref(), self.getAbsLocalPath()), 1) shutil.copytree( self.getHref(), self.getAbsLocalPath() )
def checkout(self): ctxAssert( self.isLocal() == False, "This method should not be called without first checking for an existing working copy." ) infoMessage("Checking out RSpec repository '%s' (%s)"%(self.getID(), self.getHref()), 1) if not os.path.isdir(self.getAbsLocalPath()): os.makedirs( self.getAbsLocalPath() ) self.client.checkout( self.getHref(), self.getAbsLocalPath(), self.getRSpecRevision() )
def dispatch( self ): import pickle import sys export_dump = pickle.dumps( self.export_data ) package = '%s%d$'%(export_header, len(export_dump)) infoMessage("Dispatching package to 'stdout'", 2) sys.stdout.write( package ) sys.stdout.write( export_dump )
def checkMissmatchedRepo(self): if self.isLocal(): url = self.client.getURLFromWorkingCopy(self.getAbsLocalPath()) if not ctx_common.areURLsEqual(url, self.getHref()): path = self.getAbsLocalPath() infoMessage("Removing missmatched repository: %s" % (path), 1) for root, dirs, files in os.walk(path, topdown=False): for name in files: filename = os.path.join(root, name) os.chmod(filename, stat.S_IWRITE) os.remove(filename) for name in dirs: os.rmdir(os.path.join(root, name))
def receive( self ): import pickle import sys data_buffer = str(sys.stdin.read()) # # Locate package header # i = data_buffer.rfind( export_header ) if i == -1: print data_buffer #Most likely errors from main system infoMessage("\n********** Export handler entry point **********\n\n", 2) userErrorExit("Unable to receive export package. Export header not found.\nThis is commonly the consequence of a terminal error raised by Contexo.") # # Extract package size # i += len(export_header) size_s = "" header_len = len(export_header) while data_buffer[i] != '$': size_s += data_buffer[i] header_len += 1 i += 1 header_len += 1 package_start = i+1 package_size = int(size_s) package_end = package_start + package_size # # Extract package chunk, and print everything else as regular text # package_dump = data_buffer[ package_start : package_end ] print data_buffer[ 0 : package_start - header_len ] print data_buffer[ package_end : -1 ] infoMessage("\n********** Export handler entry point **********\n\n", 2) # # Unpickle # self.export_data = pickle.loads( package_dump )
def receive( self ): import pickle import sys data_buffer = str(sys.stdin.read()) # # Locate package header # i = data_buffer.rfind( export_header ) if i == -1: print data_buffer #Most likely errors from main system infoMessage("\n********** Export handler entry point **********\n\n", 2) userErrorExit("Ctx export failed because of previous errors! Check the log for previous errors.") # # Extract package size # i += len(export_header) size_s = "" header_len = len(export_header) while data_buffer[i] != '$': size_s += data_buffer[i] header_len += 1 i += 1 header_len += 1 package_start = i+1 package_size = int(size_s) package_end = package_start + package_size # # Extract package chunk, and print >>sys.stderr, everything else as regular text # package_dump = data_buffer[ package_start : package_end ] print data_buffer[ 0 : package_start - header_len ] print data_buffer[ package_end : -1 ] infoMessage("\n********** Export handler entry point **********\n\n", 2) # # Unpickle # self.export_data = pickle.loads( package_dump )
def checkout(self): import shutil import ctx_view ctxAssert( self.isLocal() == False, "This method should not be called without first checking for an existing local copy." ) if self.getAccessPolicy() == ctx_view.AP_PREFER_REMOTE_ACCESS: infoMessage("Repository '%s' (%s) is accessible from its remote location, skipping checkout." %(self.getID(), self.getHref()), 1) elif self.getAccessPolicy() == ctx_view.AP_NO_REMOTE_ACCESS: infoMessage("Checking out repository '%s' (%s) to '%s'" %(self.getID(), self.getHref(), self.getAbsLocalPath()), 1) shutil.copytree( self.getHref(), self.getAbsLocalPath() ) else: ctxAssert( False, "Unhandled access policy '%d'"%self.getAccessPolicy() )
def __init__( self, cfgFilePath = None ): self.path = cfgFilePath self.defaultBConf = str() self.defaultView = str() self.bcPaths = list() self.cdefPaths = list() self.EnvPaths = list() self.verboseLevel = 1 #Copy default config into the user's directory if needed if not os.path.exists(cfgFilePath): import ctx_common defconfig = os.path.join( os.path.dirname(__file__), os.path.normpath('defaults/contexo.cfg') ) ctx_common.infoMessage("Copying config from '%s' to '%s'"%(defconfig, cfgFilePath), 1) try: shutil.copy( defconfig, cfgFilePath ) except IOError, (errno, strerror): print "*** Error copying file %s"%defconfig print strerror raise IOError
def update_tool(): infoMessage("Running contexo update tool (c) Scalado 2007", 0) try: contexo_root = os.path.abspath(getContexoRoot ()) svn_client = pysvn.Client () svn_client.callback_get_login = get_login svn_client.callback_ssl_server_trust_prompt = ssl_server_trust_prompt rel_dict = get_release_list (svn_client, release_url ) # Get current release ( check property: contexo-release ) cur_rel = get_current_version ( contexo_root ) if len(rel_dict) > 0: update_list = get_required_list (svn_client, cur_rel, rel_dict ) #</> # If len (update_list) > 0, there are updates to perform. # update = False if len ( update_list ) > 0: update = raw_input ("Updates available, update to the latest version? (y)/(n)") if update == 'y': for item in update_list: update_to_release ( svn_client, item, contexo_root ) cur_rel = get_current_version ( contexo_root ) infoMessage("Contexo is up-to-date. Current installed version is: " + cur_rel, 0) update = True cur_rel = get_current_version ( contexo_root ) infoMessage("Contexo is up-to-date. Current installed version is: " + cur_rel, 0) return update except: infoMessage("Contexo failed to be updated...") return False
def getLocalAccessPath(self): # TODO: wipe cache if root element and first export ok src = str() local_access_path = os.path.join( self.rspec_cache_dir, os.path.basename(self.getHref())) if not os.path.exists(self.rspec_cache_dir): os.makedirs(self.rspec_cache_dir) if self.rcs == None: if not os.path.exists( local_access_path ): infoMessage("No RCS specified for RSpec '%s', attempting regular file access"\ %(self.getHref()), 4) if not os.path.exists(self.href): userErrorExit("RSpec unreachable with regular file access: \n %s"%(self.href)) shutil.copyfile( self.getHref(), local_access_path ) # access the local rspec if accessable # otherwise the user may be confused why changes in a locally modified would not be applied. if os.path.exists(self.href): local_access_path = self.getHref() else: if self.updating == True or not os.path.exists( local_access_path ): temp_dir = getUserTempDir() rspec_name = os.path.basename(self.getHref()) temp_rspec = os.path.join( temp_dir, rspec_name ) infoMessage("Downloading (svn-exporting) RSpec from '%s' to '%s' using RCS '%s'"\ %(str(self.getHref()), str(temp_rspec), str(self.rcs)), 1) if os.path.exists(temp_rspec): os.remove( temp_rspec ) # rspec access is still handled by svn if self.rcs == 'svn' or self.rcs == 'git': svn = ctx_svn_client.CTXSubversionClient() # does this fail if rspec cannot be fetched? svn.export( self.getHref(), temp_dir, self.revision ) if not os.path.exists( os.path.join(temp_dir, os.path.basename(self.getHref()))): userErrorExit("RSpec unreachable with remote Subversion access: \n %s"%(self.getHref())) else: userErrorExit("Unsupported RCS: %s"%(self.rcs)) src = os.path.join( temp_dir, rspec_name) shutil.copyfile( src, local_access_path ) infoMessage("RSpec local access path resolved to: %s"\ %(local_access_path), 4) return local_access_path
def getLocalAccessPath(self): local_access_path = None if self.rcs == None: infoMessage("No RCS specified for RSpec '%s', attempting regular file access"\ %(self.getHref()), 4) if not os.path.exists(self.href): userErrorExit("RSpec unreachable with regular file access: \n %s"%(self.href)) local_access_path = self.getHref() else: temp_dir = getUserTempDir() rspec_name = os.path.basename(self.getHref()) temp_rspec = os.path.join( temp_dir, rspec_name ) infoMessage("Downloading (svn-exporting) RSpec from '%s' to '%s' using RCS '%s'"\ %(str(self.getHref()), str(temp_rspec), str(self.rcs)), 1) if os.path.exists(temp_rspec): os.remove( temp_rspec ) # rspec access is still handled by svn if self.rcs == 'svn' or self.rcs == 'git': svn = ctx_svn_client.CTXSubversionClient() svn.export( self.getHref(), temp_dir, self.revision ) local_access_path = temp_rspec #elif self.rcs == 'git': #git = ctx_git_client.CTXGitClient() else: userErrorExit("Unsupported RCS: %s"%(self.rcs)) infoMessage("RSpec local access path resolved to: %s"\ %(local_access_path), 4) return local_access_path
def update(self): import ctx_view ctxAssert( self.isLocal(), "This method should not be called without first checking for an existing local copy." ) ctxAssert( self.getAccessPolicy() != None, "No access policy has been set for repository '%s'"%(self.getID()) ) if self.getAccessPolicy() == ctx_view.AP_PREFER_REMOTE_ACCESS: infoMessage("Repository '%s' (%s) is accessed from its remote location, skipping update."%(self.getID(), self.getHref()), 1) elif self.getAccessPolicy() == ctx_view.AP_NO_REMOTE_ACCESS: if not treesAreEqual( self.getAbsLocalPath(), self.getHref() ): print '\n' infoMessage("Regular file repository '%s' is out of sync.\n'%s' and '%s' doesn't match. The system is unable to\nperform intelligent synchronization of non-revisioned repositories.\nDo you want to overwrite (delete and replace) the local copy '%s'\nwith the contents of the remote copy '%s'?"\ %(self.getID(), self.getAbsLocalPath(), self.getHref(), self.getAbsLocalPath(), self.getHref() ), 0) choice = raw_input( "> yes/no: " ).lower() while choice not in ['yes','no']: infoMessage("Invalid choice, try again.", 0) choice = raw_input( "> yes/no: " ).lower() if choice == 'yes': infoMessage("Updating (replacing) local copy '%s' with '%s'"\ %(self.getAbsLocalPath(), self.getHref()), 1) shutil.rmtree( self.getAbsLocalPath() ) shutil.copytree( self.getHref(), self.getAbsLocalPath() ) elif choice == 'no': infoMessage("Skipping update of repository '%s'"%self.getID(), 2) else: ctxAssert( False, "Unhandled choice" ) else: infoMessage("Repository '%s' (%s) is up to date"%(self.getID(), self.getHref()), 1) else: ctxAssert( False, "Unhandled access policy '%d'"%self.getAccessPolicy() )