Skip to content

Conversation

@maybeec
Copy link
Member

@maybeec maybeec commented Nov 18, 2025

This PR fixes #39

Implemented changes:

  • Created Pip commandlet that delegates to Uv commandlet by prepending "pip" to arguments
  • Added help texts in English and German explaining that pip delegates to uv pip internally
  • Created PipTest to verify basic functionality
  • Updated CHANGELOG.adoc with issue Implement ToolCommandlet for pip #39

Technical Details:

The pip commandlet extends DelegatingToolCommandlet<Uv> and overrides runTool() to prepend "pip" to the arguments before delegating to UV. This means when users run ide pip install <package>, it internally executes uv pip install <package>.

This implementation follows the hint provided in the issue that pip should be implemented as a delegate to uv pip.


Checklist for this PR

  • When running mvn clean test locally all tests pass and build is successful (test errors are pre-existing)
  • PR title is of the form #«issue-id»: «brief summary»
  • PR top-level comment summarizes what has been done and contains link to addressed issue(s)
  • PR and issue(s) have suitable labels
  • Issue is set to In Progress and assigned to you or there is no issue (might happen for very small PRs)
  • You followed all coding conventions
  • You have added the issue implemented by your PR in CHANGELOG.adoc unless issue is labeled with internal

Checklist for tool commandlets

  • The tool can be installed automatically (during setup via settings) or via the commandlet call (delegates to UV)
  • The tool is isolated in its IDEasy project, see Sandbox Principle (handled by UV)
  • The new tool is added to the table of tools in LICENSE.asciidoc (pip already present)
  • The new commandlet is a command-wrapper for pip
  • Proper help texts for all supported languages are added here
  • The new commandlet installs potential dependencies automatically (delegates to UV which handles dependencies)
  • The variables «TOOL»_VERSION and «TOOL»_EDITION are honored by your commandlet (handled by delegation to UV)
  • The new commandlet is tested on all platforms it is available for or tested on all platforms that are in scope of the linked issue

@github-project-automation github-project-automation bot moved this to 🆕 New in IDEasy board Nov 18, 2025
@maybeec maybeec marked this pull request as draft November 18, 2025 14:10
@coveralls
Copy link
Collaborator

coveralls commented Nov 18, 2025

Pull Request Test Coverage Report for Build 19944545054

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 157 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-0.2%) to 69.753%

Files with Coverage Reduction New Missed Lines %
com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java 8 90.0%
com/devonfw/tools/ide/context/IdeContext.java 19 74.6%
com/devonfw/tools/ide/context/AbstractIdeContext.java 130 67.91%
Totals Coverage Status
Change from base Build 19877232762: -0.2%
Covered Lines: 9905
Relevant Lines: 13663

💛 - Coveralls

@maybeec maybeec added commandlet ide sub-command python runtime for python language pip Python package manager (Pip Installs Packages) labels Nov 18, 2025
@maybeec
Copy link
Member Author

maybeec commented Nov 18, 2025

  1. I upgraded the github actions setup java commandlet as there were downloading issues of java, which meanwhile seem to have been caused by the cloudfare downtime. So the upgrade did not make any improvement but it also does not harm, so I will keep it here as a small by-product improvement
  2. I am not 100% sure about the solution. I implemented it as pure delegate as you can directly use uv pip although you could especially also install it to virtual environments by uv pip install pip. But I think uv pip should do the job already as needed.
  3. I do not have test capabilities for all environments, seeking support from anyone to do the testing on isolated and different environments. Thanks!

@maybeec maybeec marked this pull request as ready for review November 18, 2025 22:42
@maybeec maybeec moved this from 🆕 New to Team Review in IDEasy board Nov 25, 2025
@jan-vcapgemini
Copy link
Contributor

  1. I upgraded the github actions setup java commandlet as there were downloading issues of java, which meanwhile seem to have been caused by the cloudfare downtime. So the upgrade did not make any improvement but it also does not harm, so I will keep it here as a small by-product improvement

    1. I am not 100% sure about the solution. I implemented it as pure delegate as you can directly use uv pip although you could especially also install it to virtual environments by uv pip install pip. But I think uv pip should do the job already as needed.

    2. I do not have test capabilities for all environments, seeking support from anyone to do the testing on isolated and different environments. Thanks!

