Posted on Leave a comment

Remote deployment script for Magento extensions using modman and rsync

Magento Logo

In order to have an efficient way of deploying Magento extensions to (remote) Magento setups I’ve created a simple deployment script based on modman and rsync.

How it works

This script copies your Magento extension to the .modman directory of your destination Magento project and deploys it there using modman. In addition, it exludes files and folders (such as .git) so that only relevant files are copied. This script uses rsync to copy files to your (remote) Magento project.

For example:

  1. Let’s say you develop a Magento extension in /home/my_user/workspace/MyExtension
  2. Your development Magento setup is located at /var/www/magento-dev1/
  3. This script copies your Magento extension from /home/my_user/workspace/MyExtension to /var/www/magento-dev1/.modman/ and automatically deploys it using modman.

Benefits

Although you could do the copying alone using the modman configuration file modman does not offer the possibility to exclude certain files for the deployment process. In addition, this script uses rsync, thus giving you the possibility to remotely deploy your Magento extension.

Download script

Feel free to grab the script from Github. Also, in case you have suggestions for improvements don’t hesitate to drop a comment below.

Posted on 2 Comments

Determine last day of month using Bash script

Oftentimes software systems need to carry out tasks on a regular basis at a given time, such as archiving log files or sending out newsletters. Normally cron is able to handle all kinds of time-based setups (daily, monthly, etc.) but what if you want to execute tasks on the last day of each month?

A simple bash script does the trick:

#!/bin/bash

TODAY=`/bin/date +%d`
TOMORROW=`/bin/date +%d -d "1 day"`

if [ $TOMORROW -lt $TODAY ]; then
   exit 0
fi

exit 1

So, as you can see we need to simply check if the next day is “less” than today. All you need to do is to call this script at the required time each day and it will check if it’s the last day of the current month, like so:

59 23 * * * isLastDayOfMonth.sh && yourJob.sh

Thats’s it.

Posted on Leave a comment

Generating optimized JavaScript Source Code using Dojo’s Build System

The Dojo Toolkit represents one of the most powerful and feature-rich JavaScript libraries to-date. Apart from its core functionality such as DOM manipulation (i.e. Dojo namespace) it provides developers with a vast range of widgets (Dijits, i.e. Dojo Widgets), lots of incubator code (DojoX) and numerous Utils classes. (More info can be found here: E-Learning Standards – Critical and Practical Perspectives.)

When writing more complex client side applications you will soon realize that the overall loading time increases by a factor that significantly reduces the usability and responsiveness. Thus, it would be nice to have a build script that compresses relevant JavaScript source files into optimized code that you then can include in your frontend HTML files. Additionally, you will most definitely want to be able to create different releases of your code in a simple yet consistent way. That’s were Dojo’s build system comes in handy!

Dojo Build Layer System

Before explaining the bits and pieces needed for this build script you need to understand Dojo’s build layer system. Each layer represents a list of files that should be put together to produce a compressed and optimized version, much like a C include header file. Below you find an examplary layer file for a Login module:

dojo.provide("layerLogin.js");

dojo.require("dojo.i18n");
dojo.require("custom.Login");

Line 1 declares the layer file and must match the actual file name. Following the first line are all files included in this layer. For instance, dojo.i18n represents Dojo’s internationalization (i18n) functionality and is required by this layer. Furthermore, custom.Login on Line 3 represents a file named Login.js that resides in the custom namespace and contains the Login module’s core code:

/js/custom/Login.js

The source of Login.js:

dojo.require('dijit.form.Form');
dojo.require('dijit.form.Button');
dojo.require('dijit.form.TextBox');

dojo.provide('custom.Login');
dojo.declare('custom.Login', null, {

    /**
     * Default constructor
     */
    constructor: function() {
        this.init();
    },

    /**
     * Initializes Login module.
     */
    init : function() {
        dijit.byId('loginUser').focus();
    }
});

As you can see Login represents a Dojo “class”. Although you can use plain JavaScript code in any of the included layer files Dojo classes provide you with the power of encapsulating module specific code (as you are used to when writing object oriented code). You can find more information on Dojo’s classes here: Classy JavaScript with dojo.declare

Build Layer Profile

As you might have guessed correctly we could have multiple layer files in our Dojo based application. That’s why it is good to think of layer files as modules. Consequently, the next step would be to combine all modules into a configuration profile that Dojo then can use to compress into one optimized JavaScript file. Let’s have a look at an example profile file:

dependencies = {
    layers: [
    {
        // one of the stock layers. It builds a "roll up" for
        // dijit.dijit which includes most of the infrastructure needed to
        // build widgets in a single file. We explicitly ignore the string
        // stuff via the previous exclude layer.
        name: "../dijit/dijit.js",
        // what the module's name will be, i.e., what gets generated
        // for dojo.provide(<name here>);
        resourceName: "dijit.dijit",
        // modules *not* to include code for
        layerDependencies: ["string.discard"],
        // modules to use as the "source" for this layer
        dependencies: ["dijit.dijit"]
    },
    {
        name: "../custom/layerLogin.js",
        dependencies: ["custom.layerLogin"],
        copyrightFile: "../../../../COPYRIGHT"
    },
    {
        name: "../custom/layerMain.js",
        dependencies: ["custom.layerMain"],
        copyrightFile: "../../../../COPYRIGHT"
    }],
    prefixes: [
    ["dijit", "../dijit"],
    ["dojox", "../dojox"],
    // include COPYRIGHT
    ["custom", "../custom", "../../../../COPYRIGHT"]
    ]
}

The dependencies variable at the beginning is a JSON object holding all required layers of this profile. Additionally, it defines the core files (stock layers) needed to run Dojo afterwards.

The Build Script

Now that you have an overview of the structure of a Dojo build profile let’s have a look at the actual build script. Below you find a bash script that incorporates all required steps for generating optimized JavaScript source code based on a custom build profile using Dojo’s build layer:

#!/bin/sh
#
# Script for deploying the "release" version of the currently set JS layers via the profile file.
# It will create (or overwrite) the release folder in the JS_LIB/custom/ directory,
# i.e. JS_LIB/custom/release/RELEASE_VERSION
#
# @author Matthias Kerstner <matthias@kerstner.at>
#
 
#profile file should reside inside current directory
PROFILE_FILE=custom.profile.js
 
CWD="$(cygpath -aw $(pwd))"
#UNIX: $(pwd)
 
#(absolute) path to PHP, or simply 'php' if it is in the PATH
PHP_PATH="/cygdrive/c/xampp/php/php.exe"
#UNIX: "/opt/lampp/bin/php"
 
#release number should be read from config/base.php
PHP_REQUIRE="require('$(cygpath -aw $(pwd)/../src/config/base.php)')"
#UNIX: "require('$(pwd)/../src/config/base.php');"
 
#get release version from config file
RELEASE_VERSION=`$PHP_PATH -r "$PHP_REQUIRE; echo MY_VERSION;"`
 
#determine release path
RELEASE_PATH="$(cygpath -aw $(pwd)/../src/web/js/release/)"
#UNIX: $(pwd)/../src/web/js/release/
 
# remove any previous releases
if [ -d $RELEASE_PATH ]; then
  echo "removing existing releases..."
  rm -r $RELEASE_PATH
fi
 
# create release directory again
mkdir $RELEASE_PATH
 
# path to dojo buildscript
DOJO_BUILDSCRIPT_PATH=$(pwd)/../src/web/js/util/buildscripts/
 
echo switching to buildscript path $DOJO_BUILDSCRIPT_PATH
 
#change to buildscripts folder as required by dojo's build.sh
cd $DOJO_BUILDSCRIPT_PATH
 
#call dojo's build script with profile specified above
#UNIX: build.sh
#WINDOWS: build.bat
exec ./build.bat profileFile=../../profile/"$PROFILE_FILE" \
action=release cssOptimize=comments optimize=shrinkSafe releaseName=$RELEASE_VERSION
 
#change to lib/js folder
cd $(cygpath -aw $(pwd)/../../)
#UNIX: $(pwd)/../../

This script basically does the following:

  1. Defines which profile file to use (line 11)
  2. Determines the current working directory (line 13)
  3. Sets path to PHP executable to read release version from base.php (line 17, 21 and 25)
  4. Sets release path based on release version (line 28)
  5. Removes any previous releases and creates release folder (line 32)
  6. Sets path to the build script (line 41)
  7. Executes build script from within its folder (line 51)
  8. Changes back to lib/js folder (line 55)

In order for this script to run your project needs to have a certain folder structure. I have created a reference setup which you can download from GitHub: Dojo Build Script.

Note: The script should be executed from within the scripts folder. Don’t panic if the scripts runs for a while, there are plenty of files that need to be processed during the building process. After all, you get a highly compressed layer file afterwards, right?

Feel free to customize the script to your needs 🙂