示例#1
0
def test_fetch_template_and_read_manifest():
    """Test template fetch and manifest reading.

    It fetches a local template, reads the manifest, checkouts the
    template folders and verify they exist.
    """
    with TemporaryDirectory() as tempdir:
        template_path = Path(tempdir)
        fetch_template(TEMPLATE_URL, TEMPLATE_REF, template_path)
        manifest = read_template_manifest(template_path, checkout=True)
        for template in manifest:
            template_folder = template_path / template['folder']
            assert template_folder.exists()
示例#2
0
def test_compare_manifests(svc_client_with_templates):
    """Check reading manifest template."""
    svc_client, headers, template_params = svc_client_with_templates

    response = svc_client.get("/templates.read_manifest",
                              query_string=template_params,
                              headers=headers)

    assert response
    assert {"result"} == set(response.json.keys())
    assert response.json["result"]["templates"]

    with TemporaryDirectory() as temp_dir:
        temp_path = Path(temp_dir)
        manifest_file = fetch_template(template_params["url"],
                                       template_params["ref"], temp_path)
        manifest = read_template_manifest(temp_path)

        assert manifest_file and manifest_file.exists()
        assert manifest

        templates_service = response.json["result"]["templates"]
        templates_local = manifest
        default_index = template_params["index"] - 1
        assert templates_service[default_index] == templates_local[
            default_index]
示例#3
0
def test_compare_manifests(svc_client_with_templates):
    """Check reading manifest template."""
    svc_client, headers, template_params = svc_client_with_templates

    response = svc_client.get('/templates.read_manifest',
                              query_string=template_params,
                              headers=headers)

    assert response
    assert {'result'} == set(response.json.keys())
    assert response.json['result']['templates']

    with TemporaryDirectory() as temp_dir:
        temp_path = Path(temp_dir)
        manifest_file = fetch_template(TEMPLATE_URL, TEMPLATE_REF, temp_path)
        manifest = read_template_manifest(temp_path)

        assert manifest_file and manifest_file.exists()
        assert manifest

        templates_service = response.json['result']['templates']
        templates_local = manifest
        default_index = TEMPLATE_INDEX - 1
        assert templates_service[default_index] == templates_local[
            default_index]
示例#4
0
def test_fetch_template(template):
    """Test fetching a template.

    It fetches a template from remote and verifies that the manifest
    file is there.
    """
    # ? Can't parametrize with fixtures yet
    # ? REF: https://docs.pytest.org/en/stable/proposals/parametrize_with_fixtures.html
    parametrize = [
        {
            "url": template["url"],
            "ref": template["ref"],
            "error": None
        },
        {
            "url": "fake",
            "ref": template["ref"],
            "error": errors.GitError
        },
        {
            "url": template["url"],
            "ref": "fake",
            "error": errors.GitError
        },
    ]
    for parameters in parametrize:
        with TemporaryDirectory() as tempdir:
            with raises(parameters["error"]):
                manifest_file = fetch_template(parameters["url"],
                                               parameters["ref"],
                                               Path(tempdir))
                assert Path(tempdir) / TEMPLATE_MANIFEST == manifest_file
                assert manifest_file.exists()
示例#5
0
    def run(self):
        from renku.core.commands.init import fetch_template, read_template_manifest

        with TemporaryDirectory() as tempdir:
            # download and extract template data
            temppath = Path(tempdir)
            print("downloading Renku templates...")
            fetch_template(URL, REFERENCE, temppath)
            read_template_manifest(temppath, checkout=True)

            # copy templates
            current_path = Path.cwd()
            template_path = current_path / "renku" / "templates"
            if template_path.exists():
                shutil.rmtree(str(template_path))
            shutil.copytree(str(temppath),
                            str(template_path),
                            ignore=shutil.ignore_patterns(".git"))
示例#6
0
def test_fetch_template(url, ref, result, error):
    """Test fetching a template.

    It fetches a template from remote and verifies that the manifest
    file is there.
    """
    with TemporaryDirectory() as tempdir:
        with raises(error):
            manifest_file = fetch_template(url, ref, Path(tempdir))
            assert manifest_file == Path(tempdir) / TEMPLATE_MANIFEST
            assert manifest_file.exists()
示例#7
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)
示例#8
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)
示例#9
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)