Skip to content

feat: support uv to download package#60

Open
fatelei wants to merge 2 commits intojunjiem:mainfrom
fatelei:uv
Open

feat: support uv to download package#60
fatelei wants to merge 2 commits intojunjiem:mainfrom
fatelei:uv

Conversation

@fatelei
Copy link

@fatelei fatelei commented Mar 20, 2026

fix #61

Summary by CodeRabbit

  • Bug Fixes

    • Hardened directory handling and added early exits for safer repackaging
    • Improved dependency resolution and offline packaging reliability
    • Streamlined ignore-file cleanup and macOS backup handling
  • New Features

    • Multi-step dependency pipeline with automatic requirement generation when missing
    • Platform-target selection for packaging and an option to allow prerelease dependency resolution
    • Expanded, structured logging with file-size reporting for downloads and final packages

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

📝 Walkthrough

Walkthrough

Reworked plugin_repackaging.sh to harden directory handling, implement robust pip detection, add optional uv-based generation of requirements.txt from pyproject.toml, perform multi-step wheel downloads with --prefer-binary, refine ignore-file handling, add CLI flags (-R, -p) and structured status logging for each step.

Changes

Cohort / File(s) Summary
Repackage script
plugin_repackaging.sh
Major refactor of repackage() and CLI parsing: detect usable pip (python3 -m pippippip3), detect/adjust Python version for pip invocation, support optional uv resolution to generate requirements.txt from pyproject.toml (with -R to allow prereleases), download wheels into ./wheels with --prefer-binary, count/report downloaded artifacts and sizes, update requirements.txt for offline packaging, remove ^wheels/ ignore entries (prefer .difyignore over .gitignore) and consolidate macOS .bak cleanup, enforce `cd $CURR_DIR

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Script as plugin_repackaging.sh
    participant Python as Python/pip
    participant UV as uv (optional)
    participant FS as Filesystem

    User->>Script: invoke script (with -p / -R as needed)
    Script->>FS: cd $CURR_DIR || exit 1
    Script->>Python: detect pip (python3 -m pip / pip / pip3)
    alt pip not found
        Script->>User: exit with error
    else pip found
        Script->>FS: check for `requirements.txt` or `pyproject.toml`
        alt pyproject.toml present and requirements absent
            Script->>UV: run `uv lock`/`uv export` (with --prerelease when -R) to generate requirements.txt
            UV->>Script: success/fail
            alt fail
                Script->>User: exit with error
            end
        end
        Script->>Python: `pip download --prefer-binary -r requirements.txt` -> `./wheels`
        Python->>Script: wheels downloaded (file sizes/count)
        Script->>FS: update requirements for offline, remove `^wheels/` from ignore, cleanup .bak
        Script->>FS: package plugin to `OUTPUT_PACKAGE` (report success/failure and final size)
        Script->>User: exit with status
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through scripts and toggled flags,
Chose pip with care and skipped the snags,
Asked UV kindly for a list to sow,
Gathered wheels where binary winds blow,
Packaged snug — a carrot-wrapped bag.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: support uv to download package' directly describes the main change: adding uv support for downloading packages in the repackaging workflow.
Linked Issues check ✅ Passed The PR implements uv support for package downloads as required by issue #61, including version detection, platform handling, uv lock/export pipeline, and offline mode updates.
Out of Scope Changes check ✅ Passed All changes focus on adding uv support and improving logging/directory handling in plugin_repackaging.sh, which are directly aligned with issue #61 requirements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugin_repackaging.sh`:
- Around line 155-159: The script currently runs cd ${CURR_DIR} then continues
unconditionally; add an immediate failure check after attempting to change
directory so the script exits (with an error message) if cd into CURR_DIR fails,
before running chmod or invoking ${CMD_NAME} to package
${PACKAGE_NAME}-${PACKAGE_SUFFIX}; ensure you test the cd result (and quote
variables) and abort early to avoid running the package command from the wrong
working directory.
- Around line 126-132: Change the logic so we only attempt to run "uv pip
compile pyproject.toml -o requirements.txt --index-url ${PIP_MIRROR_URL}" when
requirements.txt does not already exist: if requirements.txt is missing and
pyproject.toml exists, check for command -v uv and run the compile; if uv is not
available print a clear error like "pyproject.toml present but 'uv' not
installed; please provide requirements.txt or install uv" and exit non-zero.
This prevents overwriting an existing requirements.txt and fails gracefully when
uv is required but unavailable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cab7acdd-ccc6-4f6f-9727-d9b296642076

