Beispiel #1
0
def main():
    """Implement the "rose config-dump" command."""
    opt_parser = RoseOptionParser()
    opt_parser.add_my_options("conf_dir", "files", "no_pretty_mode")
    opts = opt_parser.parse_args()[0]
    verbosity = opts.verbosity - opts.quietness
    report = Reporter(verbosity)
    fs_util = FileSystemUtil(report)
    if opts.conf_dir:
        fs_util.chdir(opts.conf_dir)
    file_names = []
    if opts.files:
        file_names = opts.files
    else:
        for dirpath, _, filenames in os.walk("."):
            for filename in fnmatch.filter(filenames, "rose-*.conf"):
                path = os.path.join(dirpath, filename)[2:]  # remove leading ./
                file_names.append(path)
    for file_name in file_names:
        handle = NamedTemporaryFile()
        node = ConfigLoader()(file_name)
        if (not opts.no_pretty_mode and
                os.path.basename(file_name) != META_CONFIG_NAME):
            pretty_format_config(node, ignore_error=True)
        ConfigDumper()(node, handle)
        handle.seek(0)
        if not filecmp.cmp(handle.name, file_name, shallow=False):
            report(ConfigDumpEvent(file_name))
            ConfigDumper()(node, file_name)
Beispiel #2
0
def main():
    """Implement the "rose config-dump" command."""
    opt_parser = RoseOptionParser()
    opt_parser.add_my_options("conf_dir", "files", "no_pretty_mode")
    opts, args = opt_parser.parse_args()
    verbosity = opts.verbosity - opts.quietness
    report = Reporter(verbosity)
    fs_util = FileSystemUtil(report)
    if opts.conf_dir:
        fs_util.chdir(opts.conf_dir)
    file_names = []
    if opts.files:
        file_names = opts.files
    else:
        for dirpath, dirnames, filenames in os.walk("."):
            for filename in fnmatch.filter(filenames, "rose-*.conf"):
                p = os.path.join(dirpath, filename)[2:]  # remove leading ./
                file_names.append(p)
    for file_name in file_names:
        t = NamedTemporaryFile()
        node = ConfigLoader()(file_name)
        if (not opts.no_pretty_mode
                and os.path.basename(file_name) != META_CONFIG_NAME):
            pretty_format_config(node, ignore_error=True)
        ConfigDumper()(node, t)
        t.seek(0)
        if not filecmp.cmp(t.name, file_name, shallow=False):
            report(ConfigDumpEvent(file_name))
            ConfigDumper()(node, file_name)
Beispiel #3
0
def main():
    """Implement the "rose config-dump" command."""
    opt_parser = RoseOptionParser()
    opt_parser.add_my_options("conf_dir", "files", "no_pretty_mode")
    opts, args = opt_parser.parse_args()
    verbosity = opts.verbosity - opts.quietness
    report = Reporter(verbosity)
    fs_util = FileSystemUtil(report)
    if opts.conf_dir:
        fs_util.chdir(opts.conf_dir)
    file_names = []
    if opts.files:
        file_names = opts.files
    else:
        for dirpath, dirnames, filenames in os.walk("."):
            for filename in fnmatch.filter(filenames, "rose-*.conf"):
                p = os.path.join(dirpath, filename)[2:] # remove leading ./
                file_names.append(p)
    for file_name in file_names:
        t = NamedTemporaryFile()
        node = ConfigLoader()(file_name)
        if not opts.no_pretty_mode:
            pretty_format_config(node)
        ConfigDumper()(node, t)
        t.seek(0)
        if not filecmp.cmp(t.name, file_name, shallow=False):
            report(ConfigDumpEvent(file_name))
            ConfigDumper()(node, file_name)
Beispiel #4
0
 def __init__(self, opts, reporter=None, popen=None, fs_util=None):
     self.opts = opts
     if reporter is None:
         self.reporter = Reporter(opts.verbosity - opts.quietness)
     else:
         self.reporter = reporter
     if popen is None:
         self.popen = RosePopener(event_handler=self.reporter)
     else:
         self.popen = popen
     if fs_util is None:
         self.fs_util = FileSystemUtil(event_handler=self.reporter)
     else:
         self.fs_util = fs_util
Beispiel #5
0
def get_suite_name(event_handler=None):
    """Find the top level of a suite directory structure"""
    fs_util = FileSystemUtil(event_handler)
    suite_name = None
    conf_dir = os.getcwd()
    while True:
        if os.path.basename(conf_dir) != "rose-stem":
            for tail in ["rose-suite.conf", "rose-stem/rose-suite.conf"]:
                conf = os.path.join(conf_dir, tail)
                if os.path.exists(conf):
                    return os.path.basename(conf_dir)
        up_dir = fs_util.dirname(conf_dir)
        if up_dir == conf_dir:
            raise SuiteNotFoundError(os.getcwd())
        conf_dir = up_dir
