Everybody is using composer these days -- including Rackspace. Their PHP SDK page instructs how to install the sdk into one's project using composer. I'm wondering mostly how to manage my git working directory when composer is being used. I've noticed some rough spots in working with a buddy.

I created an empty dir to see what these install instructions would do to.

mkdir /tmp/foo
cd /tmp/foo
# insert composer install instructions here
php composer.phar require rackspace/php-opencloud
Using version ^1.16 for rackspace/php-opencloud
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
  - Installing mikemccabe/json-patch-php (0.1.0): Downloading (100%)         
- Installing psr/log (1.0.2): Downloading (100%)
- Installing symfony/event-dispatcher (v2.8.18): Downloading (100%)
- Installing guzzle/guzzle (v3.9.3): Downloading (100%)
- Installing rackspace/php-opencloud (v1.16.0): Downloading (100%)
symfony/event-dispatcher suggests installing symfony/dependency-injection () symfony/event-dispatcher suggests installing symfony/http-kernel () guzzle/guzzle suggests installing guzzlehttp/guzzle (Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated.) Package guzzle/guzzle is abandoned, you should avoid using it. Use guzzlehttp/guzzle instead. Writing lock file Generating autoload files

Ignoring for a moment the deprecated package warning which has apparently been around for two years, and various conversations, I see that this operation has yielded a variety of files and folders:

composer.json
composer.lock
composer.phar
vendor

Now I've seen in many cases of .gitignore files that ignore the vendor folder (understandably so as one wouldn't want this bloatfest in one's repo) but I've never once seen composer.json, composer.lock, or composer.phar in the .gitignore file. I don't see composer.phar in any of these .gitignore files but it's my strong suspicion this file doesn't belong in the repo either as it has been auto-installed by the composer instructions.

What about composer.json and composer.lock? Seems to me that, because these files change with every composer require command I run, that these files could be a hotspot in the repo as separate devs all run installs for various packages they want. Do they belong in the repo? Or do we commit composer.json and leave composer.lock out? The composer docs about the lock file say that it contains the 'exact versions' of whatever files were installed (presumably by the most recent require/install/update command).

I'm guessing that composer.json and composer.lock should both go in the repo so the various devs stay in sync, but since the vendor file is .gitignored, Seems like we'll have to run php composer.phar update whenever the composer.json file gets changed by somebody.

