i got a problem with composer
In the VM instance, php and some packages installed(listed in composer.lock file)
When i try to install new package at local(i copy package folder from another VM can install via internet) the old composer.lock which list installed package will be replace with information of only new package i install.
step:
i update composer.json with new package
{
"repositories": [
{
"packagist": false
},
{
"type": "path",
"url": "/path/to/artifact/"
}
],
"require": {
"firebase/php-jwt": "^6.4"
}
}
then run
php composer.phar update
new package installed but composer.lock just have only new package(php-jwt) all other contents deleted
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 50 removals
- Removing cakephp/debug_kit (2.2.9)
- Removing clue/stream-filter (v1.6.0)
- Removing composer/installers (v1.12.0)
- Removing doctrine/instantiator (1.4.1)
...
- Locking firebase/php-jwt (6.4.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Downloading firebase/php-jwt (6.4.0)
- Installing firebase/php-jwt (6.4.0): Extracting archive
1 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
No security vulnerability advisories found
what i can do for install new package and update(append) information to composer.lock instead of add only new package to it?
Update: i change update command to require, the same result
php composer.phar require /path/to/artifact/
The command
composer update
reads the composer.json file and update/downgrade/remove/add the packages following the list in the require section to the latest version possible following its rules and avoiding conflicts.
In your case only the firebase/php-jwt is specified, so only itself and its dependecies are kept/updated and all other packages are removed and composer.lock reflects the state after the update operation.
To solve the issue you should use the full package list contained in the composer.json file that references the packages originally installed and add the firebase/php-jwt package manually to it and run the command:
composer update
or use the command:
composer require firebase/php-jwt:^6.4
to let composer add the firebase/php-jwt package to the composer.json file and install the package.
You're effectively updating the lock-file as configured and with the right command - composer update - the question is merely getting the grasp on the removals:
Lock file operations: 1 install, 0 updates, 50 removals
- Removing cakephp/debug_kit (2.2.9)
- Removing clue/stream-filter (v1.6.0)
- Removing composer/installers (v1.12.0)
- Removing doctrine/instantiator (1.4.1)
...
- Locking firebase/php-jwt (6.4.0)
Writing lock file
As composers' version locking shows every package other than firebase/php-jwt must not be installed and is/will be removed, it shows that you have a mismatch between your expectation and what you actually configured composer to do. See the --dry-run option to verify your changes before applying them to validate your expectations beforehand then you can spare yourself the trouble.
Now I wrote that this is "as configured". That is because you shared your configuration:
{
"repositories": [
{
"packagist": false
},
{
"type": "path",
"url": "/path/to/artifact/"
}
],
"require": {
"firebase/php-jwt": "^6.4"
}
}
The only package that is required is firebase/php-jwt. Where have all the others gone? Well, you haven't shared in your question so I can only guess and I'd say you edited the composer.json file and while doing so, you have removed the actual requirements of the project.
Restore the original composer.json and composer.lock files as well as the vendor folder from backup to recover the project requirements and dependencies.
And don't just blindly apply changes to those files. If you're offline just copy the two composer files and the according vendor folder and you're set.
If you can't live being offline and not able to run most of the composer commands for some reason, read the following:
COMPOSER_DISABLE_NETWORK
If set to 1, disables network access (best effort). This can be used for debugging or to run Composer on a plane or a starship with poor connectivity.
If set to prime, GitHub VCS repositories will prime the cache, so it can then be used fully offline with 1. (ref)
And additionally from my own offline experience, you don't have to disable the (default) packagist repository as composer realizes when there is no network and falls back to the cache.
Copy over the (primed) composer cache from the online machine where you get the updates from, it is pretty portable. Study the composer manual if you need dedicated tweaking like overriding the default size limit.
Related
I want to add repositories in my composer.json where the source depends on the application environment. For example, if I am in local environment, I want to include repositories from a local file path and if it is in production, then I want to include from GIT.
In local:
"repositories": [
{
"type": "path",
"url": "../local-path"
},
]
In production:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/...."
},
]
In my .env file is an APP_ENV variable. Are there any possibilities to achive this?
I think this isn't a great idea because you have a risk of potentially committing your composer.lock file from the wrong environment and deploying it. Hopefully you have stricter deployment checks in place though!
I don't have an exact solution, but some options instead:
Use a Composer config file locally
No need for separate composer file
Might get finicky about versions (I've had trouble getting composer to symlink before)
Should allow you to only maintain one composer.json and only touch the config file when you add new local repos
Documentation
In this example I created a project with a simple composer.json.
{
"name": "mickadoo/test",
"type": "project",
"require": {
"mickadoo/basedata": "dev-master"
}
}
I added a single requirement which is a package I put on packagist myself years ago.
I then created a dummy library to test it locally with the same name. It was in a library directory which contained only a composer.json file. The goal is to check if composer will install this empty library (no requirements) instead of the online one.
{
"name": "mickadoo/basedata",
"type": "library",
"require": {}
}
I then added a config.json file to the project root with configuration telling composer to add a local repo one directory up:
{
"repositories": [
{
"type": "path",
"url": "../library"
}
]
}
After all that I tried first running composer update and setting the COMPOSER_HOME env variable to my current directory. This ensures that composer will pick up the config.json and merge it into the configuration it's using.
$ COMPOSER_HOME=$PWD composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing mickadoo/basedata (dev-master): Symlinking from ../library
Writing lock file
Generating autoload files
I then deleted everything I did because I've messed around with local paths in composer before and know it can be frustrating to get working:
$ rm -rf vendor/ && rm composer.lock
Finally I tried just running composer update as normal, hoping it would skip the config.json and just pull the package from Github.
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 14 installs, 0 updates, 0 removals
- Installing symfony/polyfill-apcu (v1.13.1): Downloading (100%)
- Installing psr/log (1.1.2): Downloading (100%)
... more package installs from Github here....
Writing lock file
Generating autoload files
Which it did!
Use a separate composer.json
Keeps things pretty visible
Separate composer.lock file
Documentation
This would mean maintaining two separate files, like composer.local.json and composer.json. It might be tedious, but at least it's clear what's going on. Based on your COMPOSER env variable you can change which filename it's using
I see here a couple of options.
Use a local path to a repository. Then on the dev env checkout different one than on the production. But this would require to keep the local repository in sync with the remote.
Define dist and source for the repository and then differentiate it running composer commands (--prefer-dist on prod, --prefer-source on dev).
Build your own plugin https://getcomposer.org/doc/articles/plugins.md which would jump into action before certain events https://getcomposer.org/doc/articles/scripts.md#event-names
Another option would be to have composer.json file for production and composer-dev.json for development and run the second with setting system ENV variable first:
COMPOSER=composer-dev.json php composer install
But this can produce some incompatibility issues (when you forgot to move a package from composer-dev.json to production composer.json.
I'm trying to install gd (or ext-gd) libraries on heroku.
When I try to install them using composer (I have it as follows)
{
"name": "cool/app",
"type": "project",
"require": {
"ext-gd": "dev-master" (tried also installing "gd":"*", "ext-gd" : "*")
},
"license": "2016",
"authors": [
{
"name": "Dario",
"email": "my#email.it"
}
],
"minimum-stability": "dev"
}
I got
Problem 1
- The requested PHP extension ext-gd * is missing from your system. Install or enable PHP's gd extension.
So, tried to install from apt-get (sudo apt-get install php7-gd), but I dont have sudo permissions as I don't know the root heroku password.
Any work around on this?
EDIT
To explain better what I've done, here's the entire commands list
$ heroku run bash
Running bash on ⬢ app... up, run.1644 (Free)
~ $ composer init
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [app/app]:
Description []:
Author [, n to skip]: n
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []:
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]?
Search for a package: ext-gd
Found 15 packages matching ext-gd
[0] stil/gd-text
[1] gd/plesk-bundle
[2] quince/persian-gd
[3] xepan/gd-text
[4] zgldh/gd-text-for-chinese
[5] ext-calendar
[6] ext-iconv
[7] ext-dbus
[8] ext-xml
[9] ext-opendkim
[10] ext-mcrypt
[11] ext-openssl
[12] ext-ssh2
[13] ext-mongo
[14] ext-mbstring
Enter package # to add, or the complete package name if it is not listed: ext-gd
Enter the version constraint to require (or leave blank to use the latest version): *
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]? no
{
"name": "u11706/app",
"require": {
"ext-gd": "*"
}
}
Do you confirm generation [yes]?
~ $ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested PHP extension ext-gd * is missing from your system. Install or enable PHP's gd extension.
~ $ composer update --ignore-platform-reqs
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files
And I'm unable to use the gd libraries as php (Laravel) says Call to undefined function App\Http\Controllers\imagecreatefrompng()
If I run composer require ext-gd from my local computer I get
Using version ^0.0.0 for ext-gd
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files
First off, You must bundle with php locally.
1. Step
Include in your composer.json
{
"require": {
..
"ext-gd": "*",
...
}
}
2. Step
Update composer
composer update
it takes a time....take a coffe..
3. Step
publish with heroku cli
git push heroku master
On pusblish pay attention to output and check if you have something like my line 5 below, if you have it all's right.
1. remote: -----> PHP app detected
2. remote: -----> Bootstrapping...
3. remote: -----> Installing platform packages...
4. remote: - php (7.3.6)
5. remote: - ext-gd (bundled with php)
6. remote: - apache (2.4.39)
7. remote: - nginx (1.16.0)
8. remote: -----> Installing dependencies...
happy coding.
This is not really a Heroku problem, but something with your local computer.
You are running composer update locally to re-generate composer.lock. Your composer.json contains a requirement for ext-gd, so your local computer's PHP install must have that extension enabled, otherwise the requirements can't be satisfied and Composer throws an error about that.
That exact situation, and ways to work around it, are explained at https://devcenter.heroku.com/articles/php-support#using-optional-extensions - please follow the instructions there carefully, including the notes in the blue box that instruct you to run composer update --ignore-platform-reqs if needed.
gd is available on Heroku, you have to enable it by adding the following line to composer.json (under require section).
"ext-gd": "*"
Make sure to run composer update locally before pushing the code to heroku, or else It will not work.
Solved the issue by composer install locally and then deploy via git repository to heroku app.
What are the differences between composer update and composer install?
composer update
composer update will update your depencencies as they are specified in composer.json
For example, if you require this package as a dependency:
"mockery/mockery": "0.9.*",
and you have actually installed the 0.9.1 version of the package, running composer update will cause an upgrade of this package (for example to 0.9.2, if it's already been released)
in detail composer update will:
Read composer.json
Remove installed packages that are no more required in composer.json
Check the availability of the latest versions of your required packages
Install the latest versions of your packages
Update composer.lock to store the installed packages version
composer install
composer install will not update anything; it will just install all the dependencies as specified in the composer.lock file
In detail:
Check if composer.lock file exists (if not, it will run composer update and create it)
Read composer.lock file
Install the packages specified in the composer.lock file
When to install and when to update
composer update is mostly used in the 'development phase', to upgrade our project packages according to what we have specified in the composer.json file,
composer install is primarily used in the 'deploying phase' to install our application on a production server or on a testing environment, using the same dependencies stored in the composer.lock file created by composer update.
When you run composer install it will look for a lock file and install whatever is contained in it, if it can't find one, it'll read composer.json, install its dependencies and generate a lockfile.
When you run composer update it simply reads composer.json, installs the dependencies and updates the lockfile (or creates a new lockfile).
composer install
If composer.lock does exist.
Processes and installs dependencies from the composer.lock file.
If composer.lock does not exist.
Process package installs from composer.json.
Creates the composer.lock file based on the installed packages.
As per: composer help install:
The install command reads the composer.lock file from the current directory, processes it, and downloads and installs all the libraries and dependencies outlined in that file. If the file does not exist it will look for composer.json and do the same.
composer update
Processes dependencies from the composer.json file (installs, updates and removes).
Creates or updates the composer.lock file according to the changes.
As per: composer help update:
The update command reads the composer.json file from the
current directory, processes it, and updates, removes or installs all the
dependencies.
See also: Composer: It’s All About the Lock File
composer install
if(composer.lock existed){
installs dependency with EXACT version in composer.lock file
} else {
installs dependency with LATEST version in composer.json
generate the composer.lock file
}
composer update
composer update = remove composer.lock -> composer install
Why we need 2 commands. I think it can explain by composer.lock.
Imagine, we DON'T have composer.lock and in composer.json, there is a dependency "monolog/monolog": "1.0.*" or "monolog/monolog": "^1.0".
Then, it will have some cases
We working well today with current dependency version (eg:1.0.0) but a few
months later, the dependency update (eg:1.0.1) and it possible have some bug
Another team member may have a different dependency version if they run composer install in a different time.
What if we always use an EXACT version in composer.json such as "monolog/monolog": "1.0.1"?
We still need composer.lock because composer.json only track the main version of your dependency, it can not track the version of dependencies of dependency.
What if all dependencies of dependency also use the EXACT version?
Imagine you begin with ALL dependencies which use the EXACT version then you don't care about composer.lock. However, a few months later, you add a new dependency (or update old dependency), and the dependencies of this dependency don't use the EXACT version. Then it's better to care composer.lock at the beginning.
Besides that, there is an advantage of a semantic version over an exact version. We may update the dependency many times during development and library often have some small change such as bug fix. Then it is easier to upgrade dependency which uses semantic version.
The best difference between composer update and composer install
composer install
To add dependencies you need to add it manually to the composer.json file.
If composer.lock file exists, install exactly what's specificated on this file
Otherwise read composer.json file to look out what dependencies needs to be installed
Write the composer.lock with the information of the project (installed dependencies)
Not any component will be updated with this command.
composer update
To add or remove dependencies you need to add it manually to the composer.json file
The composer.lock file will be ignored
composer.json file dependencies will be installed and updated (if a dependency is not installed it will be downloaded)
If you can't (or don't know how to add or remove a library which is in fact easy,just add the name of the dependency and version in the require property of the file) modify the composer.json file manually or you prefer use the command line instead, composer has special functions for this :
composer require
For example if we want to add a dependency with the command line we will simply execute
composer require twig/twig
composer.json file will be modified automatically and the new dependency will be added
the dependency will be downloaded to the project
composer remove
If you want to remove an unused dependency we will execute simply :
composer remove twig/twig --update-with-dependencies
Twig will be removed with all his dependencies
I'm having an issue with composer.
I'm working with git in a local environment. I'm the only one developer.
When I need some more dependencies (or need to change some versions), I edit the composer.json and run composer install locally.
Everything's fine.
Then, when everything works locally, I commit my changes (including composer.json and composer.lock) and push to my production server.
A post-receive script updates the sources and runs a composer install on the remote server.
What is expected :
Composer should install the new dependencies according to the composer.lock file.
I should be happy.
What happens :
Composer is angry :
Warning: The lock file is not up to date with the latest changes in
composer.json. You may be getting outdated dependencies. Run update to
update them.
Composer removes all dependencies.
My production is broken.
I have a heart attack
I have to log in to my server via ssh and run a composer update to make things work fine, but I know that a composer update is not recommended on a production server.
Here's the output of the post-receive composer's section :
composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
- Removing guzzle/guzzle (v3.9.3)
- Removing symfony/event-dispatcher (v2.7.1)
- Removing geoip/geoip (v1.15)
- Removing pimple/pimple (v3.0.0)
- Removing cocur/slugify (1.1.x-dev)
- Removing bentools/url (0.2)
- Removing bentools/simplexmlextended (1.2.0)
Generating autoload files
What am I doing wrong ?
Thanks,
Ben
This warning
Warning: The lock file is not up to date with the latest changes in composer.json, you may be getting outdated dependencies, run update to update them.
occurs when the md5sum of your composer.json differs from the one stored in the composer.lock:
{
"hash": "b15ed9405e8547867f74973ce8add172",
"packages": [ ... ]
}
Make sure your composer.json and composer.lock are identically with your local ones (compare their md5sums). I suspect that something in your deploy chain is not updating them correctly.
Make sure you added your dependencies locally with the require command:
composer require new/package ~2.5
or if composer.json was edited manually at least run
composer update new/package
after that for every additionally added package to ensure that it is added to your composer.lock properly.
Another approach:
run composer update --lock in production. This will update the hash in your lock file but won't upgrade your vendors.
Then run composer install to install the vendors from your comoser.lock.
When I need some more dependencies (or need to change some versions), I edit the composer.json and run composer install locally.
That's wrong. You can edit composer.json and then must run composer update, or you let Composer do the internal editing of the json file and just run composer require new/package (optionally with a version).
Either way, you should end up with a changed composer.json and composer.lock file, commit BOTH into your repository, and the expected outcome is that the lock file will contain all packages in the correct versions, which should be installed in production with a regular composer install run.
Note that your workflow is still very dangerous. If you push, and Github is down - how would you get the ZIPs to install?
Let's say I have a composer.json file with locked dependencies:
{
"require" : {
"zendframework/zendframework" : "2.4.2"
},
"require-dev": {
"phpunit/phpunit": "4.6.6"
}
}
I want to do that because would like to update dependencies manually, so I won't be in a situation where my build fails or other developers experience issues I don't have because Composer installed a different version of the package.
Is there a good way to use Composer to list all newer versions of the locked packages, perhaps something like composer discover, where I get output: zendframework/zendframework is locked at version 2.4.2 (or 2.4.* or whatever), but there are versions 2.5.0, 2.5.1, and 2.6.0 available*?
Is any existing command capable of providing that kind of information?
Basically, I'm more about the newer versions being shown to me, so I can know what dependency to update manually. Committing the composer.lock isn't really the solution because that won't show me what to update (and my composer.json is locked at specific versions, so composer.lock won't differ anyway).
In order to do what you want, commit the composer.lock file and make sure everyone runs composer install to install the deps. This way, everyone has exact the same version/commit of each package.
You can then run composer update to get newer versions. This will update the packages and the composer.lock file, which you can commit and push, so everyone has the same versions again (after they run composer install).
This is not exactly what you are suggesting. But you can run
composer update --dry-run
to see what happens when composer updates your dependencies. This only shows you the latest version a package could be updated to, but not the versions in between:
composer update --dry-run
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Updating symfony/translation (v2.5.5) to symfony/translation (v2.5.11)
- Updating symfony/security-core (v2.5.5) to symfony/security-core (v2.5.11)
- Updating symfony/routing (v2.5.5) to symfony/routing (v2.5.11)
- Updating symfony/process (v2.5.5) to symfony/process (v2.5.11)
- Updating symfony/http-foundation (v2.5.5) to symfony/http-foundation (v2.5.11)
The simplest way would probably just to run:
composer outdated
and get a list of the outdated dependencies. The output looks roughly like this:
As has been said by others, composer does what you tell it, and will only install the versions specified from the .lock file, or update to new versions (as specified within the range of the given version).
There are outside website services that will let you know that packages have been updated though - such as Versioneye.com. You can follow a number of packages, and it will let you know when any of them have been updated, so you can update the composer file as you wish.
To show the latest version of the packages, use show with -l/--latest parameter, e.g.
composer show -l
-l, --latest Show the latest version
To see the tree of dependencies, use -t/--tree parameter, e.g.
composer show -t
-t, --tree List the dependencies as a tree
To list all available version for the given package, run:
composer show -a zendframework/zendframework
Note: Change zendframework/zendframework with your package name.
Notes:
For global, add global right after composer.
For help, run: composer global help show.