I am following the Laravel installation on their website
and I came across this line
composer create-project laravel/laravel --prefer-dist
Now, what exactly does the --prefer-dist part mean? I can't see anything on their documentation.
Thanks in advance.
--prefer-dist and --prefer-source are the two options of composer which included in various documentations with a lack of proper explanation.
--prefer-dist would try to download and unzip archives of the dependencies using GitHub or another API when available. This is used for faster downloading of dependencies in most cases. It doesn't download the whole VCS history of the dependencies and it should be better cached. Also archives on GitHub could exclude some files you don't need for just using the dependency with .gitattributes exclude directive.
--prefer-source would try to clone and keep the whole VCS repository of the dependencies when available. This is useful when you want to have the original VCS repositories cloned in your vendor/ folder. E.g. you might want to work on the dependencies - modify them, fork them, submit pull requests etc. while also using them as part of the bigger project which requires them in the first place.
Simply speaking, the --prefer-source option will prefer to create a package directory that is a "version control repository", which is equivalent to you typing:
$ git clone ...
or
$ svn checkout ...
On the other hand, the --prefer-dist option will prefer to create a non-"version control repository", which is equivalent to you typing:
$ git clone ... ; rm -fr dir/.git
or
$ svn export ...
Remember that, these are only preferences, if a dependency is required using a VCS repository which does not provide archives such as GitHub API, then the only available option is to clone the repository.
It's all available here: https://getcomposer.org/doc/03-cli.md#install
--prefer-dist: Reverse of --prefer-source, composer will install from dist if possible. This can speed up installs substantially on build
servers and other use cases where you typically do not run updates of
the vendors. It is also a way to circumvent problems with git if you
do not have a proper setup.
As per the link :
https://getcomposer.org/doc/03-cli.md#install
Here is the documentation statement for the question :-
--prefer-install: There are two ways of downloading a package: source and dist. Composer uses dist by default. If you pass --prefer-install=source (or --prefer-source) Composer will install from source if there is one. This is useful if you want to make a bugfix to a project and get a local git clone of the dependency directly. To get the legacy behavior where Composer use source automatically for dev versions of packages, use --prefer-install=auto. See also config.preferred-install. Passing this flag will override the config value.
Related
I have a hard time figuring this out; I am also puzzled of the connection - if any - with the create-project command.
As far as I can tell, the only difference between install and create-project is the execution of post-root-package-install and post-create-project-cmd hooks...
Can someone shed some more light on this?
My goal is to set up a composer infrastructure where I run create-project and this sets up a project skeleton (creates and sets directory permissions, creates default configuration files, creates blank data stores)
What exactly is the difference between project and library types in composer?
Practically, there is none. It doesn't affect how composer gets executed. You can use both install and create-project with both types of package types.
This metadata is meant to inform plugins, IDE, or even packagist.org when parsing composer.json, but on a vainilla installation, there is no practical difference in using one or the other.
(Docs on package types)
As far as I can tell, the only difference between install and create-project is the execution of post-root-package-install and post-create-project-cmd hooks.
The docs are your friends:
You can use Composer to create new projects from an existing package. This is the equivalent of doing a git clone/svn checkout followed by a composer install of the vendors.
Any time you do create-project, install is executed as well. Which means that the install hooks are executed as well.
First it clones the whole package via the appropriate CVS (git, usually), and then immediately executes composer install. By default, it removes CVS information (e.g. the .git directory), unless one uses the --keep-vcs option.
create-project is useful to bootstrap applications, so the app's directory is setup beyond what downloading composer`s dependencies would do. You can create a skeleton directory structure, etc.
Usually one would have a package proper (that could be required into an application), and a "application-skeleton" package, that would include the directory structure and would depend on the original package.
I'm posting a more succint answer to my questions, based on experimentation:
What is the difference between project and library types?
Absolutely none as far as composer is concerned. Some plugins might implement logic to treat the two package types differently though.
How does that relate to require, install, create-project commands?
In no way whatsoever. The project in package type has nothing to do with project in create-project.
How does create-project work?
Let's say we are talking about a single <package>. We have 2 workflows:
composer init <project_path> && composer require <package>
composer create-project <package> <project_path>
The first workflow will create a blank root package and add <package> as a requirement to it.
The second workflow will "clone" <package> into <project_path> as the root package.
NB: If you are working with local path type repos for development, create-project will actually create <project_path> as a symlink to <package>'s source dir. This is the default behavior of path repos, and probably a miss for composer in the need to treat create-project differently. This can create a heap of confusion (as you might be inadvertently changing and adding to <package>s sources while thinking you are just editing project_path). So for local development and testing, you are better off with cp -A rather than composer create-project.
Maybe just a stupid question.
After I download/clone composer source code from github.com, how can I run it or compile it into a phar file?
When running "php bin/composer -v", it shows such errors:
php bin/composer -v
You must set up the project dependencies using `composer install`
See https://getcomposer.org/download/ for instructions on installing Composer
Is it said that I must download another composer.phar file and run "php composer.phar install" first?
I think it is a recursive way, "composer" itself is managed by composer :(
At first: if someone wants just to use composer, they must not install it from GitHub, just follow the installation guide: https://getcomposer.org/download/
OK, back to the question.
"composer" itself is managed by composer
Yes, and why do you think it is bad?
See the official documentation for contributors. It encourages exactly that way:
Run git clone https://github.com/composer/composer.git
Download the composer.phar executable
Run Composer to get the dependencies: cd composer && php ../composer.phar install
Then you can actually use composer by launching bin/composer, or you can compile it into phar by bin/compile.
If you wonder how are composer binaries actually built, you can see it in their Travis config. They just grab previous composer release provided by Travis, and build new composer release with it.
Composer's job is to locate and install dependencies for a particular project. Everything it does could be done by hand, mostly simply by placing files in the right location, and referencing a series of autoloaders.
In order to build Composer from scratch, you need certain code that is outside of the main Composer repository, such as command-line and logging helpers. You could download all of these manually, but the natural way is to use an existing install of Composer to fetch them.
This is only necessary if you are working on Composer itself, because once you have a successful build, you can produce a PHAR file, which contains all the required code including those third-party dependencies. These are the files distributed as official releases, and are all most people need; the tool even has a self-update command which downloads a new PHAR file and overwrites the one you ran.
This kind of bootstrapping - using an existing build of a tool as part of its own build process - is actually quite common. There are some parts of PHP itself which are generated using a PHP script, and I believe the first feature-complete C++ compiler was written in C++.
When creating sites using a framework like Silverstripe I often want to use helper modules like gridfieldextensions and lumberjack.
I therefore use composer require to add the dependencies.
However when I follow my regular development work flow and use git add -A to add the module to the repo rather than the code being added to the repo I get a reference to it.
This causes problems when I then try to clone the site elsewhere (using Jenkins or another developer). The git clone or git pull leaves an empty directory.
I solve this by deleting the .git dir of the module and adding all the files.
Is there a better way to do this? Is using git submodule an option?
Somewhere i found a good .gitignore file that ignores everything and i have to tell it to include the custom modules for my project. It's like:
# ignore everything...
/*
# ...but
!/.htaccess
!/.gitignore
!/composer.json
!/composer.lock
!/Capfile
!/Gemfile
!/favicon.ico
!/touch-icon-*
!/mysite
!/some-module
#...other modules
# theme stuff
!/themes/
**/.sass-cache
**/node_modules
!**/node_modules/_manifest_exclude
#no assets in general, but /assets/.htaccess
!/assets
/assets/*
!assets/.htaccess
As FinBoWa already said you need the composer.json and composer.lock file in your project and running
composer install
on another machine it'll install the packages in the versions saved in the composer.lock file on that machine
composer install --no-dev
will only install the "normal" requirements, no dev-requirements like phpunit or other stuff you only need for developing or testing but not live
composer install --no-dev -o
will also optimize (-o) the auto loader, so it'll be a bit faster.
composer update
will update your packages, which might have funny side effects and break your site. So use it carefully and test afterwards.
composer update silverstripe/framework
will just update that package and finally
composer update silverstripe/*
will update all packages by the vendor silverstripe (e.g. framework and cms package)
See also:
gitignore documentation
composer documentation
I have a PHP project with some 3rd party developed dependencies and some developed by myself.
Some times I happen to find a bug on one of the dependencies I maintain and want to patch it on the spot or code some extra functionality that fits the main project needs.
Right now I am coding on the module project, doing a commit and then a composer update on the main project's composer.json, whose source for the module is the remote repo.
I would like to be able to have the full dependency repos on the main project, or at least commit to local and get the update without pushing to remote.
I believe I can use composer create-project for that, but the problem is I also get a lot of rubbish (the 3rd party dependency repos) that make my project huge.
Is there any way to have a composer create-project that only downloads the full repo of the dependencies I choose (those developed by myself)? Or to have the repo url point to a local git repository folder instead of a remote one?
According to the manual, create-project
is the equivalent of doing a git clone/svn checkout followed by a
"composer install" of the vendors.
Considering that, you run
composer create-project --no-install
Then you add local repos in composer.json (I'm not sure if it is documented but you can provide absolute and relative local paths as repo url) and do
composer install
I'm using the ZF2 skeleton app and it has a .gitignore that prevents external libraries from being commited to git. While debugging I like to go and change stuff here and there in the libraries' source to learn how things work. If these were version controlled it would be very easy to revert them back to their original state.
How can I force Composer to reinstall a particular framework so that I can get a fresh -unmodified- copy again?
PS: Please don't suggest removing the .gitignore file since it's there for a reason; it prevents my third party libraries from getting into my app's repository. I can always install them during an automated deployment.
The same applies to Laravel framework: it also gitignores the vendor folder.
First execute composer clearcache
Then clear your vendors folder
rm -rf vendor/*
or better yet just remove the specific module which makes problems to avoid having to download all over again.
You can use the --prefer-source flag for composer to checkout external packages with the VCS information (if any available). You can simply revert to the original state. Also if you issue the composer update command composer will detect any changes you made locally and ask if you want to discard them.
Your .gitignore file is related to your root project (ZF2 skeleton) and it prevents the vendor dir (where your third party libs are) from committing to your own VCS. The ignore file is unrelated to the git repo's of your vendors.
I didn't want to delete all the packages in vendor/ directory, so here is how I did it:
rm -rf vendor/package-i-messed-up
composer install again
What I did:
Deleted that particular library's folder
composer update --prefer-source vendor/library-name
It fetches the library again along with it's git repo
The relevant feature request is https://github.com/composer/composer/issues/3112
In 2021-05 the "reinstall" command patch got merged: https://github.com/composer/composer/pull/9915 - it is available in composer version 2.1.0 and all later ones.
The reinstall command is merged and availabe since 2.1.0:
composer reinstall <package-name> # Removes and installs the package.
Short answer
you can execute it in one cli command with &&:
composer remove vendor/package && composer require vendor/package:version
Detailed answer
Remove existing package by command:
composer remove vendor/package
this will remove folder of package from /vendor, row from composer.json and whole record of package from composer.lock right way with removing not used dependencies and not removing dependencies which used by another packages
Then install preferred one with command:
composer require vendor/package:version
this will install package with desired version right way with adding row to composer.json, adding record to composer.lock and all needed dependent packages
if there would be package which is used in more that one package, Composer
will try to install version which fits all using packages. If it will not resolve this it will crash with corresponding error message
Links
How to install a specific version of package using Composer?
How to remove a package from Laravel using composer?
Install, Uninstall and Update Modules Themes etc with Composer: https://modulesunraveled.com/drupal-8-composer-and-configuration-management/installing-and-uninstalling-modules-composer
Reinstall the dependencies. Remove the vendor folder (manually) or via rm command (if you are in the project folder, sure) on Linux before:
rm -rf vendor/
composer update -v
https://www.dev-metal.com/composer-problems-try-full-reset/
As user #aaracrr pointed out in a comment on another answer probably the best answer is to re-require the package with the same version constraint.
ie.
composer require vendor/package
or specifying a version constraint
composer require vendor/package:^1.0.0
For some reason no one suggested the obvious and the most straight forward way to force re-install:
> composer remove vendor-name/package-name && composer vendor-name/package-name
Be aware that this exact command will install latest version of the package. If you was using old version of the package and package does not have backward compatibility this will brake version compatibility. You might consider backing up your composer.json first.
Since Composer 2.1 you can do
composer reinstall vendor/package
see https://getcomposer.org/doc/03-cli.md#reinstall
In 2022
You can use composer status to list the libraries you changed.
Then composer resinstall vendor/package to overwrite the changes.
This does not change the version of the installed library like the solutions with composer require or composer install.