Skip to content

feat: use FoundryContext in all modules#18

Merged
olivermeyer merged 13 commits into
mainfrom
feat/use-context-in-all-modules
Mar 30, 2026
Merged

feat: use FoundryContext in all modules#18
olivermeyer merged 13 commits into
mainfrom
feat/use-context-in-all-modules

Conversation

@olivermeyer
Copy link
Copy Markdown
Collaborator

@olivermeyer olivermeyer commented Mar 30, 2026

This PR updates all modules to use the FoundryContext.

The commits are a bit messy as I fixed some issues along the way; I will squash merge this one.

olivermeyer and others added 9 commits March 27, 2026 16:09
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 93.33333% with 4 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/aignostics_foundry_core/foundry.py 88.23% 3 Missing and 1 partial ⚠️
Files with missing lines Coverage Δ
src/aignostics_foundry_core/boot.py 78.48% <100.00%> (+2.83%) ⬆️
src/aignostics_foundry_core/console.py 100.00% <100.00%> (ø)
src/aignostics_foundry_core/log.py 93.02% <100.00%> (+0.16%) ⬆️
src/aignostics_foundry_core/process.py 100.00% <100.00%> (ø)
src/aignostics_foundry_core/sentry.py 95.06% <100.00%> (+0.12%) ⬆️
src/aignostics_foundry_core/foundry.py 96.49% <88.23%> (-3.51%) ⬇️

olivermeyer and others added 3 commits March 30, 2026 09:38
@olivermeyer olivermeyer marked this pull request as ready for review March 30, 2026 07:48
@olivermeyer olivermeyer requested a review from a team as a code owner March 30, 2026 07:48
@olivermeyer olivermeyer added the claude Trigger Claude Code automation label Mar 30, 2026
Add a Usage section covering set_context()/boot() at startup,
get_context() for module-level access, and the explicit context
pattern for tests. Remove the scaffolding NOTE block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@olivermeyer olivermeyer force-pushed the feat/use-context-in-all-modules branch from 9246eae to 05ab569 Compare March 30, 2026 09:12
@claude
Copy link
Copy Markdown

claude Bot commented Mar 30, 2026

Claude finished @olivermeyer's task in 2m 39s —— View job


Code Review Complete ✅

Reviewing PR #18: feat: use FoundryContext in all modules


Summary

This PR successfully refactors all modules to use FoundryContext as a unified configuration mechanism. The changes flatten SentryContext into FoundryContext, add env_prefix and project_path fields, and update all modules to accept an optional context parameter. The refactor is well-executed with comprehensive tests and documentation updates.

Overall Assessment: Strong work! The code quality is high, tests follow best practices, and documentation is thorough. A few minor suggestions below for further improvement.


Issues Found

Coverage Gap (Non-Blocking)

Location: src/aignostics_foundry_core/foundry.py:155

Issue: The detached HEAD SHA validation branch in _get_vcs_ref_from_git lacks test coverage:

if len(content) == 40 and all(c in string.hexdigits for c in content):  # noqa: PLR2004
    return content[:7]

Codecov reports 88.23% patch coverage for foundry.py with 3 missing lines and 1 partial.

Suggestion: Add a test case for detached HEAD state:

