nomy-data-models 0.33.0

Data model definitions for Nomy wallet analysis data processing
Documentation
#!/bin/sh
#
# Pre-commit hook to automatically run tests and generate Rust models
# This hook will run before each commit to ensure that all tests pass and models are compiled to Rust

# Get the root directory of the repository
ROOT_DIR=$(git rev-parse --show-toplevel)

# Change to the repository root directory
cd "$ROOT_DIR"

# Add Cargo to PATH if it exists but isn't in PATH
if [ -d "$HOME/.cargo/bin" ] && ! command -v cargo >/dev/null 2>&1; then
    export PATH="$HOME/.cargo/bin:$PATH"
    echo "Added $HOME/.cargo/bin to PATH"
fi

# Try to find Python
PYTHON_PATH=""

# Check for Python in virtual environment
if [ -f "$ROOT_DIR/.venv/bin/python" ]; then
    PYTHON_PATH="$ROOT_DIR/.venv/bin/python"
elif [ -f "$ROOT_DIR/.venv/bin/python3" ]; then
    PYTHON_PATH="$ROOT_DIR/.venv/bin/python3"
# Check for system Python
elif command -v python3 >/dev/null 2>&1; then
    PYTHON_PATH=$(command -v python3)
elif command -v python >/dev/null 2>&1; then
    PYTHON_PATH=$(command -v python)
fi

# Check if Python was found
if [ -z "$PYTHON_PATH" ]; then
    echo "Error: Python not found. Please install Python or activate your Python environment."
    echo "Commit aborted."
    exit 1
fi

echo "Using Python at: $PYTHON_PATH"

# Try to use Poetry directly
if command -v poetry >/dev/null 2>&1; then
    # Ensure Poetry environment is created if it doesn't exist
    if [ ! -d "$ROOT_DIR/.venv" ]; then
        echo "Creating Poetry environment..."
        poetry install --no-interaction
    fi

    # Run code formatting checks on ALL files
    echo "Running black formatting checks on ALL files..."
    poetry run black --check nomy_data_models tests
    BLACK_RESULT=$?

    if [ $BLACK_RESULT -ne 0 ]; then
        echo "Error: Black formatting check failed. Automatically reformatting ALL files..."
        poetry run black nomy_data_models tests
        # Verify that the issues were fixed
        poetry run black --check nomy_data_models tests
        if [ $? -ne 0 ]; then
            echo "Error: black failed to fix all formatting issues. Commit aborted."
            exit 1
        fi
        # Add the reformatted files to the staging area
        echo "Adding black-reformatted files to the staging area..."
        git add $(git diff --name-only | grep "\.py$")
    fi

    # Check all files for import sorting issues
    echo "Checking ALL files for import sorting issues..."
    poetry run isort --profile black --check nomy_data_models tests
    ISORT_RESULT=$?

    if [ $ISORT_RESULT -ne 0 ]; then
        echo "Error: isort check failed. Automatically reformatting imports in ALL files..."
        # Make sure to run isort on all files, including test files
        poetry run isort --profile black nomy_data_models tests
        # Verify that the issues were fixed
        poetry run isort --profile black --check nomy_data_models tests
        if [ $? -ne 0 ]; then
            echo "Error: isort failed to fix all import issues. Commit aborted."
            exit 1
        fi
        # Add the reformatted files to the staging area
        echo "Adding isort-reformatted files to the staging area..."
        git add $(git diff --name-only | grep "\.py$")
    fi

    # Specifically check and fix the test_py_to_rust.py file, which has been causing issues
    echo "Specifically checking test_py_to_rust.py for import issues..."
    poetry run isort --profile black --check tests/python/test_py_to_rust.py
    if [ $? -ne 0 ]; then
        echo "Fixing import issues in test_py_to_rust.py..."
        poetry run isort --profile black tests/python/test_py_to_rust.py
        # Verify that the issues were fixed
        poetry run isort --profile black --check tests/python/test_py_to_rust.py
        if [ $? -ne 0 ]; then
            echo "Error: Failed to fix import issues in test_py_to_rust.py. Commit aborted."
            exit 1
        fi
        # Add the reformatted file to the staging area
        echo "Adding reformatted test_py_to_rust.py to the staging area..."
        git add tests/python/test_py_to_rust.py
    fi

    # Run Python tests without generating coverage reports
    echo "Running Python tests..."
    PYTHONPATH="$ROOT_DIR" poetry run python -m pytest tests/python
    TEST_RESULT=$?

    # Check if tests succeeded
    if [ $TEST_RESULT -ne 0 ]; then
        echo "Error: Python tests failed. Commit aborted."
        exit 1
    fi

    # Generate Rust models
    echo "Running pre-commit hook to generate and verify Rust models using Poetry..."
    poetry run "$PYTHON_PATH" "$ROOT_DIR/scripts/generate_rust.py" --verify
    RESULT=$?
