From d43a7c5f6ec2806c43c374d598c756a116c3d95b Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 27 May 2014 11:54:12 +0200 Subject: [PATCH 1/2] Added requiremin/requiremax fields for apps Apps can now specify a minimum and maximum version of ownCloud in which they are supported. --- lib/private/app.php | 84 +++++++++--- lib/private/installer.php | 5 +- tests/lib/app.php | 274 +++++++++++++++++++++++++++++--------- 3 files changed, 272 insertions(+), 91 deletions(-) diff --git a/lib/private/app.php b/lib/private/app.php index 575cc9f41a..50065197eb 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -231,7 +231,7 @@ class OC_App{ // check if the app is compatible with this version of ownCloud $info=OC_App::getAppInfo($app); $version=OC_Util::getVersion(); - if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { + if(!self::isAppCompatible($version, $info)) { throw new \Exception( $l->t("App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", array($info['name']) @@ -898,7 +898,7 @@ class OC_App{ foreach($apps as $app) { // check if the app is compatible with this version of ownCloud $info = OC_App::getAppInfo($app); - if(!isset($info['require']) or !self::isAppVersionCompatible($version, $info['require'])) { + if(!self::isAppCompatible($version, $info)) { OC_Log::write('core', 'App "'.$info['name'].'" ('.$app.') can\'t be used because it is' .' not compatible with this version of ownCloud', @@ -909,38 +909,78 @@ class OC_App{ } } + /** + * Ajust the number of version parts of $version1 to match + * the number of version parts of $version2. + * + * @param string $version1 version to adjust + * @param string $version2 version to take the number of parts from + * @return string shortened $version1 + */ + private static function adjustVersionParts($version1, $version2) { + $version1 = explode('.', $version1); + $version2 = explode('.', $version2); + // reduce $version1 to match the number of parts in $version2 + while (count($version1) > count($version2)) { + array_pop($version1); + } + // if $version1 does not have enough parts, add some + while (count($version1) < count($version2)) { + $version1[] = '0'; + } + return implode('.', $version1); + } /** - * Compares the app version with the owncloud version to see if the app - * requires a newer version than the currently active one - * @param array $owncloudVersions array with 3 entries: major minor bugfix - * @param string $appRequired the required version from the xml - * major.minor.bugfix + * Check whether the current ownCloud version matches the given + * application's version requirements. + * + * The comparison is made based on the number of parts that the + * app info version has. For example for ownCloud 6.0.3 if the + * app info version is expecting version 6.0, the comparison is + * made on the first two parts of the ownCloud version. + * This means that it's possible to specify "requiremin" => 6 + * and "requiremax" => 6 and it will still match ownCloud 6.0.3. + * + * @param string $ocVersion ownCloud version to check against + * @param array $appInfo app info (from xml) + * * @return boolean true if compatible, otherwise false */ - public static function isAppVersionCompatible($owncloudVersions, $appRequired){ - $appVersions = explode('.', $appRequired); + public static function isAppCompatible($ocVersion, $appInfo){ + $requireMin = ''; + $requireMax = ''; + if (isset($appInfo['requiremin'])) { + $requireMin = $appInfo['requiremin']; + } else if (isset($appInfo['require'])) { + $requireMin = $appInfo['require']; + } - for($i=0; $i $appVersion) { - return true; - } + if (!empty($requireMin) + && version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<') + ) { + + return false; + } + + if (!empty($requireMax) + && version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>') + ) { + + return false; } return true; } - /** * get the installed version of all apps */ diff --git a/lib/private/installer.php b/lib/private/installer.php index 667c05c9c1..3bddfa6a3b 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -133,10 +133,7 @@ class OC_Installer{ } // check if the app is compatible with this version of ownCloud - if( - !isset($info['require']) - or !OC_App::isAppVersionCompatible(OC_Util::getVersion(), $info['require']) - ) { + if(!OC_App::isAppCompatible(OC_Util::getVersion(), $info)) { OC_Helper::rmdirr($extractDir); throw new \Exception($l->t("App can't be installed because it is not compatible with this version of ownCloud")); } diff --git a/tests/lib/app.php b/tests/lib/app.php index 683820cabb..e2b578fe6b 100644 --- a/tests/lib/app.php +++ b/tests/lib/app.php @@ -1,6 +1,7 @@ + * Copyright (c) 2014 Vincent Petry * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -8,75 +9,218 @@ class Test_App extends PHPUnit_Framework_TestCase { - - public function testIsAppVersionCompatibleSingleOCNumber(){ - $oc = array(4); - $app = '4.0'; - - $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app)); + function appVersionsProvider() { + return array( + // exact match + array( + '6.0.0.0', + array( + 'requiremin' => '6.0', + 'requiremax' => '6.0', + ), + true + ), + // in-between match + array( + '6.0.0.0', + array( + 'requiremin' => '5.0', + 'requiremax' => '7.0', + ), + true + ), + // app too old + array( + '6.0.0.0', + array( + 'requiremin' => '5.0', + 'requiremax' => '5.0', + ), + false + ), + // app too new + array( + '5.0.0.0', + array( + 'requiremin' => '6.0', + 'requiremax' => '6.0', + ), + false + ), + // only min specified + array( + '6.0.0.0', + array( + 'requiremin' => '6.0', + ), + true + ), + // only min specified fail + array( + '5.0.0.0', + array( + 'requiremin' => '6.0', + ), + false + ), + // only min specified legacy + array( + '6.0.0.0', + array( + 'require' => '6.0', + ), + true + ), + // only min specified legacy fail + array( + '4.0.0.0', + array( + 'require' => '6.0', + ), + false + ), + // only max specified + array( + '5.0.0.0', + array( + 'requiremax' => '6.0', + ), + true + ), + // only max specified fail + array( + '7.0.0.0', + array( + 'requiremax' => '6.0', + ), + false + ), + // variations of versions + // single OC number + array( + '4', + array( + 'require' => '4.0', + ), + true + ), + // multiple OC number + array( + '4.3.1', + array( + 'require' => '4.3', + ), + true + ), + // single app number + array( + '4', + array( + 'require' => '4', + ), + true + ), + // single app number fail + array( + '4.3', + array( + 'require' => '5', + ), + false + ), + // complex + array( + '5.0.0', + array( + 'require' => '4.5.1', + ), + true + ), + // complex fail + array( + '4.3.1', + array( + 'require' => '4.3.2', + ), + false + ), + // two numbers + array( + '4.3.1', + array( + 'require' => '4.4', + ), + false + ), + // one number fail + array( + '4.3.1', + array( + 'require' => '5', + ), + false + ), + // pre-alpha app + array( + '5.0.3', + array( + 'require' => '4.93', + ), + true + ), + // pre-alpha OC + array( + '6.90.0.2', + array( + 'require' => '6.90', + ), + true + ), + // pre-alpha OC max + array( + '6.90.0.2', + array( + 'requiremax' => '7', + ), + true + ), + // expect same major number match + array( + '5.0.3', + array( + 'require' => '5', + ), + true + ), + // expect same major number match + array( + '5.0.3', + array( + 'requiremax' => '5', + ), + true + ), + ); } - - public function testIsAppVersionCompatibleMultipleOCNumber(){ - $oc = array(4, 3, 1); - $app = '4.3'; - - $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app)); + /** + * @dataProvider appVersionsProvider + */ + public function testIsAppCompatible($ocVersion, $appInfo, $expectedResult) { + $this->assertEquals($expectedResult, OC_App::isAppCompatible($ocVersion, $appInfo)); } - - public function testIsAppVersionCompatibleSingleNumber(){ - $oc = array(4); - $app = '4'; - - $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app)); - } - - - public function testIsAppVersionCompatibleSingleAppNumber(){ - $oc = array(4, 3); - $app = '4'; - - $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app)); - } - - - public function testIsAppVersionCompatibleComplex(){ - $oc = array(5, 0, 0); - $app = '4.5.1'; - - $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app)); - } - - - public function testIsAppVersionCompatibleShouldFail(){ - $oc = array(4, 3, 1); - $app = '4.3.2'; - - $this->assertFalse(OC_App::isAppVersionCompatible($oc, $app)); - } - - public function testIsAppVersionCompatibleShouldFailTwoVersionNumbers(){ - $oc = array(4, 3, 1); - $app = '4.4'; - - $this->assertFalse(OC_App::isAppVersionCompatible($oc, $app)); - } - - - public function testIsAppVersionCompatibleShouldWorkForPreAlpha(){ - $oc = array(5, 0, 3); - $app = '4.93'; - - $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app)); - } - - - public function testIsAppVersionCompatibleShouldFailOneVersionNumbers(){ - $oc = array(4, 3, 1); - $app = '5'; - - $this->assertFalse(OC_App::isAppVersionCompatible($oc, $app)); + /** + * Test that the isAppCompatible method also supports passing an array + * as $ocVersion + */ + public function testIsAppCompatibleWithArray() { + $ocVersion = array(6); + $appInfo = array( + 'requiremin' => '6', + 'requiremax' => '6', + ); + $this->assertTrue(OC_App::isAppCompatible($ocVersion, $appInfo)); } /** From c64e920b4d6520cfe3638262d17aadfcb28936f4 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Tue, 27 May 2014 11:54:44 +0200 Subject: [PATCH 2/2] Adjust core apps to use "requiremin" instead of "require" Also added a few missing authors. --- apps/files/appinfo/info.xml | 4 ++-- apps/files_encryption/appinfo/info.xml | 2 +- apps/files_external/appinfo/info.xml | 4 ++-- apps/files_sharing/appinfo/info.xml | 4 ++-- apps/files_trashbin/appinfo/info.xml | 2 +- apps/files_versions/appinfo/info.xml | 4 ++-- apps/user_ldap/appinfo/info.xml | 2 +- apps/user_webdavauth/appinfo/info.xml | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/files/appinfo/info.xml b/apps/files/appinfo/info.xml index 3480037853..390d645e2a 100644 --- a/apps/files/appinfo/info.xml +++ b/apps/files/appinfo/info.xml @@ -4,8 +4,8 @@ Files File Management AGPL - Robin Appelman - 4.93 + Robin Appelman, Vincent Petry + 4.93 true diff --git a/apps/files_encryption/appinfo/info.xml b/apps/files_encryption/appinfo/info.xml index 15a09a29f5..b11272f63e 100644 --- a/apps/files_encryption/appinfo/info.xml +++ b/apps/files_encryption/appinfo/info.xml @@ -5,7 +5,7 @@ The ownCloud files encryption system provides server side-encryption. After the app is enabled you need to re-login to initialize your encryption keys. Please note that server side encryption requires that the ownCloud server admin can be trusted. The main purpose of this app is the encryption of files that are stored on externally mounted storages. AGPL Sam Tuke, Bjoern Schiessle, Florin Peter - 4 + 4 true http://doc.owncloud.org/server/6.0/user_manual/files/encryption.html diff --git a/apps/files_external/appinfo/info.xml b/apps/files_external/appinfo/info.xml index 0542b7b10a..2698706c09 100644 --- a/apps/files_external/appinfo/info.xml +++ b/apps/files_external/appinfo/info.xml @@ -4,8 +4,8 @@ External storage support Mount external storage sources AGPL - Robin Appelman, Michael Gapczynski - 4.93 + Robin Appelman, Michael Gapczynski, Vincent Petry + 4.93 true diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml index 9b42c1e17b..077433a53a 100644 --- a/apps/files_sharing/appinfo/info.xml +++ b/apps/files_sharing/appinfo/info.xml @@ -4,8 +4,8 @@ Share Files File sharing between users AGPL - Michael Gapczynski - 4.93 + Michael Gapczynski, Bjoern Schiessle + 4.93 true diff --git a/apps/files_trashbin/appinfo/info.xml b/apps/files_trashbin/appinfo/info.xml index 2cc7d9a7ac..860d6b1242 100644 --- a/apps/files_trashbin/appinfo/info.xml +++ b/apps/files_trashbin/appinfo/info.xml @@ -19,7 +19,7 @@ AGPL Bjoern Schiessle true - 4.9 + 4.9 diff --git a/apps/files_versions/appinfo/info.xml b/apps/files_versions/appinfo/info.xml index a735caee94..5d536638fe 100644 --- a/apps/files_versions/appinfo/info.xml +++ b/apps/files_versions/appinfo/info.xml @@ -3,8 +3,8 @@ files_versions Versions AGPL - Frank Karlitschek - 4.93 + Frank Karlitschek, Bjoern Schiessle + 4.93 true ownCloud supports simple version control for files. The versioning app diff --git a/apps/user_ldap/appinfo/info.xml b/apps/user_ldap/appinfo/info.xml index e4a4375a73..b70f0c5435 100644 --- a/apps/user_ldap/appinfo/info.xml +++ b/apps/user_ldap/appinfo/info.xml @@ -9,7 +9,7 @@ AGPL Dominik Schmidt and Arthur Schiwon - 4.93 + 4.93 true diff --git a/apps/user_webdavauth/appinfo/info.xml b/apps/user_webdavauth/appinfo/info.xml index 20c5909cc1..16e6942505 100755 --- a/apps/user_webdavauth/appinfo/info.xml +++ b/apps/user_webdavauth/appinfo/info.xml @@ -7,7 +7,7 @@ This app is not compatible with the LDAP user and group backend. AGPL Frank Karlitschek - 4.93 + 4.93 true