Drupal Commerce Blog

What's happening in the world of Drupal Commerce.

Converting Your Existing Platform.sh Development Environment to a Makefile

Platform.sh build window: Building as a vanilla project, you are missing out!

One of the most exciting features of Platform.sh is it’s ability to use Drush makefiles to rapidly prototype sites. By default, new projects can start with a makefile that will automatically add Commerce Kickstart or vanilla Drupal. Then, using the makefile, you can add new modules, themes, and libraries, by simply adding a few lines to the makefile and commiting. When you push the changes to your platform, the entire site will be rebuilt. Plus, whenever you’re in “makefile mode” any extra files that are in the root of the respository get pushed into sites/all/default. So if you have any custom modules, you can just stick them in modules/ and they’ll end up in sites/all/default/modules. This can make your code bases not only small, but far more manageable. You can convert a site that isn’t a makefile into a makefile. And in this post, that’s exactly what we’re going to do.

NB: This guide was written assuming that the Platform CLI tool and Drush are installed and that the site to be converted is a single site (not a multi-site) and that it is currently in a Platform.sh environment. Ideally, this entire process would take place in a branch. You can find more information on Platform.sh or start a Platform Project.

Process Outline

  1. Backup your database.
  2. Check for modified modules.
  3. Generate Drush makefile.
  4. Clear out the base files.
  5. Move custom modules and themes.
  6. Migrate the contents of files/.
  7. Commit the changes.
  8. Rebuild the registry.

Backup Your Database

First things first, your database needs to be backed up. The reality is that this process can result in a completely broken site. Since all of the modules are being moved, Drupal won’t know where anything is. Without a backup, you could be completely hosed. To backup your site, just use Drush’s archive-dump feature.

What about disabling modules? Great question! In the past, to move a module you could just disable a module, move it, and then re-enable it. For live sites, it may not be possible to disable each and every module. This is especially true for Commerce modules which will complain if you try to disable them once data has been added. The process outlined here doesn't require that you do that, but if you can disable all of your modules, then give it a go.

Check For Modified Modules

Since the makefile build process will grab pristine copies of modules, any modifications that have been made will be erased. In order to make sure that the site doesn’t break once we convert, it’s imperative that each module be checked for modifications. Luckly, the Hacked! module can save a lot of time here by scanning every module on the site to see if there are changes. While this works great for modules that are downloaded directly from Drupal.org, modules that are pulled in from remote Git repositories won’t work properly. Regardless, this could take the job of checking every module from taking days to hours (or minutes).

For modules that pass, nothing else is required. Modules that do not pass will need some extra TLC. Let’s go through the process now.

Install Hacked!

So, in order for Hacked! to work, it needs to added to your site (there is a patch to run it outside of a working install, though). It doesn’t need to be activated, but it will need to be available. You can install Hacked! by running the following command:

$ drush dl hacked

Once it is downloaded, you need to get a report of the modules that are installed on the site. To generate the report, use this command from the project root directory:

$ drush hlp

You should see output that looks like the following:

Rebuilding Hacked! report
...
Finished processing: Views Slideshow                                    [ok]
Finished processing: Voting API                                         [ok]
Finished processing: Webform                                            [ok]
WD hacked: Could not download project: Spotlight                        [error]
WD hacked: Could not hash remote project: Spotlight                     [error]
WD hacked: Could not hash local project: Spotlight                      [error]
Finished processing: Spotlight                                          [ok]
Done.
 Title             Name             Version         Status     Changed  Deleted 
 Spotlight         spotlight        7.x-1           Unchecked  0        0       
 Pathauto          pathauto         7.x-1.2         Changed    2        0       
 Address Field     addressfield     7.x-1.0-beta5   Unchanged  0        0       
...

The key information here is located in that fourth column labeled Status. Anything that is labled as Unchanged should be good to go with no further work required. However, anything that says Changed or Unchecked requires further digging.

Changed (Hacked!) Modules