Beispiel #6
0
def get_suite_name(event_handler=None):
    """Find the top level of a suite directory structure"""
    fs_util = FileSystemUtil(event_handler)
    suite_name = None
    conf_dir = os.getcwd()
    while True:
        if os.path.basename(conf_dir) != "rose-stem":
            for tail in ["rose-suite.conf", "rose-stem/rose-suite.conf"]:
                conf = os.path.join(conf_dir, tail)
                if os.path.exists(conf):
                    return os.path.basename(conf_dir)
        up_dir = fs_util.dirname(conf_dir)
        if up_dir == conf_dir:
            raise SuiteNotFoundError(os.getcwd())
        conf_dir = up_dir
Beispiel #7
0
Datei: vc.py Projekt: kaday/rose
 def __init__(self,
              event_handler=None,
              popen=None,
              fs_util=None,
              force_mode=False):
     if event_handler is None:
         event_handler = self._dummy
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     self.force_mode = force_mode
     self._work_dir = None
     atexit.register(self._delete_work_dir)
     self.subversion_servers_conf = None
     subversion_servers_conf = os.getenv("ROSIE_SUBVERSION_SERVERS_CONF")
     if subversion_servers_conf:
         self.subversion_servers_conf = subversion_servers_conf
     else:
         subversion_servers_conf = os.path.expanduser(
             self.SUBVERSION_SERVERS_CONF)
         if os.path.exists(subversion_servers_conf):
             self.subversion_servers_conf = subversion_servers_conf
Beispiel #8
0
 def __init__(self, event_handler=None, popen=None, fs_util=None, **kwargs):
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     self.date_time_oper = RoseDateTimeOperator()
Beispiel #9
0
 def __init__(self, event_handler=None, popen=None, fs_util=None):
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     path = os.path.dirname(os.path.dirname(sys.modules["rose"].__file__))
     SchemeHandlersManager.__init__(self, [path], "rose.config_processors",
                                    ["process"])
Beispiel #10
0
 def __init__(self, event_handler=None):
     self.event_handler = event_handler
     self.popen = RosePopener(self.event_handler)
     self.fs_util = FileSystemUtil(self.event_handler)
     self.config_pm = ConfigProcessorsManager(self.event_handler,
                                              self.popen, self.fs_util)
     self.host_selector = HostSelector(self.event_handler, self.popen)
     self.suite_engine_proc = SuiteEngineProcessor.get_processor(
         event_handler=self.event_handler,
         popen=self.popen,
         fs_util=self.fs_util)
Beispiel #11
0
 def __init__(self, event_handler=None, popen=None, fs_util=None):
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     path = os.path.dirname(os.path.dirname(sys.modules["rose"].__file__))
     SchemeHandlersManager.__init__(
         self, [path], ns="rose.loc_handlers", attrs=["parse", "pull"],
         can_handle="can_pull")
Beispiel #12
0
 def __init__(self, event_handler=None, popen=None, fs_util=None):
     if event_handler is None:
         event_handler = self._dummy
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     self.post_commit_hook = RosieSvnPostCommitHook(
         event_handler=event_handler, popen=popen)
Beispiel #13
0
 def __init__(self, event_handler=None, popen=None, fs_util=None,
              host_selector=None, **_):
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     if host_selector is None:
         host_selector = HostSelector(event_handler, popen)
     self.host_selector = host_selector
     self.date_time_oper = RoseDateTimeOperator()
Beispiel #14
0
 def __init__(self, opts, reporter=None, popen=None, fs_util=None):
     self.opts = opts
     if reporter is None:
         self.reporter = Reporter(opts.verbosity - opts.quietness)
     else:
         self.reporter = reporter
     if popen is None:
         self.popen = RosePopener(event_handler=self.reporter)
     else:
         self.popen = popen
     if fs_util is None:
         self.fs_util = FileSystemUtil(event_handler=self.reporter)
     else:
         self.fs_util = fs_util
Beispiel #15
0
 def __init__(self, event_handler=None, popen=None, config_pm=None,
              fs_util=None, suite_engine_proc=None):
     if not self.CONF_NAME:
         self.CONF_NAME = self.NAME
     self.event_handler = event_handler
     if popen is None:
         popen = RosePopener(event_handler)
     self.popen = popen
     if fs_util is None:
         fs_util = FileSystemUtil(event_handler)
     self.fs_util = fs_util
     if config_pm is None:
         config_pm = ConfigProcessorsManager(event_handler, popen, fs_util)
     self.config_pm = config_pm
     if suite_engine_proc is None:
         suite_engine_proc = SuiteEngineProcessor.get_processor(
             event_handler=event_handler, popen=popen, fs_util=fs_util)
     self.suite_engine_proc = suite_engine_proc
     self.conf_tree_loader = ConfigTreeLoader()
Beispiel #16
0
class StemRunner(object):

    """Set up options for running a STEM job through Rose."""

    def __init__(self, opts, reporter=None, popen=None, fs_util=None):
        self.opts = opts
        if reporter is None:
            self.reporter = Reporter(opts.verbosity - opts.quietness)
        else:
            self.reporter = reporter
        if popen is None:
            self.popen = RosePopener(event_handler = self.reporter)
        else:
            self.popen = popen
        if fs_util is None:
            self.fs_util = FileSystemUtil(event_handler = self.reporter)
        else:
            self.fs_util = fs_util

    def _add_define_option(self, var, val):
        """Add a define option passed to the SuiteRunner."""

        if self.opts.defines:
            self.opts.defines.append(SUITE_RC_PREFIX + var + '=' + val )
        else:
            self.opts.defines= [ SUITE_RC_PREFIX + var + '=' + val ]
        self.reporter(ConfigVariableSetEvent(var, val))
        return

    def _get_base_dir(self, item):
        """Given a source tree return the following from 'fcm loc-layout':
           * url
           * sub_tree
           * peg_rev
           * root
           * project
        """
        
        
        rc, output, stderr = self.popen.run('fcm', 'loc-layout', item)
        if rc != 0:
            raise ProjectNotFoundException(item, stderr)

        ret = {}
        for line in output.splitlines():
            if not ":" in line:
              continue
            key, value = line.split(":", 1)
            if key:
                if value:
                    ret[key] = value.strip()

        return ret

    def _get_project_from_url(self, source_dict):
        """Run 'fcm keyword-print' to work out the project name."""

        repo = source_dict['root']
        if source_dict['project']:
            repo += '/' + source_dict['project']

        rc, kpoutput, stderr = self.popen.run('fcm', 'kp', source_dict['url'])

        project = None
        for line in kpoutput.splitlines():
            if line.rstrip().endswith(repo):
                kpresult = re.search(r'^location{primary}\[(.*)\]', line)
                if kpresult:
                    project = kpresult.group(1)
                    break
        return project

    def _ascertain_project(self, item):
        """Set the project name and top-level from 'fcm loc-layout'.
        Returns:
            * project name
            * top-level location of the source tree with revision number
            * top-level location of the source tree without revision number
            * revision number
        """

        project = ''
        if re.search(r'^\.', item):
            item = os.path.abspath(os.path.join(os.getcwd(), item))

        source_dict =  self._get_base_dir(item)
        project = self._get_project_from_url(source_dict)

        if not project:
            raise ProjectNotFoundException(item)

        if 'peg_rev' in source_dict and '@' in item:
            revision = '@' + source_dict['peg_rev']
            base = re.sub(r'@.*', r'', item)
        else:
            revision = ''
            base = item    

        # Remove subtree from base and item
        if 'sub_tree' in source_dict:
            item = item.replace(source_dict['sub_tree'], '', 1)
            base = base.replace(source_dict['sub_tree'], '', 1)

        # Remove trailing forwards-slash
        item = re.sub(r'/$',r'',item)
        base = re.sub(r'/$',r'',base)

        return project, item, base, revision

    def _generate_name(self):
        """Generate a suite name from the name of the first source tree."""
        dummy, basedir, dummy2, dummy3 = self._ascertain_project(os.getcwd())
        name = os.path.basename(basedir)
        return name

    def _this_suite(self):
        """Find the location of the suite in the first source tree."""

        # Get base of first source
        basedir = ''
        if self.opts.source:
            basedir = self.opts.source[0]
        else:
            dummy, basedir, dum2, dum3 = self._ascertain_project(os.getcwd())

        suitedir = os.path.join(basedir, DEFAULT_TEST_DIR)
        suitefile = os.path.join(suitedir, "rose-suite.conf")

        if not os.path.isfile(suitefile):
            raise RoseSuiteConfNotFoundException(suitedir)
        return suitedir

    def process(self):
        """Process STEM options into 'rose suite-run' options."""

        # Generate options for source trees
        repos = {}
        if not self.opts.source:
            self.opts.source = ['.']
        self.opts.project = list()

        for i, url in enumerate(self.opts.source):
            project, url, base, rev = self._ascertain_project(url)
            self.opts.source[i] = url
            self.opts.project.append(project)
            if project in repos:
                repos[project].append(url)
            else:
                repos[project] = [ url ]
                self._add_define_option('SOURCE_' + project.upper() + '_REV', 
                                        '"' + rev + '"')
                self._add_define_option('SOURCE_' + project.upper() + '_BASE', 
                                        '"' + base + '"')
            self.reporter(SourceTreeAddedAsBranchEvent(url))
        for project, branches in repos.iteritems():
            var = 'SOURCE_' + project.upper()
            branchstring = RosePopener.list_to_shell_str(branches)
            self._add_define_option(var, '"' + branchstring + '"')

        # Generate the variable containing tasks to run
        if self.opts.group:
            if not self.opts.defines:
                self.opts.defines = []
            self.opts.defines.append(SUITE_RC_PREFIX + 'RUN_NAMES=' +
                                     str(self.opts.group))

        # Change into the suite directory
        if self.opts.conf_dir:
            self.reporter(SuiteSelectionEvent(self.opts.conf_dir))
        else:
            thissuite = self._this_suite()
            self.fs_util.chdir(thissuite)
            self.reporter(SuiteSelectionEvent(thissuite))

        # Create a default name for the suite; allow override by user
        if not self.opts.name:
            self.opts.name = self._generate_name()

        return self.opts
Beispiel #17
0
class StemRunner(object):

    """Set up options for running a STEM job through Rose."""

    def __init__(self, opts, reporter=None, popen=None, fs_util=None):
        self.opts = opts
        if reporter is None:
            self.reporter = Reporter(opts.verbosity - opts.quietness)
        else:
            self.reporter = reporter
        if popen is None:
            self.popen = RosePopener(event_handler=self.reporter)
        else:
            self.popen = popen
        if fs_util is None:
            self.fs_util = FileSystemUtil(event_handler=self.reporter)
        else:
            self.fs_util = fs_util

    def _add_define_option(self, var, val):
        """Add a define option passed to the SuiteRunner."""

        if self.opts.defines:
            self.opts.defines.append(SUITE_RC_PREFIX + var + '=' + val)
        else:
            self.opts.defines = [SUITE_RC_PREFIX + var + '=' + val]
        self.reporter(ConfigVariableSetEvent(var, val))
        return

    def _get_base_dir(self, item):
        """Given a source tree return the following from 'fcm loc-layout':
           * url
           * sub_tree
           * peg_rev
           * root
           * project
        """

        rc, output, stderr = self.popen.run('fcm', 'loc-layout', item)
        if rc != 0:
            raise ProjectNotFoundException(item, stderr)

        ret = {}
        for line in output.splitlines():
            if ":" not in line:
                continue
            key, value = line.split(":", 1)
            if key:
                if value:
                    ret[key] = value.strip()

        return ret

    def _get_project_from_url(self, source_dict):
        """Run 'fcm keyword-print' to work out the project name."""

        repo = source_dict['root']
        if source_dict['project']:
            repo += '/' + source_dict['project']

        rc, kpoutput, stderr = self.popen.run('fcm', 'kp', source_dict['url'])

        project = None
        for line in kpoutput.splitlines():
            if line.rstrip().endswith(repo):
                kpresult = re.search(r'^location{primary}\[(.*)\]', line)
                if kpresult:
                    project = kpresult.group(1)
                    break
        return project

    def _deduce_mirror(self, source_dict, project):
        """Deduce the mirror location of this source tree."""

        # Root location for project
        proj_root = source_dict['root'] + '/' + source_dict['project']

        # Swap project to mirror
        project = re.sub(r'\.x$', r'.xm', project)
        mirror_repo = "fcm:" + project

        # Generate mirror location
        mirror = re.sub(proj_root, mirror_repo, source_dict['url'])

        # Add forwards slash after .xm if missing
        if '.xm/' not in mirror:
            mirror = re.sub(r'\.xm', r'.xm/', mirror)
        return mirror

    def _ascertain_project(self, item):
        """Set the project name and top-level from 'fcm loc-layout'.
        Returns:
            * project name
            * top-level location of the source tree with revision number
            * top-level location of the source tree without revision number
            * revision number
        """

        project = None
        try:
            project, item = item.split("=", 1)
        except ValueError:
            pass

        if re.search(r'^\.', item):
            item = os.path.abspath(os.path.join(os.getcwd(), item))

        if project is not None:
            print "[WARN] Forcing project for '{0}' to be '{1}'".format(
                item, project)
            return project, item, item, '', ''

        source_dict = self._get_base_dir(item)
        project = self._get_project_from_url(source_dict)
        mirror = self._deduce_mirror(source_dict, project)

        if not project:
            raise ProjectNotFoundException(item)

        if 'peg_rev' in source_dict and '@' in item:
            revision = '@' + source_dict['peg_rev']
            base = re.sub(r'@.*', r'', item)
        else:
            revision = ''
            base = item

        # Remove subtree from base and item
        if 'sub_tree' in source_dict:
            item = re.sub(
                r'(.*)%s/?$' % (source_dict['sub_tree']), r'\1', item, count=1)
            base = re.sub(
                r'(.*)%s/?$' % (source_dict['sub_tree']), r'\1', base, count=1)

        # Remove trailing forwards-slash
        item = re.sub(r'/$', r'', item)
        base = re.sub(r'/$', r'', base)

        # Remove anything after a point
        project = re.sub(r'\..*', r'', project)
        return project, item, base, revision, mirror

    def _generate_name(self):
        """Generate a suite name from the name of the first source tree."""
        try:
            basedir = self._ascertain_project(os.getcwd())[1]
        except ProjectNotFoundException:
            if self.opts.conf_dir:
                basedir = os.path.abspath(self.opts.conf_dir)
            else:
                basedir = os.getcwd()
        name = os.path.basename(basedir)
        self.reporter(NameSetEvent(name))
        return name

    def _this_suite(self):
        """Find the location of the suite in the first source tree."""

        # Get base of first source
        basedir = ''
        if self.opts.source:
            basedir = self.opts.source[0]
        else:
            basedir = self._ascertain_project(os.getcwd())[1]

        suitedir = os.path.join(basedir, DEFAULT_TEST_DIR)
        suitefile = os.path.join(suitedir, "rose-suite.conf")

        if not os.path.isfile(suitefile):
            raise RoseSuiteConfNotFoundException(suitedir)

        self._check_suite_version(suitefile)

        return suitedir

    def _read_site_config_and_return_options(self):
        """Read the site rose.conf file."""
        return ResourceLocator.default().get_conf().get_value(
            ["rose-stem", "automatic-options"])

    def _check_suite_version(self, fname):
        """Check the suite is compatible with this version of rose-stem."""
        if not os.path.isfile(fname):
            raise RoseSuiteConfNotFoundException(os.path.dirname(fname))
        config = rose.config.load(fname)
        suite_rose_stem_version = config.get(['ROSE_STEM_VERSION'])
        if suite_rose_stem_version:
            suite_rose_stem_version = int(suite_rose_stem_version.value)
        else:
            suite_rose_stem_version = None
        if not suite_rose_stem_version == ROSE_STEM_VERSION:
            raise RoseStemVersionException(suite_rose_stem_version)

    def process(self):
        """Process STEM options into 'rose suite-run' options."""

        # Generate options for source trees
        repos = {}
        if not self.opts.source:
            self.opts.source = ['.']
        self.opts.project = list()

        for i, url in enumerate(self.opts.source):
            project, url, base, rev, mirror = self._ascertain_project(url)
            self.opts.source[i] = url
            self.opts.project.append(project)
            if project in repos:
                repos[project].append(url)
            else:
                repos[project] = [url]
                self._add_define_option('SOURCE_' + project.upper() + '_REV',
                                        '"' + rev + '"')
                self._add_define_option('SOURCE_' + project.upper() + '_BASE',
                                        '"' + base + '"')
                self._add_define_option('SOURCE_' + project.upper() +
                                        '_MIRROR', '"' + mirror + '"')
            self.reporter(SourceTreeAddedAsBranchEvent(url))
        for project, branches in repos.iteritems():
            var = 'SOURCE_' + project.upper()
            branchstring = RosePopener.list_to_shell_str(branches)
            self._add_define_option(var, '"' + branchstring + '"')

        # Generate the variable containing tasks to run
        if self.opts.group:
            if not self.opts.defines:
                self.opts.defines = []
            expanded_groups = []
            for i in self.opts.group:
                expanded_groups.extend(i.split(','))
            self.opts.defines.append(SUITE_RC_PREFIX + 'RUN_NAMES=' +
                                     str(expanded_groups))

        # Load the config file and return any automatic-options
        auto_opts = self._read_site_config_and_return_options()
        if auto_opts:
            automatic_options = auto_opts.split()
            for option in automatic_options:
                elements = option.split("=")
                if len(elements) == 2:
                    self._add_define_option(
                        elements[0], '"' + elements[1] + '"')

        # Change into the suite directory
        if self.opts.conf_dir:
            self.reporter(SuiteSelectionEvent(self.opts.conf_dir))
            self._check_suite_version(
                os.path.join(self.opts.conf_dir, 'rose-suite.conf'))
        else:
            thissuite = self._this_suite()
            self.fs_util.chdir(thissuite)
            self.reporter(SuiteSelectionEvent(thissuite))

        # Create a default name for the suite; allow override by user
        if not self.opts.name:
            self.opts.name = self._generate_name()

        return self.opts
Beispiel #18
0
class StemRunner(object):

    """Set up options for running a STEM job through Rose."""

    def __init__(self, opts, reporter=None, popen=None, fs_util=None):
        self.opts = opts
        if reporter is None:
            self.reporter = Reporter(opts.verbosity - opts.quietness)
        else:
            self.reporter = reporter
        if popen is None:
            self.popen = RosePopener(event_handler = self.reporter)
        else:
            self.popen = popen
        if fs_util is None:
            self.fs_util = FileSystemUtil(event_handler = self.reporter)
        else:
            self.fs_util = fs_util

    def _add_define_option(self, var, val):
        """Add a define option passed to the SuiteRunner."""

        if self.opts.defines:
            self.opts.defines.append(SUITE_RC_PREFIX + var + '=' + val )
        else:
            self.opts.defines= [ SUITE_RC_PREFIX + var + '=' + val ]
        self.reporter(ConfigVariableSetEvent(var, val))
        return

    def _ascertain_project(self, item):
        """Set the project name and top-level from 'fcm loc-layout'"""

        project = ''
        if re.search(r'^\.', item):
            item = os.path.abspath(os.path.join(os.getcwd(), item))
        result = re.search(r'\[(\w+)\]', item)
        if result:
            project = result.group(1)
            item = re.sub(r'\[\w+\]', r'', item)
            return project, item

        rc, output, stderr = self.popen.run('fcm', 'loc-layout', item)
        if rc != 0:
            raise ProjectNotFoundException(item, stderr)
        result = re.search(r'url:\s*(file|svn|https|http|svn\+ssh)(://.*)',
                           output)

        # Generate a unique name for this project based on fcm kp
        if result:
            urlstring = result.group(1) + result.group(2)
            rc, kpoutput, stderr = self.popen.run('fcm', 'kp', urlstring)
            kpresult = re.search(r'location{primary}\[(.*)\]\s*=', kpoutput)
            if kpresult:
                project = kpresult.group(1)
        if not project:
            raise ProjectNotFoundException(item)

        result = re.search(r'peg_rev:\s*(.*)', output)
        if '@' in item and result:
            revision = '@' + result.group(1)
            base = re.sub(r'@.*', r'', item)
        else:
            revision = ''
            base = item

        # If we're in a subdirectory of the source tree, find it and
        # remove it leaving the top-level location
        result = re.search(r'target:\s*(.*)', output)
        target=''
        if result:
            target = result.group(1)
            subtree=''
            result2 = re.search(r'sub_tree:\s*(.*)', output)
            if result2:
                subtree = result2.group(1)
                item = re.sub(subtree, r'', target)

        # Remove trailing forwards-slash
        item = re.sub(r'/$',r'',item)
        return project, item, base, revision

    def _generate_name(self):
        """Generate a suite name from the name of the first source tree."""
        dummy, basedir, dummy2, dummy3 = self._ascertain_project(os.getcwd())
        name = os.path.basename(basedir)
        return name

    def _this_suite(self):
        """Find the location of the suite in the first source tree."""

        # Get base of first source
        basedir = ''
        if self.opts.source:
            basedir = self.opts.source[0]
        else:
            dummy, basedir, dum2, dum3 = self._ascertain_project(os.getcwd())

        suitedir = os.path.join(basedir, DEFAULT_TEST_DIR)
        suitefile = os.path.join(suitedir, "rose-suite.conf")

        if not os.path.isfile(suitefile):
            raise RoseSuiteConfNotFoundException(suitedir)
        return suitedir

    def process(self):
        """Process STEM options into 'rose suite-run' options."""

        # Generate options for source trees
        repos = {}
        if not self.opts.source:
            self.opts.source = ['.']
        self.opts.project = list()

        for i, url in enumerate(self.opts.source):
            project, url, base, rev = self._ascertain_project(url)
            self.opts.source[i] = url
            self.opts.project.append(project)
            if project in repos:
                repos[project].append(url)
            else:
                repos[project] = [ url ]
                self._add_define_option('SOURCE_' + project.upper() + '_REV', 
                                        '"' + rev + '"')
                self._add_define_option('SOURCE_' + project.upper() + '_BASE', 
                                        '"' + base + '"')
            self.reporter(SourceTreeAddedAsBranchEvent(url))
        for project, branches in repos.iteritems():
            var = 'SOURCE_' + project.upper()
            branchstring = RosePopener.list_to_shell_str(branches)
            self._add_define_option(var, '"' + branchstring + '"')

        # Generate the variable containing tasks to run
        if self.opts.group:
            if not self.opts.defines:
                self.opts.defines = []
            self.opts.defines.append(SUITE_RC_PREFIX + 'RUN_NAMES=' +
                                     str(self.opts.group))

        # Change into the suite directory
        if self.opts.conf_dir:
            self.fs_util.chdir(self.opts.conf_dir)
            self.reporter(SuiteSelectionEvent(self.opts.conf_dir))
        else:
            thissuite = self._this_suite()
            self.fs_util.chdir(thissuite)
            self.opts.conf_dir = thissuite
            self.reporter(SuiteSelectionEvent(thissuite))

        # Create a default name for the suite; allow override by user
        if not self.opts.name:
            self.opts.name = self._generate_name()

        return self.opts
Beispiel #19
0
class StemRunner(object):
    """Set up options for running a STEM job through Rose."""
    def __init__(self, opts, reporter=None, popen=None, fs_util=None):
        self.opts = opts
        if reporter is None:
            self.reporter = Reporter(opts.verbosity - opts.quietness)
        else:
            self.reporter = reporter
        if popen is None:
            self.popen = RosePopener(event_handler=self.reporter)
        else:
            self.popen = popen
        if fs_util is None:
            self.fs_util = FileSystemUtil(event_handler=self.reporter)
        else:
            self.fs_util = fs_util

    def _add_define_option(self, var, val):
        """Add a define option passed to the SuiteRunner."""

        if self.opts.defines:
            self.opts.defines.append(SUITE_RC_PREFIX + var + '=' + val)
        else:
            self.opts.defines = [SUITE_RC_PREFIX + var + '=' + val]
        self.reporter(ConfigVariableSetEvent(var, val))
        return

    def _get_base_dir(self, item):
        """Given a source tree return the following from 'fcm loc-layout':
           * url
           * sub_tree
           * peg_rev
           * root
           * project
        """

        rc, output, stderr = self.popen.run('fcm', 'loc-layout', item)
        if rc != 0:
            raise ProjectNotFoundException(item, stderr)

        ret = {}
        for line in output.splitlines():
            if not ":" in line:
                continue
            key, value = line.split(":", 1)
            if key:
                if value:
                    ret[key] = value.strip()

        return ret

    def _get_project_from_url(self, source_dict):
        """Run 'fcm keyword-print' to work out the project name."""

        repo = source_dict['root']
        if source_dict['project']:
            repo += '/' + source_dict['project']

        rc, kpoutput, stderr = self.popen.run('fcm', 'kp', source_dict['url'])

        project = None
        for line in kpoutput.splitlines():
            if line.rstrip().endswith(repo):
                kpresult = re.search(r'^location{primary}\[(.*)\]', line)
                if kpresult:
                    project = kpresult.group(1)
                    break
        return project

    def _deduce_mirror(self, source_dict, project):
        """Deduce the mirror location of this source tree."""

        # Root location for project
        proj_root = source_dict['root'] + '/' + source_dict['project']

        # Swap project to mirror
        project = re.sub(r'\.x$', r'.xm', project)
        mirror_repo = "fcm:" + project

        # Generate mirror location
        mirror = re.sub(proj_root, mirror_repo, source_dict['url'])

        # Add forwards slash after .xm if missing
        if '.xm/' not in mirror:
            mirror = re.sub(r'\.xm', r'.xm/', mirror)
        return mirror

    def _ascertain_project(self, item):
        """Set the project name and top-level from 'fcm loc-layout'.
        Returns:
            * project name
            * top-level location of the source tree with revision number
            * top-level location of the source tree without revision number
            * revision number
        """

        project = ''
        if re.search(r'^\.', item):
            item = os.path.abspath(os.path.join(os.getcwd(), item))

        source_dict = self._get_base_dir(item)
        project = self._get_project_from_url(source_dict)
        mirror = self._deduce_mirror(source_dict, project)

        if not project:
            raise ProjectNotFoundException(item)

        if 'peg_rev' in source_dict and '@' in item:
            revision = '@' + source_dict['peg_rev']
            base = re.sub(r'@.*', r'', item)
        else:
            revision = ''
            base = item

        # Remove subtree from base and item
        if 'sub_tree' in source_dict:
            item = re.sub(r'(.*)%s/?$' % (source_dict['sub_tree']),
                          r'\1',
                          item,
                          count=1)
            base = re.sub(r'(.*)%s/?$' % (source_dict['sub_tree']),
                          r'\1',
                          base,
                          count=1)

        # Remove trailing forwards-slash
        item = re.sub(r'/$', r'', item)
        base = re.sub(r'/$', r'', base)

        # Remove anything after a point
        project = re.sub(r'\..*', r'', project)
        return project, item, base, revision, mirror

    def _generate_name(self):
        """Generate a suite name from the name of the first source tree."""
        try:
            basedir = self._ascertain_project(os.getcwd())[1]
        except ProjectNotFoundException:
            if self.opts.conf_dir:
                basedir = os.path.abspath(self.opts.conf_dir)
            else:
                basedir = os.getcwd()
        name = os.path.basename(basedir)
        self.reporter(NameSetEvent(name))
        return name

    def _this_suite(self):
        """Find the location of the suite in the first source tree."""

        # Get base of first source
        basedir = ''
        if self.opts.source:
            basedir = self.opts.source[0]
        else:
            basedir = self._ascertain_project(os.getcwd())[1]

        suitedir = os.path.join(basedir, DEFAULT_TEST_DIR)
        suitefile = os.path.join(suitedir, "rose-suite.conf")

        if not os.path.isfile(suitefile):
            raise RoseSuiteConfNotFoundException(suitedir)

        self._check_suite_version(suitefile)

        return suitedir

    def _read_site_config_and_return_options(self):
        """Read the site rose.conf file."""
        return ResourceLocator.default().get_conf().get_value(
            ["rose-stem", "automatic-options"])

    def _check_suite_version(self, fname):
        """Check the suite is compatible with this version of rose-stem."""
        if not os.path.isfile(fname):
            raise RoseSuiteConfNotFoundException(os.path.dirname(fname))
        config = rose.config.load(fname)
        suite_rose_stem_version = config.get(['ROSE_STEM_VERSION'])
        if suite_rose_stem_version:
            suite_rose_stem_version = int(suite_rose_stem_version.value)
        else:
            suite_rose_stem_version = None
        if not suite_rose_stem_version == ROSE_STEM_VERSION:
            raise RoseStemVersionException(suite_rose_stem_version)

    def process(self):
        """Process STEM options into 'rose suite-run' options."""

        # Generate options for source trees
        repos = {}
        if not self.opts.source:
            self.opts.source = ['.']
        self.opts.project = list()

        for i, url in enumerate(self.opts.source):
            project, url, base, rev, mirror = self._ascertain_project(url)
            self.opts.source[i] = url
            self.opts.project.append(project)
            if project in repos:
                repos[project].append(url)
            else:
                repos[project] = [url]
                self._add_define_option('SOURCE_' + project.upper() + '_REV',
                                        '"' + rev + '"')
                self._add_define_option('SOURCE_' + project.upper() + '_BASE',
                                        '"' + base + '"')
                self._add_define_option(
                    'SOURCE_' + project.upper() + '_MIRROR',
                    '"' + mirror + '"')
            self.reporter(SourceTreeAddedAsBranchEvent(url))
        for project, branches in repos.iteritems():
            var = 'SOURCE_' + project.upper()
            branchstring = RosePopener.list_to_shell_str(branches)
            self._add_define_option(var, '"' + branchstring + '"')

        # Generate the variable containing tasks to run
        if self.opts.group:
            if not self.opts.defines:
                self.opts.defines = []
            expanded_groups = []
            for i in self.opts.group:
                expanded_groups.extend(i.split(','))
            self.opts.defines.append(SUITE_RC_PREFIX + 'RUN_NAMES=' +
                                     str(expanded_groups))

        # Load the config file and return any automatic-options
        auto_opts = self._read_site_config_and_return_options()
        if auto_opts:
            automatic_options = auto_opts.split()
            for option in automatic_options:
                elements = option.split("=")
                if len(elements) == 2:
                    self._add_define_option(elements[0],
                                            '"' + elements[1] + '"')

        # Change into the suite directory
        if self.opts.conf_dir:
            self.reporter(SuiteSelectionEvent(self.opts.conf_dir))
            self._check_suite_version(
                os.path.join(self.opts.conf_dir, 'rose-suite.conf'))
        else:
            thissuite = self._this_suite()
            self.fs_util.chdir(thissuite)
            self.reporter(SuiteSelectionEvent(thissuite))

        # Create a default name for the suite; allow override by user
        if not self.opts.name:
            self.opts.name = self._generate_name()

        return self.opts