def _copy1(self, info_config, from_id): """Copy a suite from the same repository.""" from_id_url = "%s/%s@%s" % ( from_id.to_origin(), from_id.branch, from_id.revision, ) self.popen("svn", "info", from_id_url) # Die if from_id not exists prefix = from_id.prefix temp_local_copy = os.path.join(self._get_work_dir(), "work") new_id = None # N.B. This is probably the simplest logic to maintain, # but not the most efficient for runtime. Does it matter? while new_id is None: if os.path.exists(temp_local_copy): shutil.rmtree(temp_local_copy) self.popen( "svn", "checkout", "-q", "--depth", "empty", SuiteId.get_prefix_location(prefix), temp_local_copy, ) new_id = SuiteId.get_next(prefix) for i in range(len(new_id.sid)): dir_ = os.path.join( temp_local_copy, os.sep.join(new_id.sid[0 : i + 1]) ) self.popen("svn", "update", "-q", "--depth", "empty", dir_) if not os.path.isdir(dir_): os.mkdir(dir_) self.popen("svn", "add", "-q", dir_) dir_ = os.path.join(temp_local_copy, os.sep.join(new_id.sid)) self.popen( "svn", "cp", "-q", from_id_url, os.path.join(dir_, "trunk") ) metomi.rose.config.dump( info_config, os.path.join(dir_, "trunk", "rose-suite.info") ) message = self.COMMIT_MESSAGE_COPY % ( new_id, from_id.to_string_with_version(), ) try: self.popen( "svn", "commit", "-q", "-m", message, temp_local_copy ) self.event_handler(SuiteCreateEvent(new_id)) self.event_handler(SuiteCopyEvent(new_id, from_id)) except RosePopenError as exc: try: self.popen("svn", "info", new_id.to_origin()) new_id = None except RosePopenError: raise exc finally: self._delete_work_dir() return new_id
def create(self, info_config, from_id=None, prefix=None, meta_suite_mode=False): """Create a suite. info_config -- A metomi.rose.config.ConfigNode object, which will be used as the content of the "rose-suite.info" file of the new suite. from_id -- If defined, copy items from it. prefix -- If defined, create the suite in the suite repository named by the prefix instead of the default one. meta_suite_mode -- If True, create the special metadata suite. Ignored if from_id is not None. Return the SuiteId of the suite on success. """ if from_id is not None and (not prefix or from_id.prefix == prefix): return self._copy1(info_config, from_id) dir_ = self._get_work_dir() try: # Create a temporary suite in the file system if from_id: from_id_url = "%s/%s@%s" % ( from_id.to_origin(), from_id.branch, from_id.revision, ) self.popen("svn", "export", "-q", "--force", from_id_url, dir_) else: open(os.path.join(dir_, "rose-suite.conf"), "w").close() metomi.rose.config.dump(info_config, os.path.join(dir_, "rose-suite.info")) # Attempt to import the temporary suite to the repository new_id = None while new_id is None: if meta_suite_mode: if prefix is None: new_id = SuiteId(id_text="ROSIE") else: idx = SuiteId.FORMAT_IDX % (prefix, "ROSIE") new_id = SuiteId(id_text=idx) else: new_id = SuiteId.get_next(prefix) new_origin = new_id.to_origin() + "/" + new_id.BRANCH_TRUNK try: if from_id: message = self.COMMIT_MESSAGE_COPY % ( new_id, from_id.to_string_with_version(), ) else: message = self.COMMIT_MESSAGE_CREATE % str(new_id) self.popen("svn", "import", "-q", "-m", message, dir_, new_origin) self.event_handler(SuiteCreateEvent(new_id)) if from_id: self.event_handler(SuiteCopyEvent(new_id, from_id)) except RosePopenError as exc: try: self.popen("svn", "info", new_origin) if not meta_suite_mode: new_id = None except RosePopenError: raise exc return new_id finally: self._delete_work_dir()