Giter VIP home page Giter VIP logo

zf-console's Introduction

ZF\Console: Console Tool Helper

Repository abandoned 2019-12-05

This repository is no longer maintained. Other projects in the ecosystem, such as symfony/console, provide more robust and flexible solutions, and we recommend users target those runtimes instead.

Build Status Coverage Status

Introduction

zf-console provides functionality on top of Zend\Console, specifically a methodology for creating standalone PHP console applications using Zend\Console's DefaultRouteMatcher. It includes built-in "help" and "version" commands, and colorization (via Zend\Console), as well as support for shell autocompletion.

Requirements

Please see the composer.json file.

Installation

Run the following composer command:

$ composer require zfcampus/zf-console

Alternately, manually add the following to your composer.json, in the require section:

"require": {
    "zfcampus/zf-console": "^1.3"
}

And then run composer update to ensure the module is installed.

Creating an application

Console applications written with zf-console consist of:

  • Defining console routes
  • Mapping route names to PHP callables
  • Creating and running the application

Defining console routes

Routes in zf-console are typically configuration driven. Each route is an associative array consisting of the following members:

  • name (required): The name of the route. Names MUST be unique across the application.
  • route (optional): The "route", or console arguments, to match (more below); if not specified, name is utilized. Additionally, if the route does not start with name, name will be prepended to the route (unless you opt out of this feature).
  • description (optional): A detailed help description for the given route.
  • short_description (optional): A short help description for the given route, used in command summaries.
  • options_descriptions (optional): An array of option name/description pairs, corresponding to the arguments the route matches.
  • constraints (optional): An array of name/regex pairs to use when matching arguments, corresponding to the arguments in the route. If a regex fails for a given argument, the route will not match.
  • aliases (optional): An array of alias/argument pairs; if an alias is provided in the arguments, it will be returned as the named argument on a successful match.
  • defaults (optional): Default values to return on a successful match for arguments that were not matched.
  • filters (optional): An array of name/Zend\Filter\FilterInterface pairs. The filter provided will be used to filter/normalize the named argument when matched.
  • validators (optional): An array of name/Zend\Validator\ValidatorInterface pairs. The validator provided will be used to validate the named argument when matched; failure to validate will cause the route not to match.
  • handler (optional): A PHP callable, or a class name of a class with no constructor arguments which is also invokable; if specified, and no command has been mapped in the Dispatcher, this handler will be used to handle the command when invoked.
  • prepend_command_to_route (optional): A flag that, if specified, indicates whether or not the command name will be prepended to the route. Since this is the default behavior, only a value of boolean false makes sense here.

Alternately, you can create a ZF\Console\Route instance. The signature is similar:

$route = new ZF\Console\Route(
    $name,
    $route,
    $constraints, // optional
    $defaults,    // optional
    $aliases,     // optional
    $filters,     // optional
    $validators   // optional
);
$route->setDescription($description);
$route->setShortDescription($shortDescription);
$route->setOptionsDescription($optionsDescription);

When defining routes, you will need to provide either an array or Traversable object of route configuration arrays or Route instances (they can be mixed).

We suggest putting your routes in a configuration file:

// config/routes.php

return array(
    array(
        'name'  => 'self-update',
        'description' => 'When executed via the Phar file, performs a self-update by querying
the package repository. If successful, it will report the new version.',
        'short_description' => 'Perform a self-update of the script',
    ),
    array(
        'name' => 'build',
        'route' => '<package> [--target=]',
        'description' => 'Build a package, using <package> as the package filename, and --target
as the application directory to be packaged.',
        'short_description' => 'Build a package',
        'options_descriptions' => array(
            '<package>' => 'Package filename to build',
            '--target'  => 'Name of the application directory to package; defaults to current working directory',
        ),
        'defaults' => array(
            'target' => getcwd(), // default to current working directory
        ),
        'handler' => 'My\Builder',
    ),
);

On Routes

ZF\Console\Route is an extension of Zend\Console\RouteMatcher\DefaultRouteMatcher, and follows its rules for route definitions and matching. In general, a route string will consist of:

  • Literal parameters (literal strings to match; e.g., build)
  • Literal flags (e.g., --help, -h, etc; flags do not have associated values)
  • Positional value parameters (named captures that do not use flags; e.g., <email>)
  • Value flag parameters (aka long options, with associated values; e.g., '--target=')

