New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --global option to install packages in $PATH bin dir and global code dir (e.g. /usr/lib/composer) #55

Closed
naderman opened this Issue Oct 22, 2011 · 26 comments

Comments

Projects
None yet
@naderman
Member

naderman commented Oct 22, 2011

It should work like npm's option http://npmjs.org/doc/faq.html#How-do-I-install-something-everywhere

Globally installed packages will neither be in include_path nor in autoloaders of projects. If you want to install a dependency for a project, install it locally.

The only reason to install a package globally is to get some global commandline utility.

@naderman

This comment has been minimized.

@Seldaek

This comment has been minimized.

Member

Seldaek commented Nov 30, 2011

One thing we do differently is that we usually install from a composer.json, but I'm thinking for global deps we should instead just say for example composer install --global phpunit/phpunit. That would create a Request for phpunit/phpunit to be installed in global code dir + bins linked in global bin dir. And all its deps would obviously follow.

Another thing would be to also write phpunit/phpunit as a requirement into ~/.composer/composer.json. That way you could do composer update --global and it would update all. But then we have no version constraints, which will be problematic.

@naderman

This comment has been minimized.

Member

naderman commented Nov 30, 2011

--global should not use ~/.composer but something like /usr/lib/composer - apart from that I'd go for the latter where we actually keep a composer.json and just make the command add/remove items from/to it. We would then also have to have an composer update --global phpunit/phpunit option of course to update only one item and not all.

@ghost ghost assigned Seldaek Dec 1, 2011

@tamagokun

This comment has been minimized.

tamagokun commented Apr 5, 2012

+1 Is this in the works at all, or does it need a volunteer?

@Seldaek

This comment has been minimized.

Member

Seldaek commented Apr 5, 2012

Nobody is really working on it, since it's kind of easy to set it up yourself. You can just create any directory containing dependencies and add that dir's bin dir to your PATH to leverage any package having binaries.

If you would like to work on it, you may, but I would like if we could discuss a bit and have a clear concept of what we want to do first.

@tamagokun

This comment has been minimized.

tamagokun commented Jun 7, 2012

https://gist.github.com/2890866

Took a stab at fleshing this out a bit. Haven't give any thought to an implementation but a concept should be developed first.

@mheap

This comment has been minimized.

mheap commented Nov 9, 2012

Bump. This one would be pretty nice for packages like PHPUnit.

It could default to ~/.composer by default, but have a ~/.composer/.composerconfig file (bit like .gitconfig) that lets you change the global install dir/other options such as minimum stability (although that'd be a different issue, it's a nice example use case for .composerconfig)

@stof

This comment has been minimized.

Contributor

stof commented Nov 9, 2012

@mheap there is already a global config file (it does not allow changing the minimum stability though): ~/.composer/config.json.

@Evanlec

This comment has been minimized.

Evanlec commented Feb 4, 2013

Any progress on this? would like to use composer instead of PEAR (hate pear) to install global packages...things like phing, phpCodeSniffer, etc..
I really like the way npm handles this and I am all for something similar (a simple composer install -g switch would be awesome ;)

@tamagokun

This comment has been minimized.

tamagokun commented Feb 8, 2013

This is how I have been doing it: http://ripeworks.com/using-composer-globally/

@sbuzonas

This comment has been minimized.

Contributor

sbuzonas commented Feb 8, 2013

I think it would be nice that if a global option is added, dependencies can be marked as satisfied and add their install paths to the autoloader as well as symlink global bins to the project bin dir.

Require dev isn't essential for the project to function, and why would you need n+ phpunit/phpunit installations unless a specific version is required and can not be satisfied globally. Or projects that have a requirement on phing to do a post install/update command surely if a satisfiable version of phing is provided it can be utilized.

@thomascube

This comment has been minimized.

thomascube commented Mar 21, 2013

+1 for me, too. Some packagers are hard to convince of the local installation approach composer suggest.

@Anahkiasen

This comment has been minimized.

Anahkiasen commented Apr 7, 2013

What is the state of this ? There are some really great packages on Composer now that would profit from being installed globally such as PHPUnit, PHPCS and all. I've been doing with a Composer file in my dev folder that moves the binaries in the bin folder but I agree a composer install phpunit -g would be awesome.

@anderseknert

This comment has been minimized.

anderseknert commented May 4, 2013

+1. No need to clutter each project directory with "dependencies" that should really be global.

@scribu

This comment has been minimized.

scribu commented May 8, 2013

As a developer of such a CLI utility, I have to say that a --global flag is the single biggest missing feature from Composer right now.

@thomascube

This comment has been minimized.

thomascube commented Jun 2, 2013

As an intermediate solution I created a script that will install the Composer dependencies into a global vendor dir and also uses the pear installer to globally install PEAR modules required by your project. See https://gist.github.com/thomascube/5693475 for a short description and the code.
Please not that this is just a proof-of-concept prototype and not yet complete nor fully tested.

@pjvds

This comment has been minimized.

pjvds commented Jun 19, 2013

You have my vote!

@scribu

This comment has been minimized.

scribu commented Jul 1, 2013

I think I see at least one gotcha that @Seldaek was talking about:

When invoking a CLI script, you don't want to have a combined vendor/autoload.php (which might straight-up require() a bunch of unrelated stuff); you want to load only the dependencies for that particular script.

And if that's the case, just use @tamagokun's solution, except replace .composer with .your-project. You can even generate the composer.json file programmatically:

composer init --require='wp-cli/wp-cli@stable' --no-interaction
composer config bin-dir bin

