diff options
author | Morris Jobke <hey@morrisjobke.de> | 2015-06-19 14:40:15 +0200 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2015-06-19 14:40:15 +0200 |
commit | 5ed9743570173fbea59f150c2fe8da8d6c681cba (patch) | |
tree | 9271bbcec92b163be62f3cfcf4b0f95e542eac0e | |
parent | 5c2646a4bfe235487ba4177bd5733a278ab2101e (diff) | |
parent | b230b8e2c6aa59ccc72b99d8c3b12d67c51693c3 (diff) | |
download | nextcloud-server-5ed9743570173fbea59f150c2fe8da8d6c681cba.tar.gz nextcloud-server-5ed9743570173fbea59f150c2fe8da8d6c681cba.zip |
Merge pull request #17041 from owncloud/ocp-since-checker
Add tool to check OCP for missing @since tag
-rwxr-xr-x | autotest.sh | 3 | ||||
-rw-r--r-- | build/OCPSinceChecker.php | 115 | ||||
-rw-r--r-- | lib/public/appframework/db/doesnotexistexception.php | 1 | ||||
-rw-r--r-- | lib/public/appframework/db/entity.php | 10 | ||||
-rw-r--r-- | lib/public/appframework/db/mapper.php | 2 | ||||
-rw-r--r-- | lib/public/appframework/db/multipleobjectsreturnedexception.php | 1 | ||||
-rw-r--r-- | lib/public/defaults.php | 1 | ||||
-rw-r--r-- | lib/public/files/folder.php | 1 | ||||
-rw-r--r-- | lib/public/files/locknotacquiredexception.php | 10 | ||||
-rw-r--r-- | lib/public/iuser.php | 2 | ||||
-rw-r--r-- | lib/public/iusermanager.php | 1 |
11 files changed, 146 insertions, 1 deletions
diff --git a/autotest.sh b/autotest.sh index 3ce88c64974..8e99c8f0ca9 100755 --- a/autotest.sh +++ b/autotest.sh @@ -89,6 +89,9 @@ if [ "$1" ]; then fi fi +# check for the presence of @since in all OCP methods +$PHP build/OCPSinceChecker.php + # Back up existing (dev) config if one exists and backup not already there if [ -f config/config.php ] && [ ! -f config/config-autotest-backup.php ]; then mv config/config.php config/config-autotest-backup.php diff --git a/build/OCPSinceChecker.php b/build/OCPSinceChecker.php new file mode 100644 index 00000000000..c059b687393 --- /dev/null +++ b/build/OCPSinceChecker.php @@ -0,0 +1,115 @@ +<?php +/** + * @author Morris Jobke <hey@morrisjobke.de> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + + +require_once(dirname(__DIR__) . '/3rdparty/autoload.php'); + +/** + * Class SinceTagCheckVisitor + * + * this class checks all methods for the presence of the @since tag + */ +class SinceTagCheckVisitor extends \PhpParser\NodeVisitorAbstract { + + /** @var string */ + protected $namespace = ''; + /** @var string */ + protected $className = ''; + /** @var bool */ + protected $deprecatedClass = false; + + /** @var array */ + protected $errors = []; + + public function enterNode(\PhpParser\Node $node) { + if($this->deprecatedClass) { + return; + } + + if($node instanceof \PhpParser\Node\Stmt\Namespace_) { + $this->namespace = $node->name; + } + + if($node instanceof \PhpParser\Node\Stmt\Interface_ or + $node instanceof \PhpParser\Node\Stmt\Class_) { + $this->className = $node->name; + + /** @var \PhpParser\Comment\Doc[] $comments */ + $comments = $node->getAttribute('comments'); + if(count($comments) !== 0) { + $comment = $comments[count($comments) - 1]; + $text = $comment->getText(); + if(strpos($text, '@deprecated') !== false) { + $this->deprecatedClass = true; + } + } + } + + if($node instanceof \PhpParser\Node\Stmt\ClassMethod) { + /** @var \PhpParser\Node\Stmt\ClassMethod $node */ + /** @var \PhpParser\Comment\Doc[] $comments */ + $comments = $node->getAttribute('comments'); + + if(count($comments) === 0) { + $this->errors[] = 'PHPDoc is needed for ' . $this->namespace . '\\' . $this->className . '::' . $node->name; + return; + } + $comment = $comments[count($comments) - 1]; + $text = $comment->getText(); + if(strpos($text, '@since') === false && strpos($text, '@deprecated') === false) { + $this->errors[] = '@since or @deprecated tag is needed in PHPDoc for ' . $this->namespace . '\\' . $this->className . '::' . $node->name; + return; + } + } + } + + public function getErrors() { + return $this->errors; + } +} + +echo 'Parsing all files in lib/public for the presence of @since or @deprecated on each method...' . PHP_EOL . PHP_EOL; + + +$parser = new PhpParser\Parser(new PhpParser\Lexer); + +/* iterate over all .php files in lib/public */ +$Directory = new RecursiveDirectoryIterator(dirname(__DIR__) . '/lib/public'); +$Iterator = new RecursiveIteratorIterator($Directory); +$Regex = new RegexIterator($Iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); + +$errors = []; + +foreach($Regex as $file) { + $stmts = $parser->parse(file_get_contents($file[0])); + + $visitor = new SinceTagCheckVisitor($this->blackListedClassNames); + $traverser = new \PhpParser\NodeTraverser(); + $traverser->addVisitor($visitor); + $traverser->traverse($stmts); + + $errors = array_merge($errors, $visitor->getErrors()); +} + +if(count($errors)) { + echo join(PHP_EOL, $errors) . PHP_EOL . PHP_EOL; + exit(1); +} diff --git a/lib/public/appframework/db/doesnotexistexception.php b/lib/public/appframework/db/doesnotexistexception.php index 6df0477498c..2cefa0fe827 100644 --- a/lib/public/appframework/db/doesnotexistexception.php +++ b/lib/public/appframework/db/doesnotexistexception.php @@ -34,6 +34,7 @@ class DoesNotExistException extends \Exception { /** * Constructor * @param string $msg the error message + * @since 7.0.0 */ public function __construct($msg){ parent::__construct($msg); diff --git a/lib/public/appframework/db/entity.php b/lib/public/appframework/db/entity.php index a12f759357e..f7beebef154 100644 --- a/lib/public/appframework/db/entity.php +++ b/lib/public/appframework/db/entity.php @@ -92,6 +92,10 @@ abstract class Entity { $this->_updatedFields = array(); } + /** + * Generic setter for properties + * @since 7.0.0 + */ protected function setter($name, $args) { // setters should only work for existing attributes if(property_exists($this, $name)){ @@ -112,6 +116,10 @@ abstract class Entity { } } + /** + * Generic getter for properties + * @since 7.0.0 + */ protected function getter($name) { // getters should only work for existing attributes if(property_exists($this, $name)){ @@ -148,6 +156,7 @@ abstract class Entity { /** * Mark am attribute as updated * @param string $attribute the name of the attribute + * @since 7.0.0 */ protected function markFieldUpdated($attribute){ $this->_updatedFields[$attribute] = true; @@ -212,6 +221,7 @@ abstract class Entity { * that value once its being returned from the database * @param string $fieldName the name of the attribute * @param string $type the type which will be used to call settype() + * @since 7.0.0 */ protected function addType($fieldName, $type){ $this->_fieldTypes[$fieldName] = $type; diff --git a/lib/public/appframework/db/mapper.php b/lib/public/appframework/db/mapper.php index 157bea36916..2b99c99b71e 100644 --- a/lib/public/appframework/db/mapper.php +++ b/lib/public/appframework/db/mapper.php @@ -193,6 +193,7 @@ abstract class Mapper { * Checks if an array is associative * @param array $array * @return bool true if associative + * @since 8.1.0 */ private function isAssocArray(array $array) { return array_values($array) !== $array; @@ -202,6 +203,7 @@ abstract class Mapper { * Returns the correct PDO constant based on the value type * @param $value * @return PDO constant + * @since 8.1.0 */ private function getPDOType($value) { switch (gettype($value)) { diff --git a/lib/public/appframework/db/multipleobjectsreturnedexception.php b/lib/public/appframework/db/multipleobjectsreturnedexception.php index cdfb748b145..988bf6bb033 100644 --- a/lib/public/appframework/db/multipleobjectsreturnedexception.php +++ b/lib/public/appframework/db/multipleobjectsreturnedexception.php @@ -34,6 +34,7 @@ class MultipleObjectsReturnedException extends \Exception { /** * Constructor * @param string $msg the error message + * @since 7.0.0 */ public function __construct($msg){ parent::__construct($msg); diff --git a/lib/public/defaults.php b/lib/public/defaults.php index 2d55a64f002..723c6ecbb78 100644 --- a/lib/public/defaults.php +++ b/lib/public/defaults.php @@ -48,6 +48,7 @@ class Defaults { /** * creates a \OC_Defaults instance which is used in all methods to retrieve the * actual defaults + * @since 6.0.0 */ function __construct() { $this->defaults = new \OC_Defaults(); diff --git a/lib/public/files/folder.php b/lib/public/files/folder.php index f5f91e8158c..533e490634f 100644 --- a/lib/public/files/folder.php +++ b/lib/public/files/folder.php @@ -107,6 +107,7 @@ interface Folder extends Node { * @param string $path relative path of the new file * @return \OCP\Files\File * @throws \OCP\Files\NotPermittedException + * @since 6.0.0 */ public function newFile($path); diff --git a/lib/public/files/locknotacquiredexception.php b/lib/public/files/locknotacquiredexception.php index 66e131ab1e5..d078ff34818 100644 --- a/lib/public/files/locknotacquiredexception.php +++ b/lib/public/files/locknotacquiredexception.php @@ -41,12 +41,20 @@ class LockNotAcquiredException extends \Exception { /** @var integer $lockType The type of the lock that was attempted */ public $lockType; + /** + * @since 7.0.0 + */ public function __construct($path, $lockType, $code = 0, \Exception $previous = null) { $message = \OC::$server->getL10N('core')->t('Could not obtain lock type %d on "%s".', array($lockType, $path)); parent::__construct($message, $code, $previous); } - // custom string representation of object + /** + * custom string representation of object + * + * @return string + * @since 7.0.0 + */ public function __toString() { return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; } diff --git a/lib/public/iuser.php b/lib/public/iuser.php index 393ab90d260..6cbcfbf2312 100644 --- a/lib/public/iuser.php +++ b/lib/public/iuser.php @@ -93,6 +93,7 @@ interface IUser { * get the users home folder to mount * * @return string + * @since 8.0.0 */ public function getHome(); @@ -116,6 +117,7 @@ interface IUser { * check if the backend supports changing passwords * * @return bool + * @since 8.0.0 */ public function canChangePassword(); diff --git a/lib/public/iusermanager.php b/lib/public/iusermanager.php index 212d21759b0..e3857d6231a 100644 --- a/lib/public/iusermanager.php +++ b/lib/public/iusermanager.php @@ -64,6 +64,7 @@ interface IUserManager { /** * remove all user backends + * @since 8.0.0 */ public function clearBackends() ; |