Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve test coverage #462

Open
wants to merge 128 commits into
base: master
Choose a base branch
from
Open

Improve test coverage #462

wants to merge 128 commits into from

Conversation

tony
Copy link
Member

@tony tony commented Mar 8, 2025

Summary by Sourcery

Documentation:

  • Adds a comprehensive document describing the VCSPull project, its architecture, configuration, and usage.

Copy link

sourcery-ai bot commented Mar 8, 2025

Reviewer's Guide by Sourcery

This pull request adds a comprehensive 'about.md' document to the 'notes' directory. This document provides a detailed overview of the VCSPull project, covering its purpose, architecture, configuration, codebase structure, development practices, tooling, and usage.

Class Diagram for VCSPull Configuration

Loading
classDiagram
    class ConfigFile {
        +str path
        +dict repos
    }
    class Repository {
        +str url
        +dict remotes
    }
    class VCSClient {
        +str vcs_type
        +str url
        +sync()
    }

    ConfigFile -- Repository : contains
    Repository -- VCSClient : uses

File-Level Changes

Change Details Files
Added a comprehensive project analysis document.
  • Introduced a detailed overview of the VCSPull project.
  • Described the core purpose of VCSPull, including simplifying repository management and enabling declarative configuration.
  • Outlined the configuration-driven architecture and key design patterns such as Factory, Command, Facade, and Template Method.
  • Explained the YAML/JSON configuration format with examples.
  • Detailed the codebase structure, including core components like Configuration Management, CLI Interface, and Type System.
  • Listed the project's dependencies, including libvcs, PyYAML, and colorama.
  • Summarized the development practices, such as strong type hints, comprehensive test coverage, and modern Python features.
  • Described the project's tooling, including uv, Ruff, Mypy, and Pytest.
  • Documented the configuration file locations and usage patterns.
  • Provided insights into the project's evolution and architecture.
notes/2025-03-08 - about.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

codecov bot commented Mar 8, 2025

Codecov Report

Attention: Patch coverage is 22.46521% with 780 lines in your changes missing coverage. Please review.

Project coverage is 23.92%. Comparing base (924ae0f) to head (3f9e9d4).

Files with missing lines Patch % Lines
src/vcspull/operations.py 8.83% 227 Missing ⚠️
src/vcspull/cli/commands.py 10.71% 200 Missing ⚠️
src/vcspull/vcs/mercurial.py 17.74% 102 Missing ⚠️
src/vcspull/vcs/git.py 18.33% 98 Missing ⚠️
src/vcspull/vcs/svn.py 21.35% 81 Missing ⚠️
src/vcspull/vcs/base.py 36.73% 31 Missing ⚠️
src/vcspull/config/loader.py 68.42% 19 Missing and 5 partials ⚠️
src/vcspull/_internal/logger.py 21.05% 15 Missing ⚠️
src/vcspull/config/models.py 95.23% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master     #462       +/-   ##
===========================================
- Coverage   78.98%   23.92%   -55.07%     
===========================================
  Files           8       10        +2     
  Lines         414     1045      +631     
  Branches       85      150       +65     
===========================================
- Hits          327      250       -77     
- Misses         52      789      +737     
+ Partials       35        6       -29     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @tony - I've reviewed your changes - here's some feedback:

Overall Comments:

  • This is a great overview of the project, but it's unclear how it improves test coverage as the title suggests.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@tony tony force-pushed the improve-test-coverage branch 6 times, most recently from 45d442a to 5be857c Compare March 8, 2025 22:38
@tony tony force-pushed the master branch 2 times, most recently from 02b87ec to 3e3654b Compare March 8, 2025 22:52
@tony tony force-pushed the improve-test-coverage branch from 5be857c to ac5af18 Compare March 8, 2025 22:53
@tony tony force-pushed the improve-test-coverage branch 9 times, most recently from 126baa7 to 06fdc1f Compare March 15, 2025 11:27
# Infer VCS from URL if not already set
if "vcs" not in repo_data and "url" in repo_data:
url = repo_data["url"]
if "github.com" in url or url.endswith(".git"):

Check failure

Code scanning / CodeQL

Incomplete URL substring sanitization High

The string
github.com
may be at an arbitrary position in the sanitized URL.

Copilot Autofix AI 13 days ago

To fix the problem, we need to replace the substring check with a more robust method that parses the URL and checks the hostname. Specifically, we should use the urlparse function from the urllib.parse module to extract the hostname and then check if it matches the expected domain.

  1. Import the urlparse function from the urllib.parse module.
  2. Replace the substring check with a parsed URL check.
  3. Ensure that the check handles arbitrary subdomain sequences correctly.
Suggested changeset 1
src/vcspull/config/migration.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/vcspull/config/migration.py b/src/vcspull/config/migration.py
--- a/src/vcspull/config/migration.py
+++ b/src/vcspull/config/migration.py
@@ -13,3 +13,3 @@
 from typing import Any, Optional
-
+from urllib.parse import urlparse
 import yaml
@@ -222,5 +222,6 @@
                     url = repo_data["url"]
-                    if "github.com" in url or url.endswith(".git"):
+                    parsed_url = urlparse(url)
+                    if parsed_url.hostname and (parsed_url.hostname == "github.com" or url.endswith(".git")):
                         repo_data["vcs"] = "git"