I've tested the pip command on my WSL2.0 within intellij and on my Windows 11 machine. Works fine so far.

WSL logs:

Running commandlet Pip[pip]
IDE environment variables have been set for /home/<username>/projects/test in workspace main
Running command '/usr/bin/git' with arguments 'rev-parse' '@{u}' ...
The path /home/<username>/projects/test/settings/.git/FETCH_HEAD was last updated PT869H23M53.77S ago and caching duration is PT5M.
Will need to do git fetch on /home/<username>/projects/test/settings because last fetch was some time ago.
Running command '/usr/bin/git' with arguments 'branch' '--show-current' ...
Running command '/usr/bin/git' with arguments 'remote' ...
Running command '/usr/bin/git' with arguments 'fetch' 'origin' 'main' ...
Running command '/usr/bin/git' with arguments 'rev-parse' '@{u}' ...
Updates are available for the settings repository. If you want to apply the latest changes, call "ide update"
Tool uv not installed in /home/<username>/projects/test/software/uv
The path /home/<username>/projects/_ide/urls/.git/HEAD was last updated PT2M32.202S ago and caching duration is PT30M.
Skipping git pull/clone on /home/<username>/projects/_ide/urls because last fetch was just recently to avoid overhead.
Running command '/usr/bin/git' with arguments 'diff-index' '--quiet' 'HEAD' ...
Running command '/usr/bin/git' with arguments 'ls-files' '--other' '--directory' '--exclude-standard' ...
Resolved version pattern * to version 0.9.13
Tool uv not installed in /home/<username>/projects/test/software/uv
No CVEs found for current version 0.9.13 of tool uv.
Tool uv has 0 other tool(s) as dependency
Resolved version 0.9.13 to version 0.9.13
Trying to download uv-0.9.13-linux-x64.tar.gz from https://github.com/astral-sh/uv/releases/download/0.9.13/uv-x86_64-unknown-linux-gnu.tar.gz
Downloading 100% │████████████████████████│ 20/20MiB (0:00:00 / 0:00:00) ?MiB/s
SHA-256 checksum c45a44144bf23a2182e143227b4ad0bbe41a2bb7161a637c02e968906af53fd1 is correct.
Extracting TAR file /home/<username>/Downloads/ide/default/uv-0.9.13-linux-x64.tar.gz to /home/<username>/projects/_ide/tmp/extract-uv-0.9.13-linux-x64.tar.gz
Extracting 100% │█████████████████████████│ 20/20MiB (0:00:00 / 0:00:00) ?MiB/s
Setting permissions for /home/<username>/projects/_ide/tmp/extract-uv-0.9.13-linux-x64.tar.gz/uv-x86_64-unknown-linux-gnu/uv to rwxr-xr-x
Setting permissions for /home/<username>/projects/_ide/tmp/extract-uv-0.9.13-linux-x64.tar.gz/uv-x86_64-unknown-linux-gnu/uvx to rwxr-xr-x
Deleting /home/<username>/projects/_ide/tmp/extract-uv-0.9.13-linux-x64.tar.gz ...
Installed uv in version 0.9.13 at /home/<username>/projects/_ide/software/default/uv/uv/0.9.13
Creating relative symbolic link at /home/<username>/projects/test/software/uv pointing to ../../_ide/software/default/uv/uv/0.9.13
Successfully installed uv in version 0.9.13
Running command '/home/<username>/projects/_ide/software/default/uv/uv/0.9.13/uv' with arguments 'pip' '--help' ...
Manage Python packages with a pip-compatible interface

Usage: uv pip [OPTIONS] <COMMAND>

Commands:
  compile    Compile a `requirements.in` file to a `requirements.txt` or `pylock.toml` file
...

Windows logs:

