A lot of support/bug requests have the underlying problem of external command(s) not being available. These are mostly Windows based but with a few *nix here had there (e.g. using source control before related command installed / path pointing to odd command version).

It would greatly help debugging such problems and potentially reduce support/bug reports if there was a command in the "self-update" vein that check which commands were available and where Drush was executing them.

Attached is code for a new "Check Drush Externals" (self_check_externals) command set. This could be rolled into core command set like self-update is, but a separate command set for testing/demo works best right now.

This code contains a list of all external command I could find that the core drush code calls. (See output samples below). They are contained in an array form that allows for hard requirements to be flagged but with alternative commands. For example, the code will flag a missing requirement if at least one of the five DB command lines tools is not found. (see Windows sce-list sample below).

The structure is easy to extend / add commands as needed. below is a sample of the array behind it. The key is the command name and value array define it's attributes.

One other thing to note about the code is that it uses a PhP based "which" function instead of the external command to locate the executables. This might also be rolled into core to eliminate/speed up the many "which" shell calls done by the code.

Sample of External Command Definitions

  $externals = array(
  // General stuff
    'which' => array(
      'category' => 'General',
      'description' => 'Used to find executables for many commands.',
      'required' => TRUE,
    ),
  // Download information
    'wget' => array (
      'category' => 'Downloading information',
      'description' => 'Used to download files.',
      'required' => TRUE,
      'alternatives' => array(
        'curl',
      )
    ),
    'curl' => array (
      'category' => 'Downloading information',
      'description' => 'Alternate to wget. Used to download files.',
      'required' => TRUE,
      'alternatives' => array(
        'wget',
      )
    ),
  // Archiving / Compression Utils.
    'tar' => array (
      'category' => 'Archive / Compression Utils',
      'required' => TRUE,
      'description' => 'Used to create / expand archives',
      'alternatives' => array(
        'bsdtar',
      ),
    ),
    'bsdtar' => array (
      'category' => 'Archive / Compression Utils',
      'required' => TRUE,
      'description' => 'Used to create / expand archives',
      'alternatives' => array(
        'tar',
      ),
    ),
    'gzip' => array (
      'category' => 'Archive / Compression Utils',
      'required' => TRUE,
      'description' => 'Used to compress / expand archives',
    ),
    'bzip2' => array (
      'category' => 'Archive / Compression Utils',
      'required' => FALSE,
      'description' => 'Used to compress / expand archives',
    ),
    'unzip' => array (
      'category' => 'Archive / Compression Utils',
      'required' => FALSE,
      'description' => 'Used to uncompress archives',
    ),
...

Here is some output samples for the commands:

Help info

Check Drush Externals: (self_check_externals)
 self-check-externals  Generate a status report of common external commands
 -info (sce-info)      that Drush uses.
 self-check-externals  Show a list of common external commands and their status
 -list (sce-list)

Sce-list Command *nix Output

monroe@fedora:~$ drush sce-list
 Command   Location/Status
 which     /usr/bin/which
 wget      /usr/bin/wget
 curl      Command not found on path. Using alternative wget
 tar       /bin/tar
 bsdtar    /usr/bin/bsdtar
 gzip      /bin/gzip
 bzip2     /bin/bzip2
 unzip     /usr/bin/unzip
 mysql     /usr/bin/mysql
 psql      Command not found on path. Using alternative mysql
 sqlite3   Command not found on path. Using alternative mysql
 sqlcmd    Command not found on path. Using alternative mysql
 sqlplus   Command not found on path. Using alternative mysql
 bzr       Command not found. Some commands/options will not work.
 git       /usr/bin/git
 svn       Command not found. Some commands/options will not work.
 ssh       /usr/bin/ssh
 rsync     /usr/bin/rsync
 echo      /bin/echo
 more      /bin/more
 less      /usr/bin/less
 xdg-open  /usr/bin/xdg-open
 open      /bin/open

Sce-list Command Windows output

C:\DukeCE\EclipsePhP\DrupalSN\application>drush sce-list
 Command   Location/Status
 which     C:\Dev\drush5\gnuwin32\bin\which.EXE
 wget      C:\Dev\drush5\gnuwin32\bin\wget.EXE
 curl      C:\Program Files (x86)\Git\bin\curl.EXE
 tar       C:\Dev\drush5\gnuwin32\bin\tar.EXE
 bsdtar    C:\Dev\drush5\gnuwin32\bin\bsdtar.EXE
 gzip      C:\Dev\drush5\gnuwin32\bin\gzip.EXE
 bzip2     C:\Dev\drush5\gnuwin32\bin\bzip2.EXE
 unzip     Command not found. Some commands/options will not work.
 mysql     *** REQUIRED or ALTERNATIVE Command not found on path!
 psql      *** REQUIRED or ALTERNATIVE Command not found on path!
 sqlite3   *** REQUIRED or ALTERNATIVE Command not found on path!
 sqlcmd    *** REQUIRED or ALTERNATIVE Command not found on path!
 sqlplus   *** REQUIRED or ALTERNATIVE Command not found on path!
 bzr       Command not found. Some commands/options will not work.
 git       C:\Program Files (x86)\Git\bin\git.EXE
 svn       C:\Dev\SlikSVN\bin\svn.EXE
 ssh       C:\Program Files (x86)\Git\bin\ssh.EXE
 rsync     Command not found. Some commands/options will not work.
 echo      C:\Dev\drush5\gnuwin32\bin\echo.EXE
 more      C:\Windows\System32\more.COM
 less      C:\Dev\drush5\gnuwin32\bin\less.EXE
 xdg-open  Command not found. Some commands/options will not work.
 open      Command not found. Some commands/options will not work.

The sce-info output is more descriptive and longer. Here's a *nix output sample:

Sce-info *nix Output

Category: General

  Command: which
    Description:   Used to find executables for many commands.
    Location:      /usr/bin/which


Category: Downloading information

  Command: wget
    Description:   Used to download files.
    Location:      /usr/bin/wget
    Alternatives:  curl

  Command: curl
    Description:   Alternate to wget. Used to download files.
    Location:      Command not found on path. Using alternative wget
    Alternatives:  wget


Category: Archive / Compression Utils

  Command: tar
    Description:   Used to create / expand archives
    Location:      /bin/tar
    Alternatives:  bsdtar

  Command: bsdtar
    Description:   Used to create / expand archives
    Location:      /usr/bin/bsdtar
    Alternatives:  tar

  Command: gzip
    Description:   Used to compress / expand archives
    Location:      /bin/gzip

  Command: bzip2
    Description:   Used to compress / expand archives
    Location:      /bin/bzip2

  Command: unzip
    Description:   Used to uncompress archives
    Location:      /usr/bin/unzip


Category: Database command line tools

  Command: mysql
    Description:   Do database actions on MySQL.
    Location:      /usr/bin/mysql
    Alternatives:  psql, sqlite3, sqlcmd, sqlplus

  Command: psql
    Description:   Do database actions on PostGres SQL.
    Location:      Command not found on path. Using alternative mysql
    Alternatives:  mysql, sqlite3, sqlcmd, sqlplus

  Command: sqlite3
    Description:   Do database actions on SQL Lite.
    Location:      Command not found on path. Using alternative mysql
    Alternatives:  mysql, psql, sqlcmd, sqlplus

  Command: sqlcmd
    Description:   Do database actions on MS SQL Server.
    Location:      Command not found on path. Using alternative mysql
    Alternatives:  mysql, psql, sqlite3, sqlplus

  Command: sqlplus
    Description:   Do database actions on Oracle Server.
    Location:      Command not found on path. Using alternative mysql
    Alternatives:  mysql, psql, sqlite3, sqlcmd


Category: Version control commands

  Command: bzr
    Description:   Bazaar version control system
    Location:      Command not found. Some commands/options will not work.

  Command: git
    Description:   Subversion version control system
    Location:      /usr/bin/git

  Command: svn
    Description:   Subversion version control system
    Location:      Command not found. Some commands/options will not work.


Category: Remote access commands

  Command: ssh
    Description:   Secure Shell remote access program
    Location:      /usr/bin/ssh

  Command: rsync
    Description:   Remote file sync command
    Location:      /usr/bin/rsync


Category: Miscelaneous commands

  Command: echo
    Description:   Send lines to a file or piped command
    Location:      /bin/echo

  Command: more
    Description:   Pager for file output (interactive mode)
    Location:      /bin/more
    Alternatives:  less

  Command: less
    Description:   Pager for file output (interactive mode)
    Location:      /usr/bin/less
    Alternatives:  more

  Command: xdg-open
    Description:   Opens a file in it default application (e.g. browser)
    Location:      /usr/bin/xdg-open
    Alternatives:  open

  Command: open
    Description:   Opens a file in it default application (e.g. browser)
    Location:      /bin/open
    Alternatives:  open
CommentFileSizeAuthor
self_check_externals.tar_.gz3.2 KBcgmonroe

Comments

jonhattan’s picture

Component: Core Commands » Base system (internal API)
Status: Needs review » Needs work

We definitely need an api to check for external commands but I don't think it needs to be exposed as a command, or at least such a command is not our main target.

1/ Some drush commands require the external command in order to work (rsync). In this case, the external commands could be added to the command definition in hook_drush_command() and checked as a requirement.

2/ Some drush commands needs a dynamic check for the external command, based on environment or cli options (sql-cli, decompress operations).

3/ Some external commands are required by engines rather than drush commands (package-handler, version-control) so engine definitions could be extended to declare external commands required, similar to the case in 1/.

Lastly, the check should allow for alternatives, for example: wget or curl.

We do several kind of checks:

* don't test
* which
* call the command: wget --version

Here're some places where we do check for external commands availability:

* package_handler_validate()
* drush_core_runserver_validate()
* _drush_sync_via_http_download_file()
* _drush_download_file()
* drush_start_browser()
* Version control signature in pm_drush_engine_version_control() and drush_pm_include_version_control()

Other related function: drush_has_bash().

In case bash is available, i've recently seen at http://stackoverflow.com/questions/592620/check-if-a-program-exists-from... that `command -v wget` is the best option.

Sumarizing, this is more ambitious than your initial proposal, and probably needs to be done in several steps.

ps. post patches or files next time, to ease revision.

greg.1.anderson’s picture

Version: » 8.x-6.x-dev
Status: Needs work » Closed (won't fix)
Issue tags: +Needs migration

This issue was marked closed (won't fix) because Drush has moved to Github.

If this feature is still desired, you may copy it to our Github project. For best results, create a Pull Request that has been updated for the master branch. Post a link here to the PR, and please also change the status of this issue to closed (duplicate).

Please ask support questions on Drupal Answers.