Skip to content

feat(python): add pyproject.toml support and uv path settings (TC-3860)#256

Closed
a-oren wants to merge 1 commit into
redhat-developer:mainfrom
a-oren:TC-3860
Closed

feat(python): add pyproject.toml support and uv path settings (TC-3860)#256
a-oren wants to merge 1 commit into
redhat-developer:mainfrom
a-oren:TC-3860

Conversation

@a-oren

@a-oren a-oren commented Apr 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add pyproject.toml recognition as a Python manifest across all plugin code paths (stack analysis, component analysis, exclude/SA intentions)
  • Add PyprojectCAAnnotator for TOML-based dependency parsing and vulnerability annotations
  • Add uv executable path setting to the settings UI with TRUSTIFY_DA_UV_PATH system property propagation
  • Bump trustify-da-java-client to 0.0.17-SNAPSHOT and trustify-da-api-spec to 2.0.7 for pyproject.toml pip report support and uv provider

Test plan

  • Open pyproject.toml in IntelliJ — verify red lines appear on vulnerable dependencies
  • Right-click pyproject.toml → verify "Dependency Analytics Report" action appears and generates report
  • Settings → Dependency Analytics → verify "uv > Executable: Path" field exists
  • Open requirements.txt → verify existing functionality unchanged
  • Test with uv.lock present → verify uv provider is used instead of pip
  • Test with complex deps (extras, markers, version ranges) → verify annotations appear

🤖 Generated with Claude Code

Add pyproject.toml recognition as a Python manifest across all plugin
code paths (stack analysis, component analysis, exclude/SA intentions).
Add PyprojectCAAnnotator for TOML-based dependency parsing and
vulnerability annotations. Add uv executable path setting to the
settings UI with TRUSTIFY_DA_UV_PATH system property propagation.
Bump trustify-da-java-client to 0.0.17-SNAPSHOT and api-spec to 2.0.7
for pyproject.toml pip report support and uv provider.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Add pyproject.toml support and uv path settings for Python dependency analysis

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add pyproject.toml recognition as Python manifest file across all plugin code paths
• Implement PyprojectCAAnnotator for TOML-based dependency parsing and vulnerability annotations
• Add uv executable path setting to settings UI with TRUSTIFY_DA_UV_PATH system property
  propagation
• Bump trustify-da-java-client to 0.0.17-SNAPSHOT and trustify-da-api-spec to 2.0.7
Diagram
flowchart LR
  A["pyproject.toml<br/>manifest file"] -->|"recognized in"| B["CAAnnotator<br/>ExcludeManifestIntentionAction<br/>SAIntentionAction<br/>SaAction<br/>SaUtils"]
  A -->|"parsed by"| C["PyprojectCAAnnotator<br/>PyprojectCAInspection"]
  C -->|"creates"| D["Vulnerability<br/>annotations"]
  E["Settings UI"] -->|"adds"| F["uv executable<br/>path field"]
  F -->|"propagates"| G["TRUSTIFY_DA_UV_PATH<br/>system property"]
  H["Dependencies"] -->|"bumped to"| I["trustify-da-java-client<br/>0.0.17-SNAPSHOT<br/>trustify-da-api-spec<br/>2.0.7"]
Loading

Grey Divider

File Changes

1. src/main/java/org/jboss/tools/intellij/componentanalysis/CAAnnotator.java ✨ Enhancement +1/-1

Add pyproject.toml to package manager detection

src/main/java/org/jboss/tools/intellij/componentanalysis/CAAnnotator.java


2. src/main/java/org/jboss/tools/intellij/componentanalysis/ExcludeManifestIntentionAction.java ✨ Enhancement +1/-0

Add pyproject.toml file availability check

src/main/java/org/jboss/tools/intellij/componentanalysis/ExcludeManifestIntentionAction.java


3. src/main/java/org/jboss/tools/intellij/componentanalysis/SAIntentionAction.java ✨ Enhancement +1/-0

Add pyproject.toml file availability check

src/main/java/org/jboss/tools/intellij/componentanalysis/SAIntentionAction.java


View more (12)
4. src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java ✨ Enhancement +260/-0

New TOML-based dependency parser and annotator

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java


5. src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAInspection.java ✨ Enhancement +39/-0

New inspection tool for pyproject.toml files

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAInspection.java


6. src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java ✨ Enhancement +70/-0

New quick fix action for pyproject.toml dependencies

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java


7. src/main/java/org/jboss/tools/intellij/exhort/ApiService.java ✨ Enhancement +7/-2

Add uv path system property and pyproject.toml support

src/main/java/org/jboss/tools/intellij/exhort/ApiService.java


8. src/main/java/org/jboss/tools/intellij/settings/ApiSettingsComponent.java ✨ Enhancement +21/-0

