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)
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)
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)
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 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
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
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()
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"])
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)
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")
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)
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()
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()
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
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
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
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