def test_create_from_template(local_client):
    """Test repository creation from a template.

    It creates a renku projects from one of the local templates and it verifies
    the data are properly copied to the new renku project folder.
    """
    with TemporaryDirectory() as tempdir:
        temppath = Path(tempdir) / 'local'
        shutil.copytree(str(template_local), str(temppath))
        manifest = read_template_manifest(temppath)
        template_path = temppath / manifest[0]['folder']
        create_from_template(
            template_path, local_client, METADATA['name'],
            METADATA['description']
        )
        template_files = [
            f
            for f in local_client.path.glob('**/*') if '.git' not in str(f) and
            not str(f).endswith('.renku/metadata.yml')
        ]
        for template_file in template_files:
            expected_file = template_path / template_file.relative_to(
                local_client.path
            )
            assert expected_file.exists()
Beispiel #2
0
def test_template_filename(local_client):
    """Test using a template with dynamic filenames.
    """
    with TemporaryDirectory() as tempdir:
        template_folder = Path(tempdir) / "first"

        template_folder.mkdir(parents=True)

        template_file = template_folder / "{{ name }}.r"
        template_file.write_text("{{ name }}")

        (local_client.path / ".renku").mkdir()

        create_from_template(template_folder, local_client, name="test")

        assert (local_client.path / "test.r").exists()
Beispiel #3
0
def test_template_filename(local_client):
    """Test using a template with dynamic filenames.
    """
    with TemporaryDirectory() as tempdir:
        template_folder = Path(tempdir) / 'first'

        template_folder.mkdir(parents=True)

        template_file = template_folder / '{{ name }}.r'
        template_file.write_text('{{ name }}')

        (local_client.path / '.renku').mkdir()

        create_from_template(template_folder, local_client, name='test')

        assert (local_client.path / 'test.r').exists()
Beispiel #4
0
def test_create_from_template(local_client, template):
    """Test repository creation from a template.

    It creates a renku projects from one of the local templates and it verifies
    the data are properly copied to the new renku project folder.
    """
    with TemporaryDirectory() as tempdir:
        temppath = Path(tempdir) / "local"
        shutil.copytree(str(template_local), str(temppath))
        manifest = read_template_manifest(temppath)
        template_path = temppath / manifest[0]["folder"]
        create_from_template(template_path, local_client, "name",
                             template["metadata"])
        template_files = [
            f for f in local_client.path.glob("**/*") if ".git" not in str(f)
            and not str(f).endswith(".renku/metadata.yml")
        ]
        for template_file in template_files:
            expected_file = template_path / template_file.relative_to(
                local_client.path)
            assert expected_file.exists()
