diff --git a/README.md b/README.md index 8c6f8e9d..f0451261 100644 --- a/README.md +++ b/README.md @@ -629,7 +629,7 @@ This increasing the chances and the probability a lot that the automatic install ##### Usage A New setting is introduced - `TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS` (as both env variable/key in `options` object) 1. `TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS`="false" - install requirements.txt while respecting declared versions for all packages. -2. `TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS`="true" - install all packages from requirements.txt, not respecting the declared version, but trying to install a version tailored for the used python version, when using this setting,you must set setting `MATCH_MANIFEST_VERSIONS`="false" +2. `TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS`="true" - install all packages from requirements.txt, not respecting the declared version, but trying to install a version tailored for the used python version. When using this setting, you must set `TRUSTIFY_DA_PYTHON_VIRTUAL_ENV`="true" and `MATCH_MANIFEST_VERSIONS`="false" ##### Using `pipdeptree` By Default, The API algorithm will use native commands of PIP installer as data source to build the dependency tree. diff --git a/src/main/java/io/github/guacsec/trustifyda/utils/PythonControllerBase.java b/src/main/java/io/github/guacsec/trustifyda/utils/PythonControllerBase.java index c7441cb9..7ee7b385 100644 --- a/src/main/java/io/github/guacsec/trustifyda/utils/PythonControllerBase.java +++ b/src/main/java/io/github/guacsec/trustifyda/utils/PythonControllerBase.java @@ -75,12 +75,20 @@ void installPackages(String pathToRequirements) { public final List> getDependencies( String pathToRequirements, boolean includeTransitive) { + boolean installBestEfforts = + Environment.getBoolean(PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS, false); + if (installBestEfforts && !automaticallyInstallPackageOnEnvironment()) { + throw new IllegalStateException( + "Conflicting settings, " + + PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS + + "=true requires " + + PROP_TRUSTIFY_DA_PYTHON_VIRTUAL_ENV + + "=true"); + } if (isVirtualEnv() || isRealEnv()) { prepareEnvironment(pathToPythonBin); } if (automaticallyInstallPackageOnEnvironment()) { - boolean installBestEfforts = - Environment.getBoolean(PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS, false); /* make best efforts to install the requirements.txt on the virtual environment created from the python3 passed in. that means that it will install the packages without referring to @@ -90,7 +98,7 @@ public final List> getDependencies( if (installBestEfforts) { boolean matchManifestVersions = Environment.getBoolean(PROP_MATCH_MANIFEST_VERSIONS, true); if (matchManifestVersions) { - throw new RuntimeException( + throw new IllegalStateException( "Conflicting settings, " + PythonControllerBase.PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS + "=true can only work with " diff --git a/src/test/java/io/github/guacsec/trustifyda/utils/PythonControllerRealEnvTest.java b/src/test/java/io/github/guacsec/trustifyda/utils/PythonControllerRealEnvTest.java index 4aa98d2c..43fee7fd 100644 --- a/src/test/java/io/github/guacsec/trustifyda/utils/PythonControllerRealEnvTest.java +++ b/src/test/java/io/github/guacsec/trustifyda/utils/PythonControllerRealEnvTest.java @@ -17,6 +17,8 @@ package io.github.guacsec.trustifyda.utils; import static io.github.guacsec.trustifyda.Provider.PROP_MATCH_MANIFEST_VERSIONS; +import static io.github.guacsec.trustifyda.utils.PythonControllerBase.PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS; +import static io.github.guacsec.trustifyda.utils.PythonControllerBase.PROP_TRUSTIFY_DA_PYTHON_VIRTUAL_ENV; import static io.github.guacsec.trustifyda.utils.PythonControllerBaseTest.matchCommandPipFreeze; import static io.github.guacsec.trustifyda.utils.PythonControllerBaseTest.matchCommandPipShow; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -334,6 +336,21 @@ void get_Dependency_Name_with_extras_and_special_operators() { PythonControllerRealEnv.getDependencyName("package[extra]~=1.0 ; python_version >= \"3\"")); } + /** Verifies that BEST_EFFORTS=true without VIRTUAL_ENV=true throws a descriptive error. */ + @Test + @RestoreSystemProperties + @SetSystemProperty(key = PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS, value = "true") + @SetSystemProperty(key = PROP_TRUSTIFY_DA_PYTHON_VIRTUAL_ENV, value = "false") + void best_Efforts_Without_Virtual_Env_Should_Throw_Runtime_Exception() { + String requirementsTxt = getFileFromString("requirements.txt", "flask==9.9.9\n"); + IllegalStateException exception = + assertThrows( + IllegalStateException.class, + () -> pythonControllerRealEnv.getDependencies(requirementsTxt, true)); + assertTrue(exception.getMessage().contains(PROP_TRUSTIFY_DA_PYTHON_INSTALL_BEST_EFFORTS)); + assertTrue(exception.getMessage().contains(PROP_TRUSTIFY_DA_PYTHON_VIRTUAL_ENV)); + } + @Test void automaticallyInstallPackageOnEnvironment() { assertFalse(pythonControllerRealEnv.automaticallyInstallPackageOnEnvironment());