Most parameters may be made optional by surrounding them with brackets (e.g., [--target=], [<command>]).

For a full overview of how to create route specification strings, please review the ZF2 console routes documentation.

Route definitions

Note that, by default, the route name will be prefixed to the route you pass. In the example above, the build route becomes build <package> [--target=]. If you wish to be explicit, you can include the command name in your route definition yourself, or pass the prepend_command_to_route flag with a boolean false value to disable prepending the command name.

Prepending is done to make explicit the idea the mapping of the command name to the route -- which is particularly prudent when considering usage of the help system (which is command centric).

Mapping routes to callables

In order to execute commands, you will need to map route names to code that will dispatch them. ZF\Console\Dispatcher provides the ability to define such a map, via its map() method:

$dispatcher = new ZF\Console\Dispatcher;
$dispatcher->map('some-command-name', $callable)

The $callable argument may be any PHP callable. Additionally, you may provide a string class name, so long as that class can be instantiated without constructor arguments, and so long as it defines an __invoke() method.

All callables should expect up to two arguments:

function (\ZF\Console\Route $route, \Zend\Console\Adapter\AdapterInterface $console) {
}

Additionally, callables should return an integer status to use as the application's exit status; a 0 indicates success, while anything else indicates a failure.

Callables may be defined in route configuration

As noted in the previous section, you can also provide the callable for handling the route via the handler key of your route configuration. The same rules apply to that argument as for the map() method.

Any callables mapped directly to the Dispatcher instance will be preferred over those passed via configuration.

Creating and running the application

Creating the application consists of

  • Setting up or retrieving the list of routes
  • Setting up the dispatch map
  • Instantiating the application
  • Running the application

For the following example, we'll assume that the classes My\SelfUpdate and My\Build are autoloadable, and each define the method __invoke().

use My\SelfUpdate;
use Zend\Console\Console;
use ZF\Console\Application;
use ZF\Console\Dispatcher;

require_once __DIR__ . '/vendor/autoload.php'; // Composer autoloader

define('VERSION', '1.1.3');

$dispatcher = new Dispatcher();
$dispatcher->map('self-update', new SelfUpdate($version));
$dispatcher->map('build', 'My\Build');

$application = new Application(
    'Builder',
    VERSION,
    include __DIR__ . '/config/routes.php',
    Console::getInstance(),
    $dispatcher
);
$exit = $application->run();
exit($exit);

Features

zf-console provides a number of features "out of the box." These include:

  • Usage reporting
  • Help message reporting
  • Version reporting
  • Shell autocompletion
  • Exception handling

Usage reporting may be observed by executing an application with no arguments, or with only the help argument:

$ ./script.php
Builder, version 1.1.3

Available commands:

 autocomplete   Command autocompletion setup
 build          Build a package
 help           Get help for individual commands
 self-update    Perform a self-update of the script
 version        Display the version of the script

Help reporting for individual commands may be observed by executing script help <command name>:

$ ./script.php help self-update
Builder, version 1.1.3

Usage:
 self-update

Help:
When executed via the Phar file, performs a self-update by querying
the package repository. If successful, it will report the new version.

Name routes after the command

We recommend naming routes after the command name. In part, this simplifies finding the matching route definition, but more importantly: if a user specifies the command, but does not specify valid arguments for it, the command will be used to provide a help usage message for that route.

As an example, in the above, if I typed script.php build without any additional arguments, the usage message for the build command will be displayed, since the command and route name match.

Version reporting can be observed by executing script --version or script -v:

$ ./script --version
Builder, version 1.1.3

You can override the default behavior in several ways.

First, you can override either of the help or version commands by mapping them in your Dispatcher instance prior to creating your Application instance:

$dispatcher->map('help', $myCustomHelpCommand);
$dispatcher->map('version', $myVersionCommand);

Second, you can set both custom banners and footers for the usage and help messages using the setBanner() and/or setFooter() methods of the Application instance. Each accepts either a string message, or a callable that to invoke in order to display the message; if using a callable, it will be passed the Console instance as the sole argument.

