Exemplo n.º 1
0
 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
Exemplo n.º 2
0
Arquivo: vc.py Projeto: wxtim/rose
    def generate_info_config(self, from_id=None, prefix=None, project=None):
        """Generate a metomi.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 metomi.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 = metomi.rose.config.load(StringIO(out_data))

        res_loc = ResourceLocator.default()
        older_config = None
        info_config = metomi.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=metomi.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 = metomi.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],
                        metomi.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