Skip to content

Commit 48dc82c

Browse files
ruromeroclaude
andcommitted
refactor: remove all Poetry fallbacks and related code
Poetry dependencies are explicitly rejected; remove the remaining Poetry-specific fallbacks for name/version/license, the Poetry dependency parsing and version-conversion methods, and all corresponding tests to avoid false expectations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3378a54 commit 48dc82c

2 files changed

Lines changed: 0 additions & 218 deletions

File tree

src/main/java/io/github/guacsec/trustifyda/providers/PythonPyprojectProvider.java

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,6 @@ protected String getRootComponentName() {
349349
if (name != null && !name.isBlank()) {
350350
return name;
351351
}
352-
String poetryName = toml.getString("tool.poetry.name");
353-
if (poetryName != null && !poetryName.isBlank()) {
354-
return poetryName;
355-
}
356352
} catch (IOException e) {
357353
log.fine("Failed to parse pyproject.toml for root component name: " + e.getMessage());
358354
}
@@ -367,10 +363,6 @@ protected String getRootComponentVersion() {
367363
if (version != null && !version.isBlank()) {
368364
return version;
369365
}
370-
String poetryVersion = toml.getString("tool.poetry.version");
371-
if (poetryVersion != null && !poetryVersion.isBlank()) {
372-
return poetryVersion;
373-
}
374366
} catch (IOException e) {
375367
log.fine("Failed to parse pyproject.toml for root component version: " + e.getMessage());
376368
}
@@ -390,10 +382,6 @@ public String readLicenseFromManifest() {
390382
if (licenseText != null && !licenseText.isBlank()) {
391383
return licenseText;
392384
}
393-
String poetryLicense = toml.getString("tool.poetry.license");
394-
if (poetryLicense != null && !poetryLicense.isBlank()) {
395-
return poetryLicense;
396-
}
397385
} catch (IOException e) {
398386
log.fine("Failed to parse pyproject.toml for license: " + e.getMessage());
399387
}
@@ -437,16 +425,6 @@ private void collectIgnoredDeps() throws IOException {
437425
checkIgnored(rawLines, dep, dep);
438426
}
439427
}
440-
441-
// [tool.poetry.dependencies] - production only
442-
TomlTable poetryDeps = toml.getTable("tool.poetry.dependencies");
443-
if (poetryDeps != null) {
444-
for (String name : poetryDeps.keySet()) {
445-
if (!"python".equalsIgnoreCase(name)) {
446-
checkIgnored(rawLines, name, name);
447-
}
448-
}
449-
}
450428
}
451429

452430
List<String> parseDependencyStrings() throws IOException {
@@ -461,15 +439,6 @@ List<String> parseDependencyStrings() throws IOException {
461439
}
462440
}
463441

464-
TomlTable poetryDeps = toml.getTable("tool.poetry.dependencies");
465-
if (poetryDeps != null) {
466-
for (String name : poetryDeps.keySet()) {
467-
if (!"python".equalsIgnoreCase(name)) {
468-
deps.add(poetryDepToRequirement(name, poetryDeps, name));
469-
}
470-
}
471-
}
472-
473442
return deps;
474443
}
475444

@@ -482,80 +451,6 @@ private void checkIgnored(List<String> rawLines, String searchToken, String depI
482451
}
483452
}
484453