-                    elif "bitbucket.org" in url and not url.endswith(".git"):
+                    elif parsed_url.hostname and parsed_url.hostname == "bitbucket.org" and not url.endswith(".git"):
                         repo_data["vcs"] = "hg"
EOF
@@ -13,3 +13,3 @@
from typing import Any, Optional

from urllib.parse import urlparse
import yaml
@@ -222,5 +222,6 @@
url = repo_data["url"]
if "github.com" in url or url.endswith(".git"):
parsed_url = urlparse(url)
if parsed_url.hostname and (parsed_url.hostname == "github.com" or url.endswith(".git")):
repo_data["vcs"] = "git"
elif "bitbucket.org" in url and not url.endswith(".git"):
elif parsed_url.hostname and parsed_url.hostname == "bitbucket.org" and not url.endswith(".git"):
repo_data["vcs"] = "hg"
Copilot is powered by AI and may make mistakes. Always verify output.

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

url = repo_data["url"]
if "github.com" in url or url.endswith(".git"):
repo_data["vcs"] = "git"
elif "bitbucket.org" in url and not url.endswith(".git"):

Check failure

Code scanning / CodeQL

Incomplete URL substring sanitization High

The string
bitbucket.org
may be at an arbitrary position in the sanitized URL.

Copilot Autofix AI 13 days ago

To fix the problem, we need to ensure that the URL is properly parsed and validated to confirm that the host is exactly "bitbucket.org" and not just a substring within the URL. We can use the urlparse function from the urllib.parse module to parse the URL and then check the hostname.

  • Parse the URL using urlparse.
  • Extract the hostname from the parsed URL.
  • Check if the hostname is exactly "bitbucket.org".

This change should be made in the migrate_v1_to_v2 function, specifically around the lines where the URL is being checked for "bitbucket.org".

Suggested changeset 1
src/vcspull/config/migration.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/vcspull/config/migration.py b/src/vcspull/config/migration.py
--- a/src/vcspull/config/migration.py
+++ b/src/vcspull/config/migration.py
@@ -222,5 +222,6 @@
                     url = repo_data["url"]
-                    if "github.com" in url or url.endswith(".git"):
+                    parsed_url = urlparse(url)
+                    if "github.com" in parsed_url.hostname or url.endswith(".git"):
                         repo_data["vcs"] = "git"
-                    elif "bitbucket.org" in url and not url.endswith(".git"):
+                    elif parsed_url.hostname == "bitbucket.org" and not url.endswith(".git"):
                         repo_data["vcs"] = "hg"
EOF
@@ -222,5 +222,6 @@
url = repo_data["url"]
if "github.com" in url or url.endswith(".git"):
parsed_url = urlparse(url)
if "github.com" in parsed_url.hostname or url.endswith(".git"):
repo_data["vcs"] = "git"
elif "bitbucket.org" in url and not url.endswith(".git"):
elif parsed_url.hostname == "bitbucket.org" and not url.endswith(".git"):
repo_data["vcs"] = "hg"
Copilot is powered by AI and may make mistakes. Always verify output.

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

@tony tony force-pushed the improve-test-coverage branch from 32f5564 to 3de18f2 Compare March 23, 2025 21:17
tony added 29 commits March 23, 2025 16:20
why: Enable users to lock repositories to specific revisions for deployment consistency
     and reproducible environments. This allows teams to ensure all members are working
     with the same codebase state.

what:
- Added LockFile and LockedRepository models to config/models.py
- Implemented lock_repositories and apply_lock functions in operations.py
- Added get_revision and update_repo abstract methods to VCSInterface
- Implemented these methods for Git, Mercurial, and Subversion handlers
- Created CLI commands for locking repositories and applying locks
- Updated public exports in __init__.py files

refs: Completes CLI Tools / Version Locking section from notes/TODO.md
…odels

why: Enhance test coverage and verification of configuration models through property-based testing,
ensuring models behave correctly with a wide variety of inputs beyond specific examples.

what:
- Implement property-based testing using Hypothesis for configuration models
- Create comprehensive test strategies for generating valid URLs, paths, and model instances
- Add tests verifying serialization roundtrips and invariant properties
- Ensure tests verify Repository, Settings, VCSPullConfig, LockFile, and LockedRepository models
- Fix type annotations and linting issues in test files
- Add Hypothesis dependency to development dependencies

refs: Addresses "Property-Based Testing" item from TODO.md
…n loader

why: Enhance test coverage and reliability of the configuration system by implementing
property-based testing with Hypothesis and comprehensive integration tests.

what:
- Created property-based tests for configuration loading, saving, and include resolution
- Added test generators for repository URLs, paths, and configuration objects
- Implemented integration tests for complete configuration workflow
- Fixed circular include detection in resolve_includes to prevent infinite recursion
- Added proper tracking of processed paths to avoid duplicated processing
- Ensured all code follows project style guidelines and has proper type annotations
- Improved test reliability with proper temporary file and directory handling

refs: Completes "Property-Based Testing" section in notes/TODO.md
why: Facilitate user transition from old nested config format to new Pydantic v2 format
what:
- Implement migration module to detect and convert configuration versions
- Add CLI command with dry-run, backup, and color output options
- Create comprehensive test suite with property-based testing
- Write detailed migration guide for users

See also: notes/proposals/01-config-format-structure.md
@tony tony force-pushed the improve-test-coverage branch from 3de18f2 to 982b920 Compare March 23, 2025 21:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant