1
0
Fork 0
mirror of https://github.com/Oreolek/kohana-migrations.git synced 2024-06-16 15:01:08 +03:00

Removing non-migration related files

In an ideal world I would've been able to simply strip out the unwanted stuff
using git filter-branch, however it seems that command is limited to only one subdirectory
This commit is contained in:
Matt Button 2011-02-06 01:35:23 +00:00
parent a880742631
commit 12670e28ef
11 changed files with 0 additions and 679 deletions

105
README.md
View file

@ -1,105 +0,0 @@
# Minion
*NOTE: Minion is currently in a beta state, please report any issues in the issue tracker*
Minion is a module for running database migrations located in the Kohana cascading filesystem, but it also provides a useful framework for creating cli based tasks.
The original "need" behind Minion was the lack of a good db migrations system, capable of selecting migrations
from multiple locations (i.e. different modules).
The system is inspired by ruckusing, which had a nice system for defining tasks but lacked the desired flexibility.
**Please don't PM me with support / feature requests, instead create an issue in [the tracker](https://github.com/kohana-minion/core/issues).**
## Requirements
* [kohana-database](https://github.com/kohana/database) is required by the migration tasks
## Compatibility
Minion should be compatible with both Kohana 3.0.x and 3.1.x
## Getting Started
First off, download and enable the module in your bootstrap
Then copy the bash script `minion` alongside your index.php (most likely the webroot).
If you'd rather the executable be in a different location to index.php then simply modify the bash script to point to index.php.
You can then run minion like so:
./minion {task}
To view a list of minion tasks, run minion without any parameters, or with the `--help` option
./minion
./minion --help
To view help for a specific minion task run
./minion {task} --help
For security reasons Minion will only run from the cli. Attempting to access it over http will cause
a `Kohana_Exception` to be thrown.
If you're unable to use the binary file for whatever reason then simply replace `./minion {task}` in the above
examples with
php index.php --uri=minion --task={task}
## Writing your own tasks
All minion tasks must be located in `classes/minion/task/`. They can be in any module, thus allowing you to
ship custom minion tasks with your own module / product.
Each task must extend the abstract class `Minion_Task` and implement `Minion_Task::execute()`.
See `Minion_Task` for more details.
## Documentation
Code should be commented well enough not to need documentation, and minion can extract a class' doccomment to use
as documentation on the cli.
## Testing
This module is unittested using the [unittest module](http://github.com/kohana/unittest).
You can use the `minion` group to only run minion tests.
i.e.
phpunit --group minion
Feel free to contribute tests(!), they can be found in the `tests/minion` directory. :)
## License
This is licensed under the [same license as Kohana](http://kohanaframework.org/license).
This project is not endorsed by the Kohana Framework project.
## FAQ
### Can't I just create my own controllers instead of creating "tasks"
Yes, controllers offer just as much control as tasks, however there are a number of advantages to tasks:
* They can only be run via command line or through code (see note about http)
* All the groundwork for interacting with the user on the command line is already in place, you
just need to take advantage of it
* It provides a uniform way to access and perform tasks on the command line, rather than creating an elaborate
collection of controllers while trying to restrict access to them. If you create a module that requires command
line interaction then you just ship a minion task with it and users will be able to start using it with minimal
setup & configuration
### Eeew why aren't you using ORM xyz?
In order to prevent conflicts across installations Minion aims to have as few dependencies as possible.
### This is awesome! How can I contribute?
Thanks for wanting to help out, just fork, commit, push, and send a pull request :)
### UR DOIN IT WRONG
Sorry you feel that way, it'd be useful if you could create an issue outlining what you think should be changed.

View file

@ -1,119 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Controller for interacting with minion on the cli
*
* @author Matt Button <matthew@sigswitch.com>
*/
class Controller_Minion extends Controller
{
/**
* The task to be executed
* @var string
*/
protected $_task = NULL;
/**
* Prevent Minion from being run over http
*/
public function before()
{
if ( ! Kohana::$is_cli)
{
throw new Kohana_Exception("Minion can only be ran from the cli");
}
$this->_task = $this->request->param('task');
$options = CLI::options('help', 'task');
if (array_key_exists('help', $options))
{
$this->request->action = 'help';
}
if ( ! empty($options['task']))
{
$this->_task = $options['task'];
}
return parent::before();
}
/**
* Prints out the help for a specific task
*
*/
public function action_help()
{
$tasks = Minion_Util::compile_task_list(Kohana::list_files('classes/minion/task'));
$view = NULL;
if (empty($this->_task))
{
$view = new View('minion/help/list');
$view->tasks = $tasks;
}
else
{
$class = Minion_Util::convert_task_to_class_name($this->_task);
if ( ! class_exists($class))
{
echo View::factory('minion/help/error')
->set('error', 'Task "'.$task.'" does not exist');
exit(1);
}
$inspector = new ReflectionClass($class);
list($description, $tags) = Minion_Util::parse_doccomment($inspector->getDocComment());
$view = View::factory('minion/help/task')
->set('description', $description)
->set('tags', (array) $tags)
->set('task', $this->_task);
}
echo $view;
}
/**
* Handles the request to execute a task.
*
* Responsible for parsing the tasks to execute & also any config items that
* should be passed to the tasks
*/
public function action_execute()
{
if (empty($this->_task))
{
return $this->action_help();
}
try
{
$task = Minion_Task::factory($this->_task);
}
catch(Exception $e)
{
echo View::factory('minion/help/error')
->set('error', 'Task "'.$this->_task.'" does not exist');
exit(1);
}
$config = array();
$options = (array) $task->get_config_options();
if ( ! empty($options))
{
$options = $task->get_config_options();
$config = call_user_func_array(array('CLI', 'options'), $options);
}
echo $task->execute($config);
}
}

View file

@ -1,73 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Interface that all minion tasks must implement
*/
abstract class Minion_Task {
/**
* Factory for loading minion tasks
*
* @throws Kohana_Exception
* @param string The task to load
* @return Minion_Task The Minion task
*/
public static function factory($task)
{
if (is_string($task))
{
$class = Minion_Util::convert_task_to_class_name($task);
$task = new $class;
}
if ( ! $task instanceof Minion_Task)
{
throw new Kohana_Exception(
"Task ':task' is not a valid minion task",
array(':task' => get_class($task))
);
}
return $task;
}
/**
* A set of config options that the task accepts on the command line
* @var array
*/
protected $_config = array();
/**
* Gets the task name for the task
*
* @return string
*/
public function __toString()
{
static $task_name = NULL;
if ($task_name === NULL)
{
$task_name = Minion_Util::convert_class_to_task($this);
}
return $task_name;
}
/**
* Get a set of config options that this task can accept
*
* @return array
*/
public function get_config_options()
{
return $this->_config;
}
/**
* Execute the task with the specified set of config
*
* @return boolean TRUE if task executed successfully, else FALSE
*/
abstract public function execute(array $config);
}

View file

@ -1,47 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Purges the application, requires at least one cache configuration group to be
* specified
*
* Available config options:
*
* --cache=cache1[,cache2,cache2...]
*
* Specify the caches to clear, each item in the list is the key of a cache
* config group in config/cache.php
*
* This is a required config option
*
* @author Matt Button <matthew@sigswitch.com>
*/
class Minion_Task_Cache_Purge extends Minion_Task
{
/**
* An array of config options that this task can accept
*/
protected $_config = array();
/**
* Clears the cache
*/
public function execute(array $config)
{
if (empty($config['cache']))
{
return 'Please specify a set of cache configs.';
}
$config['cache'] = trim($config['cache'], ',');
$caches = explode(',', $config['cache']);
foreach ($caches as $cache)
{
Cache::instance($cache)
->delete_all();
}
return 'Cleared caches for '.$config['cache'];
}
}

View file

@ -1,124 +0,0 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Utility class for Minion
*/
class Minion_Util
{
/**
* The separator used to separate different levels of tasks
* @var string
*/
public static $task_separator = ':';
/**
* Parses a doccomment, extracting both the comment and any tags associated
*
* Based on the code in Kodoc::parse()
*
* @param string The comment to parse
* @return array First element is the comment, second is an array of tags
*/
public static function parse_doccomment($comment)
{
// Normalize all new lines to \n
$comment = str_replace(array("\r\n", "\n"), "\n", $comment);
// Remove the phpdoc open/close tags and split
$comment = array_slice(explode("\n", $comment), 1, -1);
// Tag content
$tags = array();
foreach ($comment as $i => $line)
{
// Remove all leading whitespace
$line = preg_replace('/^\s*\* ?/m', '', $line);
// Search this line for a tag
if (preg_match('/^@(\S+)(?:\s*(.+))?$/', $line, $matches))
{
// This is a tag line
unset($comment[$i]);
$name = $matches[1];
$text = isset($matches[2]) ? $matches[2] : '';
$tags[$name] = $text;
}
else
{
$comment[$i] = (string) $line;
}
}
$comment = trim(implode("\n", $comment));
return array($comment, $tags);
}
/**
* Compiles a list of available tasks from a directory structure
*
* @param array Directory structure of tasks
* @return array Compiled tasks
*/
public static function compile_task_list(array $files, $prefix = '')
{
$output = array();
foreach ($files as $file => $path)
{
$file = substr($file, strrpos($file, '/') + 1);
if (is_array($path) AND count($path))
{
$task = Minion_Util::compile_task_list($path, $prefix.$file.Minion_Util::$task_separator);
if ($task)
{
$output = array_merge($output, $task);
}
}
else
{
$output[] = strtolower($prefix.substr($file, 0, -strlen(EXT)));
}
}
return $output;
}
/**
* Converts a task (e.g. db:migrate to a class name)
*
* @param string Task name
* @return string Class name
*/
public static function convert_task_to_class_name($task)
{
$task = trim($task);
if (empty($task))
return '';
return 'Minion_Task_'.implode('_', array_map('ucfirst', explode(Minion_Util::$task_separator, $task)));
}
/**
* Gets the task name of a task class / task object
*
* @param string|Minion_Task The task class / object
* @return string The task name
*/
public static function convert_class_to_task($class)
{
if (is_object($class))
{
$class = get_class($class);
}
return strtolower(str_replace('_', Minion_Util::$task_separator, substr($class, 12)));
}
}

View file

@ -1,8 +0,0 @@
<?php
Route::set('minion', 'minion(/<action>)(/<task>)', array('action' => 'help'))
->defaults(array(
'controller' => 'minion',
'action' => 'execute',
));

26
minion
View file

@ -1,26 +0,0 @@
#!/bin/bash
#
# Usage: ./minion [task:name] [--option1=optval1 --option2=optval2]
#
# And so on.
#
# To get help, pass in --help
#
# # Minion general help
# ./minion --help
# ./minion
#
# # Task specific help
# ./minion task:name --help
#
if [[ $# > 0 && $1 != --* ]]
then
TASK="--task=$1"
shift 1
fi
php index.php --uri=minion "$TASK" "$@"
# Pass the exit code back out
exit $?

View file

@ -1,136 +0,0 @@
<?php
/**
* Test case for Minion_Util
*
* @group minion
**/
class Minion_UtilTest extends Kohana_Unittest_TestCase
{
/**
* Provides test data for test_parse_doccoment()
*
* @return array Test data
*/
public function provider_parse_doccoment()
{
return array(
array(
array(
"This is my comment from something or\nother",
array(
'author' => 'Matt Button <matthew@sigswitch.com>',
),
),
" /**\n * This is my comment from something or\n * other\n * \n * @author Matt Button <matthew@sigswitch.com>\n */",
),
);
}
/**
* Tests Minion_Util::prase_doccoment
*
* @test
* @dataProvider provider_parse_doccoment
* @covers Minion_Util::parse_doccomment
* @param array Expected output
* @param string Input doccoment
*/
public function test_parse_doccoment($expected, $doccomment)
{
$this->assertSame($expected, Minion_Util::parse_doccomment($doccomment));
}
/**
* Provides test data for test_compile_task_list()
*
* @return array Test data
*/
public function provider_compile_task_list()
{
return array(
array(
array(
'db:migrate',
'db:status',
),
array (
'classes/minion/task/db' => array (
'classes/minion/task/db/migrate.php' => '/var/www/memberful/memberful-core/modules/kohana-minion/classes/minion/task/db/migrate.php',
'classes/minion/task/db/status.php' => '/var/www/memberful/memberful-core/modules/kohana-minion/classes/minion/task/db/status.php',
),
),
),
);
}
/**
* Tests that compile_task_list accurately creates a list of tasks from a directory structure
*
* @test
* @covers Minion_Util::compile_task_list
* @dataProvider provider_compile_task_list
* @param array Expected output
* @param array List of files
* @param string Prefix to use
* @param string Separator to use
*/
public function test_compile_task_list($expected, $files, $prefix = '', $separator = ':')
{
$this->assertSame($expected, Minion_Util::compile_task_list($files, $prefix, $separator));
}
/**
* Provides test data for test_convert_task_to_class_name()
*
* @return array
*/
public function provider_convert_task_to_class_name()
{
return array(
array('Minion_Task_Db_Migrate', 'db:migrate'),
array('Minion_Task_Db_Status', 'db:status'),
array('', ''),
);
}
/**
* Tests that a task can be converted to a class name
*
* @test
* @covers Minion_Util::convert_task_to_class_name
* @dataProvider provider_convert_task_to_class_name
* @param string Expected class name
* @param string Input task name
*/
public function test_convert_task_to_class_name($expected, $task_name)
{
$this->assertSame($expected, Minion_Util::convert_task_to_class_name($task_name));
}
/**
* Provides test data for test_convert_class_to_task()
*
* @return array
*/
public function provider_convert_class_to_task()
{
return array(
array('db:migrate', 'Minion_Task_Db_Migrate'),
);
}
/**
* Tests that the task name can be found from a class name / object
*
* @test
* @covers Minion_Util::convert_class_to_task
* @dataProvider provider_convert_class_to_task
* @param string Expected task name
* @param mixed Input class
*/
public function test_convert_class_to_task($expected, $class)
{
$this->assertSame($expected, Minion_Util::convert_class_to_task($class));
}
}

View file

@ -1,7 +0,0 @@
<?php echo $error; ?>
Run
index.php --uri=minion
for more help

View file

@ -1,17 +0,0 @@
Minion is a cli tool for performing tasks
Usage
php index.php --uri=minion/{task}
Where {task} is one of the following:
<?php foreach($tasks as $task): ?>
* <?php echo $task; ?>
<?php endforeach; ?>
For more information on what a task does and usage details execute
php index.php --uri=minion/help/{task}

View file

@ -1,17 +0,0 @@
Usage
=======
php index.php --uri=minion/<?php echo $task; ?> [--option1=value1] [--option2=value2]
Details
=======
<?php foreach($tags as $tag_name => $tag_content): ?>
<?php echo ucfirst($tag_name) ?>: <?php echo $tag_content ?>
<?php endforeach; ?>
Description
===========
<?php echo $description; ?>