Beispiel #5
0
def init(ctx, client, use_external_storage, path, name, template,
         template_source, template_ref, template_variables, description,
         print_manifest, force):
    """Initialize a project in PATH. Default is current path."""
    # verify dirty path
    if not is_path_empty(path) and not force and not print_manifest:
        raise errors.InvalidFileOperation(
            'Folder "{0}" is not empty. Please add --force '
            'flag to transform it into a Renku repository.'.format(str(path)))

    if not check_git_user_config():
        raise errors.ConfigurationError(
            'The user name and email are not configured. '
            'Please use the "git config" command to configure them.\n\n'
            '\tgit config --global --add user.name "John Doe"\n'
            '\tgit config --global --add user.email '
            '"*****@*****.**"\n')

    # select template source
    if template_source:
        click.echo('Fetching template from {0}@{1}... '.format(
            template_source, template_ref),
                   nl=False)
        template_folder = Path(mkdtemp())
        fetch_template(template_source, template_ref, template_folder)
        template_manifest = read_template_manifest(template_folder,
                                                   checkout=True)
        click.secho('OK', fg='green')
    else:
        template_folder = Path(
            pkg_resources.resource_filename('renku', 'templates'))
        template_manifest = read_template_manifest(template_folder)

    # select specific template
    repeat = False
    template_data = None
    if template:
        template_filtered = [
            template_elem for template_elem in template_manifest
            if template_elem['name'] == template
        ]
        if len(template_filtered) == 1:
            template_data = template_filtered[0]
        else:
            click.echo('The template "{0}" is not available.'.format(template))
            repeat = True

    if print_manifest:
        if template_data:
            click.echo(create_template_sentence([template_data]))
        else:
            click.echo(create_template_sentence(template_manifest))
        return

    if not template or repeat:
        templates = [template_elem for template_elem in template_manifest]
        if len(templates) == 1:
            template_data = templates[0]
        else:
            template_num = click.prompt(text=create_template_sentence(
                templates, True),
                                        type=click.IntRange(1, len(templates)),
                                        show_default=False,
                                        show_choices=False)
            template_data = templates[template_num - 1]

    # set local path and storage
    store_directory(path)
    if not client.use_external_storage:
        use_external_storage = False
    ctx.obj = client = attr.evolve(client,
                                   path=path,
                                   use_external_storage=use_external_storage)
    if not is_path_empty(path):
        from git import GitCommandError
        try:
            commit = client.find_previous_commit('*')
            branch_name = 'pre_renku_init_{0}'.format(commit.hexsha[:7])
            with client.worktree(path=path,
                                 branch_name=branch_name,
                                 commit=commit,
                                 merge_args=[
                                     '--no-ff', '-s', 'recursive', '-X',
                                     'ours', '--allow-unrelated-histories'
                                 ]):
                click.echo(
                    'Saving current data in branch {0}'.format(branch_name))
        except AttributeError:
            click.echo('Warning! Overwriting non-empty folder.')
        except GitCommandError as e:
            click.UsageError(e)

    # clone the repo
    template_path = template_folder / template_data['folder']
    click.echo('Initializing new Renku repository... ', nl=False)
    with client.lock:
        try:
            create_from_template(template_path, client, name, description,
                                 template_variables, force)
        except FileExistsError as e:
            raise click.UsageError(e)

    # Install git hooks
    from .githooks import install
    ctx.invoke(install, force=force)
