def __init__(self, root=None, prefix=None): if root is None: config = rose.config.default_node() node = config.get(["rosie-ws-client", "ws-root-default"]) root = node.value self.root = root if prefix is None: prefix = SuiteId.get_prefix_default() self.prefix = prefix
def __init__(self, prefix=None): if prefix is None: prefix = SuiteId.get_prefix_default() self.prefix = prefix conf = ResourceLocator.default().get_conf() root = conf.get_value(["rosie-id", "prefix-ws." + self.prefix]) if root is None: raise UnknownRootError(self.prefix) if not root.endswith("/"): root += "/" self.root = root
def __init__(self, prefix=None, popen=None, prompt_func=None): if prefix is None: prefix = SuiteId.get_prefix_default() self.prefix = prefix self.auth_manager = RosieWSClientAuthManager(self.prefix, popen=popen, prompt_func=prompt_func) self.root = self.auth_manager.root self.requests_kwargs = {} res_loc = ResourceLocator.default() https_ssl_verify_mode_str = ( res_loc.default().get_conf().get_value(["rosie-id", "prefix-https-ssl-verify." + prefix]) ) if https_ssl_verify_mode_str: https_ssl_verify_mode = ast.literal_eval(https_ssl_verify_mode_str) self.requests_kwargs["verify"] = bool(https_ssl_verify_mode) https_ssl_cert_str = res_loc.default().get_conf().get_value(["rosie-id", "prefix-https-ssl-cert." + prefix]) if https_ssl_cert_str: https_ssl_cert = shlex.split(https_ssl_cert_str) if len(https_ssl_cert) == 1: self.requests_kwargs["cert"] = https_ssl_cert[0] else: self.requests_kwargs["cert"] = tuple(https_ssl_cert[0:2])
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.replace("=", "") 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 = 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 generate_info_config(self, from_id=None, prefix=None, project=None): """Generate a rose.config.ConfigNode for a rose-suite.info. This is suitable for passing into the create method of this class. If from_id is defined, copy items from it. Return the rose.config.ConfigNode instance. """ from_project = None from_title = None if from_id is not None: from_info_url = "%s/%s/rose-suite.info@%s" % (from_id.to_origin(), from_id.branch, from_id.revision) out_data = self.popen("svn", "cat", from_info_url)[0] from_config = rose.config.load(StringIO(out_data.decode())) res_loc = ResourceLocator.default() older_config = None info_config = rose.config.ConfigNode() # Determine project if given as a command-line option on create if from_id is None and project is not None: info_config.set(["project"], project) # Set the compulsory fields and use the project and metadata if # available. meta_config = load_meta_config( info_config, config_type=rose.INFO_CONFIG_NAME) if from_id is None and project is not None: 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 == "compulsory" and value == "true": info_config.set([sect], "") info_config.set(["project"], project) else: if from_project is None: info_config.set(["project"], "") if from_title is None: info_config.set(["title"], "") # Determine prefix if prefix is None: if from_id is None: prefix = SuiteId.get_prefix_default() else: prefix = from_id.prefix # Determine owner: # 1. From user configuration [rosie-id]prefix-username # 2. From username of a matching group in [groups] in # ~/.subversion/servers # 3. Current user ID owner = res_loc.get_conf().get_value( ["rosie-id", "prefix-username." + prefix]) if not owner and self.subversion_servers_conf: servers_conf = rose.config.load(self.subversion_servers_conf) groups_node = servers_conf.get(["groups"]) if groups_node is not None: prefix_loc = SuiteId.get_prefix_location(prefix) prefix_host = urlparse(prefix_loc).hostname for key, node in groups_node.value.items(): if fnmatch(prefix_host, node.value): owner = servers_conf.get_value([key, "username"]) break if not owner: owner = pwd.getpwuid(os.getuid())[0] info_config.set(["owner"], owner) # Copy description try: from_id.to_string_with_version() info_config.set( ["description"], "Copy of %s" % (from_id.to_string_with_version())) except AttributeError: pass # Copy fields provided by the user try: from_config.walk(no_ignore=False) for node_keys, node in from_config.walk(no_ignore=False): if isinstance(node.value, dict): continue sect, key = node_keys value = node.value if (key in ["description", "owner", "access-list"] or (key == "project" and from_project is not None)): pass else: info_config.set([key], value) except UnboundLocalError: pass # Determine access list access_list_str = res_loc.get_conf().get_value( ["rosie-vc", "access-list-default"]) if access_list_str: info_config.set(["access-list"], access_list_str) if from_id is None and project is not None: 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 == "value-hints" or key == "values": reminder = ("please remove all commented hints/lines " + "in the main/top section before saving.") info_config.set([sect], rose.variable.array_split(value)[0], comments=[value, reminder]) if older_config is not None: for node_keys, node in older_config.walk(no_ignore=True): if isinstance(node.value, dict): continue sect, key = node_keys value = node.value info_config.set([key], value) return info_config
def generate_info_config(self, from_id=None, prefix=None): """Generate a rose.config.ConfigNode for a rose-suite.info. This is suitable for passing into the create method of this class. If from_id is defined, copy items from it. Return the rose.config.ConfigNode instance. """ from_project = None from_title = None if from_id is not None: from_info_url = "%s/%s/rose-suite.info@%s" % (from_id.to_origin(), from_id.branch, from_id.revision) out_data = self.popen("svn", "cat", from_info_url)[0] from_config = rose.config.load(StringIO(out_data)) if from_config.get(["project"]) is not None: from_project = from_config.get(["project"]).value if from_config.get(["title"]) is not None: from_title = from_config.get(["title"]).value res_loc = ResourceLocator.default() info_config = rose.config.load( res_loc.locate("rosie-create/rose-suite.info")) if from_id is not None: prefix = from_id.prefix elif prefix is None: prefix = SuiteId.get_prefix_default() # Determine owner: # 1. From user configuration [rosie-id]prefix-username # 2. From username of a matching group in [groups] in # ~/.subversion/servers # 3. Current user ID owner = res_loc.get_conf().get_value( ["rosie-id", "prefix-username." + prefix]) if not owner and self.subversion_servers_conf: servers_conf = rose.config.load(self.subversion_servers_conf) groups_node = servers_conf.get(["groups"]) if groups_node is not None: group = None prefix_loc = SuiteId.get_prefix_location(prefix) prefix_host = urlparse(prefix_loc).hostname for key, node in groups_node.value.items(): if fnmatch(prefix_host, node.value): owner = servers_conf.get_value([key, "username"]) break if not owner: owner = pwd.getpwuid(os.getuid())[0] info_config.set(["owner"], owner) if from_project: info_config.set(["project"], from_project) else: info_config.set(["project"], "") if from_title: info_config.set(["title"], "Copy of %s: %s" % (from_id.to_string_with_version(), from_title)) else: info_config.set(["title"], "") return info_config
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 generate_info_config(self, from_id=None, prefix=None, project=None): """Generate a rose.config.ConfigNode for a rose-suite.info. This is suitable for passing into the create method of this class. If from_id is defined, copy items from it. Return the rose.config.ConfigNode instance. """ from_project = None from_title = None if from_id is not None: from_info_url = "%s/%s/rose-suite.info@%s" % ( from_id.to_origin(), from_id.branch, from_id.revision) out_data = self.popen("svn", "cat", from_info_url)[0] from_config = rose.config.load(StringIO(out_data)) res_loc = ResourceLocator.default() older_config = None info_config = rose.config.ConfigNode() # Determine project if given as a command-line option on create if from_id is None and project is not None: info_config.set(["project"], project) # Set the compulsory fields and use the project and metadata if # available. meta_config = load_meta_config(info_config, config_type=rose.INFO_CONFIG_NAME) if from_id is None and project is not None: 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 == "compulsory" and value == "true": info_config.set([sect], "") info_config.set(["project"], project) else: if from_project is None: info_config.set(["project"], "") if from_title is None: info_config.set(["title"], "") # Determine prefix if prefix is None: if from_id is None: prefix = SuiteId.get_prefix_default() else: prefix = from_id.prefix # Determine owner: # 1. From user configuration [rosie-id]prefix-username # 2. From username of a matching group in [groups] in # ~/.subversion/servers # 3. Current user ID owner = res_loc.get_conf().get_value( ["rosie-id", "prefix-username." + prefix]) if not owner and self.subversion_servers_conf: servers_conf = rose.config.load(self.subversion_servers_conf) groups_node = servers_conf.get(["groups"]) if groups_node is not None: prefix_loc = SuiteId.get_prefix_location(prefix) prefix_host = urlparse(prefix_loc).hostname for key, node in groups_node.value.items(): if fnmatch(prefix_host, node.value): owner = servers_conf.get_value([key, "username"]) break if not owner: owner = pwd.getpwuid(os.getuid())[0] info_config.set(["owner"], owner) # Copy description try: from_id.to_string_with_version() info_config.set(["description"], "Copy of %s" % (from_id.to_string_with_version())) except AttributeError: pass # Copy fields provided by the user try: from_config.walk(no_ignore=False) for node_keys, node in from_config.walk(no_ignore=False): if isinstance(node.value, dict): continue sect, key = node_keys value = node.value if (key in ["description", "owner", "access-list"] or (key == "project" and from_project is not None)): pass else: info_config.set([key], value) except UnboundLocalError: pass # Determine access list access_list_str = res_loc.get_conf().get_value( ["rosie-vc", "access-list-default"]) if access_list_str: info_config.set(["access-list"], access_list_str) if from_id is None and project is not None: 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 == "value-hints" or key == "values": reminder = ("please remove all commented hints/lines " + "in the main/top section before saving.") info_config.set([sect], rose.variable.array_split(value)[0], comments=[value, reminder]) if older_config is not None: for node_keys, node in older_config.walk(no_ignore=True): if isinstance(node.value, dict): continue sect, key = node_keys value = node.value info_config.set([key], value) return info_config
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)
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 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()) info_config_new = None interactive_mode = not opts.non_interactive if opts.info_file is None: try: info_config = client.generate_info_config(from_id, opts.prefix, opts.project) except (RosePopenError) as e: report(e) sys.exit(1) info_file = tempfile.NamedTemporaryFile() if args: 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]) rose.config.dump(info_config, info_file) info_file.write(CREATE_INFO_CONFIG_COMMENT) info_file.seek(0) command_list = client.popen.get_cmd("editor", info_file.name) client.popen(*command_list, stdout=sys.stdout) info_config = rose.config.load(info_file) try: info_config_new, error_reported = client.check_fields(info_config, interactive_mode, from_id, opts.prefix) except (RosePopenError, SuiteInfoFieldError, SuiteIdOverflowError) as e: report(e) sys.exit(1) while error_reported is True: info_file = tempfile.NamedTemporaryFile() info_config = info_config_new if (info_config.get(["project"]).value is not None and opts.project is None): project = info_config.get(["project"]).value info_config = client.generate_info_config(from_id, opts.prefix, project, info_config) rose.config.dump(info_config, info_file) info_file.write(CREATE_INFO_CONFIG_COMMENT) info_file.seek(0) command_list = client.popen.get_cmd("editor", info_file.name) client.popen(*command_list, stdout=sys.stdout) info_config = rose.config.load(info_file) try: info_config_new, error_reported = client.check_fields( info_config, interactive_mode, from_id, opts.prefix) except (RosePopenError, SuiteInfoFieldError, SuiteIdOverflowError) as e: report(e) sys.exit(1) elif opts.info_file == "-": info_config = rose.config.load(sys.stdin) try: info_config_new, error_reported = client.check_fields(info_config, interactive_mode, from_id, opts.info_file, opts.prefix) except (RosePopenError, SuiteInfoFieldError, SuiteIdOverflowError) as e: report(e) sys.exit(1) else: info_config = rose.config.load(opts.info_file) try: info_config_new, error_reported = client.check_fields(info_config, interactive_mode, from_id, opts.info_file, opts.prefix) except (RosePopenError, SuiteInfoFieldError, SuiteIdOverflowError) as e: report(e) sys.exit(1) if interactive_mode: 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)
def generate_info_config(self, from_id=None, prefix=None): """Generate a rose.config.ConfigNode for a rose-suite.info. This is suitable for passing into the create method of this class. If from_id is defined, copy items from it. Return the rose.config.ConfigNode instance. """ from_project = None from_title = None if from_id is not None: from_info_url = "%s/%s/rose-suite.info@%s" % (from_id.to_origin(), from_id.branch, from_id.revision) out_data = self.popen("svn", "cat", from_info_url)[0] from_config = rose.config.load(StringIO(out_data)) if from_config.get(["project"]) is not None: from_project = from_config.get(["project"]).value if from_config.get(["title"]) is not None: from_title = from_config.get(["title"]).value res_loc = ResourceLocator.default() info_config = rose.config.ConfigNode() # Determine prefix if from_id is not None: prefix = from_id.prefix elif prefix is None: prefix = SuiteId.get_prefix_default() # Determine owner: # 1. From user configuration [rosie-id]prefix-username # 2. From username of a matching group in [groups] in # ~/.subversion/servers # 3. Current user ID owner = res_loc.get_conf().get_value( ["rosie-id", "prefix-username." + prefix]) if not owner and self.subversion_servers_conf: servers_conf = rose.config.load(self.subversion_servers_conf) groups_node = servers_conf.get(["groups"]) if groups_node is not None: group = None prefix_loc = SuiteId.get_prefix_location(prefix) prefix_host = urlparse(prefix_loc).hostname for key, node in groups_node.value.items(): if fnmatch(prefix_host, node.value): owner = servers_conf.get_value([key, "username"]) break if not owner: owner = pwd.getpwuid(os.getuid())[0] info_config.set(["owner"], owner) # Determine project and title if from_project: info_config.set(["project"], from_project) else: info_config.set(["project"], "") if from_title: info_config.set(["title"], "Copy of %s: %s" % (from_id.to_string_with_version(), from_title)) else: info_config.set(["title"], "") # Determine access list access_list_str = res_loc.get_conf().get_value( ["rosie-vc", "access-list-default"]) if access_list_str: info_config.set(["access-list"], access_list_str) return info_config