Over the course of a number of recent development phases in different software projects, I’ve been working to simplify installation and dependency management, while leaving room for the sort of experimentation required in research projects (indeed, many software projects?)
Way back in November 2013, I was working for Gill Clough on the Tricky Topic tool, for the JuxtaLearn European funded project. Initial work for the tool was done by Martin Hawksey, and built on WordPress. When I took over, I decided to use Git submodules to manage the dependencies on WordPress, third-party plugins, and custom plugins being developed for the project.
You can see what this looks like on GitHub in the first screen-shot …
Some potential benefits to note about Git submodules – you can see the dependencies, and their Git SHA-1 sums directly in GitHub, as the above screen shot shows. However, as anyone who has tried submodules tends to realise, their are a number of drawbacks.
There are alternatives, built to work fairly closely with Git. However, these would all require evaluation, and would probably prove difficult to support in our small, busy team. So, after some experimentation, I concluded it was safer to adopt the de facto standard dependency-manager for PHP, Composer, in my next project. This was the LACE Evidence Hub, for Rebecca Ferguson and Doug Clow.
The LACE Evidence Hub was also built on WordPress, and grew in part out of the work on the OER Research Hub. Discoveries that helped me decide on Composer were this 2013 post, and the WordPress Packagist repository.
A requirement that became apparent, during the work for LACE, and later
Open Media Player, was the ability to enable (and disable), optional packages
composer.json manifest. The
composer.json schema allows for the inclusion of
suggestions, however by default, these are merely displayed to the developer –
they aren’t used by Composer.
The modified use of Composer suggestions involves JSON containing a
package name on the left (eg.
wpackagist-plugin/wp-postratings), and on the right
a string that starts with a precise version constraint and a semi-colon (
followed by free text that can optionally contain tags (eg.
Here’s a short JSON example:
Here is a longer example:
"wordpress/wordpress": "4.3; WP-4.3.x",
"wordpress/wordpress": "4.3.1; WP-4.3.1 / LAC-E only for now!",
"wpackagist-plugin/facetious": "1.1.4; wp-facet [LAC-E] & [OERR-H] projects",
"cftp/facetious": "dev-master; cftp-facet-1.2 [LAC-E] project",
"wpackagist-plugin/wp-postratings": "1.82; postratings [LACE] & [OERRH]"
Some points worth noting:
- The package
../google-universal-analyticsis always required;
- Their are two optional WordPress versions, which can override the default version (4.1);
- Almost all the
suggestionsuse a precise version constraint – this is safer!
composer.jsonvalidates – if the
composer-suggestplugin is not used Composer falls back to its default behaviour.
After earlier false starts, the keywords mentioned above are used in a
which is loaded via phpdotenv. The
NF_COMPOSER_SUGGEST environment variable
can either contain a single keyword, eg.
LACE, or a
A simple example of a single keyword in the
And, a more complex example of a regular expression in the
.env file – all suggestions containing the pipe-separated keywords will be installed:
Referring back, you can see that the
WP-4.3.1 in the regular expression, equates
to line 12 of the
composer.json example above.
The only potential drawbacks to the use of
- You probably can’t commit the
composer.lockfile to your code repository;
- You need to specify quite tight version constraints to reduce the effect of the point 1.
In conclusion, the
composer-suggest plugin provides a light-weight,
simple to use method to enable and disable optional packages to fine-tune your Composer-based project.
In the case of LACE, this enables us to try third-party WordPress plugins on the test server, and then deploy them to the live server at our leisure all with the same code base. In Open Media Player, it enables us to present a core of requirements, and then a simple means to allow some options, for example adding more oEmbed providers.
All this within a conventional Composer-based workflow.