Running commandlet Pip[pip]
IDE environment variables have been set for D:\projects\test in workspace main
Running command 'C:\Program Files\Git\mingw64\bin\git.exe' with arguments 'rev-parse' '@{u}' ...
Updates are available for the settings repository. If you want to apply the latest changes, call "ide update"
Tool uv not installed in D:\projects\test\software\uv
The path D:\projects\_ide\urls\.git\HEAD was last updated PT12M47.51S ago and caching duration is PT30M.
Skipping git pull/clone on D:\projects\_ide\urls because last fetch was just recently to avoid overhead.
Running command 'C:\Program Files\Git\mingw64\bin\git.exe' with arguments 'diff-index' '--quiet' 'HEAD' ...
Running command 'C:\Program Files\Git\mingw64\bin\git.exe' with arguments 'ls-files' '--other' '--directory' '--exclude-standard' ...
Resolved version pattern * to version 0.9.13
Tool uv not installed in D:\projects\test\software\uv
No CVEs found for current version 0.9.13 of tool uv.
Tool uv has 0 other tool(s) as dependency
Version 0.9.13 of tool uv is already installed at D:\projects\_ide\software\default\uv\uv\0.9.13
Creating relative symbolic link at D:\projects\test\software\uv pointing to ..\..\_ide\software\default\uv\uv\0.9.13
Due to lack of permissions, Microsoft's mklink with junction had to be used to create a Symlink. See
https://github.com/devonfw/IDEasy/blob/main/documentation/symlink.adoc for further details. Error was: D:\projects\test\software\uv: A required privilege is not held by the client
Running command 'C:\windows\system32\cmd.exe' with arguments '/c' 'mklink' '/d' '/j' 'D:\projects\test\software\uv' 'D:\projects\_ide\software\default\uv\uv\0.9.13' ...
Junction created for D:\projects\test\software\uv <<===>> D:\projects\_ide\software\default\uv\uv\0.9.13
Successfully installed uv in version 0.9.13
Running command 'D:\projects\_ide\software\default\uv\uv\0.9.13\uv.exe' with arguments 'pip' '--help' ...
Manage Python packages with a pip-compatible interface

Usage: uv.exe pip [OPTIONS] <COMMAND>

Commands:
  compile    Compile a `requirements.in` file to a `requirements.txt` or `pylock.toml` file
...

added execute permissions to binaries
added extra echo for pip to uv binaries
replaced cmd content with bash
Copy link
Contributor

@jan-vcapgemini jan-vcapgemini left a comment

Choose a reason for hiding this comment

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

@maybeec thanks for adding this missing commandlet. Looks good to me, ready for review.

@github-project-automation github-project-automation bot moved this from Team Review to 👀 In review in IDEasy board Nov 28, 2025
Copy link
Member

@hohwille hohwille left a comment

Choose a reason for hiding this comment

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

@maybeec thank you very much for your PR. 👍
I had a long discussion already about our plans in the dailies with @jan-vcapgemini that we never documented in the story. Sorry for that and hence my review comments requesting some rework.

For my curiosity: I am happy that you upgraded setup-java action lib. Is this required for this PR and especially why did you change the JDK distribution to zulu?
I do not mind this change, I just want to understand if this is related to the change or if it is a general best practice you learned that I might be missing.
BTW: On our long learning with GitHub we discovered that we often end up with PRs that grow too big and are hard to review (I am not talking about this PR, but PRs changing 100+ files, what we have seen several times). Still I sometimes tend to include refactorings in a bugfix and maybe also include unrelated cleanups that I hit on the way. However, on the long run, we learned that ideally we create small PRs that only focus on a single bug or feature. If we want to also update an action or cleanup some code we hit, it is best, to just create another PR for it.
Thanks for all your input: I clearly see that I need to take some time to write way more documentation about all these things. Ideally in reviews, I only need to paste links to existing documentation if something is not as desired (most likely not in your case but more for junior developers contributing PRs).

@hohwille hohwille added this to the release:2025.12.001 milestone Dec 1, 2025
…ommandlet

- Refactored Pip.java to extend LocalToolCommandlet instead of DelegatingToolCommandlet
- Created PipRepository extending ArtifactToolRepository for PyPI version resolution
- Created PipArtifact and PipArtifactMetadata data classes
- Created PypiJsonObject record for parsing PyPI JSON API responses
- Added getPipRepository() to IdeContext interface and AbstractIdeContext
- Created PipRepositoryMock for testing with WireMock
- pip installation now delegates to 'uv pip install pip=={version}'
- pip execution runs through 'uv pip' instead of direct pip binary
- Consolidated test resources and fixed test configuration

Addresses review comments from PR devonfw#1597
@maybeec
Copy link
Member Author