📥 Commits

Reviewing files that changed from the base of the PR and between bf1f8da and da61c77.

📒 Files selected for processing (2)
  • dify-plugin-darwin-arm64
  • plugin_repackaging.sh

@kurokobo
Copy link

@fatelei
Thanks for working on this.

I haven't been able to test it thoroughly yet, but when there is a pyproject.toml inside the difypkg, the Plugin Daemon runs uv sync. So I think it would be good if this repackager could add the following section to it:

[tool.uv]
no-index = true
find-links = ["./wheels"]

If there is no pyproject.toml, it falls back to uv pip install, and in that case, the existing sed on requirements.txt should still work.

With this change, I think we can fully revert the --offline implementation on the Plugin Daemon side. What do you think?

@fatelei
Copy link
Author

fatelei commented Mar 20, 2026

@fatelei Thanks for working on this.

I haven't been able to test it thoroughly yet, but when there is a pyproject.toml inside the difypkg, the Plugin Daemon runs uv sync. So I think it would be good if this repackager could add the following section to it:

[tool.uv]
no-index = true
find-links = ["./wheels"]

If there is no pyproject.toml, it falls back to uv pip install, and in that case, the existing sed on requirements.txt should still work.

With this change, I think we can fully revert the --offline implementation on the Plugin Daemon side. What do you think?

ok

@kurokobo
Copy link

@fatelei
Could you add logic to append three lines to pyproject.toml?
If we want to implement it roughly, we could simply echo those three lines, or even just delete pyproject.toml and intentionally fall back to requirements.txt.

Anyway, I’ve made a PR to revert --offline: langgenius/dify-plugin-daemon#651

@kurokobo
Copy link

Published simplified alternative with pyproject.toml support: https://github.com/kurokobo/dify-plugin-offline-packager

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
plugin_repackaging.sh (3)

181-191: Remove redundant 2>&1 redirections.

The &> operator already redirects both stdout and stderr, making the trailing 2>&1 redundant.

♻️ Proposed fix
-	if python3 -m pip --version &> /dev/null 2>&1; then
+	if python3 -m pip --version &> /dev/null; then
 		PIP_CMD="python3 -m pip"
-	elif command -v pip &> /dev/null && pip --version &> /dev/null 2>&1; then
+	elif command -v pip &> /dev/null && pip --version &> /dev/null; then
 		PIP_CMD=pip
-	elif command -v pip3 &> /dev/null && pip3 --version &> /dev/null 2>&1; then
+	elif command -v pip3 &> /dev/null && pip3 --version &> /dev/null; then
 		PIP_CMD=pip3
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin_repackaging.sh` around lines 181 - 191, The shell snippet setting
PIP_CMD contains redundant redirections like "&> /dev/null 2>&1"; edit the
if/elif conditions that check python3 -m pip --version, pip --version, and pip3
--version to remove the trailing "2>&1" so each redirect uses only "&>
/dev/null", keeping the same checks and assignments for PIP_CMD and leaving the
echo/exit behavior unchanged; update the three occurrences around the commands
referenced (the python3 -m pip check and the pip and pip3 checks) to eliminate
the duplicate stderr redirection.

238-255: Redundant pattern *manylinux* in case statement.

The pattern *linux* already matches strings containing "manylinux", making *manylinux* redundant in the alternation.

♻️ Proposed fix
 	case "$RAW_PLATFORM" in
-		*linux*|*manylinux* )
+		*linux* )
 			UV_PLATFORM="linux"
 			echo "Target platform: Linux (cross-compilation from $OS_TYPE)"
 			;;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin_repackaging.sh` around lines 238 - 255, The case branch matching
