Zesk Commands

Zesk has a simple interface to enable creation of chainable, command-line functions which work within your application's context.

zesk [arguments] [command] [command-arguments]

The main binary is zesk found at $ZESK_ROOT/bin in turn invokes zesk-command.php.

zesk scans the current directory upwards for a .application.php file; and then runs the installed vendor/bin/zesk-command.php.

This allows you to have a single copy of the main zesk binary in your path, and it will find and run the local installed version of zesk-command.php for the application.

Why do I care?

When running different versions of Zesk in different projects, it uses the currently installed version of Zesk PHP code for each application.

The command starts at the current working directory and looks for a file ending with .application.php in parent directories until found or the root of the file system is reached.

The application.php file's location sets your application root directory, like composer.json does.

Once found, it runs your commands in PHP after first including the primary application include file. This allows your application to load its context, such as globals, database settings, or any other basic configuration needed to run commands.

Again - setting up the database, connecting to your external services, and configuration your application is all done in a single, central location.

Special arguments for zesk

To change to a directory prior or during command invocation:

zesk --cd $HOME/live/application/content convert-content

Changes the file system current directory running the application. YMMV. See PHP's getcwd and any command which depends on this.

--set name=value · Set arbitrary global

To set a global value in Zesk prior to invoking a command, the --set parameter allows setting of globals in Zesk via zesk::set.

zesk --set "zesk\Database::debug=1" update

Be sure to use proper backslash escaping when using the command line.

--[variable] · Set arbitrary global to true

When specified prior to the first command, this argument will set a zesk global to true.

zesk --zesk\\Database::debug update

--[variable]=[value] · Set arbitrary global to string value

Similarly, you can specify a value for the global as value

zesk --LOG_PATH=$HOME/log update

--define [variable]=[value] · Set arbitrary global to string value

Similarly, you can define a variable before loading the application context:

zesk --define PHPUNIT update

If the value (and the =) are not supplied, then the variable is defined to be true.

--unset variable

Unset a previously set variable.

Commands

The Zesk command can take PHP include files as parameters, or command which essentially point to a class or function to invoke. If the parameter is a file which can be included, it is included directly and no further action is taken.

If the parameter is not a file, then Zesk looks to see if it corresponds to a command by searching the paths listed by $application->zeskCommandPath()

Note: This is different from $application->commandPath() which is the path used to find shell commands in the system.

All commands are loaded in the directory in memory before running. Shortcuts are gathered from each command class's $this->shortcuts member.

Command Arguments

When a command is specified, each command is allowed to process its own arguments, and may stop processing at any time. This allows sets of commands to be chained to allow for complex commands to be invoked from a single command line.

If a command does not process a command line argument, then it may be handled by the Special arguments handling above. To debug how arguments are handled for your command, try using a global debug setting:

zesk --command_debug globals

For commands which are functions, the current argument list (including the name of the command as invoked) is passed to the function. The function should then process arguments as needed, and return any unprocessed arguments.

For example, a very simple command which loads modules could be saved to $ZESK_ROOT/classes/command/module.inc:

<?php
function zesk_command_module(array $arguments) {
    if (count($arguments) === 0) {
        throw new ParameterException("Need at least one module to load");
    }
    $module = array_shift($arguments);
    zesk::module($module);
    return $arguments;
}

The equivalent can be written as a Command class:

<?php
class Command_Module extends Command {
    protected array $option_types = array("+" => "string");
    function run() {
        zesk::module($this->get_arg("module"));
    }
}

The difference is that the Command class keeps track of the arguments which have been processed or not, and there's no need to return the unprocessed arguments.

Chaining commands

Certain commands can be chained, and others can not, depending on the command. A simple example which outlines how this works is as follows:

zesk module server module jquery modules --loaded

Outputs:

jquery: true
server: true

Commands should be implemented such that they use only arguments which are known to it. In addition, classes which extend zesk\Command SHOULD specify a wildcard parameter for remaining parameters, unless the command is always last in a chain (for example database-connect).

Some commands can specify an terminating string, which should be standardized to the double-dash argument (e.g. "--"):

zesk eval "echo zesk()->configuration->init;" "zesk()->hooks->call('alert')" -- globals

For example the eval command stops when it encounters the -- argument, and then passes control to the next command.