Problem/Motivation
Currently config differ strips (ignores) uuid configuration key on all configuration levels. That's not correct behaviour, since it's normal for some configurations to contain uuid (fe. image styles). Here is one example:
langcode: en
status: true
dependencies: { }
name: thumbnail
label: 'Thumbnail (100×100)'
effects:
1cfec298-8620-4749-b100-ccb6c4500779:
uuid: 1cfec298-8620-4749-b100-ccb6c4500779
id: image_scale
weight: 0
data:
width: 100
height: 100
upscale: false
Proposed resolution
Ignored configuration keys array $ignore = ['uuid', '_core'] should be applied only on root level of configuration.
Here is an example of implementation and it would be good to port it into config_update module.
Remaining tasks
- Migrate implementation from
update_helper into config_update, or reimplement logic in config_update since it's not so complicated
- Write tests
Open questions
- Is configuration key ignore for all configuration levels still required?
- If not, can we simply use existing constructor argument for root level key ignore list of we have to introduce new parameters?
Comments
Comment #2
jhodgdonOK, that seems reasonable... Want to make a patch?
Comment #3
mtodor commented@jhodgdon - Yes, I can provide a patch. Can you just clarify open questions?
I would say, simplest solution:
$ignore)Comment #4
jhodgdonLet's see... I think that your conclusion here is correct: removing UUID and _core at all levels of the configuration was a bad implementation decision, so it is a bug that we can fix, and it is OK to change buggy behavior. So I think that we can just change the documentation of the $ignore parameter to the constructor, to say "Config components to ignore at the top level", and leave it at that.
The only caveat I have is that I would want to test this on a real site and verify that with the patch, I don't get a lot more items in the report marked as "changed" because we are no longer stripping out things that are not actually different. But I agree, stripping UUID out of the insides of image styles is not correct, and I'm also pretty sure _code is only added by the config system at the top level.
So... Implementation: Yes, let's just use the existing constructor parameter and change the docs slightly.
It looks like we'd need to add a second argument to the normalize() method, to detect whether we're at the top level or not, because this method is called recursively, and we only want to strip the ignore list at the top level. I would do something like
and then when it is called recursively, put in FALSE.
Comment #5
mtodor commentedHere is a proposal.
Following changes are made:
NULLvalue is used, since that's where translatioin is used. It would be good, if someone has better solution? (tests are added)Comment #6
jhodgdonThe patch looks mostly good to me, and our tests passed, so that is also good. I'm assuming you tested it on your case?
One thing needs a quick fix:
I'll fix up that method documentation, just pasting it here to remind myself to do that.
Another question I have is what these additions to the test are:
It seems like those might have been things you tried but decided you didn't need? Thanks!
Comment #7
jhodgdonOh, it looks like the weekly test of this module is failing, that is the t() thing you fixed. I created a separate issue for that, so let's take the fix for that out of this patch and put it on
#2961886: Unit test for Config Differ is failing
Comment #8
mtodor commented@jhodgdon thank you for review.
I have tested integration with our module and I removed overwrites in our class for (normalize, same and diff) and tests are passing. So it looks good.
Regarding part of the code with added
null_value- it is needed. It is relevant because, translation is used only forNULLvalue. If you take a look at this part of code:You will notice that I have changed code for mockup of
translateStringto always return(NULL)and that's executed (or used) bytestDiff(). With that we are testing that formatting of NULL values is working properly.That's what I have mentioned at #5-3. If someone has a better proposal?
P.S. Since you have merged #2961886: Unit test for Config Differ is failing, you have to take care when you merge this patch so that you don't lose the relevant part for translation.
Comment #9
jhodgdonSo, I looked at this some more.
This patch is doing more than what the issue summary says. Normalization used to remove empty arrays from config, and this patch reverses that. This is not a good idea, based on my manual testing when I was first writing this module. It was leading to a lot of false positives, where I had installed a site a while back, and since then some new component had been added to the config, but it was empty. There was no functional difference between the config in my system and the new config, hence I didn't want it to show up in my reports as being changed when there was no real change.
So, I've put that back, and changed the test accordingly. Also updated the documentation mentioned in #6. The test passes locally... let's see what the bot says about all the tests.
Comment #11
jhodgdonFix test failure... hopefully! Odd, this didn't fail locally for me but anyway, I understand the problem.
Comment #12
jhodgdonPasses this time, but two little coding standards fixes...
Comment #13
mtodor commentedNice progress! I think we are getting somewhere.
I have checked the code and it looks clean.
I guess this should be
$new = $this->normalizeArray($value);.Well, I'm not sure about this. I'm really against removing of key, no mather if it's empty or not. I'm always looking from perspective of diffing. And to have config like this:
to be same as this one:
is not good solution for me. :(
Nice solution!
Comment #14
jhodgdonThat is a good point about empty arrays, and thanks for catching my syntax error!
So, let's think about this question of arrays.
- It seems like empty arrays should *not* be removed if they are in numerically-sequenced config.
- I still think empty arrays should be removed if they are in keyed config, to avoid meaningless config differences.
Let's look at an example:
In this example, I think we should remove b, because it has no values in it. But we shouldn't remove the empty array under the C sequence, because that would break the sequence numbering.
This points to the fact that we don't have any tests that include numeric sequences. So... let's see if we can put this example into the test (or something substantially similar) and make it work. Thoughts?
Comment #15
alexpottIt's tricky. The problem is that this module doesn't decide the meaning of configuration. Different implementations do. And it is possible for an empty array to mean something different from not being set. It wouldn't be great for the the user but it is totally possible and probably that someone has configured something to work that way. The same unfortunately goes for order of configuration. Ideally it'd never make a difference or we'd be enforcing orders via schema (there are patches to do this). But there are definitely examples in the wild were the order matters.
Comment #16
jhodgdonOK, I would be willing to get rid of the "remove empty arrays" thing.
But are there actually examples of config where the order of the keys, at some level, in a mapping (not a sequence) matters? I don't even know if that is possible to retain, given that there is a schema, and if you save config, it gets saved in the order of the schema.
Comment #17
jhodgdonThe problem is that if you don't normalize the config at all, you end up seeing a bunch of "THIS CONFIG CHANGED" entries in your config update reports. Most of them are not real differences, they're just that you imported config a while back, and since then the schema has changed, and hopefully the module developer has also updated their stored config accordingly, so it has a bunch of minor changes that don't affect your actual site behavior. Like adding new options that have sensible (empty) defaults, and reordering things.
So the point of the normalization is to omit the things that don't matter, so you can see what has actually changed. I think it should cover the 99% case, so that the report is pretty good at telling you if there have been substantive changes that you should be aware of. If some module is doing something weird and unstable with config, I don't think we need to cover that rare and probably ill-advised possibility. But something like removing empty arrays in the middle of a sequence, we shouldn't do.
So with that in mind, ... I think I'm still in favor of (a) reordering config and (b) removing empty arrays except in sequences, because most of the time the reason the active config item has nothing and the one in config/install has an empty array is that there's a new key added to the schema since you installed, and it has a sensible (empty) default. Your site is working, after all, so there must have been a default... and if there was some non-empty data in there, it would show up in the diff, and if the active config needed to have that empty array in there, there would have been a hook_update_N() to add it.
Comment #18
mtodor commentedI would suggest that we make followup ticket that will solve "remove empty arrays" problematics and just finish what we have started here. There is no point keeping things back because of other no related stuff.
So last required change is
$new = $this->normalizearray($value);in camel case and we are fine.Comment #20
jhodgdonGood idea. So, I committed the change (with the syntax fix). I created a child issue #2962529: Figure out normalization for ConfigDiffer as well as a change notice for this change.
https://www.drupal.org/node/2962527
Thanks for the comments and patches!