Some Drupal modules have a lot of files. Therefore trying to rename or clone such a module can be unwieldy. This is not limited to Drupal modules either. This is applicable to any package with similar characteristics.

I’ve found that the first step is defining the source and destination properties (path, module name, etc). The second step is to remove any unnecessary files. After that, it is a matter of “search and replace.” Good old find and sed can take care of that for us.

Below is a bash script that does all of the steps sequentially:

#!/usr/bin/env bash

# Define source and dest paths.
SRC='/var/www/html/web/modules/contrib'
DEST='/var/www/html/web/profiles/myprofile/modules'

# Define parent and child modules names.
PARENT='myoldmodule'
PARENT_HUMAN_NAME='My Old Module'
PARENT_CLASS_NAME='MyOldModule'

CHILD='mymodule'
CHILD_HUMAN_NAME='My Module'
CHILD_CLASS_NAME='MyModule'

# Remove the destination if it already exists.
if [ -d "${DEST}/${CHILD}" ]; then
  rm -rf ${DEST}/${CHILD}
fi

# Copy module.
cp -R ${SRC}/${PARENT} ${DEST}/${CHILD}

# Define files or directories to be removed from cloned module.
REMOVE_LIST=('README.txt' 'composer.json')

# Remove unnecessary/deprecated files.
for i in "${REMOVE_LIST[@]}"
do
  printf "Removing ${DEST}/${CHILD}/${i}\n"
  rm -rf ${DEST}/${CHILD}/${i}
done

# Change into new module's directory to avoid collision with module name in path.
cd ${DEST}/${CHILD}

# Rename files.
find . -name "${PARENT}*" | sed -e "p;s/${PARENT}/${CHILD}/" | xargs -n2 mv

# Replace all references to the module's machine name.
find . -type f -exec sed -i "s/${PARENT}/${CHILD}/g" '{}' \;

# Replace all references to the human-readable name.
find . -type f -exec sed -i "s/${PARENT_HUMAN_NAME}/${CHILD_HUMAN_NAME}/g" '{}' \;

# Replace all references to the camel-case version of the module names.
find . -type f -exec sed -i "s/${PARENT_CLASS_NAME}/${CHILD_CLASS_NAME}/g" '{}' \;

A few caveats: the script above works with GNU find and sed. BSD/macOS version behave differently so the script might need to be modified. Also, the find/sed/xargs command might not work if the module’s name is part of the path (nested directories).

Funny story: GNU sed is case-sensitive. If we had wanted it to be case-insentitive, we would have had to add I at the end of the command. This is the opposite effect of putting I in Vim’s search and replace command.

Resources