PY-82426 conda: environment.yaml: Fix add dependencies in edge cases

Signed-off-by: Nikita.Ashihmin <nikita.ashihmin@jetbrains.com>

GitOrigin-RevId: d2cfa776a63ab9bd629e31fd8a87a65fe7506ecd
This commit is contained in:
Nikita.Ashihmin
2025-07-05 23:22:37 +00:00
committed by intellij-monorepo-bot
parent d6fe8316e9
commit c5be56c32b
5 changed files with 56 additions and 0 deletions
@@ -56,6 +56,8 @@ class PyRequirementVisitor(
val sdk = module.pythonSdk ?: return
val manager = PythonPackageManager.forSdk(module.project, sdk)
val requirementsManager = manager.getDependencyManager() ?: return
if (requirementsManager.getDependenciesFile() == null)
return
val installedNotDeclaredChecker = InstalledButNotDeclaredChecker(ignoredPackages, manager)
val packageName = installedNotDeclaredChecker.getUndeclaredPackageName(importedPyModule = importedPyModule) ?: return
@@ -45,6 +45,10 @@ object EnvironmentYmlModifier {
val dependenciesText = "dependencies:"
val dependenciesIndex = text.indexOf(dependenciesText)
if (dependenciesIndex < 0) {
modifiedContent.append("\ndependencies:\n - $packageName")
}
if (dependenciesIndex >= 0) {
// Find the indentation level by looking at existing entries
val indentPattern = INDENT_PATTERN
@@ -0,0 +1,21 @@
# environment.yml - Comprehensive test file for dependency parsing
name: test-environment
channels:
- defaults
- conda-forge
- bioconda
- pytorch
- nvidia
- anaconda
- https://conda.anaconda.org/pyviz
# Environment variables
variables:
CUDA_HOME: /usr/local/cuda
PYTHONPATH: /custom/python/path
API_KEY: your-api-key-here
DEBUG: "1"
# Prefix for installation (optional)
prefix: /path/to/conda/envs/test-environment
@@ -0,0 +1 @@
tqdm==1.2.3
@@ -4,6 +4,7 @@ package com.jetbrains.python.packaging.conda
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFileManager
import com.jetbrains.python.fixtures.PyTestCase
import com.jetbrains.python.packaging.PyRequirement
import com.jetbrains.python.packaging.PyRequirementParser
import com.jetbrains.python.packaging.conda.environmentYml.format.CondaEnvironmentYmlParser
import com.jetbrains.python.packaging.conda.environmentYml.format.EnvironmentYmlModifier
@@ -11,6 +12,33 @@ import org.junit.jupiter.api.Assertions
import java.io.File
class EnvironmentYmlHelperTest : PyTestCase() {
fun testAddRequirementEmpty() {
val virtualFile = getVirtualFileByName("$testDataPath/requirement/environmentYmlEmpty/environment.yml")!!
// Create a temporary copy of the file
val tempDir = FileUtil.createTempDirectory(getTestName(false), null)
val tempFile = File(tempDir.path, "environment.yml")
virtualFile.inputStream.use { input ->
tempFile.outputStream().use { output ->
input.copyTo(output)
}
}
val tempVirtualFile = VirtualFileManager.getInstance().refreshAndFindFileByUrl("file://${tempFile.absolutePath}")!!
// Parse the updated file and check if the package was added
val requirements = CondaEnvironmentYmlParser.fromFile(tempVirtualFile)!!
Assertions.assertEquals(emptyList<PyRequirement>(), requirements)
// Add a new package that doesn't exist in the file
val newPackageName = "new-test-package"
EnvironmentYmlModifier.addRequirement(myFixture.project, tempVirtualFile, newPackageName)
val newPackageRequirement = PyRequirementParser.fromLine(newPackageName)!!
// Parse the file again and check that the package appears only once
val updatedRequirements = CondaEnvironmentYmlParser.fromFile(tempVirtualFile)!!
Assertions.assertEquals(listOf(newPackageRequirement), updatedRequirements)
}
fun testAddRequirement() {
val virtualFile = getVirtualFileByName("$testDataPath/requirement/environmentYml/environment.yml")!!