Browse Source

Added requiremin/requiremax fields for apps

Apps can now specify a minimum and maximum version of ownCloud in which
they are supported.
remotes/origin/ldap_group_count
Vincent Petry 12 years ago
parent
commit
d43a7c5f6e
  1. 84
      lib/private/app.php
  2. 5
      lib/private/installer.php
  3. 274
      tests/lib/app.php

84
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<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
*/

5
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"));
}

274
tests/lib/app.php

@ -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.
@ -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));
}
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));
}
/**

Loading…
Cancel
Save