else
    # Run code formatting checks using system Python on ALL files
    echo "Running black formatting checks on ALL files using system Python..."
    "$PYTHON_PATH" -m black --check nomy_data_models tests
    BLACK_RESULT=$?

    if [ $BLACK_RESULT -ne 0 ]; then
        echo "Error: Black formatting check failed. Automatically reformatting ALL files..."
        "$PYTHON_PATH" -m black nomy_data_models tests
        # Verify that the issues were fixed
        "$PYTHON_PATH" -m black --check nomy_data_models tests
        if [ $? -ne 0 ]; then
            echo "Error: black failed to fix all formatting issues. Commit aborted."
            exit 1
        fi
        # Add the reformatted files to the staging area
        echo "Adding black-reformatted files to the staging area..."
        git add $(git diff --name-only | grep "\.py$")
    fi

    # Check all files for import sorting issues using system Python
    echo "Checking ALL files for import sorting issues using system Python..."
    "$PYTHON_PATH" -m isort --profile black --check nomy_data_models tests
    ISORT_RESULT=$?

    if [ $ISORT_RESULT -ne 0 ]; then
        echo "Error: isort check failed. Automatically reformatting imports in ALL files..."
        # Make sure to run isort on all files, including test files
        "$PYTHON_PATH" -m isort --profile black nomy_data_models tests
        # Verify that the issues were fixed
        "$PYTHON_PATH" -m isort --profile black --check nomy_data_models tests
        if [ $? -ne 0 ]; then
            echo "Error: isort failed to fix all import issues. Commit aborted."
            exit 1
        fi
        # Add the reformatted files to the staging area
        echo "Adding isort-reformatted files to the staging area..."
        git add $(git diff --name-only | grep "\.py$")
    fi

    # Specifically check and fix the test_py_to_rust.py file, which has been causing issues
    echo "Specifically checking test_py_to_rust.py for import issues using system Python..."
    "$PYTHON_PATH" -m isort --profile black --check tests/python/test_py_to_rust.py
    if [ $? -ne 0 ]; then
        echo "Fixing import issues in test_py_to_rust.py..."
        "$PYTHON_PATH" -m isort --profile black tests/python/test_py_to_rust.py
        # Verify that the issues were fixed
        "$PYTHON_PATH" -m isort --profile black --check tests/python/test_py_to_rust.py
        if [ $? -ne 0 ]; then
            echo "Error: Failed to fix import issues in test_py_to_rust.py. Commit aborted."
            exit 1
        fi
        # Add the reformatted file to the staging area
        echo "Adding reformatted test_py_to_rust.py to the staging area..."
        git add tests/python/test_py_to_rust.py
    fi

    # Run Python tests using system Python without generating coverage reports
    echo "Running Python tests using system Python..."
    PYTHONPATH="$ROOT_DIR" "$PYTHON_PATH" -m pytest tests/python
    TEST_RESULT=$?

    # Check if tests succeeded
    if [ $TEST_RESULT -ne 0 ]; then
        echo "Error: Python tests failed. Commit aborted."
        exit 1
    fi

    # Generate Rust models
    echo "Running pre-commit hook to generate and verify Rust models using system Python..."
    "$PYTHON_PATH" "$ROOT_DIR/scripts/generate_rust.py" --verify
    RESULT=$?
fi

# Check if the script succeeded
if [ $RESULT -ne 0 ]; then
    echo "Error: Failed to generate or verify Rust models. Commit aborted."
    echo "If Cargo is not found, please install Rust and Cargo from https://rustup.rs/"
    echo "After installing, make sure it's in your PATH by running 'source $HOME/.cargo/env' or restarting your terminal."
    exit 1
fi

# Run Rust formatting checks
if command -v cargo >/dev/null 2>&1; then
    echo "Running Rust formatting checks on ALL files..."
    cargo fmt -- --check
    FMT_RESULT=$?

    if [ $FMT_RESULT -ne 0 ]; then
        echo "Error: Rust formatting check failed. Automatically reformatting ALL Rust code..."
        cargo fmt
        # Add the reformatted files to the staging area
        echo "Adding rust-fmt reformatted files to the staging area..."
        git add $(git diff --name-only | grep "\.rs$")
    fi

    # Run Rust linting with Clippy
    echo "Running Rust linting with Clippy on ALL files..."
    cargo clippy -- \
        -A clippy::too_many_arguments \
        -A unused_imports \
        -A non_camel_case_types
    CLIPPY_RESULT=$?

    if [ $CLIPPY_RESULT -ne 0 ]; then
        echo "Error: Clippy linting failed. Please fix the warnings before committing."
        exit 1
    fi

    # Run cargo fix to address warnings in the generated Rust code
    echo "Running cargo fix to address warnings in ALL generated Rust code..."
    cargo fix --allow-dirty --allow-staged --lib -p nomy-data-models

    # Check if cargo fix succeeded
    if [ $? -ne 0 ]; then
        echo "Warning: Failed to run cargo fix. Continuing with commit anyway."
    else
        # Add any files modified by cargo fix
        echo "Adding files modified by cargo fix to the staging area..."
        git add $(git diff --name-only | grep "\.rs$")
    fi
else
    echo "Warning: Cargo not found. Skipping Rust formatting checks."
    echo "To enable Rust formatting and linting, install Rust and Cargo from https://rustup.rs/"
    echo "After installing, run 'source $HOME/.cargo/env' or restart your terminal."
fi

# Remove coverage files if they were generated
if [ -f "$ROOT_DIR/coverage.xml" ]; then
    rm -f "$ROOT_DIR/coverage.xml"
fi

if [ -d "$ROOT_DIR/coverage_html" ]; then
    rm -rf "$ROOT_DIR/coverage_html"
fi

# Continue with the commit
exit 0