Prologue
Versioning Scheme
ProjectCLI follows Semantic Versioning.
Contribution Guide
TBD
Getting Started
Prerequisites
- PHP CLI 7.2 or newer (incl. extensions: zlib, json, intl, xml, curl)
Homebrew
brew install php@7.2
Ubuntu
Make sure the available version meets the requirements:
apt show php
If not, add the following repository:
add-apt-repository -y ppa:ondrej/php \ && apt-get update
Install the PHP CLI and extensions:
apt install php-cli php-xml php-curl php-zip php-intl php-json
Installation
After you've installed all dependencies, get the latest ProjectCLI release here and move it to /usr/local/bin/project or /usr/bin/project, depending on your system. The project command will be available after you restart your terminal session.
Update
Manually update ProjectCLI:
project self-update
Uninstall
rm -rf $HOME/.project $(which project)
Usage
Directory Structure
It's mandatory, that the project has the according directory structure and files in order for ProjectCLI to work properly.
root ├── commands │ - Contains project specific commands (see 'project make:command') ├── conf │ - Add configuration files for project components (like nginx, PHP, crontab, supervisor, etc) ├── scripts │ - Can contain scripts for deployment, HTTP requests or other complex tasks ├── src │ - Contains the application source └── temp - Temp directory for docker-compose service mounts
Project Configuration
The following configuration properties are available:
# project name including the vendor name (mandatory) name: vendor/name-of-the-project # the actual project version (mandatory) version: v1.0.0 # specify multiple plugins required for this project require: - projectcli/laravel
Commands
ProjectCLI gives you the ability to write project specific commands, which can be used to translate complex tasks into a single command. For example, to completely setup a project, there need to be run many specific commands. So, instead of letting contributors execute command after command after command, there's just one command to rule them all.
If you clone a project via the clone
command
and the project provides a setup
or install
command,
ProjectCLI will automatically ask, if those commands should be
executed. So it's best practice to use the clone
command to start
setting up the project.
Writing Commands
First, let's create the command via:
project make:command SetupCommand
You'll then find the appropriate command in ./commands/SetupCommand.php
If you are in a PHP project with Composer support, you can
require the ProjectCLI dev
package, which provides all necessary interfaces for your IDE:
project composer require --dev chriha/project-cli-dev
Components
Since ProjectCLI is based on the Symfony
Console, commands are defined in classes, extending \Chriha\ProjectCLI\Commands\Command
.
Every command consists of 4 components: The name, description, configuration and the
handling.
This $defaultName
variable specifies the argument of how the command
will be called.
/** @var string */ protected static $defaultName = 'setup';
The $description
gives a short, but exact description for the
command.
/** @var string */ protected $description = 'Set up the project.';
Configure the command
public function configure() : void { $this // the full command description shown when running the command with // via "project help COMMAND" option ->setHelp('This command allows you to create a user...') // specify command arguments via: ->addArgument($name, $mode = null, $description = '', $default = null) // specify command options via: ->addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) }
Consult the Symfony documentation for further instructions on how to use arguments and options.
Command handler
The handle method is where all the magic happens. If you, for example, would like to
create a
setup
command for your project, let's do the following:
public function handle() : void { // check if there's already an env file to use for Docker if ( ! file_exists(Helpers::projectPath('.env'))) { copy(Helpers::projectPath('.env.example'), Helpers::projectPath('.env')); } // same goes for application env variables if ( ! file_exists(Helpers::projectPath('src/.env'))) { copy(Helpers::projectPath('src/.env.example'), Helpers::projectPath('src/.env')); } // install all necessary composer packages $this->call('composer', ['install']); // generate application key $this->call('artisan', ['key:generate']); // run all database migrations $this->call('artisan', ['migrate:fresh']); // install all necessary Node packages $this->call('npm', ['install']); // compile static files $this->call('npm', ['run', 'dev']); // print a success message for the user $this->info('Project successfully installed'); }
For the artisan
command, the projectcli/laravel
plugin is required.
For all available helpers, see Helpers.php.
Plugins
Where commands are specific to and only available in each project, plugins are basically global commands.
Find Plugins
There are two ways to search for plugins. Via the console:
project plugins:search YOUR_QUERY
Install Plugins
Installing a plugin is as easy as:
project plugins:install VENDOR/NAME
You will also find the command to install a plugin on every plugin page, e.g. projectcli/laravel.
Update Plugins
project plugins:update VENDOR/NAME
Uninstall Plugins
project plugins:uninstall VENDOR/NAME
Require Plugins
If a certain plugin is required for the project, you can specify that in the
project's configuration file project.yml
:
name: vendor/project-name version: v1.0.4 require: - projectcli/laravel
In this case, ProjectCLI will notify the user every time, a command is executed inside the project.
**************************************************** * Required plugins * **************************************************** - projectcli/laravel
All missing, but required plugins can be installed easily via:
project plugins:install
Writing Plugins
project plugins:uninstall VENDOR/NAME
Easily create the boilerplate via the following command:
project make:plugin
During the process, you can specify your vendor as well as the plugin name. ProjectCLI will tell you the according path to the plugin, whenever the plugin was successfully created.
The commands each plugin holds have the exact same structure as project specific commands. So head over to the writing commands chapter, if you're curious on how to write commands.
Additionally to normal commands, plugin commands have an extra method, which you can use to enable and disable the according command. Let's see an example from the projectcli/laravel package:
public static function isActive() : bool { // via the constant, check if the command should only be available // inside a project and if the artisan file exists return PROJECT_IS_INSIDE && file_exists(Helpers::projectPath('src/artisan')); }
Make Commands available
Plugin commands are not automatically loaded and available. Require the PHP file for
each command in the ./plugin.php
and specify the Namespace in the
plugins ./project.yml
:
name: projectcli/laravel description: Laravel specific commands version: v1.0.0 commands: - \ProjectCLI\Laravel\Commands\ArtisanCommand
Composer packages inside plugins are not supported.
Publishing Plugins
For easy installation in the future or for other users to be able to use your plugin
via the plugins:install
command, you have to create a public Github
repository and create a tag for every new version. After that, you can
submit your plugin as an issue to the registry.