Пример #1
0
def test_columns_with_dbcols():
    model_str = """
    model test
    constraint dbcols applies to attr
    entity First {
        a: Second: dbcols(trt, vrt)
    }

    entity Second {
        #b: Third
    }

    entity Third {

        #c: int
        #d: string(10)
    }

    """

    mm = get_language('er')
    model = mm.model_from_str(model_str)

    ent = model.elements[0]
    attr = ent.attributes[0]
    cols = columns(ent, attr)
    assert len(cols) == 2
    assert cols[0].name == 'trt'
    assert cols[1].name == 'vrt'
Пример #2
0
def test_columns_without_dbcols():
    model_str = """
    model test
    entity First {
        a: Second
    }

    entity Second {
        #b: Third
    }

    entity Third {

        #c: int
        #d: string(10)
    }

    """

    mm = get_language('er')
    model = mm.model_from_str(model_str)

    ent = model.elements[0]
    attr = ent.attributes[0]
    cols = columns(ent, attr)
    assert len(cols) == 2
    assert cols[0].name == 'c'
    assert cols[1].name == 'd'
Пример #3
0
def genconf_model():
    """
    Returns genconf model for 'er_flask' generator and 'er'
    language.
    """
    gc_meta = get_language("genconf")
    curr_dir = os.path.dirname(__file__)
    gc_model = gc_meta.model_from_file(
        os.path.join(curr_dir, 'er_flask.genconf'))

    return gc_model
Пример #4
0
def genconf_model():
    """
    Returns genconf model for '{{package_name}}' generator and '{{language}}'
    language.
    """
    gc_meta = get_language("genconf")
    curr_dir = os.path.dirname(__file__)
    gc_model = gc_meta.model_from_file(
        os.path.join(curr_dir, '{{package_name}}.genconf'))

    # Check parameters
    for p in gc_model.params:
        if p.name not in PARAM_NAMES:
            raise TextXToolsException(
                'Undefined generator parameter "{}".'.format(p.name))
Пример #5
0
def check(language, model_file, debug):
    """
    Checks (meta)model syntax validity.
    """
    try:
        if language == 'textx':
            click.echo('Checking model using language "textx".')
            metamodel_from_file(model_file, debug=debug)
            click.echo('Meta-model OK.')
        else:
            mm = get_language(language)
            click.echo('Checking model using language "{}".'.format(language))
            mm.model_from_file(model_file, debug=debug)
            click.echo('Model OK.')
    except TextXError as e:
        click.echo(e)
Пример #6
0
def vis(model_file, language, debug):
    """
    Visualize (meta)model using dot.
    """
    try:
        if language == 'textx':
            mm = metamodel_from_file(model_file, debug=debug)
            click.echo("Generating '%s.dot' file for meta-model." % model_file)
            click.echo("To convert to PDF run 'dot -Tpdf -O %s.dot'"
                       % model_file)
            metamodel_export(mm, "%s.dot" % model_file)
        else:
            mm = get_language(language)
            model = mm.model_from_file(model_file, debug=debug)
            click.echo("Generating '%s.dot' file for model." % model_file)
            click.echo("To convert to PDF run 'dot -Tpdf -O %s.dot'"
                       % model_file)
            model_export(model, "%s.dot" % model_file)
    except TextXError as e:
        click.echo(e)
Пример #7
0
def generate(genconf_model, project_folder):
    """
    Interprets genconf model and generates code using rules from the genconf
    model.

    Args:
        genconf_model (genconf textX model):
        project_folder (str):
    """

    gendesc = get_generator_desc(genconf_model.gen_name)
    meta = get_language(gendesc.lang)

    # Path for templates overrides
    templates_path = os.path.join(project_folder, 'templates',
                                  genconf_model.gen_name)

    output_root = os.path.join(project_folder, genconf_model.output)

    def _create_folder(output_file):
        try:
            os.makedirs(os.path.dirname(output_file))
        except FileExistsError:
            pass

    # For each model configured in the current genconf
    for model_path in genconf_model.models:

        click.echo('Processing model "{}"'.format(model_path))
        model = meta.model_from_file(
            os.path.join(project_folder, 'model', model_path))

        # Validate model using generator specific validation.
        if gendesc.validate:
            gendesc.validate(model)

        params = {}
        # Adding generator params
        for p in genconf_model.params:
            params[p.name] = p.value

        # Processing all rules
        for rule in genconf_model.rules:

            # Sanity check
            if len(rule.types) != len(rule.var_names):
                raise TextXToolsError('Number of variables don\'t match'
                                      ' number of types in rule "{}"'.format(
                                          rule.name))

            # Collect all object of each given type
            type_objs = []
            for t in rule.types:
                type_objs.append(children_of_type(model, t))

            if rule.all:
                context = {'__builtins__': {}}
                for ind, obj in enumerate(type_objs):
                    params[rule.var_names[ind]] = obj
                context.update(params)
                for t in rule.trans:
                    target_path = eval(t.python_path_expr, context)
                    output_file = os.path.join(output_root, target_path)

                    click.echo("Generating {}".format(output_file))

                    _create_folder(output_file)
                    with open(output_file, 'w') as f:
                        f.write(
                            gendesc.render(t.template_path, params,
                                           templates_path))
            else:
                if len(rule.types) > 1:
                    raise TextXToolsError('Multiple types/variables are not'
                                          ' possible for "non-all" rules.')
                for obj in type_objs[0]:
                    params[rule.var_names[0]] = obj
                    context = {'__builtins__': {}}
                    context.update(params)
                    for t in rule.trans:
                        target_path = eval(t.python_path_expr, context)
                        output_file = os.path.join(output_root, target_path)
                        click.echo("Generating {}".format(output_file))
                        _create_folder(output_file)

                        with open(output_file, 'w') as f:
                            f.write(
                                gendesc.render(t.template_path, params,
                                               templates_path))
Пример #8
0
def startproject(project_type, language, project_name):
    """
    Generates scaffolding for textX projects.
    """
    if project_type == 'gen':
        if not language:
            click.echo('Language must be specified for generator'
                       ' projects. See -l switch.')
            sys.exit(1)
        else:
            try:
                get_language(language)
            except TextXError as e:
                click.echo(e)
                click.echo('There was an error loading language "{}".'.format(
                    language))
                click.echo('Is it installed? Try to install it '
                           'with "pip install textx-lang-{}"'.format(language))
                click.echo('Use "textx list-langs" to see all registered '
                           'languages.')
                sys.exit(1)

    if not _check_project_name(project_name):
        click.echo('Project name may contain letters, digits and dashes.')
        sys.exit(1)

    if project_type == 'lang':
        package_name = _project_name_to_package_name(project_name)
        full_project_name = 'textx-{}-{}'.format(project_type, project_name)
    elif project_type == 'gen':
        package_name = "{}_{}".format(
            language, _project_name_to_package_name(project_name))
        full_project_name = 'textx-{}-{}-{}'.format(project_type, language,
                                                    project_name)
    else:
        package_name = _project_name_to_package_name(project_name)
        full_project_name = project_name

    project_type_full = {
        'lang': 'language',
        'gen': 'generator'
    }.get(project_type, project_type)

    click.echo('Generating {} project "{}" in folder "{}".'.format(
        project_type_full, project_name, full_project_name))

    context = {
        'project_name': project_name,
        'full_project_name': full_project_name,
        'package_name': package_name,
        'project_type': project_type,
        'language': language
    }

    try:
        _generate_project(context)
    except TextXToolsError as e:
        click.echo(e)
        sys.exit(1)

    click.echo('Done.')