#!/usr/local/bin/perl
use strict;
use warnings;
use LWP;
use Getopt::Long;
### TODO
# XML Parsing instead of regexes
my $USERNAME;
my $PASSWORD;
my $VERBOSE;
my $REMOTEFILE;
my $LOCALFILE;
my $MESSAGE;
GetOptions(
"username=s" => \$USERNAME,
"password=s" => \$PASSWORD,
"verbose|v" => \$VERBOSE,
"remotefile=s" => \$REMOTEFILE,
"localfile=s" => \$LOCALFILE,
"message|m=s" => \$MESSAGE,
);
&useage if ((!$USERNAME) or (!$PASSWORD) or (!$REMOTEFILE) or (!$LOCALFILE) or (!$MESSAGE));
if(!-f $LOCALFILE) {
print "$LOCALFILE is not a valid localfile!\n";
exit;
}
{
package SubversionClient;
our @ISA = qw(LWP::UserAgent);
sub get_basic_credentials {
return $USERNAME, $PASSWORD;
}
}
my $ua = SubversionClient->new;
$ua->agent("deltavputfile 0.1");
my $UUID = $^T . "." . $$;
$REMOTEFILE =~ m|(http.?//.*?)(/.*)/([^/]+)$|;
my $servername = $1;
my $directory = $2;
my $file = "/$3";
#OPTIONS
my $options_pass_in = qq||;
my $options = DeltaV(type => "OPTIONS", url => $servername . $directory, xml => $options_pass_in, ec => 200);
$options->content =~ m|([^<]+?)|;
my $actset = $1;
$actset =~ m|([^!]+)!|;
my $repo = $1;
#MKACTIVITY
my $mkactivity = DeltaV(type => "MKACTIVITY", url => $servername . $actset . $UUID, ec => 201);
#PROPFIND
my $vcc = propfind(
xml => qq||,
url => $servername . $directory,
ec => 207,
re => qr|([^<]+?)|,
);
#PROPFIND
my $checkedin = propfind(
url => $servername . $vcc,
ec => 207,
re => qr|([^<]+?)|,
);
#CHECKOUT
my $checkout_xml_in = qq|$servername$actset$UUID|;
my $checkout = DeltaV(type => "CHECKOUT", url => $servername . $checkedin, xml => $checkout_xml_in, ec => 201);
$checkout->content =~ m|
Checked-out resource (.+?) has been created\.
|;
my $activityset = $1;
#PROPPATCH
my $message_xml_format = <
$MESSAGE
END
my $proppatch = DeltaV(type => "PROPPATCH", url => $servername . $activityset, xml => $message_xml_format, ec => 207);
my $proppatch_xml = $proppatch->content; # do we do anything with this?
#PROPFIND
my $checkedinb = propfind(
xml => qq||,
url => $servername . $directory,
ec => 207,
re => qr|([^<]+?)|,
);
#CHECKOUT
my $checkout_xml_ina = qq|$servername$actset$UUID|;
my $checkouta = DeltaV(type => "CHECKOUT", url => $servername . $checkedinb . $file, xml => $checkout_xml_ina, ec => 201);
$checkouta->content =~ m|Checked-out resource (.+?) has been created\.
|;
my $workingfile = $1;
#PUT
open(FILE, "<$LOCALFILE") or die "Can't open $LOCALFILE for reading: $!\n";
my $filecontent = join("", );
close(FILE);
my $put = DeltaV(type => "PUT", url => $servername . $workingfile, xml => $filecontent, ec => 204);
#MERGE
my $merge_xml = qq|$servername$actset$UUID|;
my $merge = DeltaV(type => "MERGE", url => $servername . $directory, xml => $merge_xml, ec => 200);
#DELETE
my $delete = DeltaV(type => "DELETE", url => $servername . $actset. $UUID, ec => 204);
sub propfind {
my %opts = @_;
my $xml = $opts{xml} || "";
my $url = $opts{url};
my $ec = $opts{ec};
my $re = $opts{re};
my $propfind = DeltaV(type => "PROPFIND", url => $url, xml => $xml, ec => $ec, depth => 0);
$propfind->content =~ m/$re/;
my $returnvar = $1;
return $returnvar;
}
sub DeltaV {
my %opts = @_;
my $type = $opts{type};
my $url = $opts{url};
my $xml = $opts{xml};
my $ec = $opts{ec};
my $depth = $opts{depth};
my $dv = HTTP::Request->new($type => $url);
$dv->authorization_basic(SubversionClient->get_basic_credentials);
$dv->content($xml) if ($xml);
$dv->header(depth => $depth) if (defined($depth));
my $dv_response = $ua->request($dv);
if (($VERBOSE) or ($dv_response->code != $ec)) {
print "#SENT###########################################################################\n";
print $dv->as_string, "\n";
print "#GOT############################################################################\n";
print $dv_response->as_string(), "\n";
print "################################################################################\n";
}
if ($dv_response->code != $ec) {
die "Error";
}
return $dv_response;
}
sub useage {
print <
--password
--message
--remotefile (http://server/path/to/file.txt)
--localfile
END
exit;
}