$application->setBanner('Some ASCI art for a banner!'); // string
$application->setBanner(function ($console) {           // callable
    $console->writeLine(
        $console->colorize('Builder', \Zend\Console\ColorInterface::BLUE)
        . ' - for building deployment packages'
    );
    $console->writeLine('');
    $console->writeLine('Usage:', \Zend\Console\ColorInterface::GREEN);
    $console->writeLine(' ' . basename(__FILE__) . ' command [options]');
    $console->writeLine('');
});

$application->setFooter('Copyright 2014 Zend Technologies');

Disabling banners

The banner is shown by default. In some cases, you may not want to display it; e.g., when piping output to another process.

Starting with version 1.3.0, you can disable banner output using:

$application->setBannerDisabledForUserCommands(true);

Additionally, starting with 1.3.0, you can explicitly nullify both the banner and footer:

$application->setBanner(null);
$application->setFooter(null);

Autocompletion

Autocompletion is a useful feature of many login shells. zf-console provides autocompletion support for bash, zsh, and any shell that understands autocompletion rules in a similar fashion. Rules are generated per-script, using the autocomplete command:

$ ./script autocomplete

Running this will output a shell script that you can save and add to your toolchain; the script itself contains information on how to save it and add it to your shell. In most cases, this will look something like:

$ {script} autocomplete > > $HOME/bin/{script}_autocomplete.sh
$ echo "source \$HOME/bin/{script}_autocomplete.sh" > > $HOME/{your_shell_rc}

where {script} is the name of the command, and {your_shell_rc} is the location of your shell's runtime configutation file (e.g., .bashrc, .zshrc).

Dispatcher callables

The Dispatcher will invoke the callable associated with a given route by calling it with two arguments:

  • The ZF\Console\Route instance that matched
  • The Zend\Console adapter currently in use

In most cases, you will use the Route instance to gather arguments passed to the application, and the Console instance to provide any feedback or to prompt for any additional information.

The Route instance contains several methods of interest:

  • getMatches() will return an array of all named arguments matched.
  • matchedParam($name) will tell you if a given argument was matched.
  • getMatchedParam($name, $default = null) will return the value for the given argument as matched, and, if not matched, the $default value you provide.
  • getName() will return the name of the route (which may be useful if you use the same callable for multiple routes).

Custom dispatchers

  • Since 1.3.0

You may create a custom dispatcher by implementing ZF\Console\DispatcherInterface, which defines the following methods:

namespace ZF\Console;

use Zend\Console\Adapter\AdapterInterface as ConsoleAdapter;

interface DispatcherInterface
{
    /**
     * Map a command name to its handler.
     *
     * @param string $command
     * @param callable|string $command A callable command, or a string service
     *     or class name to use as a handler.
     * @return self Should implement a fluent interface.
     */
    public function map($command, $callable);

    /**
     * Does the dispatcher have a handler for the given command?
     *
     * @param string $command
     * @return bool
     */
    public function has($command);

    /**
     * Dispatch a routed command to its handler.
     *
     * @param Route $route
     * @param ConsoleAdapter $console
     * @return int The exit status code from the command.
     */
    public function dispatch(Route $route, ConsoleAdapter $console);
}

When you do, instantiate your custom dispatcher and pass it to the Application instance when initializing it:

$application = new Application('App', 1.0, $routes, null, $dispatcher);

Pulling commands from a container

  • Since 1.3.0

Instead of specifying a callable or a class name for a command handler, you may store your handlers within a dependency injection container compatible with the PSR-11 specification; when you do so, you can specify the service name of the handler instead.

To do this, you will need to create a Dispatcher instance, passing it the container you are using at instantiation:

$serviceManager = new ServiceManager(/* ... */);

// use `zend-servicemanager` as container
$dispatcher = new Dispatcher($serviceManager);

From there, you can configure routes using the service name (which is often a class name):

$routes = [
    [
        'name' => 'hello',        
        'handler' => HelloCommand::class,
    ]
];

Finally, do not forget to pass your dispatcher to your application when you initialize it:

$application = new Application('App', 1.0, $routes, null, $dispatcher);

In the above examples, when the hello route is matched, the Dispatcher will attempt to pull the HelloCommand service from the container prior to dispatching it.

Exception Handling

zf-console provides exception handling by default, via ZF\Console\ExceptionHandler. When your console application raises an exception, this handler will provide a "pretty" view of the error, instead of the full stack trace (unless you want to include the stack trace in your view!).

The default message looks like the following:

======================================================================
   The application has thrown an exception!
======================================================================

 :className:
 :message

where :className will be filled with the exception's class name, and message will contain the exception message, if any.

You may provide your own template if desired:

$application->getExceptionHandler()->setMessageTemplate($template);

The following template variables are defined:

  • :className
  • :message
  • :code
  • :file
  • :line
  • :stack
  • :previous (this is used to report previous exceptions in a trace)

If you want to provide your own exception handler, you may do so by providing any PHP callable to the setExceptionHandler() method:

$application->setExceptionHandler($handler);

Debug mode

If you want normal PHP stack traces and error reporting, you can put the application into debug mode:

$application->setDebug(true);

Using zf-console in Zend Framework 2 Applications

While Zend Framework 2 integrates console functionality into the MVC, you may want to write scripts that do not use the MVC. For instance, it may be easier to write an application-specific script without going through the hoops of creating a controller, adding console configuration, etc. However, you will likely still want access to services provided within modules, and also want the ability to honor service and configuration overrides.

To do this, you will need to bootstrap your application first. We'll assume you're putting your script in your application's bin/ directory for this example.

use Zend\Console\Console;
use Zend\Console\ColorInterface as Color;
use ZF\Console\Application;
use ZF\Console\Dispatcher;

chdir(dirname(__DIR__));
require 'init_autoloader.php'; // grabs the Composer autoloader and/or ZF2 autoloader
$application = Zend\Mvc\Application::init(require 'config/application.config.php');
$services    = $application->getServiceManager();

$buildModel = $services->get('My\BuildModel');

$dispatcher = new Dispatcher();
$dispatcher->map('build', function ($route, $console) use ($buildModel) {
    $opts = $route->getMatches();
    $result = $buildModel->build($opts['package'], $opts['target']);
    if (! $result) {
        $console->writeLine('Error building package!', Color::WHITE, Color::RED);
        return 1;
    }

    $console->writeLine('Finished building package ' . $opts['package'], Color::GREEN);
    return 0;
});

$application = new Application(
    'Builder',
    VERSION,
    array(
        array(
            'name' => 'build',
            'route' => 'build <package> [--target=]',
            'description' => 'Build a package, using <package> as the package filename, and --target
    as the application directory to be packaged.',
            'short_description' => 'Build a package',
            'options_descriptions' => array(
                '<package>' => 'Package filename to build',
                '--target'  => 'Name of the application directory to package; defaults to current working directory',
            ),
            'defaults' => array(
                'target' => getcwd(), // default to current working directory
            ),
        ),
    ),
    Console::getInstance(),
    $dispatcher
);
$exit = $application->run();
exit($exit);

Essentially, you're calling Zend\Mvc\Application::init(), but not it's run() method. This ensures all modules are bootstrapped, which means all configuration is loaded and merged, all services are wired, and all listeners are attached. You then pull relevant services from the ServiceManager and pass them to your console callbacks.

Best Practices

We recommend the following practices when creating applications using zf-console.

Use Zend\Console to create output

Use Zend\Console to create any output you send. This ensures that the output works cross-platform (including Unix-like systems and Windows). As examples:

$dispatcher->map('some-command', function ($route, $console) {
    $console->writeLine('Executing some-command!');
});

Install your script via Composer

You can tell Composer to install your script in the vendor/bin/ directory, making it trivial for end-users to locate and execute your script within their own applications.

{
    "require": {
        "php": ">=5.3.23",
        "zfcampus/zf-console": "~1.0-dev"
    },
    "bin": ["script.php"]
}

If you do this, be sure to name your script uniquely.

Use filters or validators

Zend\Console's RouteMatcher sub-component allows you to specify filters and/or validators for each matched argument of a route. These let you provide normalization (filters) and more robust validation logic when desired.

As an example, consider a common scenario of using comma-separated values for an argument; you could split those into an array as follows:

// config/routes.php

use Zend\Filter\Callback as CallbackFilter;

return array(
    array(
        'name' => 'filter',
        'route' => 'filter [--exclude=]',
        'default' => array(
            'exclude' => array(),
        ),
        'filters' => array(
            'exclude' => new CallbackFilter(function ($value) {
                if (! is_string($value)) {
                    return $value;
                }
                $exclude = explode(',', $value);
                array_walk($exclude, 'trim');
                return $exclude;
            }),
        ),
    )
);

Using filters and validators well, you can ensure that when your dispatch callbacks receive data, it is already sanitized and ready to use.

Filters provided by zf-console

zf-console provides several filters for your convenience:

  • ZF\Console\Filter\Explode allows you to specify a delimiter to use to "explode" a string value to an array of values. As an example:

    // config/routes.php
    
    use ZF\Console\Filter\Explode as ExplodeFilter;
    
    return array(
        array(
            'name' => 'filter',
            'route' => 'filter [--exclude=]',
            'default' => array(
                'exclude' => array(),
            ),
            'filters' => array(
                'exclude' => new ExplodeFilter(','),
            ),
        )
    );

    The above would explode values provided to --exclude using a ,; --exclude=foo,bar,baz would set exclude to array('foo', 'bar', 'baz'). By default, if no delimiter is provided, , is assumed.

  • ZF\Console\Filter\Json allows you to specify a JSON-formatted string; it will then deserialize it to native PHP values.

    // config/routes.php
    
    use ZF\Console\Filter\Json as JsonFilter;
    
    return array(
        array(
            'name' => 'filter',
            'route' => 'filter [--exclude=]',
            'default' => array(
                'exclude' => array(),
            ),
            'filters' => array(
                'exclude' => new JsonFilter(),
            ),
        )
    );

    The above would deserialize a JSON value provided to --exclude; --exclude='["foo","bar","baz"]' would set exclude to array('foo', 'bar', 'baz').

  • ZF\Console\Filter\QueryString allows you to specify a form-encoded string; it will then deserialize it to native PHP values.

    // config/routes.php
    
    use ZF\Console\Filter\QueryString;
    
    return array(
        array(
            'name' => 'filter',
            'route' => 'filter [--exclude=]',
            'default' => array(
                'exclude' => array(),
            ),
            'filters' => array(
                'exclude' => new QueryString(),
            ),
        )
    );

    The above would deserialize a form-encoded value provided to --exclude; --exclude='foo=bar&baz=bat' would set exclude to array('foo' => 'bar', 'baz' => 'bat').

Classes

This library defines the following classes:

  • ZF\Console\Application, which handles actual execution of the script, including usage reporting.
  • ZF\Console\Dispatcher, which maps route names to PHP callables, and dispatches them when selected.
  • ZF\Console\HelpCommand, which provides the default "help" logic for displaying command usage.
  • ZF\Console\Route, an extension of Zend\Console\RouteMatcher\DefaultRouteMatcher that adds aggregation of route metadata, including the name and description.
  • ZF\Console\RouteCollection, which implements Zend\Console\RouteMatcher\RouteMatcherInterface, aggregates ZF\Console\Route instances, and performs route matching.
  • ZF\Console\Filter\Explode, which implements Zend\Filter\FilterInterface, and which is described above.
  • ZF\Console\Filter\Json, which implements Zend\Filter\FilterInterface, and which is described above.
  • ZF\Console\Filter\QueryString, which implements Zend\Filter\FilterInterface, and which is described above.

zf-console's People

Contributors

1ma avatar arnaudligny avatar asurrey avatar geerteltink avatar michalbundyra avatar mtymek avatar slaff avatar stefanotorresi avatar weierophinney avatar zf2timo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zf-console's Issues

Running with service manager

Could you gave example how to do dependency injection from service manager ( container interop ) that define in the configuration to the handler ?

Commands and subcommands

How to create this console router?

myscript.php zone <command> <args>

Command can be: import and export.
<args> can be path or id

Some problems:

zone 

must print list of available commands (like 'Available commands: import, export')

zone import (without any other args)

must print help for zone import command (like 'usage zone import /path/to/file.json`)

zone export

must print help for zone export command (like 'usage zone export ')

and now

zone import file.json

or

zone export 100

must launch any one or two functions from \Foo\Bar class

How can i do this?

Positional value parameters with name

Hi,

I would like to provide the parameter name with positional value parameter.

Currently, if I pass the name it appends that name to the value.

Example:

php script.php build project=1 name=Test

Expected results

[
'project' => 1,
'name' => 'Test',
]

Actual results

[
'project' => 'project=1',
'name' => 'name=Test',
]

I know, I can add an optional parameter like [--project=1] and then add a check on code level. But I don't want to do this.

Is there any possibility we can achieve this?

Any help would be much appreciated.

Thanks

Adding a RouteInterface definition

Hi,

I started using this microframework about a week ago. Works great especially when integrating with a ZF3 framework or resuing existing ZF3 modules.

I wrote a lot of route handlers and got a little lazy at figuring out what the __invoke function should have as arguments. So I wrote a Route Interface definition to ensure compliance with how handlers are invoked.

If you are interested, I forked the project and added RouteInterface.php under the src folder.

I am quite new to GitHub as a contributor and I am not sure about how to do pull requests and such.

Thanks
Eric

Wrong zend/console requirement version

as DefaultRouteMatcher and RouteMatcherInterface was introduced in Zend 2.3.0 release the composer.json requirement specified as

"zendframework/zend-console": "~2.0"

could not met the proper version of ZendConsole which cause the errors when importing

use Zend\Console\RouteMatcher\DefaultRouteMatcher;
use Zend\Console\RouteMatcher\RouteMatcherInterface;

minimal version requirements should be reviewed to prevent that issue

Better error handling

What I am missing is good default error handler that prints information based on a template set in the configuration. Something similar to:

======================================================================
   The application has thrown an exception!
======================================================================
 :className
 :message

when not in debug mode and the full exception stack trace when in debug mode.

Supply useful filters

Per @slaff:

  • QueryString: to allow arguments such as --directives=session.save_handler=cluster&something=else, which would be parsed to the array ["session.save_handler" => "cluster", "something" => "else"]. PHP's parse_str() could be used for an initial implementation; however, it munges keys to valid PHP variable names, and thus a custom implementation should likely be used.
  • JSON: to allow arguments such as --directives='{"session.save_handler": "cluster", "something": "else"}', which would parse to the same value as in the QueryString example above.
  • Explode: to allow delimited arguments to be parsed to an array: --modules=foo,bar,baz would be come ['foo', 'bar', 'baz']. The delimiter would be a comma by default, but could be specified during instantiation (or, if using the FilterPluginManager, when requesting the filter).

At service-manager to handle commands / all objects?

I thought of adding the ZF2 ServiceManager to handle the commands. I think it would make it much easier to create factories to create command instances. Or we could even add all objects to the ServiceManager, especially the Application instance. That would make it much easier to inject the Application instance to the HelpCommand as well. We could even refactor the Application class and pull out the standard commands to external classes (like the HelpCommand). An extra interface could standardize the __invoke() methods for all commands.

Would the effort be worth it or would it introduce an unwanted complexity or overhead?

Warning generated every time I use console

Hello.

In multiple applications, every time I use a console route I get the following warning:

HP Warning:  cli_set_process_title(): cli_set_process_title had an error: Not initialized correctly in /Users/geeh/www/modules.zendframework.com/vendor/zfcampus/zf-console/src/Application.php on line 534

This happens both inside and outside of ZF2 app.

Thank you.

Create Skeleton Application

Make it easy for every PHP developer to start creating a ZF-CLI application.

  • Create boilerplate code
  • Add simple getting started example(s)
  • Add phar support (pack your app in a single stand-alone file).
  • Documentation: Add an article or short tutorial.

Disabling banner and footer from an argument

Is there a way or a suggested solution to disable banner and footer from a command-line argument?

I would like to be able to use an argument like --disable_banner to disable the banner. This would be useful when piping the output but I would like to have control it from the command line.

I figure that I could preparse the arguments before $app->run() is called to look for the --quiet argument.

Any suggestions?

Thanks

Please create new version 1.0.4

The last commits merged since 1.0.3 are not tagged with a version number. If I install this via composer I cannot use:

"require": {
    "zfcampus/zf-console": "1.*"
},

I must use:

"require": {
    "zfcampus/zf-console": "dev-master*"
},

Better error handling

Now is little bit tricky to eg. log errors in zf-console.

I like the idea of new error handler in stratigility. Especially error response (message) generation, triggering listeners (useful for logging) etc.

Do you have any idea how this implement in zf-console? Your opinions?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.