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:
parent
a880742631
commit
12670e28ef
105
README.md
105
README.md
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
47
classes/minion/task/cache/purge.php
vendored
47
classes/minion/task/cache/purge.php
vendored
|
@ -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'];
|
||||
}
|
||||
}
|
|
@ -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)));
|
||||
}
|
||||
}
|
8
init.php
8
init.php
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
|
||||
Route::set('minion', 'minion(/<action>)(/<task>)', array('action' => 'help'))
|
||||
->defaults(array(
|
||||
'controller' => 'minion',
|
||||
'action' => 'execute',
|
||||
));
|
26
minion
26
minion
|
@ -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 $?
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?php echo $error; ?>
|
||||
|
||||
Run
|
||||
|
||||
index.php --uri=minion
|
||||
|
||||
for more help
|
|
@ -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}
|
||||
|
|
@ -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; ?>
|
||||
|
||||
|
Loading…
Reference in a new issue