It’s not uncommon for someone to be developing a site and come across a bug and for a patch to be applied that resolves said bug. Many people feel okay with using a patch applied to the last recommended (i.e. not -dev, -rc, or -beta) release. What matters is that it does happen. Also, people change stuff. Many times a bug might be fixed by a developer without having looked at the issue queue. At any rate, to find out what has been changed, run the following command (substituting pathauto with any module that showed up as changed):

drush hlp pathauto

The output will be a patch. This patch simply lists the changes between the version you have and the version it says it is (in the module’s .info file).

When you have a changed file, the right thing to do is to find out what is going on and take one of the following next steps:

  1. Identify the patch(es) involved and write them down. When building the makefile, there is a place to add patches that can be applied to each module. So if the patches are already in the issue queue but haven’t been added to the repository, make a list of them so that they can be added to the makefile.
  2. Update the module. If the module is out of date, consider updating the module so that the patches aren’t required anymore. This could require some more testing, but it is cleaner in the long run.
  3. If the patches fix a bug that is in the issue queue and doesn’t have a patch (or doesn’t exist), upload the patch to the issue queue and create the bug report. Use discretion on this one, but if you have the time, upload the patch and then use that uploaded patch in your makefile. Others might be interested in the patch as well!
  4. Lastly, just build a local copy of the patch so you can include it. While not generally recommended, sometimes the only choice is to create a local patch that includes the changes in the module and then putting them in a local patch directory. This is a last resort.

Unchecked or Custom Modules

Modules that listed as Unchecked are be sourced from areas outside of Drupal.org. This includes purchased themes, Github-based projects, or custom modules written for this site. These are special cases and need to be written down for later on in the process.

Generate Drush makefile

Okay, so there should be a list of modules that are stock, patches (if any), and custom modules. With all of that in hand, the next step is to generate a makefile using Drush. What this command does is creates a makefile that records the current version of the modules that are currently on your site along with libraries and then outputs a complete Drush make file. This command will do the job:

drush make-generate

You can copy-and-paste the output or you can pipe it to an external file by adding > project.make at the end of it.

Depending on the number of external libraries in the code base, this could take a little while, but once the library definitions have been defined, those can be kept in a shared list somewhere and pulled in as this process is completed for other sites.

In the output, if there are eternal libraries in the code base, drush make-generate will output blocks that resemble this:

; Please fill the following out. Type may be one of get, git, bzr or svn,
; and url is the url of the download.
libraries[jquery_cycle][download][type] = ""
libraries[jquery_cycle][download][url] = ""
libraries[jquery_cycle][directory_name] = "jquery_cycle"
libraries[jquery_cycle][type] = "library"

These blocks will need to be updated to link to their proper destination. Usually this means adding the URL to the downloadable version of the library. For instance, the block above (at time of writing) becomes this:

libraries[jquery.cycle][download][type] = "file"
libraries[jquery.cycle][download][url] = "http://malsup.github.io/jquery.cycle.all.js"

The final result will resemble the following and should be placed into the project as project.make:

; This file was auto-generated by drush make
core = 7.x

api = 2
projects[drupal][version] = "7.28"

; Modules
projects[views_bulk_operations][version] = "3.2"
projects[addressfield][version] = "1.0-beta5"
projects[admin_menu][version] = "3.0-rc4"
...
libraries[jquery.cycle][download][type] = "file"
libraries[jquery.cycle][download][url] = "http://malsup.github.io/jquery.cycle.all.js"
...

Once you’ve added updated all of the libraries or items that require user input and removed modules and themes that are custom, save it and add it to the project repository.

Clear Out the Repository

So now that a makefile has been added, the repository can be cleaned out. To start, remove all of the core Drupal files and directories. You can run the following command to remove all of the root Drupal

rm -r authorize.php CHANGELOG.txt COPYRIGHT.txt cron.php includes index.php INSTALL.mysql.txt INSTALL.pgsql.txt install.php INSTALL.sqlite.txt INSTALL.txt LICENSE.txt MAINTAINERS.txt misc modules profiles README.txt robots.txt scripts themes update.php UPGRADE.txt web.config xmlrpc.php