Beispiel #6
0
def init(
    ctx,
    client,
    external_storage_requested,
    path,
    name,
    template_id,
    template_index,
    template_source,
    template_ref,
    metadata,
    list_templates,
    force,
    describe,
    data_dir,
):
    """Initialize a project in PATH. Default is the current path."""
    # verify dirty path
    if not is_path_empty(path) and not force and not list_templates:
        existing_paths = [
            str(p.relative_to(path)) for p in Path(path).iterdir()
        ]
        existing_paths.sort()
        raise errors.InvalidFileOperation(
            f'Folder "{str(path)}" is not empty and contains the following files/directories:'
            + "".join((f"\n\t{e}" for e in existing_paths)) +
            "\nPlease add --force flag to transform it into a Renku repository."
        )

    data_dir = resolve_data_directory(data_dir, path)

    if not check_git_user_config():
        raise errors.ConfigurationError(
            "The user name and email are not configured. "
            'Please use the "git config" command to configure them.\n\n'
            '\tgit config --global --add user.name "John Doe"\n'
            "\tgit config --global --add user.email "
            '"*****@*****.**"\n')

    # select template source
    if template_source:
        click.echo("Fetching template from {0}@{1}... ".format(
            template_source, template_ref),
                   nl=False)
        template_folder = Path(mkdtemp())
        fetch_template(template_source, template_ref, template_folder)
        template_manifest = read_template_manifest(template_folder,
                                                   checkout=True)
        click.secho("OK", fg="green")
    else:
        template_folder = Path(
            pkg_resources.resource_filename("renku", "templates"))
        template_manifest = read_template_manifest(template_folder)
        template_source = "renku"

    # select specific template
    repeat = False
    template_data = None
    if template_id:
        if template_index:
            raise errors.ParameterError(
                "Use either --template-id or --template-index, not both",
                '"--template-index"')
        template_filtered = [
            template_elem for template_elem in template_manifest
            if template_elem["folder"] == template_id
        ]
        if len(template_filtered) == 1:
            template_data = template_filtered[0]
        else:
            click.echo(
                f'The template with id "{template_id}" is not available.')
            repeat = True

    if template_index or template_index == 0:
        if template_index > 0 and template_index <= len(template_manifest):
            template_data = template_manifest[template_index - 1]
        else:
            click.echo(
                f"The template at index {template_index} is not available.")
            repeat = True

    if list_templates:
        if template_data:
            click.echo(
                create_template_sentence([template_data], describe=describe))
        else:
            click.echo(
                create_template_sentence(template_manifest, describe=describe))
        return

    if repeat or not (template_id or template_index):
        templates = [template_elem for template_elem in template_manifest]
        if len(templates) == 1:
            template_data = templates[0]
        else:
            template_index = click.prompt(
                text=create_template_sentence(templates,
                                              describe=describe,
                                              instructions=True),
                type=click.IntRange(1, len(templates)),
                show_default=False,
                show_choices=False,
            )
            template_data = templates[template_index - 1]

        template_id = template_data["folder"]

    # verify variables have been passed
    template_variables = template_data.get("variables", {})
    template_variables_keys = set(template_variables.keys())
    input_parameters_keys = set(metadata.keys())
    for key in template_variables_keys - input_parameters_keys:
        value = click.prompt(
            text=(f'The template requires a value for "{key}" '
                  f"({template_variables[key]})"),
            default="",
            show_default=False,
        )
        metadata[key] = value
    useless_variables = input_parameters_keys - template_variables_keys
    if len(useless_variables) > 0:
        click.echo(INFO +
                   "These parameters are not used by the template and were "
                   "ignored:\n\t{}".format("\n\t".join(useless_variables)))
        for key in useless_variables:
            del metadata[key]

    # set local path and storage
    store_directory(path)
    if not client.external_storage_requested:
        external_storage_requested = False
    ctx.obj = client = attr.evolve(
        client,
        path=path,
        data_dir=data_dir,
        external_storage_requested=external_storage_requested)
    if not is_path_empty(path):
        from git import GitCommandError

        try:
            commit = client.find_previous_commit("*")
            branch_name = "pre_renku_init_{0}".format(commit.hexsha[:7])
            with client.worktree(
                    path=path,
                    branch_name=branch_name,
                    commit=commit,
                    merge_args=[
                        "--no-ff", "-s", "recursive", "-X", "ours",
                        "--allow-unrelated-histories"
                    ],
            ):
                click.echo(
                    "Saving current data in branch {0}".format(branch_name))
        except AttributeError:
            click.echo("Warning! Overwriting non-empty folder.")
        except GitCommandError as e:
            click.UsageError(e)

    # supply additional metadata
    metadata["__template_source__"] = template_source
    metadata["__template_ref__"] = template_ref
    metadata["__template_id__"] = template_id
    metadata["__namespace__"] = ""
    metadata["__sanitized_project_name__"] = ""
    metadata["__repository__"] = ""
    metadata["__project_slug__"] = ""

    # clone the repo
    template_path = template_folder / template_data["folder"]
    click.echo("Initializing new Renku repository... ", nl=False)
    with client.lock:
        try:
            create_from_template(
                template_path=template_path,
                client=client,
                name=name,
                metadata=metadata,
                force=force,
                data_dir=data_dir,
            )
        except FileExistsError as e:
            raise click.UsageError(e)

    # Install git hooks
    from .githooks import install

    ctx.invoke(install, force=force)
