Skip to content

refactor: extract volume and image matching logic from rm_build.rs#124

Merged
jamiesunderland merged 1 commit intocoast-guard:mainfrom
mukeshblackhat:refactor/rm-build-extract-matching-121
Mar 23, 2026
Merged

refactor: extract volume and image matching logic from rm_build.rs#124
jamiesunderland merged 1 commit intocoast-guard:mainfrom
mukeshblackhat:refactor/rm-build-extract-matching-121

Conversation

@mukeshblackhat
Copy link
Contributor

Summary

  • Extracted two pure matching functions from async Docker-dependent code in coast-daemon/src/handlers/rm_build.rs:
    • volume_belongs_to_project(name, project, labels) — checks shared, compose, shared-services, and isolated volume naming patterns with label verification
    • image_matches_project(repo_tags, project) — checks repo tags for coast-image/{project}: and {project}-coasts prefixes
  • Updated remove_project_volumes and remove_project_images to delegate to the new helpers
  • Added 13 unit tests covering all matching cases
  • Existing #[allow(clippy::...)] annotations on the handle functions are kept as-is per ticket scope

What was there before

remove_project_volumes and remove_project_images had matching logic inlined inside async Docker-dependent loops. This made it impossible to unit test the matching rules without a real Docker daemon.

What changed

Single file: coast-daemon/src/handlers/rm_build.rs

Extracted functions (both private, pure, no async):

Function What it checks
volume_belongs_to_project Shared volumes (coast-shared--{project}--), compose volumes ({project}-coasts), shared-services volumes ({project}-shared-services), isolated volumes (coast-- + label match)
image_matches_project Tags starting with coast-image/{project}: or {project}-coasts

Parent functions updated:

  • remove_project_volumes — replaced inline matching with volume_belongs_to_project call
  • remove_project_images — replaced inline matching with image_matches_project call

13 unit tests added:

volume_belongs_to_project (8 tests):

  • Shared volume matches / different project doesn't
  • Compose volume matches
  • Shared-services volume matches
  • Isolated volume with correct label / wrong label / no label
  • Unrelated volume doesn't match

image_matches_project (5 tests):

  • Coast image tag matches
  • Coasts compose image matches
  • Different project doesn't match
  • Empty tags doesn't match
  • Multiple tags, one matches

Test plan

Verify the extraction

# Run only the new tests
cargo test -p coast-daemon -- rm_build::tests

# Should see 13 tests pass

Run lint and full tests

# Zero warnings expected
make lint

# All tests pass
make test

Verify behavior is unchanged

# The matching logic is pure — same rules as before:
# - coast rm-build still removes the correct volumes and images
# - No Docker behavior changed, just code organization

Closes #121

Extract pure matching logic from async Docker-dependent functions into
testable helpers:

- volume_belongs_to_project: checks shared, compose, shared-services,
  and isolated volume naming patterns with label verification
- image_matches_project: checks repo tags for coast-image and coasts
  compose prefixes

Adds 13 unit tests covering all matching cases listed in the ticket.
Parent functions (remove_project_volumes, remove_project_images) now
delegate to the helpers. Existing #[allow] annotations on handle
functions are kept as-is per ticket scope.

Closes coast-guard#121
Copy link
Contributor

@jamiesunderland jamiesunderland left a comment

Choose a reason for hiding this comment

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

Perfect! Thanks @mukeshblackhat

@jamiesunderland jamiesunderland merged commit c8426b6 into coast-guard:main Mar 23, 2026
2 checks passed
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.

Extract volume and image matching logic from rm_build.rs into testable pure functions

2 participants