Is "content-hash" a mandatory part of composer.lock? - composer-php

Like most people writing (and reading) the question about whether to keep composer.lock in version-control, we keep ours there.
However, this causes us trouble every time the file is independently updated in different code-branches. Even when the changes are unrelated and affect the sections of the file afar from each other, the "content-hash" line is causing a conflict every time. Worse, neither "side" is correct and whoever is doing the merging must regenerate the file by hand...
Maybe, the line is not really necessary? Before asking, whether (the current version of) composer will work without it, what functionality would be missing? The hash seems to guard against the file itself changing -- but the source-control system is already doing that...
Can I simply remove the line? If it can not be done today, would it be a desirable feature for composer?

Purpose of the content hash
As you can see in Composer\Package\Locker::getContentHash(), the content hash takes into account the following fields of composer.json:
$relevantKeys = array(
'name',
'version',
'require',
'require-dev',
'conflict',
'replace',
'provide',
'minimum-stability',
'prefer-stable',
'repositories',
'extra',
);
The only reason for the content hash to change is a change of one of the values of the corresponding properties in composer.json.
Composer uses the content hash to determine whether relevant fields in composer.json are in sync with composer.lock. You can run
$ composer validate
to find out if they are in sync.
If composer.json and composer.lock are not in sync, a message similar to this will be shown
The lock file is not up to date with the latest changes in composer.json, it is recommended that you run composer update.
For reference, see https://getcomposer.org/doc/03-cli.md#validate:
You should always run the validate command before you commit your composer.json file, and before you tag a release. It will check if your composer.json is valid.
Resolving conflicts in composer.lock
If you have trouble resolving conflicts in composer.lock, maybe this helps:
Step 1: Accept upstream changes
Usually, you will probably attempt to rebase a branch on top of the upstream changes. When already in conflict, use your IDE, or run
$ git checkout --theirs composer.lock
to accept the upstream changes to composer.lock. Since this is a generated file, you really don't want to resolve conflicts in it.
Step 2: Re-apply changes to composer.json and composer.lock
As pointed out earlier, there are a range of the relevant keys in composer.json. Some of them can be modified by corresponding commands, others cannot.
For example, if one of the changes is a newly added or removed package, run
$ composer require foo/bar:^1.2.3
or
$ composer remove foo/bar
to apply the changes.
If the changes cannot be applied by running a command, manually modify composer.json, then run
$ composer update --lock
This will update the content hash.
For reference, see https://getcomposer.org/doc/03-cli.md#update:
--lock: Only updates the lock file hash to suppress warning about the lock file being out of date.

TL;DR version from #localheinz:
Just resolve the conflict and then regenerate the lock file with:
$ composer update --lock
This will update the content hash.
For reference, see https://getcomposer.org/doc/03-cli.md#update:
--lock: Only updates the lock file hash to suppress warning about the lock file being out of date.

Related

How to deal with yarn's `.pnp.js` merge conflicts?

