bitbull/cli


README

A collection of useful scripts to deploy, init and configure PHP applications.

Install

Using installation script

Use the installation script hosted from https://cli.bitbull.io/install, is it possibile to pass a parameter with the desidered version (default is "latest").

curl -s https://cli.bitbull.io/install | sudo bash -s latest

Manually download and nstall phar file

Download the latest stable phar-file:

wget https://cli.bitbull.io/dev/bb-cli.phar

Now you can make the phar-file executable:

chmod +x ./bb-cli.phar

And now you can run it using

./bb-cli.phar --version

If you want to use the command system wide you can copy it to /usr/local/bin (for both Mac and Linux users).

sudo mv ./bb-cli.phar /usr/local/bin/bb-cli

and use it

bb-cli --version

Composer project

Require it in you project

composer require bitbull/cli

Use it from vendor/bin

./vendor/bin/bb-cli --version

Global composer require

composer global require bitbull/cli

Use it using

bb-cli --version

Using Docker image

Copy this snippet into /usr/local/bin/bb-cli file

#!/bin/bash

docker run -it --rm -v $(pwd):/app bitbull/cli:dev $@

make the script executable

sudo chmod +x /usr/local/bin/bb-cli

now you can use bb-cli command to execute a temporary Docker container without installing any other dependencies.

Contributing

Clone this repo and install composer modules

composer install

Deployment

Build the PHAR srchive using the internal command phar:build

./bin/bb-cli phar:build

Add new commands

Commands are wrapped in different class inside src\Commands. If you want to add new commands add new class in the commands directory or edit and existing one adding the command function, remember to extend Bitbull\Cli\Commands\BaseCommand parent command.

<?php

namespace Bitbull\Cli\Commands\CommandDirectoryHere;

use Bitbull\Cli\Commands\BaseCommand;
use Symfony\Component\Console\Input\InputOption;

class ClassNameCommand extends BaseCommand
{
    /**
     * Command description
     *
     * @param $myparameter
     * @param $opts array
     */
    function myCommandName($myparameter, $opts = [
        'param' => null,
        'flag' => false,
        'required' => InputOption::VALUE_REQUIRED,
        'withDefault' => 'defaultvalue',
    ])
    {
        // Use task here
    }
}

Command class are automatic loaded and Robo convert function name into command: my:command-name.

Follow the Robo command guide for more details.

Add new tasks

Task are simply helper function used to exec commands or editing file where the true intelligence resides. Add new task in src\Tasks creating a new class or editing an existing one following the Robo task guide.

<?php

namespace Bitbull\Cli\Tasks\Utils;

use Bitbull\Cli\Tasks\BaseTask;
use Robo\Result;

class MyTask extends BaseTask {

    function run()
    {
        return Result::success($this);
    }
}

If your task use only a process call extends Bitbull\Cli\Tasks\BaseTaskCommand and implement the getCommand method.

<?php

namespace Bitbull\Cli\Tasks\Utils;

use Bitbull\Cli\Tasks\BaseTaskCommand;

class MyCommandTask extends BaseTaskCommand {
    
    /**
     * {@inheritdoc}
     */
    public function getCommand()
    {
        return "ls";
    }
}

To load the task in command class you have to import the specific trait, so when you add a new task remember to create the connected trait or adding the load method.

<?php

namespace Bitbull\Cli\Tasks\Utils;

trait UtilsTasks
{
    protected function taskMyTask()
    {
        return $this->task(MyTask::class); //pass you task class
    }
    
    protected function taskMyTaskWithConstructorParam($param1)
    {
        return $this->task(MyCommandTask::class, $param1); //pass you task class with constructor params
    }
}

Add new applications

Application resides in src\Application directory, add new class extending Bitbull\Cli\Application\BaseApplication

<?php
namespace Bitbull\Cli\Application;

use Bitbull\Cli\Application\BaseApplication;

class NewApplication extends BaseApplication
{
    // override parent methods
}

Then edit the Bitbull\Cli\Application\ApplicationFactory to handle the new application name in app.type config

<?php

  /**
   * @return ApplicationInterface
   */
  public function getInstance()
  {

      switch ($this->type) {
          case "laravel":
              return new Laravel($this->rootPath);
              break;
          case "magento":
              return new Magento($this->rootPath);
              break;
          case "magentowp":
              return new MagentoWordpress($this->rootPath);
              break;
          case "magento2":
              return new Magento2($this->rootPath);
              break;
          case "wordpress":
              return new Wordpress($this->rootPath);
              break;
          case "composer":
              return new Composer($this->rootPath);
              break;
          case "newapplication": // add the new application
              return new NewApplication($this->rootPath);
              break;
      }

      return new Composer($this->rootPath);
  }
  

Configuration file

Robo can load command and task options from a yaml configuration file, anyway is possible to add any configuration structure and load the config value using dot notation:

<?php

$value = Robo::Config()->get('app.config.custom', 'default value');

By default configurations are loaded from .bb-cli.yml file in the CWD, it's possible to merge or override some values using a different configuration file:

./bb-cli

You can also use environment variable interpolation with bash-like syntax:

test:
  config: "${CONFIG_FILE}"
  locale:
    default: "${REGION}_${LANG}"

Working directory

By default all commands will use the CWD base on where the command is called, you can specify a different root path with option:

./bb-cli --root=/my/different/directory

Remember that the configuration file location is based on this param, so the default configuration will be searched in /my/different/directory/.bb-cli.yml unless you use the configuration file options, example:

cd /project
./bb-cli

config file /project/.bb-cli.yml will be used

./bb-cli --root=/my/different/directory --config="/my/other/directory/env-override.yml"

config file /my/different/directory/.bb-cli.yml will be merged with /my/other/directory/env-override.yml

./bb-cli --root=/my/different/directory --config="env-override.yml"

config file /my/different/directory/.bb-cli.yml will be merged with /project/env-override.yml

Application

To make life easier we created a set of command based on the application type, the most famous CMS/Framework are supported: Wordpress Laravel Magento 1 Magento 2 Magento + Wordpress

Every application respect the Bitbull\Cli\Application\ApplicationInterface to expose build, install and deploy commands.

The selected application is loaded in the Bitbull\Cli\Commands\BaseCommand based on file configuration

app:
  type: "magento"
  version: "2.2"

or using APP_TYPE environment variable.

Dependencies

Every application have different dependencies, this tool does not replace the application specific CLI.

Common requirements

Wordpress

Magento 1

Magento 2

Laravel

CLI Options

OptionDescription
-h, --helpDisplay this help message
-q, --quietDo not output any message
-V, --versionDisplay this application version
--ansi                           | Force ANSI output
--no-ansi                        | Disable ANSI output

-n, --no-interaction | Do not ask any interactive question

--simulate                       | Run in simulated mode (show what would have happened).
--progress-delay=PROGRESS-DELAY  | Number of seconds before progress bar is displayed in long-running task collections. Default: 2s. [default: 2]

-D, --define=DEFINE | Define a configuration item value. (multiple values allowed)

--config[=CONFIG]                | Configuration file.
--root[=ROOT]                    | Custom root path.

-v, -vv, -vvv, --verbose | Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands

Base

CommandDescription
helpDisplays help for a command
listLists commands
self:installInstall CLI
self:removeRemove CLI

Configuration

CommandDescription
config:env-interpolateInterpolate environment variable into file

Application

CommandDescription
app:anonymizeAnonymize application data
app:buildBuild application
app:cache-cleanClean application cache
app:cache-disableDisable application cache
app:cache-enableEnable application cache
app:cleanClean application directory
app:config-generateCreate application config file
app:update-databaseUpdate application database

CDN

CommandDescription
cdn:cloudfront-invalidateInvalidate CDN

Development

CommandDescription
dev:dump-configDump config
dev:dump-cwdGet current working directory
dev:dump-phpDump PHP infos
dev:image-minifyMinify Images
dev:javascript-minifyMinify Javascript
dev:less-compileCompile Less
dev:scss-compileCompile Scss
dev:style-minifyMinify Style
dev:watchWatch for file changes

Phar

CommandDescription
phar:buildBuild the phar executable
phar:disable-writeDeny phar creation
phar:enable-writeAllow phar creation

GIT

CommandDescription
git:update-changelogUpdate Changelog

Init

CommandDescription
init:bitbucketInit Bitbucket pipeline
init:gitlabInit Gitlab pipeline
init:travisInit Travis pipeline

Local environment

CommandDescription
local:docker-downDestroy local Docker environment
local:docker-initCreate Docker compose file
local:docker-startStart Docker environment
local:docker-stopStop local Docker environment
local:docker-upCreate local Docker environment
local:vagrant-downDestroy local Vagrant environment
local:vagrant-initCreate Vagrant file
local:vagrant-startStart local Vagrant environment
local:vagrant-stopStop local Vagrant environment
local:vagrant-upCreate local Vagrant environment

Pipeline CI/CD

CommandDescription
check:grumphpCheck CodeStyle using grumphp
check:phpcsCheck CodeStyle using php cs
check:phpmdCheck CodeStyle using php md
test:phpunitTest application using PHP Unit
pipeline:deploy-codedeployDeploy application using AWS CodeDeploy
pipeline:deploy-dockerDeploy application to Docker repository
pipeline:deploy-dockercomposeuiDeploy application using Docker Compose UI
pipeline:deploy-sftpDeploy application using SFTP
pipeline:release-activateActivated release using blue-green
pipeline:release-installInstall application
pipeline:remote-sshDeploy application to a remote server with SSH

Sync Environment

CommandDescription
sync:database-anonymizeAnonymize database
sync:database-createCreate Database
sync:database-dumpCreate dump from database
sync:database-dump-downloadDownload database dump
sync:database-dump-uploadUpload database dump
sync:database-restoreRestore database from dump
sync:media-archiveCreate media archive
sync:media-archive-downloadDownload media archive
sync:media-archive-uploadUpload media archive
sync:media-extractExtract media archive

WebServer

CommandDescription
webserver:apache-authAdd http auth
webserver:apache-forwarded-headerPatch htaccess behind a proxy
webserver:apache-httpsredirectAdd http to https redirect

Cloud Management

CommandDescription
aws:ami-updateUpdate AMI
aws:s3-shareCreate sharing link for S3 bucket object
aws:security-group-exportExport security group
aws:security-group-importImport security group dump
aws:sns-publishSend message to SNS topic
aws:ssm-describe-commandDescribe SSM command
newrelic:deploymentNotify new deployment on New Relic
rundeck:job-executeExecute Rundeck Job
maxmind:database-updateUpdate and check MaxMind Database
maxmind:ipinfoRetrieve IP info from MaxMind database

Swarm

CommandDescription
portainer:execute-commandExecute command inside container
portainer:service-updateDeploy application to portainer
portainer:stack-deleteDelete portainer stack
portainer:stack-updateDeploy application to portainer
swarm:execute-commandExecute command inside container