Once this is done, the only directory remaining to should be sites/. Now, with the list of modules that was generated earlier, the ones that were unchanged can be removed from the sites/all/modules/ or sites/default/modules/. While in these directories, make sure to remove any libraries as well. Optionally, the libraries could be removed from the makefile and instead the libraries/ directory could be kept in the repository. But it’s cleaner just to leave them in the makefile. The whole goal here is simply to get rid of everything out of the repository that’s included in the makefile.

Move Custom Modules and Themes

At the end of the purging process, all that should remain are the custom/non-drupal.org modules, usually inside of sites/default/modules/ and sites/default/themes/. If that is the case, then all that is needed now is to move the modules/ and themes/ directory to the root of the repository. Whenever a project makefile is being built, the contents of repository root (minus the make files) are put into sites/default/. This includes a settings.local.php file which can include site specific settings.php changes.

The repository should now look something like this:

project.make
sites/
modules/
themes/

Migrating files/

Whenever a platform build is done, the code gets mounted on the PHP container in a read-only state. But the files are managed in a separate partition. To migrate them over, your best bet is to rsync them over. This will likely have already been done during the import of the project initially, but in case it hasn’t been done yet, you can find out more information in Platform.sh’s site migration documentation.

Once the files/ directory is empty, remove the sites/ directory from the repository root and go to the next step.

Try the Build and Commit the Site

At this point, the build can be attempt and initial kinks (if any) worked out. To do a build, use the following command from the repository root:

platform build

Once this command finishes, the output will contain the result of the build. If there are errors, those should be fixed. Make sure that libraries are linked properly and that any changes that were made manually use the proper makefile syntax.

If the build was successful, the the end result will be a complete drupal site in the www/ directory in the parent directory of the repository. Refreshing the site in a local development environment will likely fail with a white-screen and drush commands will also likely fail. Never fear, there is still a single step remaining.

Rebuild Drupal’s Registry

Drupal 7 uses something called a code registry here’s a brief description (emphasis added):

Drupal 7 introduces a code registry - an inventory of all classes and interfaces for all enabled modules and Drupal’s core files. The registry stores the path to the file a given class or interface is defined in, and loads the file when necessary.

The makefile build process guarantees to most (if not all) of the site modules to a different place. While it is possible for this process to break a site, more than likely the registry will need to be rebuilt so that Drupal knows where to find all of the files that have been moved.

To do this, the Registry Rebuild module accomplish this task. The module page has instructions on how to use it, but to make the process work on Platform, the following should suffice.

$ drush @<platform>.<branch> ssh
   ___ _      _    __ 
  | _ \ |__ _| |_ / _|___ _ _ _ __ 
  |  _/ / _` |  _|  _/ _ \ '_| '  \
  |_| |_\__,_|\__|_| \___/_| |_|_|_|

 Welcome to Platform.

 This is environment <branch>
 of project <project>.

web@<project>-<branch>--php:~/public$ cd ../tmp
web@<project>-<branch>--php:~/tmp$ drush dl registry_rebuild
web@<project>-<branch>--php:~/tmp$ cd ../public
web@<project>-<branch>--php:~/tmp$ php ../tmp/registry_rebuild/registry_rebuild.php
And now the registry should be rebuilt. Next, make sure you clear caches: drush cc all. Now refresh the site. If it's a simple site, the process should be done. But for more complex sites, further tweaking for modules like AES or other modules that store things outside of the code base (like keys or secrets files) might need to be manually put into the
~/private/
directory on the Platform.sh environment. Those modules will also likely need to have their configuration updated as well.

Wrap Up

Now your site should be in makefile format and you can enjoy quickly adding and updating modules along with the super maintainability that comes with this project workflow.
Nicholas Vahalik
Posted: Jul 21, 2014