Saturday, December 6, 2008

By Moradin's Hammer!

We're just now getting around to formalizing our builds using a standard based around Module::Build.  Our subclass is named Moradin, keeping with our "tradition" of using D&D deities.  Basically, we've implemented support for the following on top of the regular Module::Build functionality:

  • Downloading and installing other custom modules from their distribution source in our local SVN repository
  • Auto-installing other required modules from CPAN based on local CPAN config for the project
  • Building a directory tree structure which is different from that of a regular perl module, including adding empty folders necessary for app functionality, creating symlinks, and copying build files to arbitrary destinations.
  • Applying an appropriate (as determined at build time) 'use lib' line to installed executables (such as .cgi scripts)
  • Arbitrary string replacement inside source files
  • Applying permissions based on matching rules
  • Applying SELinux security context

We also hope to implement additional features such as:

  • Database structure setup/update/rollback (in conjunction with appropriate database update files with our source revisions)
  • Generated source files for CSS management
  • Support for build automation (which we haven't really gotten to, yet)

Danny and I had a minor disagreement about implementation; we are supplying a minimal build script example with the module, and I was about to put code which prompted for required data in that script.  Danny objected strongly to this saying it was wrong, but we had a difficult back-and-forth as to why I shouldn't do that apart from propriety.  After some reflection, I realize there are a couple of very good reasons to do it "his" way (one of which he brought up at the time but I dismissed), by putting that logic in the module:

  • Makes it so the user can't inadvertently remove functionality that needs to be present.
  • The build script should only require the user to supply data.  If the user wishes to write some code to get that data, that's fine.  But the key is that we separate the module's logic from the data on which it operates.

Anyway, I just thought I'd put that out there.  Still have some fun to go.  In addition to implementing the above, I'm having trouble figuring out how to complete the unit tests in a comprehensive way.  In particular the automated module install bits.

After all, am I supposed to install a CPAN module to test that functionality?  And then remove it again?  Should I stat every file when testing permission setting to make sure those permissions are set properly?  Is there a tool that can do it for me?  And maybe most significantly, is there a way I can actually unit test that functionality without doing a complete test installation for each test?

When we figure out how to proceed, I'll post the plan.