On 12/14/2017 12:02 PM, Bo Berglund wrote:
On Thu, 14 Dec 2017 10:26:22 +0000, Mark Morgan Lloyd
<markmll.fpc-pas...@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?

I recently used the same code, so I tried to execute your code (below). I'd suggest adding the two lines (shown below) to troubleshoot. I didn't execute svnlook but ppcx64 with parameter -h and that works okay with your code.


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);

// I'd suggest adding these two lines to troubleshoot:
    writeln(SvnData.Text);
    writeln('Number of bytes = ', i);

   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.




_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to