Add uv executable path UI field and label

src/main/java/org/jboss/tools/intellij/settings/ApiSettingsComponent.java


9. src/main/java/org/jboss/tools/intellij/settings/ApiSettingsConfigurable.java ✨ Enhancement +3/-0

Add uv path to settings modification and persistence

src/main/java/org/jboss/tools/intellij/settings/ApiSettingsConfigurable.java


10. src/main/java/org/jboss/tools/intellij/settings/ApiSettingsState.java ✨ Enhancement +1/-0

Add uvPath field to persistent settings state

src/main/java/org/jboss/tools/intellij/settings/ApiSettingsState.java


11. src/main/java/org/jboss/tools/intellij/stackanalysis/SaAction.java ✨ Enhancement +1/-0

Add pyproject.toml to supported manifest files list

src/main/java/org/jboss/tools/intellij/stackanalysis/SaAction.java


12. src/main/java/org/jboss/tools/intellij/stackanalysis/SaUtils.java ✨ Enhancement +2/-0

Add pyproject.toml to SA analysis and package manager detection

src/main/java/org/jboss/tools/intellij/stackanalysis/SaUtils.java


13. src/test/java/org/jboss/tools/intellij/componentanalysis/ManifestExclusionManagerSimpleTest.java 🧪 Tests +1/-1

Add pyproject.toml to manifest file test cases

src/test/java/org/jboss/tools/intellij/componentanalysis/ManifestExclusionManagerSimpleTest.java


14. gradle/libs.versions.toml Dependencies +2/-2

Bump trustify-da dependencies to latest versions

gradle/libs.versions.toml


15. src/main/resources/META-INF/plugin.xml ⚙️ Configuration changes +9/-0

Register pyproject.toml inspection and annotator plugins

src/main/resources/META-INF/plugin.xml


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Apr 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0)

Grey Divider


Action required

1. Quickfix drops extras/markers 🐞 Bug ≡ Correctness
Description
PyprojectCAIntentionAction rewrites the whole dependency entry to "<name>==<version>", which drops
PEP508 extras ("pkg[extra]") and environment markers ("; ...") and can change the dependency
semantics when users apply the quick-fix.
Code

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java[R45-58]

+        String depString = text.substring(1, text.length() - 1);
+        String name = PyprojectCAAnnotator.parseName(depString);
+        if (name == null) {
+            return;
+        }
+
+        String newText = "\"" + name + "==" + version + "\"";
+        Document document = PsiDocumentManager.getInstance(project).getDocument(file);
+        if (document != null) {
+            int start = literal.getTextRange().getStartOffset();
+            int end = literal.getTextRange().getEndOffset();
+            document.replaceString(start, end, newText);
+            PsiDocumentManager.getInstance(project).commitDocument(document);
+        }
Evidence
The quick-fix reconstructs the string from only the parsed name and a pinned version, so any suffix
content in the original literal (extras, specifier ranges, markers) is lost. Additionally, the
annotator considers a quick-fix applicable whenever any non-blank trailing text exists (including
marker-only dependencies), increasing the chance of destructive rewrites.

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java[35-58]
src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[140-157]
src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[207-218]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The pyproject.toml quick-fix currently replaces the entire dependency string literal with `"<name>==<version>"`, which discards extras (`[extra]`), environment markers (`; ...`), and any existing specifier structure.

### Issue Context
For pyproject dependencies, users commonly include extras and/or environment markers in the same string literal. The quick-fix should update only the version portion (or replace the version spec portion) while preserving any extras and markers.

### Fix Focus Areas
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java[35-58]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[140-157]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[207-218]

### Suggested implementation direction
- Parse the original dependency string into `{name, extras, versionSpec, marker}` (at minimum, split on the first `;` to preserve marker suffix).
- When applying the fix, rebuild as `name + extras + "==" + version + marker` (or keep the existing operator strategy, but preserve extras/marker).
- Tighten `isQuickFixApplicable` to only return true when an actual version specifier/operator exists, not when the suffix is marker-only.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Single-quoted deps skipped 🐞 Bug ≡ Correctness
Description
PyprojectCAAnnotator only treats TOML string literals as dependencies when they are double-quoted,
so single-quoted dependency strings are ignored (no vulnerability annotations and ignore comments
won’t match).
Code

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[R123-126]

+            String text = literal.getText();
+            if (text.length() < 2 || !text.startsWith("\"") || !text.endsWith("\"")) {
+                continue;
+            }
Evidence
Dependency extraction, ignore parsing, and quick-fix applicability all require
TomlLiteral.getText() to start/end with a double quote, so a valid TOML string literal using
single quotes will be skipped. In contrast, existing TOML quick-fix code elsewhere in the repo
explicitly supports both quote styles when editing TOML literals, indicating the plugin should
handle both.