Landing #1813 (or some other attempt) would be a lot more useful.

@hotzeplotz

This comment has been minimized.

hotzeplotz commented Jul 15, 2013

i have been going through the solutions proposed above as well as various scenarios as part of my work to get Composer and wp-cli in Debian, for which a global option would be great.

the 'install packages' part is delicate but doable e.g. via #1813 or similar code, however it is the 'use packages' part which seems really crucial to deterministically avoid autoloading unrelated code, mismatched versions or forks, etc. from a system-wide "pool".

before i start working on the code i have been outlining in my initial research, which may take a while to take shape, i wanted to check what Composer developers think about letting package developers use a system-wide Composer to do the heavy lifting of finding and loading dependencies, rather than relying (e.g. in vendor binaries) on the common __DIR__.'/../vendor/autoload.php' + __DIR__.'/../../../autoload.php' pattern.

in other words, when a package is installed system-wide, its composer.json (or perhaps composer.lock?) should be stored with a unique id into a system registry (e.g. /usr/share/php/composer/registry/<ID>/composer.json), and thereafter vendor binaries should only load (ideally from the include path, i think) a specific Composer namespace which brings in a function that locates the project's composer.json (in the project's vendor folder first, to cater for per-project composer use, and then in one or more system-wide registry locations - which could be set by distro packagers in case of distributions, or in a default location if installing Composer system-wide from source).

at this point, rather than letting the vendor binary rely on the autoloader stub files normally generated by Composer in a project's vendor folder, the system-wide Composer would parse the composer.json specific to the calling binary (and any other binaries from the same package) from the system-wide registry, locate the appropriate libraries from a system-wide install (this could also allow to have multiple versions installed, similarly to what Bundler allows to do, as well as integration PEAR libs) and autoload only the namespaces and classes needed, at the desired version, on the fly.

other issues that i've been considering for the above proposal are installations from repositories other than Packagist, namespace collisions when autoloading 'everything' from a system-wide install if forks of the same library are installed (and the namespaces are not updated per-fork), coexistence with PEAR libraries (e.g. as installed via apt-get)...

my knowledge of Composer's internals is still incomplete at the moment, so i wanted to gather feedback on this plan first.

@Seldaek

This comment has been minimized.

Member

Seldaek commented Jul 15, 2013

There are two things with regard to global installs:

  • "Binaries" and tools that you want available everywhere on CLI: These can clearly be useful to have globally, not all though because for some things like phpunit the project can depend on a particular version of it for example, in which case having one globally might hurt you. But some utils make sense to have just at the latest version globally. And for that you can already "roll your own" solution by having a project somewhere which bin's dir is in your PATH.
  • Libraries/regular dependencies which is more what you are talking about, and this stuff I quite strongly disagree that they should be installed globally. I can see why in some rare cases it's preferable, but for most people project-specific vendors are much easier to manage and work pretty well. As such I'd rather not even consider this until we can get a 1.0 stable out. That said if it were to happen I'd think the best would be to have a central directory with /packagename/packageversion/content and then symlinking that into the vendor dir perhaps so that the project can be like a regular one but without the duplication of vendors. Having an autoload resolver and whatnot that allows you to pick which version you want at runtime sounds way too slow to me.
@hotzeplotz

This comment has been minimized.

hotzeplotz commented Jul 15, 2013

@Seldaek thanks for your comments. i have in mind specifically
the *nix distributions scenario, where some Composer packages
might need to be packaged as dependencies for the few PHP binaries that
are packaged for the distribution: in general, i agree that per-project
dependencies are better installed in the project's vendor folder
for regular developer projects.

you're right about performance hit with runtime autoload resolver:
in case symlinks turn out not to be enough (see below), it's probably
enough to generate/update the autoloader files exactly as Composer would
do in a per-project setting, just saving these in a system-wide location,
which would avoid the performance hit.

in my initial proof of concept i run into issues with cases where a
Packagist package is actually a fork of the canonical upstream, while
keeping the same top-level PHP namespace - other than this, a central
directory with all the package/version folders should work fine, as
long as binaries that support global installs only pull in the
namespaces they need without require()'ing more than they strictly
need.

anyways - i'll keep testing these ideas in my fork for later review, making
sure that any global behaviour does not affect in any way users using Composer
in the regular scenario (i.e. per-project vendor).

@Anahkiasen

This comment has been minimized.

Anahkiasen commented Jul 15, 2013

There are some PHP packages that are more convenient to use globally to me : PHPUnit, PHPMD, PHPCS, PHPDoc etc.

@renanbr

This comment has been minimized.

Contributor

renanbr commented Jul 17, 2013

👍 One the most interesting thing (for me) in Composer is that it's possible coding in my computer applications that required different versions of the same library. No VMs, no cut corners, no pain to start coding a new software... Composer has changed my life.
my 2 cents to this issue: it would be nice keep the possibility to install globally many versions of same library

@Seldaek

This comment has been minimized.

Member

Seldaek commented Aug 13, 2013

I implemented a helper command to operate on a global repo in #2172 - if anyone wants to give it a shot and give feedback.

@Seldaek Seldaek closed this in 7311bc7 Aug 17, 2013

digitalkaoz pushed a commit to digitalkaoz/composer that referenced this issue Nov 22, 2013

@tuo4075

This comment has been minimized.

tuo4075 commented Dec 6, 2013

How do you update global packages installed w/ composer i.e. phpunit?

@johnpbloch

This comment has been minimized.

johnpbloch commented Dec 6, 2013

@tuo4075

composer global update
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment