diff --git a/src/MipsEqLogicTrait.php b/src/MipsEqLogicTrait.php index 09933a1..8105bab 100644 --- a/src/MipsEqLogicTrait.php +++ b/src/MipsEqLogicTrait.php @@ -194,14 +194,15 @@ private static function getRequiredPackageDetail(string $requirementLine, &$pack * Return the installed package detail from the installed packages list if it exists * * @param string $packageName - * @param string $installedPackages the list of installed packages in the format 'package==version||package==version' + * @param array $installedPackages the list of installed packages * @param string[] $packageDetail if the package is installed, it will contain the following: * - [0] 'package==version' * - [1] the version * @return bool true if the package is installed, false otherwise */ - private static function getInstalledPackageDetail(string $packageName, string $installedPackages, &$packageDetail) { - return preg_match('/' . $packageName . '==([\d+\.?]+)/i', $installedPackages, $packageDetail) === 1; + private static function getInstalledPackageDetail(string $packageName, array $installedPackages, &$packageDetail) { + $packages = "||" . join("||", $installedPackages); + return preg_match('/\|\|\K' . $packageName . '==([\d+\.?]+)/i', $packages, $packageDetail) === 1; } private static function pythonRequirementsInstalled(string $pythonPath, string $requirementsPath) { @@ -209,19 +210,20 @@ private static function pythonRequirementsInstalled(string $pythonPath, string $ return false; } exec("{$pythonPath} -m pip freeze", $packages_installed); - $packages = join("||", $packages_installed); exec("cat {$requirementsPath}", $requirements); foreach ($requirements as $requirement_line) { if (self::getRequiredPackageDetail($requirement_line, $package_details)) { - list($required_package_name, $required_package_operator, $required_package_version) = $package_details; - if (self::getInstalledPackageDetail($required_package_name, $packages, $install)) { - if ($required_package_operator == '==' && $required_package_version != $install[1]) { + if (self::getInstalledPackageDetail($package_details['name'], $packages_installed, $install)) { + if ($package_details['operator'] == '==' && $package_details['version'] != $install[1]) { + log::add(__CLASS__, 'debug', "Package {$package_details['name']} version is {$install[1]} but version {$package_details['version']} is required"); return false; - } elseif (version_compare($required_package_version, $install[1], '>')) { + } elseif (version_compare($package_details['version'], $install[1], '>')) { + log::add(__CLASS__, 'debug', "Package {$package_details['name']} version is {$install[1]} but version at least {$package_details['version']} is required"); return false; } } else { + log::add(__CLASS__, 'debug', "Package {$package_details['name']} seems not installed"); return false; } } diff --git a/tests/MipsEqLogicTraitTest.php b/tests/MipsEqLogicTraitTest.php index ad76d03..443b4fc 100644 --- a/tests/MipsEqLogicTraitTest.php +++ b/tests/MipsEqLogicTraitTest.php @@ -57,6 +57,24 @@ public function testgetRequiredPackageDetail_greaterthan() { $this->assertEquals('1.0.0', $details['version']); } + public function testgetRequiredPackageDetail_greater_or_equal() { + $trait = new class { + use MipsEqLogicTrait { + getRequiredPackageDetail as public; // make the method public + } + }; + + $result = $trait->getRequiredPackageDetail('requests>=2.31', $details); + $this->assertTrue($result); + $this->assertCount(7, $details); + $this->assertEquals('requests', $details[1]); + $this->assertEquals('requests', $details['name']); + $this->assertEquals('>=', $details[2]); + $this->assertEquals('>=', $details['operator']); + $this->assertEquals('2.31', $details[3]); + $this->assertEquals('2.31', $details['version']); + } + public function testgetRequiredPackageDetail_extra() { $trait = new class { use MipsEqLogicTrait { @@ -147,6 +165,24 @@ public function testgetRequiredPackageDetail_equal() { $this->assertEquals('1.0.0', $details['version']); } + public function testgetRequiredPackageDetail_package_with_hyphen() { + $trait = new class { + use MipsEqLogicTrait { + getRequiredPackageDetail as public; // make the method public + } + }; + + $result = $trait->getRequiredPackageDetail('python-slugify~=8.0.4', $details); + $this->assertTrue($result); + $this->assertCount(7, $details); + $this->assertEquals('python-slugify', $details[1]); + $this->assertEquals('python-slugify', $details['name']); + $this->assertEquals('~=', $details[2]); + $this->assertEquals('~=', $details['operator']); + $this->assertEquals('8.0.4', $details[3]); + $this->assertEquals('8.0.4', $details['version']); + } + public function testgetRequiredPackageDetail_only_name() { $trait = new class { use MipsEqLogicTrait { @@ -196,7 +232,6 @@ public function testgetRequiredPackageDetail_invalidPackage() { $this->assertFalse($result); } - // tests on getInstalledPackageDetail public function testgetInstalledPackageDetail_present() { $trait = new class { use MipsEqLogicTrait { @@ -204,7 +239,7 @@ public function testgetInstalledPackageDetail_present() { } }; - $result = $trait->getInstalledPackageDetail('jeedomdaemon', 'jeedomdaemon==1.1.0||anotherpackage==1.1.1', $details); + $result = $trait->getInstalledPackageDetail('jeedomdaemon', ['jeedomdaemon==1.1.0', 'anotherpackage==1.1.1'], $details); $this->assertTrue($result); $this->assertEquals('jeedomdaemon==1.1.0', $details[0]); $this->assertEquals('1.1.0', $details[1]); @@ -218,7 +253,7 @@ public function testgetInstalledPackageDetail_present_mix_case() { } }; - $result = $trait->getInstalledPackageDetail('unidecode', 'Unidecode==1.1.0||anotherpackage==1.1.1', $details); + $result = $trait->getInstalledPackageDetail('unidecode', ['Unidecode==1.1.0', 'anotherpackage==1.1.1'], $details); $this->assertTrue($result); $this->assertEquals('Unidecode==1.1.0', $details[0]); $this->assertEquals('1.1.0', $details[1]); @@ -231,7 +266,29 @@ public function testgetInstalledPackageDetail_absent() { } }; - $result = $trait->getInstalledPackageDetail('jeedomdaemon', 'anotherpackage==1.1.1', $details); + $result = $trait->getInstalledPackageDetail('jeedomdaemon', ['anotherpackage==1.1.1'], $details); + $this->assertFalse($result); + } + + public function testgetInstalledPackageDetail_absent_hyphen() { + $trait = new class { + use MipsEqLogicTrait { + getInstalledPackageDetail as public; // make the method public + } + }; + + $result = $trait->getInstalledPackageDetail('Unidecode', ['requests-toolbelt==1.0.0', 'text-unidecode==1.3'], $details); + $this->assertFalse($result); + } + + public function testgetInstalledPackageDetail_absent_hyphen2() { + $trait = new class { + use MipsEqLogicTrait { + getInstalledPackageDetail as public; // make the method public + } + }; + + $result = $trait->getInstalledPackageDetail('requests', ['requests-toolbelt==1.0.0', 'text-unidecode==1.3'], $details); $this->assertFalse($result); } }