src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[111-137]
src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[159-174]
src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[207-214]
src/main/java/org/jboss/tools/intellij/componentanalysis/cargo/CargoCAIntentionAction.java[70-83]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
PyprojectCAAnnotator currently only recognizes dependency string literals when they are wrapped in double quotes (`"..."`). Single-quoted TOML string literals (`'...'`) will be skipped in:
- dependency extraction
- ignore comment association
- quick-fix applicability

### Issue Context
Other TOML handling in this repo preserves/handles both `"` and `'` quote styles during updates, so pyproject parsing should accept both styles for consistency and to avoid missing dependencies.

### Fix Focus Areas
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[111-137]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[159-174]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[207-214]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java[35-58]

### Suggested implementation direction
- Introduce a small helper like `unwrapTomlStringLiteral(String text)` that:
 - detects quote char (`"` or `'`)
 - validates matching end quote
 - returns the unquoted content + the quote char for later reconstruction.
- Use it in `parseDependencyArray`, `getIgnoredDependencies`, `isQuickFixApplicable`, and `updateVersion` so single-quoted strings are parsed and preserved on write.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@sonarqubecloud

Copy link
Copy Markdown

Comment on lines +45 to +58
String depString = text.substring(1, text.length() - 1);
String name = PyprojectCAAnnotator.parseName(depString);
if (name == null) {
return;
}

String newText = "\"" + name + "==" + version + "\"";
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
if (document != null) {
int start = literal.getTextRange().getStartOffset();
int end = literal.getTextRange().getEndOffset();
document.replaceString(start, end, newText);
PsiDocumentManager.getInstance(project).commitDocument(document);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Quickfix drops extras/markers 🐞 Bug ≡ Correctness

PyprojectCAIntentionAction rewrites the whole dependency entry to "<name>==<version>", which drops
PEP508 extras ("pkg[extra]") and environment markers ("; ...") and can change the dependency
semantics when users apply the quick-fix.
Agent Prompt
### Issue description
The pyproject.toml quick-fix currently replaces the entire dependency string literal with `"<name>==<version>"`, which discards extras (`[extra]`), environment markers (`; ...`), and any existing specifier structure.

### Issue Context
For pyproject dependencies, users commonly include extras and/or environment markers in the same string literal. The quick-fix should update only the version portion (or replace the version spec portion) while preserving any extras and markers.

### Fix Focus Areas
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java[35-58]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[140-157]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[207-218]

### Suggested implementation direction
- Parse the original dependency string into `{name, extras, versionSpec, marker}` (at minimum, split on the first `;` to preserve marker suffix).
- When applying the fix, rebuild as `name + extras + "==" + version + marker` (or keep the existing operator strategy, but preserve extras/marker).
- Tighten `isQuickFixApplicable` to only return true when an actual version specifier/operator exists, not when the suffix is marker-only.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +123 to +126
String text = literal.getText();
if (text.length() < 2 || !text.startsWith("\"") || !text.endsWith("\"")) {
continue;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Single-quoted deps skipped 🐞 Bug ≡ Correctness

PyprojectCAAnnotator only treats TOML string literals as dependencies when they are double-quoted,
so single-quoted dependency strings are ignored (no vulnerability annotations and ignore comments
won’t match).
Agent Prompt
### Issue description
PyprojectCAAnnotator currently only recognizes dependency string literals when they are wrapped in double quotes (`"..."`). Single-quoted TOML string literals (`'...'`) will be skipped in:
- dependency extraction
- ignore comment association
- quick-fix applicability

### Issue Context
Other TOML handling in this repo preserves/handles both `"` and `'` quote styles during updates, so pyproject parsing should accept both styles for consistency and to avoid missing dependencies.

### Fix Focus Areas
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[111-137]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[159-174]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAAnnotator.java[207-214]
- src/main/java/org/jboss/tools/intellij/componentanalysis/pypi/PyprojectCAIntentionAction.java[35-58]

### Suggested implementation direction
- Introduce a small helper like `unwrapTomlStringLiteral(String text)` that:
  - detects quote char (`"` or `'`)
  - validates matching end quote
  - returns the unquoted content + the quote char for later reconstruction.
- Use it in `parseDependencyArray`, `getIgnoredDependencies`, `isQuickFixApplicable`, and `updateVersion` so single-quoted strings are parsed and preserved on write.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@a-oren

a-oren commented Apr 27, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: upstream already merged pyproject.toml support via #244. Will rebase and re-submit with only the remaining changes (version bump + uv settings).

@a-oren a-oren closed this Apr 27, 2026
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