Browse Source

Add task discovery to BakeShell.

Bake will now autodiscover any tasks that subclass BakeTask and load the
as Tasks. This makes bake easier to extend and customize.

Refs #3249
mark_story 12 years ago
parent
commit
ee3003e2b8

+ 30 - 8
src/Console/Command/BakeShell.php

@@ -149,6 +149,24 @@ class BakeShell extends Shell {
 		if (!is_dir($path)) {
 			return $tasks;
 		}
+		$candidates = $this->_findClassFiles($path, $namespace);
+		$classes = $this->_findTaskClasses($candidates);
+		foreach ($classes as $class) {
+			list($ns, $name) = namespaceSplit($class);
+			$name = substr($name, 0, -4);
+			$fullName = ($prefix ? $prefix . '.' : '') . $name;
+			$tasks[$name] = $fullName;
+		}
+		return $tasks;
+	}
+
+/**
+ * Find task classes in a given path.
+ *
+ * @param string $path The path to scan.
+ * @return array An array of files that may contain bake tasks.
+ */
+	protected function _findClassFiles($path, $namespace) {
 		$iterator = new \DirectoryIterator($path);
 		$candidates = [];
 		foreach ($iterator as $item) {
@@ -158,8 +176,18 @@ class BakeShell extends Shell {
 			$name = $item->getBasename('.php');
 			$candidates[] = $namespace . '\Console\Command\Task\\' . $name;
 		}
+		return $candidates;
+	}
+
+/**
+ * Find bake tasks in a given set of files.
+ *
+ * @param array $files The array of files.
+ * @return array An array of matching classes.
+ */
+	protected function _findTaskClasses($files) {
 		$classes = [];
-		foreach ($candidates as $classname) {
+		foreach ($files as $classname) {
 			if (!class_exists($classname)) {
 				continue;
 			}
@@ -172,13 +200,7 @@ class BakeShell extends Shell {
 			}
 			$classes[] = $classname;
 		}
-		foreach ($classes as $class) {
-			list($ns, $name) = namespaceSplit($class);
-			$name = substr($name, 0, -4);
-			$fullName = ($prefix ? $prefix . '.' : '') . $name;
-			$tasks[$name] = $fullName;
-		}
-		return $tasks;
+		return $classes;
 	}
 
 /**

+ 9 - 3
tests/TestCase/Console/Command/BakeShellTest.php

@@ -18,6 +18,7 @@ use Cake\Console\Command\BakeShellShell;
 use Cake\Controller\Controller;
 use Cake\Core\App;
 use Cake\Core\Configure;
+use Cake\Core\Plugin;
 use Cake\TestSuite\TestCase;
 
 class BakeShellTest extends TestCase {
@@ -112,11 +113,11 @@ class BakeShellTest extends TestCase {
 	}
 
 /**
- * Test loading tasks from core and app directories.
+ * Test loading tasks from core directories.
  *
  * @return void
  */
-	public function testLoadTasks() {
+	public function testLoadTasksCoreAndApp() {
 		$this->Shell->loadTasks();
 		$expected = [
 			'Behavior',
@@ -128,7 +129,8 @@ class BakeShellTest extends TestCase {
 			'Plugin',
 			'Project',
 			'Test',
-			'View'
+			'View',
+			'Zerg',
 		];
 		$this->assertEquals($expected, $this->Shell->tasks);
 	}
@@ -139,6 +141,10 @@ class BakeShellTest extends TestCase {
  * @return void
  */
 	public function testLoadTasksPlugin() {
+		Plugin::load('TestPlugin');
+		$this->Shell->loadTasks();
+		$this->assertContains('TestPlugin.Widget', $this->Shell->tasks);
+		$this->assertContains('TestPlugin.Zerg', $this->Shell->tasks);
 	}
 
 }

+ 24 - 0
tests/test_app/Plugin/TestPlugin/Console/Command/Task/WidgetTask.php

@@ -0,0 +1,24 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace TestPlugin\Console\Command\Task;
+
+use Cake\Console\Command\Task\BakeTask;
+
+/**
+ * Test stub for BakeShell.
+ */
+class WidgetTask extends BakeTask {
+
+}

+ 24 - 0
tests/test_app/Plugin/TestPlugin/Console/Command/Task/ZergTask.php

@@ -0,0 +1,24 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace TestPlugin\Console\Command\Task;
+
+use Cake\Console\Command\Task\BakeTask;
+
+/**
+ * Test stub for BakeShell.
+ */
+class ZergTask extends BakeTask {
+
+}

+ 24 - 0
tests/test_app/TestApp/Console/Command/Task/ZergTask.php

@@ -0,0 +1,24 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace TestApp\Console\Command\Task;
+
+use Cake\Console\Command\Task\BakeTask;
+
+/**
+ * Test stub for BakeShell.
+ */
+class ZergTask extends BakeTask {
+
+}