Skip to content

Can skip

Support can-skip logic from Make.

Migrated from calcipy.can_skip for general-purpose build optimization.

Functions⚓︎

can_skip ⚓︎

can_skip(*, prerequisites, targets)

Return true if the prerequisite files have newer mtime than targets.

Implements Make-style dependency checking: if all targets are newer than all prerequisites, the build can be skipped.

PARAMETER DESCRIPTION
prerequisites

List of source files (must all exist)

TYPE: list[Path]

targets

List of generated files (may or may not exist)

TYPE: list[Path]

RETURNS DESCRIPTION
bool

True if targets exist and are newer than prerequisites, False otherwise

RAISES DESCRIPTION
ValueError

if any prerequisite file does not exist

Example

from pathlib import Path

Skip test run if coverage file is newer than source⚓︎

if can_skip( … prerequisites=[Path(‘src’).rglob(‘.py’)], … targets=[Path(‘.coverage.xml’)] … ): … print(“Skipping - targets are up to date”) … return

Source code in corallium/can_skip.py
def can_skip(*, prerequisites: list[Path], targets: list[Path]) -> bool:
    """Return true if the prerequisite files have newer `mtime` than targets.

    Implements Make-style dependency checking: if all targets are newer than
    all prerequisites, the build can be skipped.

    Args:
        prerequisites: List of source files (must all exist)
        targets: List of generated files (may or may not exist)

    Returns:
        True if targets exist and are newer than prerequisites, False otherwise

    Raises:
        ValueError: if any prerequisite file does not exist

    Example:
        >>> from pathlib import Path
        >>> # Skip test run if coverage file is newer than source
        >>> if can_skip(
        ...     prerequisites=[*Path('src').rglob('*.py')],
        ...     targets=[Path('.coverage.xml')]
        ... ):
        ...     print("Skipping - targets are up to date")
        ...     return

    """
    if not (ts_prerequisites := [pth.stat().st_mtime for pth in prerequisites]):
        raise ValueError('Required files do not exist', prerequisites)

    # Collect target mtimes, skipping missing files
    ts_targets = [pth.stat().st_mtime for pth in targets if pth.is_file()]
    if ts_targets and len(ts_targets) == len(targets) and min(ts_targets) > max(ts_prerequisites):
        LOGGER.warning('Skipping because targets are newer', targets=targets)
        return True
    return False

dont_skip ⚓︎

dont_skip(*, prerequisites, targets)

Returns False. To use for testing with mock.

This is a drop-in replacement for can_skip() that always returns False, useful for testing scenarios where you want to force execution.

PARAMETER DESCRIPTION
prerequisites

List of source files (logged but not checked)

TYPE: list[Path]

targets

List of generated files (logged but not checked)

TYPE: list[Path]

RETURNS DESCRIPTION
bool

Always returns False

Source code in corallium/can_skip.py
def dont_skip(*, prerequisites: list[Path], targets: list[Path]) -> bool:
    """Returns False. To use for testing with mock.

    This is a drop-in replacement for can_skip() that always returns False,
    useful for testing scenarios where you want to force execution.

    Args:
        prerequisites: List of source files (logged but not checked)
        targets: List of generated files (logged but not checked)

    Returns:
        Always returns False

    """
    LOGGER.debug('Mocking can_skip', prerequisites=prerequisites, targets=targets)
    return False