@pytest.mark.unit
def test_get_vcs_ref_from_git_returns_short_sha_when_detached_head(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
    """Returns first 7 chars of SHA when in detached HEAD state."""
    git_dir = tmp_path / ".git"
    git_dir.mkdir()
    full_sha = "a" * 40
    (git_dir / "HEAD").write_text(full_sha)
    
    from aignostics_foundry_core.foundry import _get_vcs_ref_from_git
    result = _get_vcs_ref_from_git(tmp_path)
    assert result == "aaaaaaa"

Suggestions (Non-Blocking)

1. Magic Number Documentation

Location: src/aignostics_foundry_core/foundry.py:155

Current:

if len(content) == 40 and all(c in string.hexdigits for c in content):  # noqa: PLR2004

Suggestion: While the # noqa: PLR2004 suppresses the SonarQube rule, consider extracting to a named constant for clarity:

_GIT_SHA_FULL_LENGTH = 40
_GIT_SHA_SHORT_LENGTH = 7

if len(content) == _GIT_SHA_FULL_LENGTH and all(c in string.hexdigits for c in content):
    return content[:_GIT_SHA_SHORT_LENGTH]

Why: Improves readability and makes the intent explicit. Magic numbers should be avoided even with noqa comments.


2. Complex Fallback Chain

Location: src/aignostics_foundry_core/foundry.py:103

Current:

vcs_ref = os.environ.get("VCS_REF") or (project_path and _get_vcs_ref_from_git(project_path)) or "unknown"

Suggestion: Consider breaking this into multiple lines for readability:

vcs_ref = (
    os.environ.get("VCS_REF")
    or (project_path and _get_vcs_ref_from_git(project_path))
    or "unknown"
)

Why: The current one-liner is correct but dense. Breaking it up makes the fallback logic clearer.


3. Error Context in Git Operations

Location: src/aignostics_foundry_core/foundry.py:149-152

Current:

try:
    content = (project_path / ".git" / "HEAD").read_text().strip()
except OSError:
    return "unknown"

Suggestion: Consider logging the exception for debugging:

try:
    content = (project_path / ".git" / "HEAD").read_text().strip()
except OSError as exc:
    logger.trace(f"Could not read .git/HEAD: {exc}")
    return "unknown"

Why: While returning "unknown" is safe, logging would help diagnose git-related issues in production.


Positive Observations ✨

  1. Excellent test quality: All tests follow the required @pytest.mark.unit pattern and extract string constants per SonarQube S1192 rules. Great adherence to project standards!

  2. Comprehensive documentation: README.md now includes clear usage examples for set_context(), get_context(), and the test pattern. The decision doc (0003) is well-updated.

  3. Consistent API design: The optional context parameter pattern is applied uniformly across all functions (boot(), logging_initialize(), sentry_initialize(), get_process_info()). This creates a consistent and predictable API.

  4. Type hints are complete: All functions have proper type annotations including the TYPE_CHECKING imports to avoid circular dependencies.

  5. Good use of extraction: Test constants (PACKAGE_NAME, _SENTRY_PREFIX, _VALID_DSN, etc.) demonstrate excellent adherence to DRY principles.

  6. Clear error messages: get_context() raises RuntimeError with a helpful message guiding users to call set_context() at startup.

  7. Proper field documentation: Docstrings for version_full and project_path clearly explain their derivation logic and edge cases.

  8. Git fallback logic is robust: Handles missing files, wrong formats, and detached HEAD states gracefully.


Breaking Changes (Acknowledged)

This PR introduces breaking changes (as noted in the PR description for squash merge):

  • context.sentry.is_containercontext.is_container (flattened)
  • boot(project_name, version, ...)boot(context=...)
  • sentry_initialize(project_name, version, ...)sentry_initialize(context=...)
  • logging_initialize(project_name, version)logging_initialize(context=...)

These are intentional refactoring changes for internal consistency.


Final Recommendations

  1. Add test for detached HEAD case to achieve 100% coverage goal
  2. Consider extracting SHA length constants to eliminate the magic number
  3. Optional: Add debug logging in git operations for production diagnostics

The code is production-ready as-is. The suggestions above are quality-of-life improvements, not blockers.

Status: ✅ Approved with suggestions — Ready to merge after optional improvements


Tasks

  • Read project documentation (CLAUDE.md, CODE_STYLE.md)
  • Analyze git changes and commit history
  • Review core module changes (foundry.py, boot.py, sentry.py, log.py)
  • Review supporting module changes (console.py, process.py)
  • Review test coverage and test quality
  • Check documentation updates
  • Provide structured feedback

@sonarqubecloud
Copy link
Copy Markdown

@olivermeyer olivermeyer merged commit a99873c into main Mar 30, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude Trigger Claude Code automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant