]> source.dussan.org Git - nextcloud-server.git/commitdiff
Added requiremin/requiremax fields for apps
authorVincent Petry <pvince81@owncloud.com>
Tue, 27 May 2014 09:54:12 +0000 (11:54 +0200)
committerVincent Petry <pvince81@owncloud.com>
Tue, 27 May 2014 09:54:12 +0000 (11:54 +0200)
Apps can now specify a minimum and maximum version of ownCloud in which
they are supported.

lib/private/app.php
lib/private/installer.php
tests/lib/app.php

index 575cc9f41af67b0b83095b86ed2cfea3bae95eb7..50065197eb4ef395df2f8d68f55b38fde37e32f6 100644 (file)
@@ -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<count($appVersions); $i++){
-                       $appVersion = (int) $appVersions[$i];
+               if (isset($appInfo['requiremax'])) {
+                       $requireMax = $appInfo['requiremax'];
+               }
 
-                       if(isset($owncloudVersions[$i])){
-                               $owncloudVersion = $owncloudVersions[$i];
-                       } else {
-                               $owncloudVersion = 0;
-                       }
+               if (is_array($ocVersion)) {
+                       $ocVersion = implode('.', $ocVersion);
+               }
 
-                       if($owncloudVersion < $appVersion){
-                               return false;
-                       } elseif ($owncloudVersion > $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
         */
index 667c05c9c1608076e960d5440dd673bcb381425b..3bddfa6a3b73b671a97185242056704e09b49902 100644 (file)
@@ -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"));
                }
index 683820cabb6fdd76c1e374d87d06ebff8a0919ba..e2b578fe6b9185d2223d5a075bf7c4415085e65b 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 /**
  * Copyright (c) 2012 Bernhard Posselt <dev@bernhard-posselt.com>
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
 
 class Test_App extends PHPUnit_Framework_TestCase {
 
-       
-       public function testIsAppVersionCompatibleSingleOCNumber(){
-               $oc = array(4);
-               $app = '4.0';
-
-               $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
-       }
-
-       
-       public function testIsAppVersionCompatibleMultipleOCNumber(){
-               $oc = array(4, 3, 1);
-               $app = '4.3';
-
-               $this->assertTrue(OC_App::isAppVersionCompatible($oc, $app));
-       }
-
-
-       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));
+       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 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));
+       /**
+        * @dataProvider appVersionsProvider
+        */
+       public function testIsAppCompatible($ocVersion, $appInfo, $expectedResult) {
+               $this->assertEquals($expectedResult, OC_App::isAppCompatible($ocVersion, $appInfo));
        }
 
-
-       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));
        }
 
        /**