Perl best practices for ElectricCommander

Written by: Electric Bee
4 min read

Perl Header

I spent a lot of my working hours writing steps for ElectricCommander, either for my own projects or for the Professional Services I deliver to our customers. I usually do my code writing in Perl because

  1. I’m very familiar with the language (too long to count)

  2. There is a nice and quick API to access ElectricCommander

  3. It’s somewhat platform independent

It means my scripts start with the following lines 95 of the time:

use strict;
use ElectricCommander;
use Data::Dumper;
$| = 1;

# Create a single instance of the Perl access to ElectricCommander
my $ec = new ElectricCommander({'format' => "json"});

I don’t know about you but I’m not that great of a typist so copy/paste is a great option. The problem is that you have to remember where is your last script, then open a new TAB in your browser, open the right project/procedure/step. Also as my header and library were starting to evolve, I found it difficult to maintain them; both for issues and improvements. It’s when I decided to copy all that code in a unique place and use the awesome property substitution mechanism in ElectricCommander. I know! I may be a little biased! So now I have a property named “perlHeaderJSON” in my EC-Admin project , and my first line in all my Perl steps is simply:

$

or (if I’m working in a different project):

$

Of course you could create it as a server property but I wanted something self-contained as I release EC-Admin to GitHub for customers to consume. The same mechanism could be applied for shell scripts as the substitution mechanism happens just before runtime.

InvokeCommander(): a use case for Perl headers

The other things I use a lot are call to the ElectricCommander API. I came across some code in the EC-Utilities project call InvokeCommander. It’s a generic function that will call any API function with unlimited arguments. It then helps you manage error, display raw content, … So my API calls now look like:

($success, $json, $errMsg, $errCode)
           = InvokeCommander("SuppressLog", "getProperties",
{
'projectName'   => $pName,
'procedureName' => $procName,
'stepName'      => $stepName});

The first argument is a string that allows you do display or not the raw result returned (“SuppressLog”). You can also specify “IgnoreError” to prevent Commander to throw an error and to simply return cleanly. The second argument is the API call itself. The third (and subsequent) is(are) the argument(s) of the API call. Follow the same rules that you would if you were to call the API directly and pass arguments in the same order with the same type It returns a Boolean indicating success or not, the JSON data structure (I’ve an equivalent one for XML) and possibly the full error message and error code. As for my header I put this code in a property $ to improve maintenance and reuse. A sample code to extract a list of projects would look like:

$
$
my ($success, $result, $errMsg, $errCode) =
InvokeCommander("SuppressLog IgnoreError",
"getProjects");

if (! $success) {
printf("Cannot get the list of projectsn");
printf("Error: sn", $errMsg);
exit(1);
foreach my $node ($result->findnodes('//project')) {
my $pName=$node=>{'projectName'};
my $pluginName=$node=>{'pluginName'};
# skip plugins 
next if ($pluginName ne "");
printf("Project: sn", $pName);
}

Pretty clean don’t you think! If you were to remove the “SuppressLog” option, the log of the script would show something the raw content of the JSON request. It looks like (edited for format and length)

Return data from Commander:
$VAR1 = bless( {
'responses' => 
    }
 ]
}, 'ElectricCommander::ResponseHandler::JSON' );

When I write new code, my first run is usually without the “SuppressLog” so I get a better sense of the data with which I have to work.

Conclusion

I tried to show you how to use the power of the ElectricCommander properties to mimic a library mechanism and help improve your “implement once, reuse many”. I hope you found that useful. All those examples and more (like an XML version) can be found on our GitHub Commander repository at https://github.com/electriccommunity/electriccommander/tree/controller/EC-Admin . Give it a try and let me know what you think by leaving a comment below or contacting us directly by email . This is an ongoing project and in following posts, I will show you how I’ve built on top of this main function.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.