RAW_PLATFORM contains a redundant pattern "*manylinux*" because "*linux*"
already covers it; update the case in plugin_repackaging.sh to remove
"*manylinux*" from the linux alternative so the branch reads only "*linux*"
(keep setting UV_PLATFORM="linux" and the echo as-is) and ensure no other
branches rely on the removed pattern.

155-179: Consider checking awk/mv exit status before confirming success.

The success message on line 178 prints regardless of whether the awk or mv commands actually succeeded. If either fails, the message is misleading.

♻️ Proposed fix
-		' "$PYFILE" > "$PYFILE.tmp" && mv "$PYFILE.tmp" "$PYFILE"
-		echo "Injected [tool.uv] into $PYFILE"
+		' "$PYFILE" > "$PYFILE.tmp" && mv "$PYFILE.tmp" "$PYFILE" || {
+			echo "✗ Warning: Failed to inject [tool.uv] into $PYFILE"
+			return 1
+		}
+		echo "✓ Injected [tool.uv] into $PYFILE"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin_repackaging.sh` around lines 155 - 179, The success message is printed
unconditionally in inject_uv_into_pyproject even if the awk or mv commands fail;
update the function to detect and handle failures: run the awk pipeline writing
to "$PYFILE.tmp" and capture its exit status, only attempt mv when awk
succeeded, check mv's exit status too, remove the temporary file on failure (or
use a safe mktemp name) and only echo "Injected [tool.uv] into $PYFILE" when
both commands succeeded; reference the inject_uv_into_pyproject function, the
awk invocation that writes to "$PYFILE.tmp", and the mv "$PYFILE.tmp" "$PYFILE"
operation when implementing these checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugin_repackaging.sh`:
- Around line 367-369: Update the step header string to reflect the correct
sequence: change the echo that prints "Step 4: Packaging plugin" to "Step 5:
Packaging plugin" so the header matches the actual workflow order; locate the
echo block containing the exact string "Step 4: Packaging plugin" (the
three-line echo block) and update that string only, leaving the surrounding
separators and other echo statements unchanged.

---

Nitpick comments:
In `@plugin_repackaging.sh`:
- Around line 181-191: The shell snippet setting PIP_CMD contains redundant
redirections like "&> /dev/null 2>&1"; edit the if/elif conditions that check
python3 -m pip --version, pip --version, and pip3 --version to remove the
trailing "2>&1" so each redirect uses only "&> /dev/null", keeping the same
checks and assignments for PIP_CMD and leaving the echo/exit behavior unchanged;
update the three occurrences around the commands referenced (the python3 -m pip
check and the pip and pip3 checks) to eliminate the duplicate stderr
redirection.
- Around line 238-255: The case branch matching RAW_PLATFORM contains a
redundant pattern "*manylinux*" because "*linux*" already covers it; update the
case in plugin_repackaging.sh to remove "*manylinux*" from the linux alternative
so the branch reads only "*linux*" (keep setting UV_PLATFORM="linux" and the
echo as-is) and ensure no other branches rely on the removed pattern.
- Around line 155-179: The success message is printed unconditionally in
inject_uv_into_pyproject even if the awk or mv commands fail; update the
function to detect and handle failures: run the awk pipeline writing to
"$PYFILE.tmp" and capture its exit status, only attempt mv when awk succeeded,
check mv's exit status too, remove the temporary file on failure (or use a safe
mktemp name) and only echo "Injected [tool.uv] into $PYFILE" when both commands
succeeded; reference the inject_uv_into_pyproject function, the awk invocation
that writes to "$PYFILE.tmp", and the mv "$PYFILE.tmp" "$PYFILE" operation when
implementing these checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9782931c-f8f7-46c8-8f7d-131780cdfd19

📥 Commits

Reviewing files that changed from the base of the PR and between a71c1b1 and cb26b2a.

📒 Files selected for processing (1)
  • plugin_repackaging.sh

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.

support uv to download package

2 participants