Example #1
0
def test_file_without_any_language():
    """
    Test that asking for a language for a file or file pattern for which
    no languages are registered will raise an error.
    """

    with pytest.raises(TextXRegistrationError,
                       match='No language registered that can parse.*'):
        language_for_file('Somefile.nolang')
Example #2
0
def test_language_for_file():
    """
    Test providing language description for a given file name or pattern.
    """

    clear_language_registrations()
    tx_lang = language_description('textx')

    assert tx_lang is language_for_file('test.tx')
    assert tx_lang is language_for_file('*.tx')
Example #3
0
def test_multiple_languages_for_the_same_pattern():
    """
    If multiple languages are registered for the same file pattern
    `language_for_file` shall raise `TextXRegistrationError`.
    """
    clear_language_registrations()
    register_language('test-lang',
                      pattern='*.test',
                      description='test-lang description',
                      metamodel=mymetamodel_callable)
    register_language('test-lang2',
                      pattern='*.test',
                      description='test-lang2 description',
                      metamodel=mymetamodel_callable)

    with pytest.raises(TextXRegistrationError,
                       match='Multiple languages can parse.*'):
        language_for_file('Somefile.test')

    assert len(languages_for_file('Somefile.test')) == 2
Example #4
0
    def generate(ctx,
                 model_files,
                 output_path,
                 language,
                 target,
                 overwrite,
                 grammar=None,
                 ignore_case=False):
        """
        Run code generator on a provided model(s).

        For example::

        \b
        # Generate PlantUML output from .flow models
        textx generate mymodel.flow --target PlantUML

        \b
        # or with defined output folder
        textx generate mymodel.flow -o rendered_model/ --target PlantUML

        \b
        # To chose language by name and not by file pattern use --language
        textx generate *.flow --language flow --target PlantUML

        \b
        # Use --overwrite to overwrite target files
        textx generate mymodel.flow --target PlantUML --overwrite

        \b
        # In all above cases PlantUML generator must be registered, i.e.:
        $ textx list-generators
        flow-dsl -> PlantUML  Generating PlantUML visualization from flow-dsl

        \b
        # If the source language is not registered you can use the .tx grammar
        # file for parsing but the language name used will be `any`.
        textx generate --grammar Flow.tx --target dot mymodel.flow


        """

        debug = ctx.obj['debug']
        click.echo('Generating {} target from models:'.format(target))

        try:
            per_file_metamodel = False
            if grammar:
                metamodel = metamodel_from_file(grammar,
                                                debug=debug,
                                                ignore_case=ignore_case)
                language = 'any'
            elif language:
                metamodel = metamodel_for_language(language)
            else:
                per_file_metamodel = True

            # Find all custom arguments
            model_files = list(model_files)
            model_files_without_args = []
            custom_args = {}
            while model_files:
                m = model_files.pop(0)
                if m.startswith('--'):
                    arg_name = m[2:]
                    if not model_files or model_files[0].startswith('--'):
                        # Boolean argument
                        custom_args[arg_name] = True
                    else:
                        custom_args[arg_name] = model_files.pop(0).strip('"\'')
                else:
                    model_files_without_args.append(m)

            # Call generator for each model file
            for model_file in model_files_without_args:

                click.echo(os.path.abspath(model_file))

                if per_file_metamodel:
                    language = language_for_file(model_file).name
                    metamodel = metamodel_for_file(model_file)

                # Get custom args that match defined model parameters and pass
                # them in to be available to model processors.
                model_params = {
                    k: v
                    for k, v in custom_args.items()
                    if k in metamodel.model_param_defs
                }

                model = metamodel.model_from_file(model_file, **model_params)
                generator = generator_for_language_target(
                    language, target, any_permitted=per_file_metamodel)

                generator(metamodel, model, output_path, overwrite, debug,
                          **custom_args)

        except TextXRegistrationError as e:
            raise click.ClickException(e.message)

        except TextXError as e:
            raise click.ClickException(str(e))
Example #5
0
    def generate(ctx, model_files, output_path, language, target, overwrite,
                 grammar=None, ignore_case=False):
        """
        Run code generator on a provided model(s).

        For example::

        \b
        # Generate PlantUML output from .flow models
        textx generate mymodel.flow --target PlantUML

        \b
        # or with defined output folder
        textx generate mymodel.flow -o rendered_model/ --target PlantUML

        \b
        # To chose language by name and not by file pattern use --language
        textx generate *.flow --language flow --target PlantUML

        \b
        # Use --overwrite to overwrite target files
        textx generate mymodel.flow --target PlantUML --overwrite

        \b
        # In all above cases PlantUML generator must be registered, i.e.:
        $ textx list-generators
        flow-dsl -> PlantUML  Generating PlantUML visualization from flow-dsl

        \b
        # If the source language is not registered you can use the .tx grammar
        # file for parsing but the language name used will be `any`.
        textx generate --grammar Flow.tx --target dot mymodel.flow


        """

        debug = ctx.obj['debug']
        click.echo('Generating {} target from models:'.format(target))

        try:
            per_file_metamodel = False
            if grammar:
                metamodel = metamodel_from_file(grammar, debug=debug,
                                                ignore_case=ignore_case)
                language = 'any'
            elif language:
                metamodel = metamodel_for_language(language)
            else:
                per_file_metamodel = True

            # Find all custom arguments
            model_files = list(model_files)
            model_files_without_args = []
            custom_args = {}
            while model_files:
                m = model_files.pop(0)
                if m.startswith('--'):
                    custom_args[m[2:]] = model_files.pop(0).strip('"\'')
                else:
                    model_files_without_args.append(m)

            # Call generator for each model file
            for model_file in model_files_without_args:

                click.echo(os.path.abspath(model_file))

                if per_file_metamodel:
                    language = language_for_file(model_file).name
                    metamodel = metamodel_for_file(model_file)
                model = metamodel.model_from_file(model_file)
                generator = generator_for_language_target(
                    language, target, any_permitted=per_file_metamodel)

                generator(metamodel, model, output_path, overwrite, debug,
                          **custom_args)

        except TextXRegistrationError as e:
            click.echo(e.message)

        except TextXError as e:
            click.echo(e)