Skip to content

Instantly share code, notes, and snippets.

@m0rjc
Last active December 21, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m0rjc/6317290 to your computer and use it in GitHub Desktop.
Save m0rjc/6317290 to your computer and use it in GitHub Desktop.
Quick and dirty Perl script to deploy work in progress to Salesforce based on GIT status. This saves me a lot of time by allowing incremental compilation. Relies on my company's project layout which has two source roots - "source" and "systemtests". There is a directory called bin in which there is an ant script that provides access to the Sales…
#!/usr/bin/perl
#
# Deploy files I'm working on to Salesforce based on the GIT status.
#
# Assumptions:
# Two source roots - source and systemtests. These are normal Salesforce source roots with src/classes...
# bin/build.xml ant script with target dev.deploy called as
# ant dev.deploy -Dsf.deployRoot=<stagingdir>
#
use strict;
use POSIX;
use File::Copy;
use Cwd;
# Scan for the GIT root
my $lastdir = getcwd();
while(not -e '.git'){
chdir '..' or die 'Cannot find GIT root (error changing directory)';
my $newdir = getcwd();
die 'Cannot find GOT root (out of directories to search)' if $newdir eq $lastdir;
$lastdir = $newdir;
}
print "Changed to directory $lastdir\n";
my $staging = tmpnam();
print "Staging directory: $staging\n";
mkdir $staging;
mkdir "$staging/classes";
mkdir "$staging/labels";
my %files = ();
scanGitAndBuildStaging();
buildPackageXml();
runDeploy($staging);
#-------------------------------------------------------------------------------
# Scan GIT and build up the staging area.
# TODO: Separate into two parts so we can scan things other than GIT.
#-------------------------------------------------------------------------------
sub scanGitAndBuildStaging{
print "-------------------------------------------------------------------------------\n";
open (GITOUT, 'git status --porcelain -uno |') or die 'Unable to call GIT';
$~ = "SCANREPORT";
while (<GITOUT>) {
if(/^(A|M|AM|MM|R.\s+.+->)\s+((source|systemtests)\/src\/(classes|labels)\/(.+)\.(cls|labels))$/){
my $status = $1;
my $fullname = $2;
my $package = $3;
my $type = $4;
my $name = $5;
format SCANREPORT =
@<< @<<<<<<<<<<<< @<<<<<<<<<<<<< @*
$status, $package, $type, $name
.
write;
if ($type eq 'classes'){
registerPackageContent('ApexClass', $name);
copy($fullname,"$staging/classes/") or die "Cannot copy $fullname to $staging/classes";
copy("$fullname-meta.xml","$staging/classes/") or die "Cannot copy $fullname-meta.xml to $staging/classes";
} elsif ($type eq 'labels'){
registerPackageContent('CustomLabel', '*'); # We have to register * as the individual labels are mentioned in the file!!
copy($fullname,"$staging/labels/") or die "Cannot copy $fullname to $staging/labels";
}
}
}
close(GITOUT);
print "-------------------------------------------------------------------------------\n";
}
#-------------------------------------------------------------------------------
# Build Package.xml
#-------------------------------------------------------------------------------
sub buildPackageXml
{
open my $PACKAGEXML, ">>$staging/package.xml";
print $PACKAGEXML <<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
EOF
foreach my $type (keys %files){
my $members = $files{$type};
if (scalar @{$members} > 0) {
writeNamesToPackage($PACKAGEXML, $type, $members);
}
}
print $PACKAGEXML <<EOF;
<version>24.0</version>
</Package>
EOF
}
sub writeNamesToPackage
{
my $FILE = shift;
my $type = shift;
my $names = shift;
print $FILE " <types>\n";
foreach my $member (@{$names}) {
print $FILE " <members>$member</members>\n";
}
print $FILE " <name>$type</name>\n";
print $FILE " </types>\n";
}
sub registerPackageContent
{
my $type = shift;
my $name = shift;
if (not defined $files{$type}){
$files{$type} = [];
}
push($files{$type}, $name);
}
#-------------------------------------------------------------------------------
# Call Deploy
#-------------------------------------------------------------------------------
sub runDeploy
{
my $staging = shift;
chdir 'bin';
print "Deploying from $staging\n\n";
exec('ant','dev.deploy',"-Dsf.deployRoot=$staging");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment