Code Monkey home page Code Monkey logo

phapp-cli's Introduction

Phapp CLI

Provides standardized console commands for PHP applications.

Requirements

  • Git version >= 2.0
  • Bash 4.*
  • PHP >5.6|>7.0

Installation

Installation requires composer. As there are some dependency conflicts with the latest drush release it is recommended to install the tool via consolidation/cgr. To do so, just execute:

# Download latest stable release.
php -r "
  ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0)');
  readfile(json_decode(file_get_contents('https://api.github.com/repos/drunomics/phapp-cli/releases/latest'))->assets[0]->browser_download_url);
" > phapp
chmod +x phapp

# Optional: Ensure ~/bin exists and configure it to be available in $PATH.
[ -d ~/bin ] || mkdir ~/bin
echo $PATH | grep -q ~/bin || (echo "export PATH=~/bin:\$PATH" >> ~/.bashrc && export PATH=~/bin:$PATH)

# Make phapp executable from everywhere by moving to a destination available in $PATH.
# If you skipped the optional step above, be sure to move it to a suiting destination.
mv phapp ~/bin/phapp

Updating

Run

 phapp self:update

Usage

Run phapp list to show a list of support commands and use phapp command --help for more information about a command. The list of currently available commands is:

  build                 Builds the project with the current code checkout.
  clone                 Clones a Phapp project.
  create                Creates a new project base on a given template.
  help                  Displays help for a command
  init                  Initializes the app.
  install               Installs the application.
  list                  Lists commands
  setup                 Setups the phapp environment.
  status                Checks for a working and installed application.
  update                Updates the app.
 build
  build:branch          Builds a given branch.
  build:clean           Cleans all build related files.
 git
  git:pull              Updates local branches by pull from remote repositories.
  git:setup-remotes     Configures Git remote repositories.
 init
  init:manifest         Initializes a new phapp.yml for your project.
 self
  self:update           Updates the installed phar.

phapp.yml

An application provides basic metadata and customizes commands in its phapp.yml, the phapp manifest. See examples/phapp.yml for an example.

Phapp environment variables

Commands defined in phapp.yml may make use of the phapp environment variables.

Dotenv support

Phapp environment variables are either set by the environment; i.e. the host, or via a .env file.

In order to help with initializing the environment based upon one or multiple .env files the environment command may be used. This command is prepended the other commands (except setup) such that they may rely on the initialized environment.

Thus, the .env file can be written as part of the setup command and sourced as part of the environment command.

Available variables

Available environment variables are / must be:

Variable Description Example value
PHAPP_ENV The environment name. E.g., local, test or live live
PHAPP_ENV_TYPE The environment type; e.g. an id for the hosting environment or type of server. acquia
PHAPP_ENV_MODE The environment mode; valid values are: production, development production
PHAPP_BASE_URL The base URL of the app. https://example.com

Optional environment variables are:

Variable Description Example value
PHAPP_ENV_COLOR A color used for indicating the current environment. 302f2f

Database connection.

PHAPP_ENV_MYSQL_DEFAULT_DATABASE=database
PHAPP_ENV_MYSQL_DEFAULT_USERNAME=user
PHAPP_ENV_MYSQL_DEFAULT_PASSWORD=pass
PHAPP_ENV_MYSQL_DEFAULT_HOST=localhost
PHAPP_ENV_MYSQL_DEFAULT_PORT="3306"

Various other variables provided by the environment.

PHAPP_ENV_DUMP_DIR="/data/mysql_dumps/sync"
PHAPP_ENV_DUMP_DB_FILENAME="${PHAPP_ENV_MYSQL_DEFAULT_DATABASE}-$(date -d "1 day ago" +%Y%m%d).sql.gz"

Phapp development

Build a new phar

The phar is built using box, for details see https://github.com/box-project/box2. To built the phar just run:

 composer install --dev
 composer build

Create a new release

  • Tag a new version and push it.
  • Build a new phar (see above).
  • Upload the new phar at the github release page. Keep the filename as is.
  • Note that the packagist API is not updated immediately. Thus it takes a few minutes until the new release is picked up by the self:update command.

phapp-cli's People

Contributors

arthurlorenz avatar fago avatar hatsch avatar ivangrozni avatar nebel54 avatar rthideaway avatar vasike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

phapp-cli's Issues

Improve phapp command script execution

  • Command scripts specified in phapp.yml should be executed via /bin/bash (configurable via global config).
  • Make command arguments and options available as bash variables
  • Phapp environment variables should be available to command scripts.

Add phapp setup command

  • Add a "setup" command script for intital phap project setup, like copying settings.php
  • Document that "setup" must check first whether it needs to changes.
  • Add --force option which tries to repair setup issues, like wrong settings.php links being in place.

Add a phapp environment command

The command prints out the environment variables set after executing the bash command 'environment' from the manifest. It echos the variables that are new; thus for being able to do so it will have to compare the original environment with the modified environment and only print out variables that changed.

USAGE: $(phapp environment) custom-command

If --verbose is passed, it should also print out the executed command - as done by default by the /bin/bash prefix https://github.com/drunomics/phapp-cli/blob/master/src/Task/Exec.php#L68

The optional parameter "--show-command" makes phapp show the command instead of outputting the variables. Thus can be used as following:

eval $(phapp environment --show-command)

phapp git:pull returns error if there is no master

After the first installation of a project I ran phapp git:pull.
It returned an error:

phapp git:pull --verbose
➜  Remote origin already present.
 [drunomics\Phapp\Task\Exec] Running
/bin/bash -c 'git fetch origin'
 [drunomics\Phapp\Task\Exec] Done in 2.137s
➜  Remote platform already present.
 [drunomics\Phapp\Task\Exec] Running
/bin/bash -c 'git fetch platform'

 [drunomics\Phapp\Task\Exec] Done in 1.087s
➜  Updating develop...
 [drunomics\Phapp\Task\Exec] Running
/bin/bash -c '(git fetch $PWD origin/develop:develop -q ||
 git merge-base --is-ancestor origin/develop develop) &&
 (git fetch $PWD platform/develop:develop -q ||
 git merge-base --is-ancestor platform/develop develop)'
 [drunomics\Phapp\Task\Exec] Done in 0.029s
➜  Updating master...
 [drunomics\Phapp\Task\Exec] Running
/bin/bash -c '(git fetch $PWD origin/master:master -q ||
 git merge-base --is-ancestor origin/master master) &&
 (git fetch $PWD platform/master:master -q ||
 git merge-base --is-ancestor platform/master master)'
 [drunomics\Phapp\Task\Exec]  Exit code 1  Time 0.019s
 [notice] Stopping on fail. Exiting....
 [error]  Exit Code: 1
 [Collection]    in task drunomics\Phapp\Task\Exec


 [Collection]  Exit code 1
 [notice] Stopping on fail. Exiting....
 [error]  Exit Code: 1
 [error]    in task Robo\Collection\Collection

    in task drunomics\Phapp\Task\Exec

Undefined index "force"

If you build branch and your origin's url is different than project url, that this warning pops up:

PHP Notice:  Undefined index: force in phar:///usr/local/bin/phapp/src/Commands/GitCommands.php on line 172
PHP Stack trace:
PHP   1. {main}() /usr/local/bin/phapp:0
PHP   2. require() /usr/local/bin/phapp:10
PHP   3. drunomics\Phapp\PhappRunner->run() phar:///usr/local/bin/phapp/phapp:21
PHP   4. drunomics\Phapp\PhappRunner->run() phar:///usr/local/bin/phapp/src/PhappRunner.php:64
PHP   5. Robo\Application->run() phar:///usr/local/bin/phapp/vendor/consolidation/robo/src/Runner.php:175
PHP   6. Robo\Application->doRun() phar:///usr/local/bin/phapp/vendor/symfony/console/Application.php:125
PHP   7. Robo\Application->doRunCommand() phar:///usr/local/bin/phapp/vendor/symfony/console/Application.php:224
PHP   8. Consolidation\AnnotatedCommand\AnnotatedCommand->run() phar:///usr/local/bin/phapp/vendor/symfony/console/Application.php:906
PHP   9. Consolidation\AnnotatedCommand\AnnotatedCommand->execute() phar:///usr/local/bin/phapp/vendor/symfony/console/Command/Command.php:262
PHP  10. Consolidation\AnnotatedCommand\CommandProcessor->process() phar:///usr/local/bin/phapp/vendor/consolidation/annotated-command/src/AnnotatedCommand.php:404
PHP  11. Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter() phar:///usr/local/bin/phapp/vendor/consolidation/annotated-command/src/CommandProcessor.php:150
PHP  12. Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback() phar:///usr/local/bin/phapp/vendor/consolidation/annotated-command/src/CommandProcessor.php:181
PHP  13. call_user_func_array:{phar:///usr/local/bin/phapp/vendor/consolidation/annotated-command/src/CommandProcessor.php:235}() phar:///usr/local/bin/phapp/vendor/consolidation/annotated-command/src/CommandProcessor.php:235
PHP  14. drunomics\Phapp\Commands\BuildCommands->buildBranch() phar:///usr/local/bin/phapp/vendor/consolidation/annotated-command/src/CommandProcessor.php:235
PHP  15. drunomics\Phapp\Commands\GitCommands->setupGitRemotes() phar:///usr/local/bin/phapp/src/Commands/BuildCommands.php:119

It's because on the line 119 of BuildCommands, there is a command:

$this->getGitCommands()->setupGitRemotes(['fetch' => TRUE]);

But the array is missing "force" index. So the function setupGitRemotes is called only with "fetch" and without "force" which results into a warning (on Commands/GitCommands.php:172):

if (!$options['force']) {

Use a PHP script to massage crippled environments

Some hosts - like acquia cloud - do not allow to set environment variables and do not make it possible to have different dotenv files per environment either. Still, we need a way to enforce proper environment variables per environment.

A possible solution could be:

  • Write a PHP script that massages the environment as needed.
  • When invoked via HTTP/PHP, it can just massage the current's process environment
  • When invoked via CLI it should output the environment variable changes, so phapp scripts can source the output.
  • Then we need to make it easy / transparent for phapp shell scripts to invoke the PHP cli script. Maybe some executable .env file would be able to take care of it.

Add support for release management

Use cases:

  • Create release local only and publish immediately.
  • Create release and publish branch.
  • Finish published release and update build:master

Commands:
phapp release [VERSION] -> Creates release if necessary, finishes the release.
phapp release:create [VERSION] [--no-push]
-> Needs to update develop + master branches first. -> Run git:pull
-> Pushes the release by default.
phapp release:push VERSION
phapp release:finish VERSION [--no-push]
-> Needs to check whether the latest release has a build.
-> Pushes into the configured origin repository
-> Pushing is a separately configurable command. So we can configure WV to push two repos!!!

Extracted git commands
phapp git:pull - Updates the app's main branches. Including build branches.
phapp git:push - Pushes the apps' main branches in the app repository. Including build branches. Pushing should use --follow-tags.
phapp git:show - List central branches and mirror repositories [Default]

phapp.yml config

  • Branches that are updated and pushed.
  • git_mirrors: List of mirror repositories to push into and optionally a branch regex. So build/* branches can be pushed into a separate remote if desired.

Complete the phapp exec command allow customization via the manifest

The command allows wrapping /bin/bash per project to selectively running commands in containers

It should be included in regular output, like others. e.g.

source dotenv/load.sh
./scripts/util/exec.sh - <<SCRIPT
> echo Working dir: && pwd
> SCRIPT

Usage examples:

  • phapp exec ls → always run in app environment, it should have the correct working dir
  • phapp exec → opens shell in main container!

Without any argument, it should default to /bin/bash - thus open a new shell.

Executing manifest commands needs to be reworked, so that the API function includes the exec wrapper always.

However, we do not want to run the exec wrapper for "build" by default. But that should be configurable per project. To achieve that, we provide the name of the command to be executed in the variable "PHAPP_COMMAND". This new variable should be provided to all commands and be documented in the README as "A variable that is set to the name of the command executed if some command script of the phapp manifest is currently executed."

Then in the project templates, we control the exec command via dotenv variables:
COMMAND_EXEC_PREFIX: "docker compose exec web"

and apply them conditionally in the manifest:

setup: ...
exec:
  # Default to running build commands on the host.
  if  $PHAPP_COMMAND = 'build' ; then 
	COMMAND_EXEC_PREFIX=''
  fi
  $COMMAND_EXEC_PREFIX $@

Handle environment specific environment variables

  • Support a list of environments (live, test, dev, vagrant, ..) and a way to determine the environment.
  • Group environments into "production" and "development" environment types.
  • Add some php dotenv library and define common environment variables for things like database connections.

Extract a phapp.yml specification

phapp.yml is designed for to standardize interactions with PHP applications, as needed by CI tools, hosting infrastructure or developers that want a unified interface for dealing with PHP applications. That way CI tools can read and execute phapp.yml content independent of the phapp-cli.

While the spec is built for PHP applications, there is nothing PHP specific in it. -> Let's extract the specification in a separate phapp-spec repo which only contains the specification in human readable markdown files. Then phapp-cli should refer/depend on this specification.

phapp loads .env files in incorrect order.

There may be a case when you can have several env files and some of them rely on variables in different files. So the order of loading is important. Example:

.example-1.env:
EXAMPLE_SUFFIX=some-suffix
.example-2.env:
EXAMPLE_DOMAIN=example-${SUFFIX}.com

If the second file is loaded first then you end up with incorrect value, where EXAMPLE_DOMAIN being just example-.com instead of example-some-suffix.com. That's what is hapenning with phapp env commands. Would be great if could agree on some specific rules how to load the .env files so we can make sure they are loaded as it's inteded.

Phapp create fails

phapp create fails without giving a helpful error message:

➜  Registering global composer config...
PHP Warning:  Undefined variable $command in phar:///home/arthur/bin/phapp/src/GlobalConfig.php on line 165
 [error]  Problems settings global composer config with commands:  
ERROR: Undefined variable $command 
in phar:///home/arthur/bin/phapp/src/GlobalConfig.php:165

Make checking for PHAPP_ENV variable optional.

There might be a case where you want to set PHAPP_ENV variable during php script execution dynamically. Currently phapp does not allow to execute init/update commands when there is no PHAPP_ENV set beforehand. Would be cool to allow something like --no-phapp-env-check to allow execution without any PHAPP_ENV set beforehand.

Implement the phapp init command(s)

Phapp status: Outputs the current app's status:

  • Initialized: Phapp project has an initialized database it can work with.
  • Uninitialized: No database available.

Phapp init:

  • Make a command which can point to "phapp install" or "phapp:db-import and update"
  • The default should be install
  • The command should do nothing if status says the phapp project is already initialized.
  • If the phapp manifest file is not there, ask whether init:manifest should be executed.

init:manifest

  • Initial phapp.yml skeleton

init:config

  • Copy config defaults to user config directory.

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.