Skip to content

Commit 376d0cd

Browse files
ruromeroclaude
andcommitted
fix(pypi): preserve PEP 508 extras and markers in quick fix and version extraction
The version extraction regex was matching across the ';' environment marker boundary, and the quick fix was dropping extras and markers when rewriting the dependency string. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 604b465 commit 376d0cd

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,36 @@ static String extractPep508Name(String depString) {
330330
return null;
331331
}
332332

333+
static String extractPep508Extras(String depString) {
334+
if (depString == null || depString.isEmpty()) {
335+
return null;
336+
}
337+
Matcher nameMatcher = PEP508_NAME_PATTERN.matcher(depString.trim());
338+
if (!nameMatcher.find()) {
339+
return null;
340+
}
341+
String afterName = depString.substring(nameMatcher.end()).trim();
342+
if (afterName.startsWith("[")) {
343+
int closeBracket = afterName.indexOf(']');
344+
if (closeBracket >= 0) {
345+
return afterName.substring(0, closeBracket + 1);
346+
}
347+
}
348+
return null;
349+
}
350+
351+
static String extractPep508Markers(String depString) {
352+
if (depString == null || depString.isEmpty()) {
353+
return null;
354+
}
355+
int semiColon = depString.indexOf(';');
356+
if (semiColon >= 0) {
357+
String markers = depString.substring(semiColon).trim();
358+
return markers.isEmpty() ? null : markers;
359+
}
360+
return null;
361+
}
362+
333363
static String extractPep508Version(String depString) {
334364
if (depString == null || depString.isEmpty()) {
335365
return null;
@@ -347,6 +377,11 @@ static String extractPep508Version(String depString) {
347377
afterName = afterName.substring(closeBracket + 1).trim();
348378
}
349379
}
380+
// Strip environment markers (everything after ';')
381+
int semiColon = afterName.indexOf(';');
382+
if (semiColon >= 0) {
383+
afterName = afterName.substring(0, semiColon).trim();
384+
}
350385
if (afterName.isEmpty()) {
351386
return null;
352387
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,17 @@ protected void updateVersion(@NotNull Project project, Editor editor, PsiFile fi
4545
String depString = PyprojectCAAnnotator.unquote(literal.getText());
4646
String name = PyprojectCAAnnotator.extractPep508Name(depString);
4747
if (name != null) {
48-
replaceVersionLiteral(project, file, literal, name + "==" + version);
48+
String extras = PyprojectCAAnnotator.extractPep508Extras(depString);
49+
String markers = PyprojectCAAnnotator.extractPep508Markers(depString);
50+
StringBuilder newDep = new StringBuilder(name);
51+
if (extras != null) {
52+
newDep.append(extras);
53+
}
54+
newDep.append("==").append(version);
55+
if (markers != null) {
56+
newDep.append(" ").append(markers);
57+
}
58+
replaceVersionLiteral(project, file, literal, newDep.toString());
4959
}
5060
} else if (element instanceof TomlKeyValue keyValue) {
5161
// Poetry: key-value pair like anyio = "^3.6.2"

0 commit comments

Comments
 (0)