diff --git a/components/svn/svnclasses.pas b/components/svn/svnclasses.pas index d950494de..1800d6181 100644 --- a/components/svn/svnclasses.pas +++ b/components/svn/svnclasses.pas @@ -6,11 +6,23 @@ interface uses Classes, SysUtils, + contnrs, DOM, XMLRead; type TEntryKind = (ekUnknown, ekFile, ekDirectory); + TCommitAction = (caUnknown, caModify, caAdd, caDelete); + + { TSvnBase } + + TSvnBase = class + private + procedure LoadFromXml(ADoc: TXMLDocument); virtual; abstract; + public + procedure LoadFromStream(s: TStream); + procedure LoadFromFile(FileName: string); + end; { TCommit } @@ -65,21 +77,114 @@ type { TSvnInfo } - TSvnInfo = class + TSvnInfo = class(TSvnBase) private FEntry: TEntry; - procedure LoadFromXml(ADoc: TXMLDocument); + procedure LoadFromXml(ADoc: TXMLDocument); override; public constructor Create; destructor Destroy; override; procedure Clear; - procedure LoadFromStream(s: TStream); - procedure LoadFromFile(FileName: string); property Entry: TEntry read FEntry; end; + + { TLogPath } + + TLogPath = class + private + FAction: TCommitAction; + FCopyFromPath: string; + FCopyFromRevision: integer; + FPath: string; + procedure LoadFromNode(ANode: TDomElement); + public + property Action : TCommitAction read FAction write FAction; + property CopyFromRevision: integer read FCopyFromRevision write FCopyFromRevision; + property CopyFromPath: string read FCopyFromPath write FCopyFromPath; + property Path: string read FPath write FPath; + end; + + { TLogEntry } + + TLogEntry = class + private + FAuthor: string; + FDate: string; + FLogPaths: TFPObjectList; + FMessage: string; + FRevision: integer; + function GetLogPath(index: integer): TLogPath; + function GetLogPathCount: integer; + procedure LoadFromNode(ANode: TDOMElement); + public + constructor Create; + destructor Destroy; override; + property Author: string read FAuthor write FAuthor; + property Date: string read FDate write FDate; + property Message: string read FMessage write FMessage; + property Path[index: integer] :TLogPath read GetLogPath; + property PathCount: integer read GetLogPathCount; + property Revision: integer read FRevision write FRevision; + end; + + { TSvnLog } + + TSvnLog = class(TSvnBase) + private + FLogEntries: TFPObjectList; + function GetLogEntry(index: integer): TLogEntry; + function GetLogEntryCount: integer; + procedure LoadFromXml(ADoc: TXMLDocument); override; + public + constructor Create; + destructor Destroy; override; + procedure Clear; + property LogEntry[index: integer] :TLogEntry read GetLogEntry; + property LogEntryCount: integer read GetLogEntryCount; + end; implementation +const + ActionStrings : array[TCommitAction] of char = + (' ','M','A','D'); + +function GetChildTextContent(ANode: TDomNode; const AName: string) : string; +var + ChildNode: TDOMNode; +begin + Result := ''; + ChildNode := ANode.FindNode(AName); + if assigned(ChildNode) then + Result := ChildNode.TextContent; +end; + +{ TSvnBase } + +procedure TSvnBase.LoadFromStream(s: TStream); +var + ADoc: TXMLDocument; +begin + ReadXMLFile(ADoc, s); + try + LoadFromXml(ADoc); + finally + ADoc.Free; + end; +end; + +procedure TSvnBase.LoadFromFile(FileName: string); +var + ADoc: TXMLDocument; +begin + ReadXMLFile(ADoc, FileName); + try + LoadFromXml(ADoc); + finally + ADoc.Free; + end; +end; + { TSvnInfo } procedure TSvnInfo.LoadFromXml(ADoc: TXMLDocument); @@ -105,30 +210,6 @@ begin FEntry.Clear; end; -procedure TSvnInfo.LoadFromStream(s: TStream); -var - ADoc: TXMLDocument; -begin - ReadXMLFile(ADoc, s); - try - LoadFromXml(ADoc); - finally - ADoc.Free; - end; -end; - -procedure TSvnInfo.LoadFromFile(FileName: string); -var - ADoc: TXMLDocument; -begin - ReadXMLFile(ADoc, FileName); - try - LoadFromXml(ADoc); - finally - ADoc.Free; - end; -end; - { TEntry } procedure TEntry.LoadFromNode(ANode: TDomNode); @@ -186,21 +267,11 @@ end; { TRepository } procedure TRepository.LoadFromNode(ANode: TDomNode); -var - RepositoryNode: TDomElement; - ChildNode: TDOMNode; begin if ANode=nil then exit; - if ANode.NodeType = ELEMENT_NODE then begin - RepositoryNode := TDomElement(ANode); - ChildNode := RepositoryNode.FindNode('root'); - if assigned(ChildNode) then - FRoot := ChildNode.TextContent; - ChildNode := RepositoryNode.FindNode('uuid'); - if assigned(ChildNode) then - FUUID := ChildNode.TextContent; - end; + FRoot := GetChildTextContent(ANode, 'root'); + FUUID := GetChildTextContent(ANode, 'uuid'); end; procedure TRepository.Clear; @@ -212,21 +283,13 @@ end; { TCommit } procedure TCommit.LoadFromNode(ANode: TDomNode); -var - CommitNode: TDomElement; - ChildNode: TDOMNode; begin if ANode=nil then exit; if ANode.NodeType = ELEMENT_NODE then begin - CommitNode := TDomElement(ANode); - FRevision := StrToIntDef(CommitNode.GetAttribute('revision'),0); - ChildNode := CommitNode.FindNode('author'); - if assigned(ChildNode) then - FAuthor := ChildNode.TextContent; - ChildNode := CommitNode.FindNode('date'); - if assigned(ChildNode) then - FDate := ChildNode.TextContent; + FRevision := StrToIntDef(TDomElement(ANode).GetAttribute('revision'),0); + FAuthor := GetChildTextContent(ANode, 'author'); + FDate := GetChildTextContent(ANode, 'date'); end; end; @@ -237,5 +300,124 @@ begin FRevision := 0; end; +{ TSvnLog } + +function TSvnLog.GetLogEntry(index: integer): TLogEntry; +begin + Result := TLogEntry(FLogEntries[index]); +end; + +function TSvnLog.GetLogEntryCount: integer; +begin + Result := FLogEntries.Count; +end; + +procedure TSvnLog.LoadFromXml(ADoc: TXMLDocument); +var + LogEntryElement: TDomNode; + NewLogEntry: TLogEntry; +begin + Clear; + + LogEntryElement := ADoc.FindNode('log').FirstChild; + while assigned(LogEntryElement) do begin + if (LogEntryElement.NodeType=ELEMENT_NODE) + and (LogEntryElement.NodeName='logentry') then + begin + NewLogEntry := TLogEntry.Create; + NewLogEntry.LoadFromNode(TDomElement(LogEntryElement)); + FLogEntries.Add(NewLogEntry); + end; + LogEntryElement := LogEntryElement.NextSibling; + end; +end; + +constructor TSvnLog.Create; +begin + inherited Create; + FLogEntries := TFPObjectList.Create(true); +end; + +destructor TSvnLog.Destroy; +begin + FLogEntries.Free; + inherited Destroy; +end; + +procedure TSvnLog.Clear; +begin + FLogEntries.Clear; +end; + +{ TLogEntry } + +function TLogEntry.GetLogPath(index: integer): TLogPath; +begin + Result := TLogPath(FLogPaths[index]); +end; + +function TLogEntry.GetLogPathCount: integer; +begin + Result := FLogPaths.Count; +end; + +procedure TLogEntry.LoadFromNode(ANode: TDOMElement); +var + PathsELement: TDomNode; + PathElement: TDomNode; + NewLogPath: TLogPath; +begin + FRevision := StrToIntDef(ANode.GetAttribute('revision'),0); + FAuthor := GetChildTextContent(ANode, 'author'); + FDate := GetChildTextContent(ANode, 'date'); + FMessage := GetChildTextContent(ANode, 'msg'); + + PathsElement := ANode.FindNode('paths'); + if assigned(PathsELement) then begin + PathElement := PathsELement.FirstChild; + while assigned(PathElement) do begin + if (PathElement.NodeType=ELEMENT_NODE) + and (PathElement.NodeName='path') then + begin + NewLogPath := TLogPath.Create; + NewLogPath.LoadFromNode(TDomElement(PathElement)); + FLogPaths.Add(NewLogPath); + end; + PathElement := PathElement.NextSibling; + end; + end; +end; + +constructor TLogEntry.Create; +begin + inherited Create; + FLogPaths := TFPObjectList.Create(true); +end; + +destructor TLogEntry.Destroy; +begin + FLogPaths.Free; + inherited Destroy; +end; + +{ TLogPath } + +procedure TLogPath.LoadFromNode(ANode: TDomElement); +var + ActionStr: string; + i: TCommitAction; +begin + FPath := ANode.TextContent; + FCopyFromRevision := StrToIntDef(ANode.GetAttribute('copyfrom-rev'),0); + FCopyFromPath := ANode.GetAttribute('copyfrom-path'); + ActionStr := ANode.GetAttribute('action'); + FAction := caUnknown; + for i := low(TCommitAction) to high(TCommitAction) do + if ActionStrings[i]=ActionStr then begin + FAction := i; + break; + end; +end; + end. diff --git a/components/svn/svnpkg.lpk b/components/svn/svnpkg.lpk index 7e68b5781..3b6142f5b 100644 --- a/components/svn/svnpkg.lpk +++ b/components/svn/svnpkg.lpk @@ -7,7 +7,7 @@ - + @@ -22,7 +22,6 @@ - @@ -30,7 +29,7 @@ - + diff --git a/components/svn/svnpkg.pas b/components/svn/svnpkg.pas index 4feb857ee..ead650f80 100644 --- a/components/svn/svnpkg.pas +++ b/components/svn/svnpkg.pas @@ -7,14 +7,8 @@ unit svnpkg; interface uses - svnclasses, LazarusPackageIntf; + svnclasses; implementation -procedure Register; -begin -end; - -initialization - RegisterPackage('svnpkg', @Register); end. diff --git a/components/svn/test/fpcunitsvnpkg.lpi b/components/svn/test/fpcunitsvnpkg.lpi index 816d455eb..68bd4af7b 100644 --- a/components/svn/test/fpcunitsvnpkg.lpi +++ b/components/svn/test/fpcunitsvnpkg.lpi @@ -4,14 +4,13 @@ + + - - - @@ -30,238 +29,27 @@ - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -269,21 +57,13 @@ + + + + + - - - - - - - - - - - - - diff --git a/components/svn/test/log.xml b/components/svn/test/log.xml new file mode 100644 index 000000000..6b7d590c0 --- /dev/null +++ b/components/svn/test/log.xml @@ -0,0 +1,67 @@ + + + + vincents + 2007-02-20T10:57:42.928052Z + + /trunk/ide/Makefile + /trunk/components/tachart/Makefile.fpc + /trunk/components/tachart/tagraph.lrs + /trunk/ide/lazarus.pp + /trunk/components/Makefile + /trunk/components/tachart/TAGraph.pas + /trunk/ide/Makefile.fpc + /trunk/components/tachart/Makefile + /trunk/components/Makefile.fpc + /trunk/components/tachart/tachartlazaruspkg.lpk + /trunk/docs/xml/lcl/lclintf.xml + + TAChart: added icon, added to make bigide + + + vincents + 2007-02-20T11:24:55.592011Z + + /trunk/components/tagraph.pas + /trunk/components/tachart/TAGraph.pas + + lowercase + + + vincents + 2007-02-20T11:26:46.869961Z + + /trunk/components/tagraph.pas + /trunk/components/tachart/tagraph.pas + + tachart: fixed wrong move + + + vincents + 2007-02-20T11:31:09.651670Z + + /trunk/components/tachart/TAEngine.pas + /trunk/components/tachart/taengine.pas + /trunk/components/tachart/tachartlazaruspkg.lpk + /trunk/components/tachart/TASeries.pas + /trunk/components/tachart/taseries.pas + + tachart: user lowercase unit filenames + + + vincents + 2007-02-20T21:57:51.761388Z + + /trunk/lcl/interfaces/win32/win32callback.inc + + win32 interface: fix showing contextmenu for listviews (bug 8331) + + + vincents + 2007-02-20T23:18:34.679005Z + + /trunk/lcl/interfaces/win32/win32winapi.inc + + win32 interface: made LCLIntf.Rectangle and TCanvas.Rectangle compatible with Windows.Rectangle winapi function (bug 8342) + + diff --git a/components/svn/test/testsvnclasses.pas b/components/svn/test/testsvnclasses.pas index 7c4c02b54..5ffd32bfc 100644 --- a/components/svn/test/testsvnclasses.pas +++ b/components/svn/test/testsvnclasses.pas @@ -5,7 +5,7 @@ unit TestSvnClasses; interface uses - Classes, SysUtils, fpcunit, testutils, testregistry, + Classes, SysUtils, fpcunit, testregistry, svnclasses; type @@ -15,10 +15,15 @@ type TTestSvnClasses= class(TTestCase) private function GetInfoFileName: string; + function GetLogFileName: string; published procedure TestHookUp; procedure TestLoadInfo; - end; + procedure TestLoadLog; + procedure TestLoadSimpleLogPaths; + procedure TestLoadComplexLogPaths; + procedure TestLoadLogTwice; + end; implementation @@ -27,12 +32,19 @@ begin Result := ExtractFilePath(ParamStr(0)) + 'info.xml'; end; -procedure TTestSvnClasses.TestHookUp; -var - InfoFileName: string; +function TTestSvnClasses.GetLogFileName: string; begin - InfoFileName := GetInfoFileName; - AssertTrue(InfoFileName + ' does not exist', FileExists(InfoFileName)); + Result := ExtractFilePath(ParamStr(0)) + 'log.xml'; +end; + +procedure TTestSvnClasses.TestHookUp; + procedure CheckFile(const FileName: string); + begin + AssertTrue(FileName + ' does not exist', FileExists(FileName)); + end; +begin + CheckFile(GetInfoFileName); + CheckFile(GetLogFileName); end; procedure TTestSvnClasses.TestLoadInfo; @@ -63,6 +75,95 @@ begin end; end; +procedure TTestSvnClasses.TestLoadLog; +var + SvnLog: TSvnLog; + LogEntry: TLogEntry; +begin + SvnLog := TSvnLog.Create; + try + SvnLog.LoadFromFile(GetLogFileName); + AssertEquals('Wrong number of log entries', 6, SvnLog.LogEntryCount); + LogEntry := SvnLog.LogEntry[0]; + AssertEquals('Wrong log revision', 10660, LogEntry.Revision); + AssertEquals('Wrong log author', 'vincents', LogEntry.Author); + AssertEquals('Wrong log date', + '2007-02-20T10:57:42.928052Z', LogEntry.Date); + AssertEquals('Wrong log message', + 'TAChart: added icon, added to make bigide', LogEntry.Message); + finally + SvnLog.Free; + end; +end; + +procedure TTestSvnClasses.TestLoadSimpleLogPaths; +var + SvnLog: TSvnLog; + LogEntry: TLogEntry; + LogPath: TLogPath; +begin + SvnLog := TSvnLog.Create; + try + SvnLog.LoadFromFile(GetLogFileName); + AssertEquals('Wrong number of log entries', 6, SvnLog.LogEntryCount); + LogEntry := SvnLog.LogEntry[4]; + AssertEquals('Wrong log revision', 10664, LogEntry.Revision); + AssertEquals('Wrong number of paths', 1, LogEntry.PathCount); + LogPath := LogEntry.Path[0]; + AssertEquals('Wrong path', + '/trunk/lcl/interfaces/win32/win32callback.inc', LogPath.Path); + AssertEquals('Wrong commit action', ord(caModify), ord(LogPath.Action)); + finally + SvnLog.Free; + end; +end; + +procedure TTestSvnClasses.TestLoadComplexLogPaths; +var + SvnLog: TSvnLog; + LogEntry: TLogEntry; + + procedure AssertLogPath(i: integer; action: TCommitAction; + const path, copyfrompath: string; copyfromrev: integer); + var + LogPath: TLogPath; + begin + LogPath := LogEntry.Path[i]; + AssertEquals('Wrong commit action', ord(action), ord(LogPath.Action)); + AssertEquals('Wrong path', path, LogPath.Path); + AssertEquals('Wrong copy from revision', copyfromrev, LogPath.CopyFromRevision); + AssertEquals('Wrong copy from path', copyfrompath, LogPath.CopyFromPath); + end; +begin + SvnLog := TSvnLog.Create; + try + SvnLog.LoadFromFile(GetLogFileName); + AssertEquals('Wrong number of log entries', 6, SvnLog.LogEntryCount); + LogEntry := SvnLog.LogEntry[3]; + AssertEquals('Wrong log revision', 10663, LogEntry.Revision); + AssertEquals('Wrong number of paths', 5, LogEntry.PathCount); + AssertLogPath(0, caDelete, '/trunk/components/tachart/TAEngine.pas', '', 0); + AssertLogPath(1, caAdd, '/trunk/components/tachart/taengine.pas', + '/trunk/components/tachart/TAEngine.pas', 10662); + finally + SvnLog.Free; + end; +end; + +procedure TTestSvnClasses.TestLoadLogTwice; +var + SvnLog: TSvnLog; +begin + SvnLog := TSvnLog.Create; + try + SvnLog.LoadFromFile(GetLogFileName); + SvnLog.LoadFromFile(GetLogFileName); + AssertEquals('Wrong number of log entries', 6, SvnLog.LogEntryCount); + finally + SvnLog.Free; + end; +end; + initialization RegisterTest(TTestSvnClasses);