Files
luos/workflow/engine/classes/class.cli.php

388 lines
12 KiB
PHP
Raw Normal View History

<?php
2012-10-09 12:34:27 -04:00
/**
* class.cli.php
2012-10-09 12:34:27 -04:00
*
* @package workflow.engine.classes
*
* ProcessMaker Open Source Edition
* Copyright (C) 2011 Colosa Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2012-10-09 12:34:27 -04:00
* 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
2012-10-09 12:34:27 -04:00
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* For more information, contact Colosa Inc, 2566 Le Jeune Rd.,
* Coral Gables, FL, 33134, USA, or email info@colosa.com.
*
* @author Alexandre Rosenfeld <alexandre@colosa.com>
*/
2011-02-01 12:49:40 +00:00
/**
2012-10-09 12:34:27 -04:00
*
* @package workflow.engine.classes
2011-02-01 12:49:40 +00:00
*/
2012-10-09 12:34:27 -04:00
class CLI
{
public static $tasks = array ();
public static $currentTask = null;
2012-10-09 12:34:27 -04:00
/**
* Adds a new task defined by it's name.
* All other task functions will
* remember the current task defined here.
*
* @param string $name name of the task, used in the command-line
*/
public static function taskName ($name)
{
self::$currentTask = $name;
self::$tasks[$name] = array (
'name' => $name,
'description' => null,
'args' => array (),
'function' => null,
'opt' => array (
'short' => '',
'long' => array (),
'descriptions' => array ()
)
2012-10-09 12:34:27 -04:00
);
}
2012-10-09 12:34:27 -04:00
/**
* Adds a description to the current task.
* The description should contain a
* one-line description of the command and a few lines of text with more
* information.
*
* @param string $description task description
*/
public static function taskDescription ($description)
{
assert( self::$currentTask !== null );
2012-10-09 12:34:27 -04:00
self::$tasks[self::$currentTask]["description"] = $description;
}
2012-10-09 12:34:27 -04:00
/**
* Adds an argument to the current task.
* The options will affect how it is
* displayed in the help command. Optional will put [] in the argument and
* multiple will put ... in the end. Arguments are displayed together with
* the task name in the help command.
*
* @param string $name argument name
*/
public static function taskArg ($name, $optional = true, $multiple = false)
{
assert( self::$currentTask !== null );
2012-10-09 12:34:27 -04:00
self::$tasks[self::$currentTask]["args"][$name] = array ('optional' => $optional,'multiple' => $multiple
);
}
2012-10-09 12:34:27 -04:00
/**
* Defines short and long options as used by getopt to the current task.
*
* @param string $short short options
* @param array $long long options
*/
public static function taskOpt ($name, $description, $short, $long = null)
2012-10-09 12:34:27 -04:00
{
assert( self::$currentTask !== null );
2012-10-09 12:34:27 -04:00
$opts = self::$tasks[self::$currentTask]["opt"];
if ($short) {
2012-10-09 12:34:27 -04:00
$opts['short'] .= $short;
}
if ($long) {
2012-10-09 12:34:27 -04:00
$opts['long'][] = $long;
}
2012-10-09 12:34:27 -04:00
$opts['descriptions'][$name] = array ('short' => $short,'long' => $long,'description' => $description
);
self::$tasks[self::$currentTask]["opt"] = $opts;
}
2012-10-09 12:34:27 -04:00
/**
* Defines the function to run for the current task.
*
* @param callback $function function to run
*/
public static function taskRun ($function)
{
assert( self::$currentTask !== null );
2012-10-09 12:34:27 -04:00
self::$tasks[self::$currentTask]["function"] = $function;
}
2012-10-09 12:34:27 -04:00
/**
* Displays the help instructions.
*
* @param array $args if defined, the task name should be argument 0
* @param array $opts options as returned by getopt
*/
public static function help ($args, $opts = null)
2012-10-09 12:34:27 -04:00
{
global $argv;
$scriptName = $argv[0];
if (is_array($args) && count($args) > 0 ) {
2012-10-09 12:34:27 -04:00
$taskName = $args[0];
} else {
2012-10-09 12:34:27 -04:00
$taskName = $args;
}
2012-10-09 12:34:27 -04:00
if (! $taskName) {
echo "usage: processmaker <task> [options] [args]\n";
echo " If using Linux/UNIX, prepend './' to specify the directory: " . $scriptName . " <task> [options] [args]\n";
echo "Type 'processmaker help <task>' for help on a specific task.";
echo "\n\nAvailable tasks:\n";
2012-10-09 12:34:27 -04:00
$tasks = array ();
ksort( self::$tasks );
foreach (self::$tasks as $name => $data) {
$description = explode( "\n", $data['description'] );
$tasks[] = " $name";
}
$tasks = join( "\n", $tasks );
echo $tasks . "\n\n";
} else {
$options = array();
$tasks = array();
ksort( self::$tasks );
foreach (self::$tasks as $name => $data) {
$description = explode( "\n", $data['description'] );
$options[] = "$name";
}
if (!in_array($taskName, $options)) {
echo "\nThe task does not exist \n";
echo "Use one of the following tasks:\n";
$tasks = array ();
ksort( self::$tasks );
foreach (self::$tasks as $name => $data) {
$description = explode( "\n", $data['description'] );
$tasks[] = " $name";
}
$tasks = join( "\n", $tasks );
echo $tasks . "\n\n";
} else{
$valid_args = array ();
foreach (self::$tasks[$taskName]['args'] as $arg => $data) {
$arg = strtoupper( $arg );
if ($data['multiple']) {
$arg = "$arg...";
}
if ($data['optional']) {
$arg = "[$arg]";
}
$valid_args[] = $arg;
}
$nameHotfixFile = ($taskName == "hotfix-install")? "HOTFIX-FILE" : "";
2012-10-09 12:34:27 -04:00
$valid_args = join( " ", $valid_args );
$description = explode( "\n", self::$tasks[$taskName]['description'] );
$taskDescription = trim( array_shift( $description ) );
$description = trim( implode( "\n", $description ) );
$message = <<< EOT
$taskName: {$taskDescription}
Usage: processmaker $taskName $nameHotfixFile $valid_args
$description
EOT;
2012-10-09 12:34:27 -04:00
$valid_options = array ();
foreach (self::$tasks[$taskName]['opt']['descriptions'] as $opt => $data) {
$optString = array ();
if ($data['short']) {
2012-10-09 12:34:27 -04:00
$optString[] = "-{$data['short']}";
}
if ($data['long']) {
2012-10-09 12:34:27 -04:00
$optString[] = "--{$data['long']}";
}
2012-10-09 12:34:27 -04:00
$valid_options[] = " " . join( ", ", $optString ) . "\n\t" . wordwrap( $data['description'], 70, "\n\t" );
}
$valid_options = join( "\n", $valid_options );
if ($valid_options) {
$message .= <<< EOT
Options:
2012-10-09 12:34:27 -04:00
$valid_options
EOT;
2012-10-09 12:34:27 -04:00
}
echo $message . "\n";
}
}
}
2012-10-09 12:34:27 -04:00
/**
* Run the CLI task, which will check which command is specified and run it.
*/
public static function run ()
{
CLI::taskName( "help" );
CLI::taskRun( array ('self','help'
) );
global $argv;
$args = $argv;
$cliname = array_shift( $args );
$taskName = array_shift( $args );
while ($taskName{0} == '-') {
2012-10-09 12:34:27 -04:00
$taskName = array_shift( $args );
}
2012-10-09 12:34:27 -04:00
if (! $taskName) {
echo self::error( "Specify a task from the list below." ) . "\n\n";
self::help( null, null );
2012-10-09 12:34:27 -04:00
return;
}
$taskData = null;
2012-10-09 12:34:27 -04:00
foreach (self::$tasks as $name => $data) {
if (strcasecmp( $name, $taskName ) === 0) {
$taskData = $data;
break;
}
}
if (! $taskData) {
echo self::error( "Command not found: '$taskName'" ) . "\n\n";
self::help( null, null );
2012-10-09 12:34:27 -04:00
return;
}
2012-10-09 12:34:27 -04:00
$short = "h" . $taskData['opt']['short'];
$long = array_merge( array ("help"
), $taskData['opt']['long'] );
$getopt = Console_GetOpt::getopt2( $args, $short, $long );
if (! is_array( $getopt )) {
echo self::error( "Invalid options (" . $getopt->getMessage() . ")" ) . "\n\n";
self::help( $taskName );
return;
}
list ($options, $arguments) = $getopt;
foreach ($taskData['opt']['descriptions'] as $optName => $optDescription) {
$short = str_replace( ":", "", $optDescription['short'] );
$long = str_replace( "=", "", $optDescription['long'] );
$validOpts[$short] = $optName;
$validOpts[$long] = $optName;
}
$taskOpts = array ();
try {
foreach ($options as $opt) {
list ($optName, $optArg) = $opt;
if ($optName === "h" || $optName === "--help") {
self::help( $taskName );
return;
}
if (strpos( $optName, '--' ) === 0) {
2012-10-09 12:34:27 -04:00
$optName = substr( $optName, 2 );
}
if (! array_key_exists( $optName, $validOpts )) {
2012-10-09 12:34:27 -04:00
throw new Exception( "option not found: $optName" );
}
if (array_key_exists( $validOpts[$optName], $taskOpts )) {
2012-10-09 12:34:27 -04:00
throw new Exception( "'$optName' specified more then once" );
}
2012-10-09 12:34:27 -04:00
$taskOpts[$validOpts[$optName]] = $optArg;
}
} catch (Exception $e) {
2017-04-04 15:14:15 -04:00
echo self::error( "Invalid options: " . $e->getMessage() ) . "\n\n";
2012-10-09 12:34:27 -04:00
self::help( $taskName );
return;
}
try {
call_user_func( $taskData['function'], $arguments, $taskOpts );
} catch (Exception $e) {
2017-04-04 15:14:15 -04:00
echo self::error( "\n Error executing '$taskName':\n\n {$e->getMessage()}\n" ) . "\n";
global $tempDirectory;
if (!empty($tempDirectory)) {
G::rm_dir($tempDirectory);
}
}
2011-01-31 20:36:19 +00:00
}
2012-10-09 12:34:27 -04:00
/**
* Returns an information colorized version of the message.
*
* @param string $message the message to colorize
*/
public static function info ($message)
{
return pakeColor::colorize( $message, "INFO" );
}
2012-10-09 12:34:27 -04:00
/**
* Returns a warning colorized version of the message.
*
* @param string $message the message to colorize
*/
public static function warning ($message)
{
return pakeColor::colorize( $message, "COMMENT" );
}
2012-10-09 12:34:27 -04:00
/**
* Returns an error colorized version of the message.
*
* @param string $message the message to colorize
*/
public static function error ($message)
{
return pakeColor::colorize( $message, "ERROR" );
}
2012-10-09 12:34:27 -04:00
/**
* Prompt the user for information.
*
* @param string $message the message to display
* @return string the text typed by the user
*/
public static function prompt ($message)
{
echo "$message";
$handle = fopen( "php://stdin", "r" );
$line = fgets( $handle );
return $line;
}
2012-10-09 12:34:27 -04:00
/**
* Ask a question of yes or no.
*
* @param string $message the message to display
* @return bool true if the user choosed no, false otherwise
*/
public static function question ($message)
{
$input = strtolower( self::prompt( "$message [Y/n] " ) );
return (array_search( trim( $input ), array ("y",""
) ) !== false);
}
2012-10-09 12:34:27 -04:00
/**
* Display a message to the user.
* If filename is specified, it will setup
* a logging file where all messages will be recorded.
*
* @param string $message the message to display
* @param string $filename the log file to write messages
*/
public static function logging ($message, $filename = null)
2012-10-09 12:34:27 -04:00
{
static $log_file = null;
2012-10-09 12:34:27 -04:00
if (isset( $filename )) {
$log_file = fopen( $filename, "a" );
fwrite( $log_file, " -- " . date( "c" ) . " " . $message . " --\n" );
} else {
if (isset( $log_file )) {
2012-10-09 12:34:27 -04:00
fwrite( $log_file, $message );
}
2012-10-09 12:34:27 -04:00
echo $message;
}
}
}