Skip to content

Port colcon-python-project wheel installation & uninstallation utilities to colcon-core - #741

Merged
cottsay merged 9 commits into
colcon:masterfrom
KmoM88:federico-rossi/install_wheel
Sep 5, 2026
Merged

cottsay merged 9 commits into
colcon:masterfrom
KmoM88:federico-rossi/install_wheel

Conversation

@KmoM88

@KmoM88 KmoM88 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR ports the core Python wheel installation and uninstallation engine from the prototype extension colcon-python-project into colcon-core.

Previously, colcon-core only supported legacy setuptools-centric installations that required spawning setup.py scripts. As Python platforms move away from direct setup.py invocations in favor of standard PEP 517/518 packaging structures, this PR introduces the native utilities required to install PEP 427 wheel archives (.whl) and safely clean up existing package distributions from the installation prefix.

By implementing this metadata-driven layout manager directly inside colcon-core, we establish the foundation for native PEP 517 build task execution and modern dependency resolution.

Key Features

1. Metadata-Driven Uninstallation (remove_distributions)

  • Live Discovery: Instead of depending on ephemeral local build-cache files (such as install.log or .egg-info symlinks in the build folder), the uninstallation utility queries the target install_base prefix using InstalledDistribution.discover.
  • Clean Deletions: Traverses the registered package files and deletes them from the filesystem. It unlinks residual .egg-link files and recursively removes any empty parent directories up to the install_base.
  • Platform Resilience: Deletions are guarded against file lock exceptions (particularly on Windows) by wrapping unlink and rmdir operations in exceptions handlers, logging warnings instead of crashing.

2. Wheel Layout Extraction & Mapping (install_wheel)

  • Wheel Extraction: Extracts standard PEP 427 wheel packages and determines the target library destination (purelib or platlib) based on Root-Is-Purelib metadata inside the wheel's WHEEL file.
  • Data-Files Mapping: Decodes .data/ directory segments (e.g. package-1.0.data/data/...) inside the wheel ZIP, translating them to their platform-agnostic target locations dynamically via _get_install_path.
  • Console Scripts Wrap: Parses entry point mappings defined in entry_points.txt and uses distlib.scripts.ScriptMaker to generate executable script wrappers under the scripts folder.
  • Standard Packaging Metadata: Writes the PEP 376 compliant metadata files:
    • INSTALLER: Marked as installed by colcon-core.
    • RECORD: Finalizes and writes the cryptographic hash signatures (sha256) and sizes of all extracted and generated files.

Verification & Testing

This PR introduces comprehensive unit tests under the test suite:

  • test_remove_wheel.py:
    • Sets up a mock workspace and dynamically copies distributions (typical-dist-info, typical-egg-info, typical-egg-link).
    • Asserts that remove_distributions successfully uninstalls standard, legacy, and egg-linked packages, deletes all associated files, and cleans up empty parent directories while leaving non-empty folders untouched.
  • test_install_wheel.py:
    • Programmatically mocks pure Python wheels, platform-specific wheels, wheels with console scripts, and wheels with data files.
    • Asserts that install_wheel extracts files into correct library paths, builds CLI scripts, maps data files to share/, and writes valid INSTALLER and RECORD files.
    • Verifies that the installer cleans up older package versions prior to installation.

Automated Tests

Run the newly added test suites locally:

pytest test/test_remove_wheel.py test/test_install_wheel.py

@KmoM88
KmoM88 marked this pull request as draft June 26, 2026 19:27
@cottsay
cottsay marked this pull request as ready for review June 30, 2026 14:40
@cottsay cottsay self-assigned this Jun 30, 2026
@cottsay
cottsay self-requested a review July 17, 2026 17:02
@codecov

codecov Bot commented Jul 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.89209% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.60%. Comparing base (6428dca) to head (b42f7f2).

Files with missing lines Patch % Lines
colcon_core/python_project/wheel.py 84.89% 12 Missing and 9 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #741      +/-   ##
==========================================
- Coverage   87.66%   87.60%   -0.07%     
==========================================
  Files          74       75       +1     
  Lines        4442     4581     +139     
  Branches      771      797      +26     
==========================================
+ Hits         3894     4013     +119     
- Misses        433      445      +12     
- Partials      115      123       +8     

☔ View full report in Codecov by Harness.
📢 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.

@cottsay cottsay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll probably have more feedback but I've been sitting on these two comments for a while so I thought I'd get them posted so they can be discussed now.

Hoping I'll have time to finish the review soon 🤞

Comment thread colcon_core/python_project/wheel.py Outdated
Comment thread colcon_core/python_project/wheel.py
@KmoM88
KmoM88 requested a review from cottsay August 6, 2026 16:00
1. Remove dangling symlinks as part of uninstallation
2. Use POSIX paths in RECORD
3. Attempt to preserve executable permissions when extracting files

Assisted-by: Gemini 3.5 Flash <gemini@google.com>

@cottsay cottsay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you!

@cottsay
cottsay merged commit 845927c into colcon:master Sep 5, 2026
46 checks passed
@cottsay cottsay added this to the 0.21.2 milestone Sep 5, 2026
@cottsay cottsay added the enhancement New feature or request label Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants