def checkout(self, id_): """Create a local copy of a suite with the given ID. Return the SuiteId of the suite on success. """ if isinstance(id_, str): id_ = SuiteId(id_text=id_) if id_.revision is None: id_.revision = id_.REV_HEAD if id_.branch is None: id_.branch = id_.BRANCH_TRUNK local_copy = id_.to_local_copy() if os.path.exists(local_copy): id0 = SuiteId(location=local_copy) if id_.to_string_with_version() == id0.to_string_with_version(): self.event_handler(LocalCopyCreateSkipEvent(id_)) return id_ elif self.force_mode: self.fs_util.delete(local_copy) else: raise FileExistError(local_copy) local_copy_dir = os.path.dirname(local_copy) if not os.path.isdir(local_copy_dir): self.fs_util.makedirs(os.path.dirname(local_copy)) origin = "%s/%s@%s" % (id_.to_origin(), id_.branch, id_.revision) self.popen("svn", "checkout", "-q", origin, local_copy) self.event_handler(LocalCopyCreateEvent(id_)) return id_
def create(self, info_config, from_id=None, prefix=None, meta_suite_mode=False): """Create a suite. info_config -- A 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. """ for key in ["owner", "project", "title"]: if not info_config.get([key], no_ignore=True): raise SuiteInfoFieldError(key) if from_id is not None: return self._copy(info_config, from_id) 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 dir = self._get_work_dir() rose.config.dump(info_config, os.path.join(dir, "rose-suite.info")) open(os.path.join(dir, "rose-suite.conf"), "w").close() try: self.popen("svn", "import", "-q", "-m", "%s: new suite." % str(new_id), dir, new_origin) self.event_handler(SuiteCreateEvent(new_id)) except RosePopenError as e: try: self.popen("svn", "info", new_origin) if not meta_suite_mode: new_id = None except RosePopenError: raise e finally: self._delete_work_dir() return new_id
def delete(self, id_, local_only=False): """Delete the local copy and the origin of a suite. It takes the suite ID as an argument. Return the SuiteId of the suite on success. """ if isinstance(id_, str): id_ = SuiteId(id_text=id_) local_copy = id_.to_local_copy() if os.path.exists(local_copy): if not self.force_mode: status = self.popen("svn", "status", local_copy)[0] if status: raise LocalCopyStatusError(id_, status) if os.getcwd() == local_copy: self.fs_util.chdir(os.path.expanduser("~")) self.fs_util.delete(local_copy) if not local_only: self.popen( "svn", "delete", "-q", "-m", self.COMMIT_MESSAGE_DELETE % str(id_), id_.to_origin()) self.event_handler(SuiteDeleteEvent(id_)) return id_
def delete(argv): """CLI function: delete.""" opt_parser = RoseOptionParser().add_my_options("force_mode", "non_interactive", "local_only") opts, args = opt_parser.parse_args(argv) report = Reporter(opts.verbosity - opts.quietness) client = RosieVCClient(event_handler=report, force_mode=opts.force_mode) SuiteId.svn.event_handler = client.event_handler # FIXME if not args: args.append(SuiteId(location=os.getcwd())) interactive_mode = not opts.non_interactive prompt = ("%s: delete local+repository copies? " + "y/n/a (default n, a=yes-to-all) ") if opts.local_only: prompt = "%s: delete local copy? y/n/a (default n, a=yes-to-all) " rc = 0 for arg in args: if interactive_mode: try: response = raw_input(prompt % arg) except EOFError: rc = 1 continue if response == 'a': interactive_mode = False elif response != 'y': rc = 1 continue if opts.debug_mode: client.delete(arg, opts.local_only) else: try: client.delete(arg, opts.local_only) except (LocalCopyStatusError, RosePopenError, SuiteIdPrefixError) as e: client.event_handler(e) rc = 1 if not opts.force_mode: sys.exit(1) if rc: sys.exit(rc)
def delete(argv): """CLI function: delete.""" opt_parser = RoseOptionParser().add_my_options("force_mode", "non_interactive", "local_only") opts, args = opt_parser.parse_args(argv) report = Reporter(opts.verbosity - opts.quietness) client = RosieVCClient(event_handler=report, force_mode=opts.force_mode) SuiteId.svn.event_handler = client.event_handler if not args: args.append(SuiteId(location=os.getcwd())) interactive_mode = not opts.non_interactive prompt = PROMPT_DELETE if opts.local_only: prompt = PROMPT_DELETE_LOCAL ret_code = 0 for arg in args: if interactive_mode: try: response = raw_input(prompt % arg) except EOFError: ret_code = 1 continue if response == YES_TO_ALL: interactive_mode = False elif response != YES: ret_code = 1 continue if opts.debug_mode: client.delete(arg, opts.local_only) else: try: client.delete(arg, opts.local_only) except (LocalCopyStatusError, RosePopenError, SuiteIdPrefixError) as exc: client.event_handler(exc) ret_code = 1 if not opts.force_mode: sys.exit(1) if ret_code: sys.exit(ret_code)
def create(argv): """CLI function: create and copy.""" opt_parser = RoseOptionParser() opt_parser.add_my_options("checkout_mode", "info_file", "meta_suite_mode", "non_interactive", "prefix", "project") opts, args = opt_parser.parse_args(argv) verbosity = opts.verbosity - opts.quietness client = RosieVCClient(event_handler=Reporter(verbosity)) SuiteId.svn.event_handler = client.event_handler from_id = None if args: from_id = SuiteId(id_text=args[0]) if from_id.branch is None: from_id.branch = from_id.BRANCH_TRUNK if from_id.revision is None: from_id.revision = from_id.REV_HEAD from_id = SuiteId(id_text=from_id.to_string_with_version()) interactive_mode = not opts.non_interactive if opts.info_file is None: info_config = client.generate_info_config(from_id, opts.prefix, opts.project) if from_id is not None: meta_config = load_meta_config(info_config, directory=None, config_type=rose.INFO_CONFIG_NAME, error_handler=None, ignore_meta_error=False) for node_keys, node in meta_config.walk(no_ignore=True): if isinstance(node.value, dict): continue sect, key = node_keys value = node.value sect = sect.translate(None, "=") if key == "copy-mode" and value == "clear": info_config.set([sect], "") if key == "copy-mode" and value == "never": info_config.unset([sect]) info_config = _edit_info_config(opts, client, info_config) else: file_ = opts.info_file if opts.info_file == "-": file_ = sys.stdin info_config = rose.config.load(file_) info_config = _validate_info_config(opts, client, info_config) if interactive_mode: prefix = opts.prefix if from_id: if not prefix: prefix = from_id.prefix question = PROMPT_COPY % (from_id.to_string_with_version(), prefix) else: if not prefix: prefix = SuiteId.get_prefix_default() question = PROMPT_CREATE % prefix try: response = raw_input(question) except EOFError: sys.exit(1) if response != YES: sys.exit(1) try: id_ = client.create(info_config, from_id, opts.prefix, opts.meta_suite_mode) except (RosePopenError, SuiteIdOverflowError) as exc: client.event_handler(exc) sys.exit(1) if opts.checkout_mode: try: client.checkout(id_) except (FileExistError, RosePopenError) as exc: client.event_handler(exc) sys.exit(1)
def create(self, info_config, from_id=None, prefix=None, meta_suite_mode=False): """Create a suite. info_config -- A 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() 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()
def create(argv): """CLI function: create and copy.""" opt_parser = RoseOptionParser() opt_parser.add_my_options("checkout_mode", "info_file", "meta_suite_mode", "non_interactive", "prefix") opts, args = opt_parser.parse_args(argv) verbosity = opts.verbosity - opts.quietness report = Reporter(verbosity) client = RosieVCClient(event_handler=report) SuiteId.svn.event_handler = client.event_handler # FIXME: ugly? from_id = None if args: from_id = SuiteId(id_text=args[0]) if from_id.branch is None: from_id.branch = from_id.BRANCH_TRUNK if from_id.revision is None: from_id.revision = from_id.REV_HEAD from_id = SuiteId(id_text=from_id.to_string_with_version()) if opts.info_file is None: try: info_config = client.generate_info_config(from_id, opts.prefix) except (RosePopenError) as e: report(e) sys.exit(1) info_file = tempfile.NamedTemporaryFile(delete=False) try: rose.config.dump(info_config, info_file) info_file.write(CREATE_INFO_CONFIG_COMMENT) info_file.close() command_list = client.popen.get_cmd("editor", info_file.name) client.popen(*command_list, stdout=sys.stdout) info_config = rose.config.load(info_file.name) finally: os.unlink(info_file.name) elif opts.info_file == "-": info_config = rose.config.load(sys.stdin) else: info_config = rose.config.load(opts.info_file) if not opts.non_interactive: if from_id: question = "Copy \"%s\"?" % from_id.to_string_with_version() else: prefix = opts.prefix if not prefix: prefix = SuiteId.get_prefix_default() question = "Create suite at \"%s\"?" % prefix try: response = raw_input(question + " y/n (default n) ") except EOFError: sys.exit(1) if response != 'y': sys.exit(1) try: id = client.create(info_config, from_id, opts.prefix, opts.meta_suite_mode) except (RosePopenError, SuiteInfoFieldError, SuiteIdOverflowError) as e: report(e) sys.exit(1) if opts.checkout_mode: try: client.checkout(id) except (FileExistError, RosePopenError) as e: report(e) sys.exit(1)