Skip to content

versioning

gitversioned.versioning

GitVersioned core module for resolving versions from Git state.

This module provides the primary logic for computing PEP 440 compliant version strings. It evaluates multiple configured sources (such as tags, branches, files, and functions) and applies appropriate templates based on the current build environment and repository state.

generate_version_py(version, reference, settings, repository, environment)

Writes the resolved version metadata to a python file using templates.

This function utilizes the configured release or development templates to generate a python file containing version information, which can then be included directly within the target package.

Example: >>> path = generate_version_py(version, ref, settings, repo, env)

Parameters:

Name Type Description Default
version Version

The resolved PEP 440 version object.

required
reference GitReference

The resolved Git reference object.

required
settings Settings

Configuration rules for resolving the version.

required
repository GitRepository

The current git repository state.

required
environment BuildEnvironment

Build environment metadata.

required

Returns:

Type Description
Path | None

The Path object pointing to the written file.

Source code in src/gitversioned/versioning.py
def generate_version_py(
    version: Version,
    reference: GitReference,
    settings: Settings,
    repository: GitRepository,
    environment: BuildEnvironment,
) -> Path | None:
    """
    Writes the resolved version metadata to a python file using templates.

    This function utilizes the configured release or development templates to
    generate a python file containing version information, which can then be
    included directly within the target package.

    Example:
        >>> path = generate_version_py(version, ref, settings, repo, env)

    :param version: The resolved PEP 440 version object.
    :param reference: The resolved Git reference object.
    :param settings: Configuration rules for resolving the version.
    :param repository: The current git repository state.
    :param environment: Build environment metadata.
    :return: The Path object pointing to the written file.
    """
    logger.debug(
        f"generate_version_py called for version={version} reference={reference} "
        f"settings={settings} repository={repository} environment={environment}"
    )

    if not settings.output_file:
        logger.debug("No output file configured, skipping generation of version file.")
        return None

    template = (
        settings.template_dev if version.dev is not None else settings.template_release
    )
    context = {
        "version": version,
        "repo": repository,
        "config": settings,
        "env": environment,
        "ref": reference,
    }
    content = str(render(generate_template(template, context, use_eval=True)))

    try:
        output_path = Path(settings.output_file)
        if not output_path.is_absolute():
            output_path = settings.src_root / output_path
        output_path.parent.mkdir(parents=True, exist_ok=True)
        output_path.write_text(content, encoding="utf-8")
        logger.info(f"Generated version py file successfully at: {output_path}")
    except Exception as error:
        logger.exception(
            f"Failed to write version python file to {output_path}: {error}"
        )
        raise

    return output_path

resolve_and_generate_version(settings, repository, environment)

Main entry point to resolve the version and write the output file if configured.

This function wraps the core version resolution logic and subsequently triggers the generation of the version python file if an output file is specified in the settings. It provides a convenient single call for build hooks and integrations.

Example: >>> version, path = resolve_and_generate_version(settings, repo, env)

Parameters:

Name Type Description Default
settings Settings

Configuration rules for resolving the version.

required
repository GitRepository

The current git repository state.

required
environment BuildEnvironment

Build environment metadata.

required

Returns:

Type Description
tuple[Version, Path | None]

A tuple of the resolved Version and output Path (if generated).

Source code in src/gitversioned/versioning.py
def resolve_and_generate_version(
    settings: Settings, repository: GitRepository, environment: BuildEnvironment
) -> tuple[Version, Path | None]:
    """
    Main entry point to resolve the version and write the output file if configured.

    This function wraps the core version resolution logic and subsequently triggers
    the generation of the version python file if an output file is specified in the
    settings. It provides a convenient single call for build hooks and integrations.

    Example:
        >>> version, path = resolve_and_generate_version(settings, repo, env)

    :param settings: Configuration rules for resolving the version.
    :param repository: The current git repository state.
    :param environment: Build environment metadata.
    :return: A tuple of the resolved Version and output Path (if generated).
    """
    logger.debug(
        f"resolve_and_generate_version called for {settings} with "
        f"repo={repository} env={environment}"
    )
    version, reference = resolve_version(settings, repository, environment)
    output_path = generate_version_py(
        version, reference, settings, repository, environment
    )

    return version, output_path