Can anyone outline a protocol for dealing with composer and git together?

    You should ignore the vendor folder yes.

    composer.phar shouldn't even be in your working directory. move it to somewhere in your path, drop the .phar, and make it executable. Now you just type composer <command> no php and no .phar!

    composer.json is the file you manage, describing what you want to use. You should be editing this file with your package information as well as declaring what's a dev dependency vs an actual dependency (IE some HttpClient (per our other discussion) vs phpunit). You don't need to use composer require package to download a package. You can set up the composer.json file by hand specifying specific version requirements and then composer install or composer update to get them.

    composer.lock is a file that composer manages, you shouldn't ever edit this but it should be part of your repository. This will change as you install, remove or update packages. When you execute composer install later and have a lock file present, you will get the exact versions listed in the lock file. This means you dev and change libraries, but when you execute composer install on the server, you get exactly the same versions you tested with.

    composer update - this will update libraries to the newest versions with meet your requirements in the composer.json file (updates the lock file)
    composer require - this will install and require a new library to your project (updates the lock file)
    composer install - this will install the exact version in the lock file, if no lock file is present it will install the latest versions that satisfy the requirements of the composer.json file

    Integrating with git is basically as simple as executing a composer install after your branch changes. If you change to an older branch it may be beneficial to delete the vendor folder first to make sure it installs fresh each version.

    Edit: Oh I forgot to add, I never use the composer require command, I always edit the json file and then execute an install. This will resolve necessary version dependencies as well. Sometimes I will run composer update, but only if I plan on testing everything still works. However, composer assumes packages follow www.semver.org and so will avoid updating a library in an backwards incompatible manner.

      Here to give you an idea, this is directly from my ansible script to install my website:

      - name: checkout project
        git:
          repo: ssh://git@bitbucket.org/---/--.git
          dest: /source/derokorian.com
          version: ansible
          accept_hostkey: true
          force: true
          key_file: /root/.ssh/id_rsa
      
      - name: install composer dependencies
        command: composer install chdir=/source/derokorian.com
      

      The next steps, in order are - set up the application configuration files, then run migrations and now the app is ready to go!

        Thank you for the helpful response!

        Derokorian;11061059 wrote:

        You should ignore the vendor folder yes.

        Done. Although this worries me. Given that packages seem to get updated all the time--and that all devs may not run composer update at the same time--I'm concerned about composer.lock on my machine being out of sync with the same file on my partner's machine, the dev machine, the production machine. I'll try to provide a scenario below.

        Derokorian;11061059 wrote:

        composer.phar shouldn't even be in your working directory. move it to somewhere in your path, drop the .phar, and make it executable. Now you just type composer <command> no php and no .phar!

        This assumes one wants composer globally installed, which I sometimes don't. The presence of the composer.phar file is a result of following the local install instructions on the Composer website. I think we can both agree that we don't want composer.phar in the repo. I'm going to leave composer.phar and add it to the .gitignore file.

        Derokorian;11061059 wrote:

        composer.json is the file you manage, describing what you want to use. You should be editing this file with your package information as well as declaring what's a dev dependency vs an actual dependency (IE some HttpClient (per our other discussion) vs phpunit). You don't need to use composer require package to download a package. You can set up the composer.json file by hand specifying specific version requirements and then composer install or composer update to get them.

        Not being fluent with composer.json and its nuances, I will probably follow the instructions given on the various projects I expect to use. Also, I am not myself developing any composer-compatible or composer-based project just yet. I just want to get this site updated from its awful Joomla beginnings and launched ASAP. That being the case, I'll be using composer-require.

        Derokorian;11061059 wrote:

        composer.lock is a file that composer manages, you shouldn't ever edit this but it should be part of your repository. This will change as you install, remove or update packages. When you execute composer install later and have a lock file present, you will get the exact versions listed in the lock file. This means you dev and change libraries, but when you execute composer install on the server, you get exactly the same versions you tested with.

        It seems potentially problematic to me to have composer.lock in the repo. A require, install, or update will update this file -- and one must run install/update any time one changes composer.json or pulls changes someone else has made from the repo. If you execute 'composer install/update' on the server, then doesn't this file get changed, possibly causing it to get out of sync with dev or my workstation?

        Derokorian;11061059 wrote:

        composer update - this will update libraries to the newest versions with meet your requirements in the composer.json file (updates the lock file)
        composer require - this will install and require a new library to your project (updates the lock file)
        composer install - this will install the exact version in the lock file, if no lock file is present it will install the latest versions that satisfy the requirements of the composer.json file

        require also downloads dependencies in my experience. Are you saying that install will not touch the composer.lock file if it already exists? If so, I'm starting to see a ray of light here.

        Derokorian;11061059 wrote:

        Integrating with git is basically as simple as executing a composer install after your branch changes. If you change to an older branch it may be beneficial to delete the vendor folder first to make sure it installs fresh each version.

        I think I'm starting to get it. DON'T run composer update when deploying to server, run composer install. This will leave the composer.lock file alone and just make sure to match the package versions listed in it. Thanks for the tip about switching branches.

        Derokorian;11061059 wrote:

        Edit: Oh I forgot to add, I never use the composer require command, I always edit the json file and then execute an install. This will resolve necessary version dependencies as well. Sometimes I will run composer update, but only if I plan on testing everything still works. However, composer assumes packages follow www.semver.org and so will avoid updating a library in an backwards incompatible manner.

        I'm not prepared to go editing composer.json files just yet. Is there any particular reason you avoid the require command?

          Derokorian;11061061 wrote:

          Here to give you an idea, this is directly from my ansible script to install my website:

          - name: checkout project
            git:
              repo: ssh://git@bitbucket.org/---/--.git
              dest: /source/derokorian.com
              version: ansible
              accept_hostkey: true
              force: true
              key_file: /root/.ssh/id_rsa
          
          - name: install composer dependencies
            command: composer install chdir=/source/derokorian.com
          

          The next steps, in order are - set up the application configuration files, then run migrations and now the app is ready to go!

          Thanks for this.

            I'm not gonna quote you, by the end it seemed like you got the idea.

            The basic jist is: never ever run composer update, always use composer install. update will change as many as every single library in the vendor folder. install will get you the exact version of a library that it was tested / developed with.

            The reason I don't like require, is other libraries might change by using require, where as updating the .json file and using install will avoid changing any libraries already listed in the lock file.

              I lied, I'm quoting this

              sneakyimp;11061075 wrote:

              It seems potentially problematic to me to have composer.lock in the repo. A require, install, or update will update this file -- and one must run install/update any time one changes composer.json or pulls changes someone else has made from the repo. If you execute 'composer install/update' on the server, then doesn't this file get changed, possibly causing it to get out of sync with dev or my workstation?

              No it's not problematic - it's exactly the point. Install will NOT change the lock file, but install the exact versions listed in the lock file (down to the commit hash). Hence you should always be using install.

              The lock file is exactly how you keep different environments synchronized - because you get exactly the same version every time you install.

                19 days later
                Write a Reply...