[fpc-pascal] Is there some example of an FPC program for use in svn hook calls (email)?
Bo Berglund
bo.berglund at gmail.com
Thu Dec 14 18:02:49 CET 2017
On Thu, 14 Dec 2017 10:26:22 +0000, Mark Morgan Lloyd
<markMLl.fpc-pascal at telemetry.co.uk> wrote:
>On 14/12/17 10:00, Adriaan van Os wrote:
>> Bo Berglund wrote:
>>> Now I am looking at the same problem for svn and this time I need it>
>>> to be cross-platform, hence using FPC.> Before I start on it myself I
>>> wonder if someone here has already> written such a program for svn and
>>> if so, if it is available as open> source?
>> I use sendmail <https://en.wikipedia.org/wiki/Sendmail> from FPC, using
>> AssignStream, fpgeterrno and PClose. Haven't tried that on Windows though.
>
>With the caveat that while Sendmail is a well-respected MTA, many unix
>systems also provide a sendmail command as a generic mailer. On Windows
>Blat is an alternative.
But *sending email* is not the problem, I have done this in many
applications using Indy TIdSMTP. Instead it is getting data out oof
svn and formatting these in a friendly looking email to be sent....
Anyway I started on my own svn data collector and got stuck in a very
basic function...
I used the information in the wiki page below on how to execute a
command line program and retrieving its output data for processing.
Look at the section towards the bottom with subject "Reading large
output":
http://wiki.freepascal.org/Executing_External_Programs
To get the subversion commit data one has to use svnlook, which is a
command line program so I need to do this.
But when I use this approach I get no data at all, what could have
gone wrong here?
When I reach the end of the repeat loop there is no data at all to
process, i = 0!
But when I run the command on the command line manually I do get svn
data back.
So what did I do wrong when I used the wiki solution?
var
//Command line parameters are:
REPOS_PATH, //Full path to repository
REV, //Revision number
TXN_NAME: string; //Transaction name
DataBuf,
Parms: TStringList;
svncmd: string;
SCD: TSvnCommitData;
function GetSvnData(Command: string; Parameters: TStringList; var
SvnData: TStringList): boolean;
{Command is the full path to the executable to run (<path>\svnlook.exe
or <path>/svnlook
Parameters contain the command line parameters. A typical parameter
set could be
info
-r
2121
<repository path on server>
The result from the command will be stored into the SvnData
stringlist
}
const
BUF_SIZE = 2048; // Buffer size for reading the output in chunks
var
AProcess : TProcess;
OutputStream : TStream;
BytesRead : longint;
i: integer;
Buffer : array[1..BUF_SIZE] of byte;
begin
Result := false;
// Set up the process
AProcess := TProcess.Create(nil);
// Create a stream object to store the generated output in.
OutputStream := TMemoryStream.Create;
//Create the data buffer
try
AProcess.Executable := Command;
// Process option poUsePipes has to be used so the output can be
captured.
AProcess.Options := [poUsePipes];
for i := 0 to Parameters.Count -1 do
AProcess.Parameters.Add(Parameters[i]);
i := 0;
// Start the process (run the command)
AProcess.Execute;
// All generated output from AProcess is read in a loop until no
more data is available
repeat
// Get the new data from the process to a maximum of the buffer
size that was allocated.
// Note that all read(...) calls will block except for the last
one, which returns 0 (zero).
BytesRead := AProcess.Output.Read(Buffer, BUF_SIZE);
// Add the bytes that were read to the stream for later usage
OutputStream.Write(Buffer, BytesRead);
Inc(i, BytesRead);
until BytesRead = 0; // Stop if no more data is available
OutputStream.Position := 0; // Required to make sure all data is
copied from the start
SvnData.LoadFromStream(OutputStream);
Result := (i > 0); //(SvnData.Count > 0);
finally
OutputStream.Free;;
AProcess.Free;
end;
end;
begin
//Check for the call parameters:
if ParamCount() < 3 then
begin
Writeln('Call parameters missing!');
exit;
end;
REPOS_PATH := ParamStr(1);
REV := ParamStr(2);
TXN_NAME := ParamStr(3);
Parms := TStringList.Create;
DataBuf := TStringList.Create;
SCD := TSvnCommitData.Create;
try
// The commands for Windows and *nix are different hence the
$IFDEFs
{$IFDEF Windows}
svncmd := 'C:\Programs\Subversion\svnlook.exe';
{$ENDIF Windows}
{$IFDEF Unix}
svncmd := '/usr/bin/svnlook';
{$ENDIF Unix}
//Build the call for svnlook
{1. Get the starting information on the operation
svnlook info -r <REV> <REPOS_PATH>
}
Parms.Add('info');
Parms.Add('-r');
Parms.Add('REV');
Parms.Add('REPOS_PATH');
if GetSvnData(svncmd, Parms, DataBuf) then
begin
SCD.UserName := DataBuf[0];
SCD.CommitTime := DataBuf[1];
SCD.Logmessage := DataBuf[3];
end;
finally
SCD.Free;
DataBuf.Free;
end;
end.
--
Bo Berglund
Developer in Sweden
More information about the fpc-pascal
mailing list