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? 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 _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal