def _launch(name, event_handler=None, run_fg=False, *args, **kwargs): popen = RosePopener(event_handler) command = popen.get_cmd(name, *args) kwargs['stdin'] = sys.stdin if run_fg: return popen.run(*command, **kwargs) popen.run_bg(*command, **kwargs)
def write_source_vc_info(run_source_dir, output=None, popen=None): """Write version control information of sources used in run time. run_source_dir -- The source directory we are interested in. output -- An open file handle or a string containing a writable path. If not specified, use sys.stdout. popen -- A rose.popen.RosePopener instance for running vc commands. If not specified, use a new local instance. """ if popen is None: popen = RosePopener() if output is None: handle = sys.stdout elif hasattr(output, "write"): handle = output else: handle = open(output, "wb") msg = "%s\n" % run_source_dir _write_safely(msg, handle) environ = dict(os.environ) environ["LANG"] = "C" for vcs, args_list in [ ("svn", [ ["info", "--non-interactive"], ["status", "--non-interactive"], ["diff", "--internal-diff", "--non-interactive"]]), ("git", [["describe"], ["status"], ["diff"]])]: if not popen.which(vcs): continue cwd = os.getcwd() os.chdir(run_source_dir) try: for args in args_list: cmd = [vcs] + args ret_code, out, _ = popen.run(*cmd, env=environ) if out: _write_safely(("#" * 80 + "\n"), handle) _write_safely(("# %s\n" % popen.list_to_shell_str(cmd)), handle) _write_safely(("#" * 80 + "\n"), handle) _write_safely(out, handle) if ret_code: # If cmd fails once, it will likely fail again break finally: os.chdir(cwd)
def write_source_vc_info(run_source_dir, output=None, popen=None): """Write version control information of sources used in run time. run_source_dir -- The source directory we are interested in. output -- An open file handle or a string containing a writable path. If not specified, use sys.stdout. popen -- A rose.popen.RosePopener instance for running vc commands. If not specified, use a new local instance. """ if popen is None: popen = RosePopener() if output is None: handle = sys.stdout elif hasattr(output, "write"): handle = output else: handle = open(output, "wb") handle.write("%s\n" % run_source_dir) environ = dict(os.environ) environ["LANG"] = "C" for vcs, args_list in [ ("svn", [ ["info", "--non-interactive"], ["status", "--non-interactive"], ["diff", "--internal-diff", "--non-interactive"]]), ("git", [["describe"], ["status"], ["diff"]])]: if not popen.which(vcs): continue cwd = os.getcwd() os.chdir(run_source_dir) try: for args in args_list: cmd = [vcs] + args ret_code, out, _ = popen.run(*cmd, env=environ) if out: handle.write("#" * 80 + "\n") handle.write(("# %s\n" % popen.list_to_shell_str(cmd))) handle.write("#" * 80 + "\n") handle.write(out) if ret_code: # If cmd fails once, it will likely fail again break finally: os.chdir(cwd)
def write_source_vc_info(run_source_dir, output=None, popen=None): """Write version control information of sources used in run time. run_source_dir -- The source directory we are interested in. output -- An open file handle or a string containing a writable path. If not specified, use sys.stdout. popen -- A rose.popen.RosePopener instance for running vc commands. If not specified, use a new local instance. """ if popen is None: popen = RosePopener() if output is None: handle = sys.stdout elif hasattr(output, "write"): handle = output else: handle = open(output, "wb") environ = dict(os.environ) environ["LANG"] = "C" for vcs, cmds in [("svn", ["info", "status", "diff"]), ("git", ["describe", "status", "diff"])]: if not popen.which(vcs): continue cwd = os.getcwd() os.chdir(run_source_dir) try: for cmd in cmds: rc, out, err = popen.run(vcs, cmd, env=environ) if out: handle.write("#" * 80 + "\n") handle.write(("# %s %s\n" % (vcs, cmd)).upper()) handle.write("#" * 80 + "\n") handle.write(out) if rc: # If cmd fails once, chances are, it will fail again break finally: os.chdir(cwd)
def write_source_vc_info(run_source_dir, output=None, popen=None): """Write version control information of sources used in run time. run_source_dir -- The source directory we are interested in. output -- An open file handle or a string containing a writable path. If not specified, use sys.stdout. popen -- A rose.popen.RosePopener instance for running vc commands. If not specified, use a new local instance. """ if popen is None: popen = RosePopener() if output is None: handle = sys.stdout elif hasattr(output, "write"): handle = output else: handle = open(output, "wb") for vcs, cmds in [("svn", ["info", "status", "diff"]), ("git", ["describe", "status", "diff"])]: if not popen.which(vcs): continue cwd = os.getcwd() os.chdir(run_source_dir) try: for cmd in cmds: rc, out, err = popen.run(vcs, cmd) if out: handle.write("#" * 80 + "\n") handle.write(("# %s %s\n" % (vcs, cmd)).upper()) handle.write("#" * 80 + "\n") handle.write(out) if rc: # If cmd fails once, chances are, it will fail again break finally: os.chdir(cwd)
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 _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
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 _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