resolve_version(settings, repository, environment)

Computes the PEP 440 version based on configuration and repository state.

This function coordinates the resolution of version sources according to the provided settings, performs auto-increments if necessary, and formats the final version string based on the target build type (e.g., release, dev, alpha).

Example: >>> version, reference = resolve_version(settings, repo, env)

Parameters:

Name Type Description Default
settings Settings

Configuration rules for resolving the version.

required
repository GitRepository

The current git repository state.

required
environment BuildEnvironment

Build environment metadata.

required

Returns:

Type Description
tuple[Version, GitReference]

A tuple containing the resolved Version and the Git reference object.

Raises:

Type Description
ValueError

If an unknown source type or git type is encountered.

Source code in src/gitversioned/versioning.py
def resolve_version(
    settings: Settings, repository: GitRepository, environment: BuildEnvironment
) -> tuple[Version, GitReference]:
    """
    Computes the PEP 440 version based on configuration and repository state.

    This function coordinates the resolution of version sources according to the
    provided settings, performs auto-increments if necessary, and formats the final
    version string based on the target build type (e.g., release, dev, alpha).

    Example:
        >>> version, reference = resolve_version(settings, repo, env)

    :param settings: Configuration rules for resolving the version.
    :param repository: The current git repository state.
    :param environment: Build environment metadata.
    :return: A tuple containing the resolved Version and the Git reference object.
    :raises ValueError: If an unknown source type or git type is encountered.
    """

    logger.debug(
        f"resolving version for {settings} in repo={repository} env={environment}"
    )
    base_version, reference = _resolve_version_sources(
        settings.source_type, settings, repository, environment
    )
    logger.info(f"Resolved base version: {base_version} for git reference {reference}")

    # Determine version type to build (release, dev, alpha, post)
    version_type = str(settings.version_type).strip().lower()
    distance = reference.distance_from_head if repository.is_available else 0
    if version_type == "auto":
        if not repository.is_available and reference.commit_sha:
            on_head = True
            is_dirty = False
        else:
            on_head = repository.is_available and reference.is_head_commit
            dirty_files = _get_dirty_files(repository, settings)
            is_dirty = len(dirty_files) > 0

        version_type = "release" if on_head and not is_dirty else "dev"
        logger.info(
            f"Auto-resolved version type to: '{version_type}' "
            f"for ref {reference} and repo {repository}"
        )

    target_str = str(
        settings.auto_increment.get(
            cast(
                "Literal['release', 'dev', 'pre', 'alpha', 'nightly', 'post']",
                version_type,
            ),
            "",
        )
        if settings.auto_increment
        else ""
    ).lower()
    target_idx = {"major": 0, "minor": 1, "micro": 2, "patch": 2}.get(target_str)

    if target_idx is not None and distance > 0:
        parts = [base_version.major, base_version.minor, base_version.micro]
        parts[target_idx] += 1
        for index in range(target_idx + 1, len(parts)):
            parts[index] = 0

        version = Version(".".join(map(str, parts)))
        logger.info(
            f"Auto-incremented version from {base_version} to {version} "
            f"(target='{target_str}')"
        )
    else:
        version = base_version

    context = {
        "version": version,
        "repo": repository,
        "config": settings,
        "env": environment,
        "ref": reference,
    }

    main_version = str(
        render(generate_template(settings.format_main, context, use_eval=True))
    )
    segment = ""
    if version_type == "dev":
        segment = str(
            render(generate_template(settings.format_dev, context, use_eval=True))
        )
    elif version_type in ("pre", "alpha", "nightly"):
        segment = str(
            render(generate_template(settings.format_pre, context, use_eval=True))
        )
    elif version_type == "post":
        segment = str(
            render(generate_template(settings.format_post, context, use_eval=True))
        )

    final_version = Version(f"{main_version}.{segment}".rstrip("+."))
    logger.info(f"Resolved final version: {final_version}")

    return final_version, reference