Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save DavMorr/c3a5b73820778e2fb213cdd9d614f27a to your computer and use it in GitHub Desktop.
Save DavMorr/c3a5b73820778e2fb213cdd9d614f27a to your computer and use it in GitHub Desktop.
Drupal 8 - use sed to strip uuid line from exported config files

[Drupal 8] use sed (on OSX) to strip the uuid line from exported config files being used for module default configuration; i.e. [module_name]/config/optional|install

NOTE: this can also by bypassed in the export by using Drupal Cnnsole and including the --remove-uuid flag. Also using the --remove-config-hash flag can help prevent additional headaches.

Ex: drupal config:export --directory=”[full-path-to-location]” --tar --remove-uuid --remove-config-hash

The UUID should never be included when using when using these exported config yaml files as the default configuration pagaged with a custom module. This is suppoedly not to be a thing in the exported yaml files at some point, but until then stripping the uuid line out is a manual process which can be a pain as there can be a lot of files.

To automate this, run the following sed command in the directory containing the yaml files:

sed -i.bak '/^uuid: /d' ./*

The i.bak arg will create a backup of the affected file. When satistifed with the results, you can safely get rid of the .bak files:

rm *.bak

References:

@DavMorr
Copy link
Author

DavMorr commented Apr 17, 2023

@gaellafond Thank you for your feedback. I don't recall what this was needed for - as it was posted here 5-6 years ago - but obviously the intent was to provide a default configuration to be included-with and set upon custom module installation. I reviewed the config_split issue that you referenced as well as this gist, some notes I found from back then, and did a little quick research as to any 'official' recommendation/best practice for including a default config with custom module. The following documentation from drupal.org which provides a recommendation for this specific feature actually supports removing the UUID line(s) from the accompanying bundled YAML config file(s):
https://www.drupal.org/docs/creating-modules/include-default-configuration-in-your-drupal-module

I haven't worked with D8 in the years since this was originally posted and only recently moved back to developing for D9 from Laravel and other platforms. It looks like this solution is still viable though it may need a tweak or two - no idea. If you or anyone else who happens to stumble across this has any better recommendations/solutions for including default configs for application upon custom module install, please feel free to post them. Otherwise, feel free to use this method. If/when I find myself needing this functionality again, I will revisit and post any updates, tweaks, fixes, et al here. Cheers!

@gaellafond
Copy link

gaellafond commented Apr 18, 2023

Thanks for taking the time to look into this after all those years.

I have found many contradictory information regarding this. As far as I understand it, the UUID is used to locate and update the config when there is an update to the YAML config file in the module. Without the UUID, Drupal has no way to determine if it's a new YAML or an updated one and it would not know how to update the resource on the website. Removing the UUID would work as long as the YAML file never changes in the module, which is obviously not a good assumption to take.

Here I'm assuming Drupal would actually update the entity on the website when the YAML file is changed. I haven't tested this yet. I'm still new to Drupal 8+. I'm still discovering the ins and outs. It can be very difficult and frustrating to know the best practices in cases like this one.

If you do not remove the UUID, it's true that every website which install your module will have the same UUID, but that's a small price to pay for maintainability.

I will experiment with this today and edit this post with my findings...

[EDIT] It doesn't seems like Drupal wants to update resources created using YAML files. From what I have read, I would need to create an update function in the .install file, list the updates, loop through the list and execute them in my update function. I have changed my YAML file but the getChangeList method returns nothing.

function mymodule_update_9001() {
  $entityDefUpdateManager = Drupal::entityDefinitionUpdateManager();
  $changeList = $entityDefUpdateManager->getChangeList();

  \Drupal::logger('mymodule_update_9001')->notice("Change list: <pre>" . print_r($changeList, TRUE) . "</pre>");
  // The changeList array is empty...

  // Loop through the change list and "execute" them somehow...
}

@DavMorr
Copy link
Author

DavMorr commented Apr 18, 2023

Thanks for following up. I think we may be missing each other on intention, use case, and process (maybe not, it has been quite a while since I worked on this and I don't know what exactly your use case and or needs are).

First, distributing a UUID with a module is bad practice as it defeats the purpose of a UUID, which is Universally Unique IDentifier. I understand your POV but I can't support this approach, for whatever that's worth, as it is bad practice. The process below should be sufficient to achieve the intention and use case as described below without potential for UUID collision or failure due to its absence. Also, I defer to the drupal.org support docs page (see below) that instructs to remove the UUID row from the config export YAML as part of the process.

The intention: bundle a default default configuration with a custom module to populate the config in the database upon module install.
The use case: distribution of a custom module with a default configuration bundled.
The process (as the module developer):

  1. Install the new custom module on a dev site.
  2. Set and save the default configurations via the module's admin page(s).
  3. Perform config export for the module via the Config Sync > Export Single Item UI (admin/config/development/configuration/single/export), which is the easiest method, or from file via drush (drush cex) or full archive export via admin UI (admin/config/development/configuration/full/export).

Once you have the module's config YAML:

  1. strip the UUID per the method in this gist or whatever you prefer,
  2. follow the directions on the drupal.org support docs page that I mentioned in my previous comment (relevant excerpt below),
  3. uninstall the module (drush or UI)
  4. reenable the module
  5. run drush updb or update database script (/update.php) in browser, to to assure the defaults are picked up.

[drupal.org] Include default configuration in your Drupal module - relevant excerpt:
Create a file named node.type.example_mytype.yml and place it in your module's directory in a subdirectory called config/install. For example this file could be at /modules/example/config/install/node.type.example_mytype.yml if the module is in /modules/example.) - relevant excerpt:

Create a file named node.type.example_mytype.yml and place it in your module's directory in a subdirectory called config/install. For example this file could be at /modules/example/config/install/node.type.example_mytype.yml if the module is in /modules/example.

If I remember correctly, the above should be sufficient to the intention and use case as described above. If you wanted to make changes after the module has been published, then you would use the update hook as you described in your last post's update. Again, I think that this is correct. Things may have changed in D9 and or there could be an error in this process recommendation, as I haven't tested this recently or worked with this specifically in ~5-6 years, and your need and use case could be different from what I've described - so your mileage may vary.

Good luck!

@gaellafond
Copy link

gaellafond commented Apr 19, 2023

Thanks for the clarification. I think we are on the same page.

I'm trying to follow Drupal's best practices for my module. The module is creating some resources in Drupal: a content type with a few new fields and a view. Those resources are likely to change over time. I have created modules for Drupal 7 in the past, things always changes. I don't want to be stuck in a situation where I need to change my resource's YAML file but Drupal can't recognise the resource it created, and instead of updating it, decide to create a duplicate (or something like that).

It works perfectly fine when installing the module, when the resources doesn't exists on the website. I'm concerned about the future. How will the update process works and how Drupal find out what needs to be updated.

I tried to simulate a module update, to see how I can write an update method and understand how Drupal would update the resources created by the module. I could not even get Drupal to find out the modifications I have done to my YAML file. I'm starting to think the config/install folder simply creates resources on the website, then leave it to the user to manage them. That's not what I had in mind. I wanted a module which is able to create and maintain its own resources (content type and view).

I agree with you that the UUID should be universally unique, but that doesn't mean that's how Drupal is using them. Just open the registry in Windows to see how "not to use" UUID. I was just trying to understand why those UUIDs were there and how Drupal uses them. I'm still unsure what they are used for. Are they only used to prevent someone from exporting / importing config from a website to another website which is not a clone? That feels like an overkill ugly patch. Surely they are there for something more fundamental.

@welly
Copy link

welly commented Mar 5, 2024

@gaellafond

Config included in /config/install is default config. When you import config from a module, a UUID gets generated for that config and the config from the module you installed is never used again unless you uninstall and reinstall the module. At which point, another UUID will be generated.

When you export site config - drush cex - the config that was installed from the module will be exported into your config sync directory with the UUID intact. Default module config doesn't need a UUID to behave correctly and for Drupal to know what needs to be updated because once it's initially installed, the config in /config/install is never looked at again and that module config is handled in the config sync directory.

@DavMorr is correct in saying that module config should never include a UUID. I'd be surprised if the module actually installs correctly if it does.

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