def read_and_proc(fpath, template_vars=[], template_vars_file=None, viewcfg=None, asedit=False): """ Read a cylc parsec config file (at fpath), inline any include files, process with Jinja2, and concatenate continuation lines. Jinja2 processing must be done before concatenation - it could be used to generate continuation lines. """ if not os.path.isfile(fpath): raise FileNotFoundError, 'File not found: ' + fpath fdir = os.path.dirname(fpath) # Allow Python modules in lib/python/ (e.g. for use by Jinja2 filters). suite_lib_python = os.path.join(fdir, "lib", "python") if os.path.isdir(suite_lib_python) and suite_lib_python not in sys.path: sys.path.append(suite_lib_python) if cylc.flags.verbose: print "Reading file", fpath # read the file into a list, stripping newlines with open(fpath) as f: flines = [line.rstrip('\n') for line in f] do_inline = True do_jinja2 = True do_contin = True if viewcfg: if not viewcfg['jinja2']: do_jinja2 = False if not viewcfg['contin']: do_contin = False if not viewcfg['inline']: do_inline = False # inline any cylc include-files if do_inline: try: flines = inline(flines, fdir, fpath, False, viewcfg=viewcfg, for_edit=asedit) except IncludeFileNotFoundError, x: raise FileParseError(str(x))
def read_and_proc( fpath, template_vars=[], template_vars_file=None, viewcfg=None, asedit=False ): """ Read a cylc parsec config file (at fpath), inline any include files, process with Jinja2, and concatenate continuation lines. Jinja2 processing must be done before concatenation - it could be used to generate continuation lines. """ if not os.path.isfile( fpath ): raise FileNotFoundError, 'File not found: ' + fpath fdir = os.path.dirname(fpath) # Allow Python modules in lib/python/ (e.g. for use by Jinja2 filters). suite_lib_python = os.path.join(fdir, "lib", "python") if os.path.isdir(suite_lib_python) and suite_lib_python not in sys.path: sys.path.append(suite_lib_python) if cylc.flags.verbose: print "Reading file", fpath # read the file into a list, stripping newlines with open( fpath ) as f: flines = [ line.rstrip('\n') for line in f ] do_inline = True do_jinja2 = True do_contin = True if viewcfg: if not viewcfg['jinja2']: do_jinja2 = False if not viewcfg['contin']: do_contin = False if not viewcfg['inline']: do_inline = False # inline any cylc include-files if do_inline: try: flines = inline( flines, fdir, fpath, False, viewcfg=viewcfg, for_edit=asedit ) except IncludeFileNotFoundError, x: raise FileParseError( str(x) )
def read_and_proc(fpath, template_vars=None, viewcfg=None, asedit=False): """ Read a cylc parsec config file (at fpath), inline any include files, process with Jinja2, and concatenate continuation lines. Jinja2 processing must be done before concatenation - it could be used to generate continuation lines. """ fdir = os.path.dirname(fpath) # Allow Python modules in lib/python/ (e.g. for use by Jinja2 filters). suite_lib_python = os.path.join(fdir, "lib", "python") if os.path.isdir(suite_lib_python) and suite_lib_python not in sys.path: sys.path.append(suite_lib_python) LOG.debug('Reading file %s', fpath) # read the file into a list, stripping newlines with open(fpath) as f: flines = [line.rstrip('\n') for line in f] do_inline = True do_empy = True do_jinja2 = True do_contin = True if viewcfg: if not viewcfg['empy']: do_empy = False if not viewcfg['jinja2']: do_jinja2 = False if not viewcfg['contin']: do_contin = False if not viewcfg['inline']: do_inline = False # inline any cylc include-files if do_inline: try: flines = inline(flines, fdir, fpath, False, viewcfg=viewcfg, for_edit=asedit) except IncludeFileNotFoundError as exc: raise FileParseError(str(exc)) # process with EmPy if do_empy: if flines and re.match(r'^#![Ee]m[Pp]y\s*', flines[0]): LOG.debug('Processing with EmPy') try: from parsec.empysupport import EmPyError, empyprocess except ImportError: raise ParsecError('EmPy Python package must be installed ' 'to process file: ' + fpath) try: flines = empyprocess(flines, fdir, template_vars) except EmPyError as exc: lines = flines[max(exc.lineno - 4, 0):exc.lineno] msg = traceback.format_exc() raise FileParseError(msg, lines=lines, error_name="EmPyError") # process with Jinja2 if do_jinja2: if flines and re.match(r'^#![jJ]inja2\s*', flines[0]): LOG.debug('Processing with Jinja2') try: flines = jinja2process(flines, fdir, template_vars) except Exception as exc: # Extract diagnostic info from the end of the Jinja2 traceback. exc_lines = traceback.format_exc().splitlines() suffix = [] for line in reversed(exc_lines): suffix.append(line) if re.match(r"\s*File", line): break msg = '\n'.join(reversed(suffix)) lines = None lineno = None if hasattr(exc, 'lineno'): lineno = exc.lineno else: match = re.search(r'File "<template>", line (\d+)', msg) if match: lineno = int(match.groups()[0]) if (lineno and getattr(exc, 'filename', None) is None): # Jinja2 omits the line if it isn't from an external file. line_index = lineno - 1 if getattr(exc, 'source', None) is None: # Jinja2Support strips the shebang line. lines = flines[1:] elif isinstance(exc.source, str): lines = exc.source.splitlines() if lines: min_line_index = max(line_index - 3, 0) lines = lines[min_line_index:line_index + 1] raise FileParseError(msg, lines=lines, error_name="Jinja2Error") # concatenate continuation lines if do_contin: flines = _concatenate(flines) # return rstripped lines return [fl.rstrip() for fl in flines]
def read_and_proc(fpath, template_vars=None, viewcfg=None, asedit=False): """ Read a cylc parsec config file (at fpath), inline any include files, process with Jinja2, and concatenate continuation lines. Jinja2 processing must be done before concatenation - it could be used to generate continuation lines. """ fdir = os.path.dirname(fpath) # Allow Python modules in lib/python/ (e.g. for use by Jinja2 filters). suite_lib_python = os.path.join(fdir, "lib", "python") if os.path.isdir(suite_lib_python) and suite_lib_python not in sys.path: sys.path.append(suite_lib_python) LOG.debug('Reading file %s', fpath) # read the file into a list, stripping newlines with open(fpath) as f: flines = [line.rstrip('\n') for line in f] do_inline = True do_empy = True do_jinja2 = True do_contin = True if viewcfg: if not viewcfg['empy']: do_empy = False if not viewcfg['jinja2']: do_jinja2 = False if not viewcfg['contin']: do_contin = False if not viewcfg['inline']: do_inline = False # inline any cylc include-files if do_inline: flines = inline( flines, fdir, fpath, False, viewcfg=viewcfg, for_edit=asedit) # process with EmPy if do_empy: if flines and re.match(r'^#![Ee]m[Pp]y\s*', flines[0]): LOG.debug('Processing with EmPy') try: from parsec.empysupport import empyprocess except (ImportError, ModuleNotFoundError): raise ParsecError('EmPy Python package must be installed ' 'to process file: ' + fpath) flines = empyprocess(flines, fdir, template_vars) # process with Jinja2 if do_jinja2: if flines and re.match(r'^#![jJ]inja2\s*', flines[0]): LOG.debug('Processing with Jinja2') try: from parsec.jinja2support import jinja2process except (ImportError, ModuleNotFoundError): raise ParsecError('Jinja2 Python package must be installed ' 'to process file: ' + fpath) flines = jinja2process(flines, fdir, template_vars) # concatenate continuation lines if do_contin: flines = _concatenate(flines) # return rstripped lines return [fl.rstrip() for fl in flines]