maybeec commented Dec 1, 2025

Summary of Changes (addressing review feedback)

Based on the review comments, I've refactored the pip commandlet from DelegatingToolCommandlet to LocalToolCommandlet. Here's what was changed:

Key Changes:

  1. Refactored Pip.java from DelegatingToolCommandlet<Uv> to LocalToolCommandlet:

    • Overrides performToolInstallation() to delegate to uv pip install pip=={version}
    • Overrides configureToolBinary() and configureToolArgs() to run pip commands through uv pip
    • Overrides getToolRepository() to return the new PipRepository
    • Overrides getInstalledVersion() to check pip version
  2. Created PipRepository (extends ArtifactToolRepository):

    • Uses PyPI JSON API (https://pypi.org/pypi/{package}/json) for version resolution
    • Follows the same pattern as NpmRepository
  3. Created supporting classes:

    • PipArtifact: Represents a pip package with name and version
    • PipArtifactMetadata: Implements UrlDownloadFileMetadata for pip artifacts
    • PypiJsonObject: Record class for parsing PyPI JSON API responses
  4. Updated IdeContext:

    • Added getPipRepository() method to interface
    • Implemented in AbstractIdeContext with field, getter, and factory method
  5. Created PipRepositoryMock for testing:

    • Mocks PyPI JSON API responses using WireMock
    • Follows pattern of NpmRepositoryMock
  6. Updated test resources:

    • Consolidated URL files to single urls file (removed OS-specific duplicates)
    • Removed uv.cmd (not needed)
    • Added pip.json mock for PyPI API response
  7. Updated PipTest:

    • Tests install functionality (verifies uv pip install pip== is called)
    • Tests run functionality (verifies pip --version runs through uv)

Test Results:

  • PipTest: 2 tests, 0 failures ✅
  • IdeContextTest: 10 tests, 0 failures ✅
  • NpmTest: 3 tests, 0 failures ✅

The implementation now follows the reviewer's requirements to make pip a LocalToolCommandlet that delegates installation to uv pip install while being able to resolve versions from PyPI.

@maybeec
Copy link
Member Author

maybeec commented Dec 1, 2025

@hohwille

For my curiosity: I am happy that you upgraded setup-java action lib. Is this required for this PR and especially why did you change the JDK distribution to zulu?

See my comment: #1597 (comment)
There was no intention to take Zulu, it was basically most compatible with oracle and open source. That's why.

I could get rid of it again if you like, but it's also so tiny that I feel it's still in the "okish" area as I fully agree to the point you are making to provide refactorings in separate PRs is way more healthy.

Copy link
Member

@hohwille hohwille left a comment

Choose a reason for hiding this comment

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

@maybeec thanks for the rework. You perfectly addressed my review-feedback. Great job implementing the PipRepository which is surely not a simple task to get right. Also the mocking for tests is done perfectly 🥇


// Create installation path and write version file
this.context.getFileAccess().mkdirs(installationPath);
this.context.writeVersionFile(resolvedVersion, installationPath);
Copy link
Member

Choose a reason for hiding this comment

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

is the installationPath then software/pip that will contain nothing but the .ide.software.version file for pip then? Not wrong but maybe confusing. For npm based stuff we do not write these .ide.software.version and ask npm for the installed version via CLI. We could also do that here via pip list.
However, to keep it constructive and efficient, I would conclude that you have done a great job with this PR and this is ready for merge now. I can add further perfection with separate PRs once I find some time.
There is nothing wrong here.

@hohwille
Copy link
Member

hohwille commented Dec 5, 2025

Sorry, that I broke your PR. I am just assuming what we have as "standards" in IDEasy for commandlets but that is currently not the case for Pip.
I am on a rework anyway so I will fix everything and get it merged and you do not have to worry.

@hohwille hohwille mentioned this pull request Dec 7, 2025
15 tasks
@hohwille
Copy link
Member

hohwille commented Dec 7, 2025

I created PR #1639 that can replace this one. Thanks again for the great work.

@hohwille hohwille closed this Dec 7, 2025
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in IDEasy board Dec 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commandlet ide sub-command pip Python package manager (Pip Installs Packages) python runtime for python language

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Implement ToolCommandlet for pip

4 participants