Simple composer package workflow

by Ben on

Developing composer packages locally (especially when working in teams) throws up some interesting workflow challenges that we have been wanting to address for a while.

A common workflow for us is one that involves working on package changes at the same time as making changes to an application. We have tried a number of different techniques to try and streamline this, including a composer merge plugin, a workbench package and local composer repositories, each with their own pros and cons.

Having finally sat down and thought about the problem at hand, we came up with a pretty simple solution that we're happy with - at least for now, anyway.

In a nutshell, we have created a simple bash script, which we put inside ~/.bashrc or ~/.zshrc. There are four commands; dir, status, link and unlink.

packages()
{
    command="$1"
    name="$2"
    vendor_dir="vendor/$name"
    if [ "$3" ]; then base_dir="$3"; else base_dir="~/Sites/packages/"; fi
    dir="$base_dir$name"

    if [ -z $command ]; then
        echo "Enter a command: dir, status, link, unlink"
        return
    fi

    case $command in
        "dir" )
            if [ $name ]; then eval cd $dir; else eval cd $base_dir; fi
            ;;

        "status" )
            if [ -z $name ]; then
                echo "Which package would you like to check the status of?"
            else
                if [[ -L $vendor_dir ]]; then
                    symlink_target=$(readlink $vendor_dir)
                    echo "Package is linked in from $symlink_target"
                else
                    echo "Package is not linked."
                fi
            fi
            ;;

        "link" )
            if [ -z $name ]; then
                echo "Which package would you like to link in?"
            else
                rm -rf $vendor_dir
                eval ln -sf $dir $vendor_dir
                symlink_target=$(readlink $vendor_dir)
                composer dump-autoload --optimize
                echo "Package has been linked in from $symlink_target"
            fi
            ;;

        "unlink" )
            if [ -z $name ]; then
                echo "Which package would you like to unlink?"
            else
                rm -rf $vendor_dir
                composer update --prefer-dist $name
                echo "Package has been unlinked and installed from dist."
            fi
            ;;
    esac
}

dir

"dir" allows us to easily "cd" to the package source directory within ~/Sites/packages/

packages dir webhappens/prismic

status

"status" should be run from the application root and will report whether the package has been linked in via a symlink or not.

packages status webhappens/prismic

link

"link" should be run from the application root and will generate a symlink inside the "vendor" folder to the package source directory within ~/Sites/packages/

packages link webhappens/prismic

Note that the folder structure inside here must be the same as in the "vendor" folder.

An optional third argument may be passed to change the default directory from ~/Sites/packages/ to something else, if required.

unlink

"unlink" should be run from the application root and switches the "vendor" folder back to using the dist version of the package.

packages unlink webhappens/prismic

I hope you find this helpful, feel free to tweet me with any questions or additional ideas.

Work with us

If you enjoyed this blog post and you’re interested in working with us, drop us a message and we’d be happy to have a chat.