Beispiel #7
0
def init(ctx, client, external_storage_requested, path, name, template_id,
         template_index, template_source, template_ref, parameter,
         list_templates, force, describe, data_dir):
    """Initialize a project in PATH. Default is the current path."""
    # verify dirty path
    if not is_path_empty(path) and not force and not list_templates:
        raise errors.InvalidFileOperation(
            'Folder "{0}" is not empty. Please add --force '
            'flag to transform it into a Renku repository.'.format(str(path)))

    data_dir = resolve_data_directory(data_dir, path)

    if not check_git_user_config():
        raise errors.ConfigurationError(
            'The user name and email are not configured. '
            'Please use the "git config" command to configure them.\n\n'
            '\tgit config --global --add user.name "John Doe"\n'
            '\tgit config --global --add user.email '
            '"*****@*****.**"\n')

    # select template source
    if template_source:
        click.echo('Fetching template from {0}@{1}... '.format(
            template_source, template_ref),
                   nl=False)
        template_folder = Path(mkdtemp())
        fetch_template(template_source, template_ref, template_folder)
        template_manifest = read_template_manifest(template_folder,
                                                   checkout=True)
        click.secho('OK', fg='green')
    else:
        template_folder = Path(
            pkg_resources.resource_filename('renku', 'templates'))
        template_manifest = read_template_manifest(template_folder)

    # select specific template
    repeat = False
    template_data = None
    if template_id:
        if template_index:
            raise errors.ParameterError(
                'Use either --template-id or --template-index, not both',
                '"--template-index"')
        template_filtered = [
            template_elem for template_elem in template_manifest
            if template_elem['folder'] == template_id
        ]
        if len(template_filtered) == 1:
            template_data = template_filtered[0]
        else:
            click.echo(
                f'The template with id "{template_id}" is not available.')
            repeat = True

    if template_index or template_index == 0:
        if template_index > 0 and template_index <= len(template_manifest):
            template_data = template_manifest[template_index - 1]
        else:
            click.echo(
                f'The template at index {template_index} is not available.')
            repeat = True

    if list_templates:
        if template_data:
            click.echo(
                create_template_sentence([template_data], describe=describe))
        else:
            click.echo(
                create_template_sentence(template_manifest, describe=describe))
        return

    if repeat or not (template_id or template_index):
        templates = [template_elem for template_elem in template_manifest]
        if len(templates) == 1:
            template_data = templates[0]
        else:
            template_num = click.prompt(text=create_template_sentence(
                templates, describe=describe, instructions=True),
                                        type=click.IntRange(1, len(templates)),
                                        show_default=False,
                                        show_choices=False)
            template_data = templates[template_num - 1]

    # verify variables have been passed
    template_variables = template_data.get('variables', {})
    template_variables_keys = set(template_variables.keys())
    input_parameters_keys = set(parameter.keys())
    for key in (template_variables_keys - input_parameters_keys):
        value = click.prompt(
            text=(f'The template requires a value for "{key}" '
                  f'({template_variables[key]})'),
            default='',
            show_default=False)
        parameter[key] = value
    useless_variables = input_parameters_keys - template_variables_keys
    if (len(useless_variables) > 0):
        click.echo(INFO +
                   'These parameters are not used by the template and were '
                   'ignored:\n\t{}'.format('\n\t'.join(useless_variables)))
        for key in useless_variables:
            del parameter[key]

    # set local path and storage
    store_directory(path)
    if not client.external_storage_requested:
        external_storage_requested = False
    ctx.obj = client = attr.evolve(
        client,
        path=path,
        data_dir=data_dir,
        external_storage_requested=external_storage_requested)
    if not is_path_empty(path):
        from git import GitCommandError
        try:
            commit = client.find_previous_commit('*')
            branch_name = 'pre_renku_init_{0}'.format(commit.hexsha[:7])
            with client.worktree(path=path,
                                 branch_name=branch_name,
                                 commit=commit,
                                 merge_args=[
                                     '--no-ff', '-s', 'recursive', '-X',
                                     'ours', '--allow-unrelated-histories'
                                 ]):
                click.echo(
                    'Saving current data in branch {0}'.format(branch_name))
        except AttributeError:
            click.echo('Warning! Overwriting non-empty folder.')
        except GitCommandError as e:
            click.UsageError(e)

    # clone the repo
    template_path = template_folder / template_data['folder']
    click.echo('Initializing new Renku repository... ', nl=False)
    with client.lock:
        try:
            create_from_template(template_path=template_path,
                                 client=client,
                                 name=name,
                                 metadata=parameter,
                                 force=force,
                                 data_dir=data_dir)
        except FileExistsError as e:
            raise click.UsageError(e)

    # Install git hooks
    from .githooks import install
    ctx.invoke(install, force=force)