Using yarn 2's new plug n play (pnp) creates a long .pnp.js file. I get a bunch of merge conflicts while pulling, and these are not autofixed (unlike yarn.lock).
How are these conflicts solved? I'd rather not go them through manually as it's not clear what change to accept.
Example conflict
["virtual:844e49f9c8ad85b5809b347eb507fe8bfdc2d527102f53e0b4f78076a2ad5ea2556763170701137a2cafdc51d5a36d82e448010e65742a300748e0bc70028101#npm:11.2.7", {
"packageLocation": "./.yarn/$$virtual/#testing-library-react-virtual-2e67fd5293/0/cache/#testing-library-react-npm-11.2.7-3a0469c756-389c9f3e83.zip/node_modules/#testing-library/react/",
"packageDependencies": [
["#testing-library/react", "virtual:844e49f9c8ad85b5809b347eb507fe8bfdc2d527102f53e0b4f78076a2ad5ea2556763170701137a2cafdc51d5a36d82e448010e65742a300748e0bc70028101#npm:11.2.7"],
["#babel/runtime", "npm:7.13.10"],
<<<<<<< HEAD
["#testing-library/dom", "npm:7.30.4"],
["#types/react", "npm:17.0.3"],
["#types/react-dom", "npm:17.0.3"],
=======
["#testing-library/dom", "npm:7.31.0"],
["#types/react", "npm:17.0.8"],
["#types/react-dom", "npm:17.0.5"],
>>>>>>> d2bb5d9e537f9647e9757656de230e56282e0b15
["react", "npm:17.0.2"],
I would assume you can delete this file containing merge conflicts.
Next, you run yarn install which will generate this file again.
Or just run yarn install which will overwrite the the .pnp.cjs file and fix the merge conflicts (if any) in the yarn.lock file for you.
From the docs:
The generated .pnp.cjs file can be committed to your repository
as part of the Zero-Installs effort, removing the need to run yarn install in the first place.
As you can read, this file can - not must - be committed. However, if you commit it, you can use all your dependencies immediately after cloning the repo, switching branches, ... without need to run yarn install every time.
Note that the same does not count for yarn.lock file which you should never delete.

Joomla "Fatal error: Cannot redeclare jblogerror() in on line 0"

Here is a weird problem i'm facing; after updating Joomla to the latest version, website failed to up load but, as i've made a backup manually from these folders:
administrator
bin
cli
components
includes
layouts
libraries
modules
plugins
yt-assets
and all the root files, after restoring the backup still the website is not loading and just says
"Fatal error: Cannot redeclare jblogerror() in on line 0" !
Any suggestion? Thank you.
Apparently, the version of jBlog you are using is loading its attempting to load its own classes twice.
Let's assume the jBlog developers already fixed it and you carelessly ignored the warning to ensure all your extensions are compatible before updating.
Are you able to access administrator? Simply go there and upgrade jBlog including any modules.
Else, the issue lies within a plugin. In order to access the administrator and perform the update, you will need to manually disable the offending plugin.
A simple way is to rename its folder: start from plugins/system then plugins/content hopefully you'll have spotted it by then. Look into the subfolders of each and spot any that may be relevant to jBlog (or grep through the folder to locate the specific string)
If you have console access, simply run
# grep -rl jblogerror plugins/system
and you should see all the files that include such string, just rename their main plugin folder. But you could also do all this through ftp and guessing.

Go mod replace and github forks of /vN repositories

I've just sent a pull request to http://periph.io/x/devices/v3; it's already been merged, but something about the process was suboptimal:
First I cloned the repository (which is actually http://github.com/periph/devices; the module is named periph.io/x/devices/v3 though), so my fork is automatically called http://github.com/lutzky/devices. I wanted to test a separate piece of code I'm working on with the modified library, call it testclient; adding this to testclient/go.mod works:
replace periph.io/x/devices/v3 v3.6.9 => ../devices
However, this should also work (and would be useful if the pull request took longer to be accepted), and doesn't:
replace periph.io/x/devices/v3 v3.6.9 => github.com/lutzky/devices main
That gives this error:
testclient/go.mod:15: replace github.com/lutzky/devices:
version "v0.0.0-20210508194004-cae0146d8900" invalid:
go.mod has post-v0 module path "periph.io/x/devices/v3" at revision cae0146d8900
On a hunch, I figured I'd create a tag v3.6.9-newfeature and push that to my fork, and point the replace command at that. That doesn't work either:
testclient/go.mod:15: replace github.com/lutzky/devices:
version "v3.6.9-newfeature" invalid:
module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v3
So I can't use a v0 tag because go.mod says it's v3, but I can't use a v3 tag because the URL doesn't have /v3. I don't think I should modify go.mod in my forked repository (for one thing, that'd make the pull request silly). What's the intended way to go about this?
Here's the fix that you are looking for, I tested the following go.mod file and it works,
module test
go 1.14
replace periph.io/x/devices/v3 => github.com/lutzky/devices/v3 v3.6.9-newfeature
require (
periph.io/x/devices/v3 v3.6.9 // indirect
)
I first installed periph.io/x/devices/v3,
go get periph.io/x/devices/v3
Then I inserted the replace in go.mod,
replace periph.io/x/devices/v3 => github.com/lutzky/devices/v3 main
Format: replace <original_module> => <forked_repo> <branch>
Then I ran just go get. After that, the main in the replace instruction got swapped with v3.6.9-newfeature which is the latest tag on the forked repo's main branch, thus giving you the content that you see above.
Thanks to ramaraja-ramanujan#'s answer and a bit more debugging, I found the answer.
TL;DR - the correct answer is:
replace periph.io/x/devices/v3 v3.6.9 => github.com/lutzky/devices/v3 main
// this part was missing ^^^
This will work immediately when building, and go mod tidy (or go get) will change main to a specific tag. There are a couple of interesting side-notes to this:
The go proxy
The v3.6.9-newfeature tag was my own; I had created it as part of trying to get this to work. I've deleted it, and yet go mod tidy kept replacing main with v3.6.9-newfeature - no matter how many caches I cleared! Running strace it turned out that go was contacting http://proxy.golang.org. To disable this, I ran GOPROXY=direct go get. This replaced the line with the pseudo version v3.6.10-0.20210508194004-cae0146d8900. Note that this matches the current main commit in my fork, and neither my fork nor the original repo have v3.6.10 - it appears to have started with the existing v3.6.9 and incremented it.
The /v3 is not a subdirectory
Indeed, the source repo (https://github.com/periph/devices) does not have a v3 subdirectory. I thought what was going on is that the periph.io domain is doing some trickery - indeed going to http://periph.io/x/devices/v3 with a browser does work. However, it would appear that Go's resolution takes the final /v3 in the module path not to indicate, in this case, a subdirectory (but indeed a restriction on tag names). This is apparently allowed, and is discussed in https://golang.org/ref/mod, but it isn't entirely straightforward.

CakePHP 3.5: Cannot access Plugin Classes after installing it via Composer

So I have a CakePHP 3 project and want to load FluentDOM, a PHP plugin not specifically written for CakePHP.
According to both software documentations, Composer is the way to go. In my understanding, all I would have to do is the following:
run composer require fluentdom/fluentdom in powershell
run composer require fluentdom/selectors-phpcss in powershell
OR
add the following to composer.json in the project's root directory:
"require": {
"fluentdom/fluentdom": "^7.0",
"fluentdom/selectors-phpcss": "^1.1"
}
run composer update in powershell
Both ways will install the desired plugins to vendor/fluentdom/{pluginname}/ as expected, but /vendor/cakephp-plugins.php won't include them, as implied by CakePHP's plugin installation manual.
The following attempt to load either plugin in a controller by writing
use Cake\Core\Plugin;
Plugin::load('fluentdom/fluentdom');
Plugin::load('fluentdom/selectors-phpcss');
would cause an exception that the desired plugins were not found in plugins/ :
Make sure your plugin fluentdom/fluentdom is in the {absolute project path}\plugins\ directory and was loaded
-- Which is already odd, because Composer wouldn't install anything there to begin with.
I found that I might get around this issue by manually extending vendor/cakephp-plugins.php to include the correct paths:
'fluentdom/fluentdom' => $baseDir . '/vendor/fluentdom/fluentdom/',
'fluentdom/selectors-phpcss' => $baseDir . '/vendor/fluentdom/selectors-phpcss/'
(However, that doesn't seem the way to go, because this file is auto-generated and overwritten by Composer after every update.)
And even then, the final issue still persists: although the plugins seem to be loaded successfully (confirmed by running Plugin::loaded()), I'd finally get the following exception when trying to access FluentDOM's classes as described in their wiki:
$document = new FluentDOM\DOM\Document();
Class 'App\Controller\FluentDOM\DOM\Document' not found
Does the plugin miss out on having its' autoload executed?
Even extending the line in my controller to Plugin::load('fluentdom/fluentdom', ['autoload' => true]);, but doesn't seem to help either; according to CakePHP's doc, that shouldn't be necessary anyway.
So what am I missing?
Found it! First of all, I had the false presumption that Plugins and Vendor Packages are more or less the same: they are not; thanks to Greg Schmidt for pointing this out in the question's comments.
The issue was in the line of how I tried to access FluentDOM's class. While
$document = new FluentDOM\DOM\Document();
worked in a standalone php file, it didn't within the Cake project; I was missing a backslash:
$document = new \FluentDOM\DOM\Document();
So, the entire path of actions to load a Vendor Package is merely:
run composer require fluentdom/fluentdom in powershell
run composer require fluentdom/selectors-phpcss in powershell
Use the new classes right away with $document = new \FluentDOM\DOM\Document();
No further steps required. Side note: Composer seems to refresh autoload config after installing a vendor file with composer require {vendor}/{package}, but in case it doesn't, or autoload config is messed up from earlier experiments, composer dumpautoload should fix it.

Sort packages without adding/updating dependencies

On an existing project with a long list of packages and various feature branches where new dependencies are being added I want to mitigate and minimize merge conflicts by adding dependencies in alphabetical order.
To get this cleaned up, though, I'd like to be able to run the --sort-packages functionality on its own -- without adding or updating anything -- as just a single commit that cleans up the existing packages, and then add "sort-packages" : "true" to the "config" section of the composer.json file to ensure all new packages are added in alphabetical order going forward.
Is it possible to sort the packages listed in a messy composer.json file using composer's --sort-packages option on the CLI without actually adding or updating any dependencies?
The only workaround I've found so far is to run composer update some/package --sort-packages against a package that you're sure wont update because it is already at the latest version. This is not ideal.
I know I'm (really) late! But perhaps my answer can help others in the future ;-)
If you run
composer config sort-packages true
this will add the following in your composer.json file:
"config": {
"sort-packages": true
},
The next time you do a composer require (or update) it will automatically sort the whole list.
You can "re-require" a package you've already required. In my case, it's Symfony 3.4, so I did:
composer require symfony/symfony:3.4.*
If you don't have "sort-packages": true in your composer.json, you can do:
composer require --sort-packages symfony/symfony:3.4.*
From what I can tell, only the require command has the option for sorting packages so it seems you need to require a package for sorting to be applied.
It is since 1.0.0-alpha10 - released 2015-04-14 - that composer require has the --sort-packages option:
Added --sort-packages option to require command for sorting dependencies
This is not yet the composer.json#/config/sort-packages which is since 1.0.0-beta1 - released 2016-03-03, roughly a year later:
Added sort-packages config option to force sorting of the requirements when using the require command
It stems from pull-request #3549 and there is also a bit of backstory as well as more options discussed in Normalizing composer.json by
Andreas Möller (localheinz), Jan 2018.
First of all, +1 for using "sort-packages": true, for all the reasons you describe.
It is a bad idea to edit composer.lock directly, but I do not think the same applies to composer.json. I would edit the files in Vim, select everything inside the "require" and "require-dev" sections (one at a time) and :sort. Plus some fiddling to make sure that every line except the last has a comma.

Resources