示例#1
0
    def test_empysupport_empyprocess(self):
        lines = ["My name is @name", ""]
        variables = {'name': 'Cylc'}
        template_dir = tempfile.gettempdir()

        r = empysupport.empyprocess(lines, template_dir, variables)
        # after this, we would normally have an error in unittest as follows:
        # AttributeError: ProxyFile instance has no attribute 'getvalue'
        # That's due to a Proxy installed by EmPy to replace sys.stdout.
        # We restore the sys.stdout in the end of the tests
        # TODO: is it OK? Does everything else works OK in Jinja after this?
        # Note: writing multiple methods will result in an error too

        self.assertEqual(1, len(r))
        self.assertEqual('My name is Cylc', r[0])
        sys.stdout.getvalue = lambda: ''

        lines = []
        template_dir = tempfile.gettempdir()

        r = empysupport.empyprocess(lines, template_dir)

        self.assertEqual(0, len(r))

        # --- testing fileparse (here due to stdout issue)

        with tempfile.NamedTemporaryFile() as tf:
            fpath = tf.name
            template_vars = {'name': 'Cylc'}
            viewcfg = {
                'empy': True,
                'jinja2': False,
                'contin': False,
                'inline': False
            }
            asedit = None
            tf.write("#!empy\na=@name\n".encode())
            tf.flush()
            r = read_and_proc(fpath=fpath,
                              template_vars=template_vars,
                              viewcfg=viewcfg,
                              asedit=asedit)
            self.assertEqual(['a=Cylc'], r)

            del template_vars['name']

            with self.assertRaises(EmPyError):
                read_and_proc(fpath=fpath,
                              template_vars=template_vars,
                              viewcfg=viewcfg,
                              asedit=asedit)
            sys.stdout.getvalue = lambda: ''

        sys.stdout.getvalue = lambda: ''
示例#2
0
    def test_empysupport_empyprocess(self):
        lines = ["My name is @name", ""]
        variables = {'name': 'Cylc'}
        template_dir = tempfile.gettempdir()

        r = empysupport.empyprocess(lines, template_dir, variables)
        # after this, we would normally have an error in unittest as follows:
        # AttributeError: ProxyFile instance has no attribute 'getvalue'
        # That's due to a Proxy installed by EmPy to replace sys.stdout.
        # We restore the sys.stdout in the end of the tests
        # TODO: is it OK? Does everything else works OK in Jinja after this?
        # Note: writing multiple methods will result in an error too

        self.assertEqual(1, len(r))
        self.assertEqual('My name is Cylc', r[0])
        sys.stdout.getvalue = lambda: ''

        lines = []
        template_dir = tempfile.gettempdir()

        r = empysupport.empyprocess(lines, template_dir)

        self.assertEqual(0, len(r))

        # --- testing fileparse (here due to stdout issue)

        with tempfile.NamedTemporaryFile() as tf:
            fpath = tf.name
            template_vars = {
                'name': 'Cylc'
            }
            viewcfg = {
                'empy': True, 'jinja2': False,
                'contin': False, 'inline': False
            }
            asedit = None
            tf.write("#!empy\na=@name\n".encode())
            tf.flush()
            r = read_and_proc(fpath=fpath, template_vars=template_vars,
                              viewcfg=viewcfg, asedit=asedit)
            self.assertEqual(['a=Cylc'], r)

            del template_vars['name']

            with self.assertRaises(EmPyError):
                read_and_proc(fpath=fpath, template_vars=template_vars,
                              viewcfg=viewcfg, asedit=asedit)
            sys.stdout.getvalue = lambda: ''

        sys.stdout.getvalue = lambda: ''
示例#3
0
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 cylc.flow.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 cylc.flow.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]
示例#4
0
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

    extra_vars = process_plugins(Path(fpath).parent)

    if not template_vars:
        template_vars = {}

    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)

    template_vars['CYLC_VERSION'] = __version__

    # Push template_vars into extra_vars so that duplicates come from
    # template_vars.
    if extra_vars['templating_detected'] is not None:
        will_be_overwritten = (template_vars.keys()
                               & extra_vars['template_variables'].keys())
        for key in will_be_overwritten:
            LOG.warning(
                f'Overriding {key}: {extra_vars["template_variables"][key]} ->'
                f' {template_vars[key]}')
        extra_vars['template_variables'].update(template_vars)
        template_vars = extra_vars['template_variables']

    template_vars['CYLC_TEMPLATE_VARS'] = template_vars

    # process with EmPy
    if do_empy:
        if (extra_vars['templating_detected'] == 'empy'
                and not re.match(r'^#![Ee]m[Pp]y\s*', flines[0])):
            if not re.match(r'^#!', flines[0]):
                flines.insert(0, '#!empy')
            else:
                raise FileParseError(
                    "Plugins set templating engine = "
                    f"{extra_vars['templating_detected']}"
                    f" which does not match {flines[0]} set in flow.cylc.")
        if flines and re.match(r'^#![Ee]m[Pp]y\s*', flines[0]):
            LOG.debug('Processing with EmPy')
            try:
                from cylc.flow.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 (extra_vars['templating_detected'] == 'jinja2'
                and not re.match(r'^#![jJ]inja2\s*', flines[0])):
            if not re.match(r'^#!', flines[0]):
                flines.insert(0, '#!jinja2')
            else:
                raise FileParseError(
                    "Plugins set templating engine = "
                    f"{extra_vars['templating_detected']}"
                    f" which does not match {flines[0]} set in flow.cylc.")
        if flines and re.match(r'^#![jJ]inja2\s*', flines[0]):
            LOG.debug('Processing with Jinja2')
            try:
                from cylc.flow.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]
示例#5
0
def read_and_proc(fpath, template_vars=None, viewcfg=None, opts=None):
    """
    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).
    workflow_lib_python = os.path.join(fdir, "lib", "python")
    if (
        os.path.isdir(workflow_lib_python)
        and workflow_lib_python not in sys.path
    ):
        sys.path.append(workflow_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

    extra_vars = process_plugins(Path(fpath).parent, opts)

    if not template_vars:
        template_vars = {}

    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, viewcfg=viewcfg)

    template_vars['CYLC_VERSION'] = __version__

    template_vars = merge_template_vars(template_vars, extra_vars)

    template_vars['CYLC_TEMPLATE_VARS'] = template_vars

    # Fail if templating_detected ≠ hashbang
    process_with = hashbang_and_plugin_templating_clash(
        extra_vars['templating_detected'], flines
    )
    # process with EmPy
    if do_empy:
        if (
            extra_vars['templating_detected'] == 'empy' and
            not process_with and
            process_with != 'empy'
        ):
            flines.insert(0, '#!empy')

        if flines and re.match(r'^#![Ee]m[Pp]y\s*', flines[0]):
            LOG.debug('Processing with EmPy')
            try:
                from cylc.flow.parsec.empysupport import empyprocess
            except ImportError:
                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 (
            extra_vars['templating_detected'] == 'jinja2' and
            not process_with and
            process_with != 'jinja2'
        ):
            flines.insert(0, '#!jinja2')

        if flines and re.match(r'^#![jJ]inja2\s*', flines[0]):
            LOG.debug('Processing with Jinja2')
            try:
                from cylc.flow.parsec.jinja2support import jinja2process
            except ImportError:
                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]
示例#6
0
文件: fileparse.py 项目: cylc/cylc
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 cylc.flow.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 cylc.flow.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]