Home > database >  post-receive - Composer: Command Not Found in Shell Script - How to Fix PATH?
post-receive - Composer: Command Not Found in Shell Script - How to Fix PATH?

Time:08-18

I have been banging my head over this all day so I am breaking down in defeat and asking here for someone a little more versed in Shell Scripts than I am. I am attempting to write a post-receive script for a git repo on Inmotion Hosting. Ideally this script is just to move the files to the site and then run composer install to build the vendor directory so it is not stored in the repo. My script should look like this based on all the examples I have seen.

#!/bin/sh 
git --work-tree=/home/[user]/[site] --git-dir=/home/[user]/[site].git checkout -f
composer install --working-dir=/home/[user]/[site]

The checkout portion works, but it fails at the install line.

I have read many other posts on possible issues, but composer is installed and runs globally from the cPanel terminal. Users from the shell and terminal are the same as determined by using whoami.

This post on laracasts mentions that the PATH variable might be different. I looked for my home bins and added them to the export by running export PATH="/home/[user]/.local/bin:/home/[user]/bin:$PATH" from my shell script, but still got a not found. This is where I am a little lost on what to do or how to fix the missing composer path.

Do I need to run export PATH each time with the script, and does anyone know what I should set it to? Should I even be attempting to change the PATH? I can run my script fine through the cPanel terminal, but would really like to automate this. Thanks in advance for any help.

CodePudding user response:

The instructions in the post you've linked are correct up to a point: you must set (and preferably also export) PATH. The likely problems are:

  • there's a typo in what you tried;
  • the use of $HOME and/or the rest of the path here is incorrect; and/or
  • you've put the export PATH=... command in the wrong place.

The script should read:

#! /bin/sh
export PATH="[edit this part]:$PATH"
git --work-tree=/home/[user]/[site] --git-dir=/home/[user]/[site].git checkout -f
composer install --working-dir==/home/[user]/[site]

(where I've used your [square bracket] syntax to indicate that something goes there, but I don't know what).

Given that composer works from some other environment(s), start up a shell where it does work, and run type composer. This will tell you where the composer binary is; that needs to be on $PATH after the export.

Check carefully for typos, including an invisible character in the command that resembles composer. Invisible characters are of course hard to see: you need something that will display them, despite them being invisible. (I'm fond of the BSD vis command for this, but you might not have that one.)

CodePudding user response:

The error might not be as obvious as the diagnostic message may be read by the user.

  1. locate the absolute path of the composer command referenced in your original script. note it as <absolute-path-to-composer>.

  2. locate the absolute path of the php cli SAPI binary on that system. note it as <absolute-path-to-php>.

  3. invoke php (not composer) and tell it to load composer:

    <absolute-path-to-php> -f <absolute-path-to-composer> -- install --working-dir==/home/[user]/[site]
    

Rationale: If the composer command actually exists but not the executable for it (php and /usr/bin/env) it will still error. To reliably execute composer in an unattended install, make the configuration explicit. $PATH etc. is convenience for interactive shell use - which is not the case here, the deployment script runs non-interactive.


Additionally, the script may be easier to maintain by cd-ing into the directory first and then use relative paths.

Then for any of the commands that are used by their basename (utility names), exit unsuccessful if hash(1) reports those missing.

Further, run Composer non-interactive (-n).

#! /bin/sh

cd /home/[user]/[site] || exit 1

hash -r
hash git || exit 1

git --work-tree=. --git-dir=../[site].git checkout -f

<absolute-path-to-php> -f <absolute-path-to-composer> -- composer -n install

Further on if you still have fun, do the operation in a temporary directory - not the site-root and when done rsync(1) into the target location.

Rationale is to separate the git checkout and composer install from the file operations within the site-directory. it will minimize issues on transaction failures (site broken but can't recover as deployment has issues).

  • Related