485-
/**
486-
* Converts a Poetry dependency entry to a pip-compatible requirement string. Poetry uses {@code
487-
* ^} and {@code ~} operators which are not PEP 440, so they must be converted to PEP 440 ranges.
488-
*/
489-
static String poetryDepToRequirement(String name, TomlTable table, String key) {
490-
String version = null;
491-
if (table.isString(key)) {
492-
version = table.getString(key);
493-
} else if (table.isTable(key)) {
494-
TomlTable depTable = table.getTable(key);
495-
if (depTable != null) {
496-
version = depTable.getString("version");
497-
}
498-
}
499-
if (version == null || version.isEmpty() || "*".equals(version)) {
500-
return name;
501-
}
502-
return name + convertPoetryVersion(version);
503-
}
504-
505-
/**
506-
* Converts a Poetry version constraint to PEP 440 format.
507-
*
508-
* <ul>
509-
* <li>{@code ^X.Y.Z} → {@code >=X.Y.Z,<(X+1).0.0} (when X &gt; 0)
510-
* <li>{@code ^0.Y.Z} → {@code >=0.Y.Z,<0.(Y+1).0} (when Y &gt; 0)
511-
* <li>{@code ^0.0.Z} → {@code >=0.0.Z,<0.0.(Z+1)}
512-
* <li>{@code ~X.Y.Z} → {@code >=X.Y.Z,<X.(Y+1).0}
513-
* <li>PEP 440 operators ({@code >=}, {@code ==}, etc.) are passed through unchanged
514-
* </ul>
515-
*/
516-
static String convertPoetryVersion(String version) {
517-
if (version.startsWith("^")) {
518-
return convertCaret(version.substring(1));
519-
}
520-
if (version.startsWith("~") && !version.startsWith("~=")) {
521-
return convertTilde(version.substring(1));
522-
}
523-
if (version.matches("^\\d.*")) {
524-
return "==" + version;
525-
}
526-
// Already PEP 440 compatible (>=, ==, ~=, !=, etc.)
527-
return version;
528-
}
529-
530-
private static int parseNumericPart(String part) {
531-
return Integer.parseInt(part.replaceAll("[^0-9].*", ""));
532-
}
533-
534-
private static String convertCaret(String ver) {
535-
String[] parts = ver.split("\\.");
536-
int major = parseNumericPart(parts[0]);
537-
int minor = parts.length > 1 ? parseNumericPart(parts[1]) : 0;
538-
int patch = parts.length > 2 ? parseNumericPart(parts[2]) : 0;
539-
String fullVer = major + "." + minor + "." + patch;
540-
541-
if (major > 0) {
542-
return ">=" + fullVer + ",<" + (major + 1) + ".0.0";
543-
}
544-
if (minor > 0) {
545-
return ">=" + fullVer + ",<0." + (minor + 1) + ".0";
546-
}
547-
return ">=" + fullVer + ",<0.0." + (patch + 1);
548-
}
549-
550-
private static String convertTilde(String ver) {
551-
String[] parts = ver.split("\\.");
552-
int major = parseNumericPart(parts[0]);
553-
int minor = parts.length > 1 ? parseNumericPart(parts[1]) : 0;
554-
int patch = parts.length > 2 ? parseNumericPart(parts[2]) : 0;
555-
String fullVer = major + "." + minor + "." + patch;
556-
return ">=" + fullVer + ",<" + major + "." + (minor + 1) + ".0";
557-
}
558-
559454
static final class PipPackage {
560455
final String name;
561456
final String version;

src/test/java/io/github/guacsec/trustifyda/providers/Python_Pyproject_Provider_Test.java

Lines changed: 0 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import static org.assertj.core.api.Assertions.assertThat;
2020
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
21-
import static org.assertj.core.api.Assertions.assertThatNoException;
2221

2322
import io.github.guacsec.trustifyda.Api;
2423
import io.github.guacsec.trustifyda.ExhortTest;
@@ -64,34 +63,6 @@ void test_parse_pep621_excludes_optional_dependencies() throws IOException {
6463
assertThat(deps).doesNotContain("click==8.0.4");
6564
}
6665

67-
@Test
68-
void test_parse_poetry_dependencies_converts_to_pep440() throws IOException {
69-
Path pyprojectPath =
70-
Path.of("src/test/resources/tst_manifests/pip/pip_pyproject_toml_poetry/pyproject.toml");
71-
var provider = new PythonPyprojectProvider(pyprojectPath);
72-
List<String> deps = provider.parseDependencyStrings();
73-
assertThat(deps)
74-
.contains("anyio>=3.6.2,<4.0.0", "flask>=2.0.3,<3.0.0", "requests>=2.25.1,<3.0.0");
75-
}
76-
77-
@Test
78-
void test_parse_poetry_excludes_python() throws IOException {
79-
Path pyprojectPath =
80-
Path.of("src/test/resources/tst_manifests/pip/pip_pyproject_toml_poetry/pyproject.toml");
81-
var provider = new PythonPyprojectProvider(pyprojectPath);
82-
List<String> deps = provider.parseDependencyStrings();
83-
assertThat(deps).doesNotContain("python");
84-
}
85-
86-
@Test
87-
void test_parse_poetry_excludes_dev_group_dependencies() throws IOException {
88-
Path pyprojectPath =
89-
Path.of("src/test/resources/tst_manifests/pip/pip_pyproject_toml_poetry/pyproject.toml");
90-
var provider = new PythonPyprojectProvider(pyprojectPath);
91-
List<String> deps = provider.parseDependencyStrings();
92-
assertThat(deps).doesNotContain("click", "click>=8.0.4,<9.0.0");
93-
}
94-
9566
@Test
9667
void test_provideStack_rejects_poetry_dependencies() {
9768
Path pyprojectPath =
@@ -112,65 +83,6 @@ void test_provideComponent_rejects_poetry_dependencies() {
11283
.withMessageContaining("Poetry dependencies in pyproject.toml are not supported");
11384
}
11485

115-
@Test
116-
void test_convert_caret_major() {
117-
assertThat(PythonPyprojectProvider.convertPoetryVersion("^3.6.2")).isEqualTo(">=3.6.2,<4.0.0");
118-
}
119-
120-
@Test
121-
void test_convert_caret_zero_major() {
122-
assertThat(PythonPyprojectProvider.convertPoetryVersion("^0.5.1")).isEqualTo(">=0.5.1,<0.6.0");
123-
}
124-
125-
@Test
126-
void test_convert_caret_zero_zero() {
127-
assertThat(PythonPyprojectProvider.convertPoetryVersion("^0.0.3")).isEqualTo(">=0.0.3,<0.0.4");
128-
}
129-
130-
@Test
131-
void test_convert_caret_two_parts() {
132-
assertThat(PythonPyprojectProvider.convertPoetryVersion("^2.0")).isEqualTo(">=2.0.0,<3.0.0");
133-
}
134-
135-
@Test
136-
void test_convert_tilde() {
137-
assertThat(PythonPyprojectProvider.convertPoetryVersion("~1.2.3")).isEqualTo(">=1.2.3,<1.3.0");
138-
}
139-
140-
@Test
141-
void test_convert_tilde_two_parts() {
142-
assertThat(PythonPyprojectProvider.convertPoetryVersion("~1.2")).isEqualTo(">=1.2.0,<1.3.0");
143-
}
144-
145-
@Test
146-
void test_pep440_passthrough() {
147-
assertThat(PythonPyprojectProvider.convertPoetryVersion(">=2.0")).isEqualTo(">=2.0");
148-
assertThat(PythonPyprojectProvider.convertPoetryVersion("==1.0.0")).isEqualTo("==1.0.0");
149-
assertThat(PythonPyprojectProvider.convertPoetryVersion("~=1.4")).isEqualTo("~=1.4");
150-
}
151-
152-
@Test
153-
void test_convert_bare_version_prepends_equals() {
154-
assertThat(PythonPyprojectProvider.convertPoetryVersion("1.2.3")).isEqualTo("==1.2.3");
155-
assertThat(PythonPyprojectProvider.convertPoetryVersion("2.0")).isEqualTo("==2.0");
156-
}
157-
158-
@Test
159-
void test_convert_caret_prerelease_does_not_crash() {
160-
assertThatNoException()
161-
.isThrownBy(() -> PythonPyprojectProvider.convertPoetryVersion("^1.2.3b1"));
162-
assertThat(PythonPyprojectProvider.convertPoetryVersion("^1.2.3b1"))
163-
.isEqualTo(">=1.2.3,<2.0.0");
164-
}
165-
166-
@Test
167-
void test_convert_tilde_prerelease_does_not_crash() {
168-
assertThatNoException()
169-
.isThrownBy(() -> PythonPyprojectProvider.convertPoetryVersion("~1.2.3rc1"));
170-
assertThat(PythonPyprojectProvider.convertPoetryVersion("~1.2.3rc1"))
171-
.isEqualTo(">=1.2.3,<1.3.0");
172-
}
173-
17486
@Test
17587
void test_ignored_deps_collected_during_parsing() throws IOException {
17688
Path pyprojectPath =
@@ -193,14 +105,6 @@ void test_getRootComponentName_reads_pep621_name() {
193105
assertThat(provider.getRootComponentName()).isEqualTo("test-project");
194106
}
195107

196-
@Test
197-
void test_getRootComponentName_reads_poetry_name() {
198-
Path pyprojectPath =
199-
Path.of("src/test/resources/tst_manifests/pip/pip_pyproject_toml_poetry/pyproject.toml");
200-
var provider = new PythonPyprojectProvider(pyprojectPath);
201-
assertThat(provider.getRootComponentName()).isEqualTo("test-project");
202-
}
203-
204108
@Test
205109
void test_getRootComponentName_falls_back_to_default() {
206110
Path pyprojectPath =
@@ -219,14 +123,6 @@ void test_getRootComponentVersion_reads_pep621_version() {
219123
assertThat(provider.getRootComponentVersion()).isEqualTo("2.0.0");
220124
}
221125

222-
@Test
223-
void test_getRootComponentVersion_reads_poetry_version() {
224-
Path pyprojectPath =
225-
Path.of("src/test/resources/tst_manifests/pip/pip_pyproject_toml_poetry/pyproject.toml");
226-
var provider = new PythonPyprojectProvider(pyprojectPath);
227-
assertThat(provider.getRootComponentVersion()).isEqualTo("0.1.0");
228-
}
229-
230126
@Test
231127
void test_getRootComponentVersion_falls_back_to_default() {
232128
Path pyprojectPath =
@@ -245,15 +141,6 @@ void test_readLicenseFromManifest_reads_pep621_license() {
245141
assertThat(provider.readLicenseFromManifest()).isEqualTo("MIT");
246142
}
247143

248-
@Test
249-
void test_readLicenseFromManifest_reads_poetry_license() {
250-
Path pyprojectPath =
251-
Path.of(
252-
"src/test/resources/tst_manifests/pip/pip_pyproject_toml_poetry_license/pyproject.toml");
253-
var provider = new PythonPyprojectProvider(pyprojectPath);
254-
assertThat(provider.readLicenseFromManifest()).isEqualTo("Apache-2.0");
255-
}
256-
257144
// --- pip report parsing tests ---
258145

259146
@Test

0 commit comments

Comments
 (0)