source: trunk/Backends/Subversion/Subversion.pas

Last change on this file was 24, checked in by chronos, 2 weeks ago
  • Fixed: Test cases executed with FormTests form from Common package.
File size: 6.3 KB
Line 
1unit Subversion;
2
3interface
4
5uses
6 Classes, SysUtils, VCS, Backend, XMLRead, DOM, XML;
7
8type
9
10 { TBackendSubversion }
11
12 TBackendSubversion = class(TBackend)
13 constructor Create;
14 function IsWorkingCopy(Directory: string): Boolean; override;
15 end;
16
17
18 { TSubversion }
19
20 TSubversion = class(TWorkingCopy)
21 protected
22 procedure Execute(Parameters: array of string);
23 public
24 procedure Checkout; override;
25 procedure Update; override;
26 procedure CleanUp; override;
27 procedure Commit(Message: string); override;
28 procedure Move(Source, Dest: string); override;
29 procedure Merge; override;
30 procedure Add(FileName: string); override;
31 procedure Remove(FileName: string); override;
32 procedure GetLog(FileName: string; Log: TLogItems); override;
33 procedure GetStatus(FileName: string; Status: TFileStatuses); override;
34 end;
35
36 { TRepositorySubversion }
37
38 TRepositorySubversion = class(TRepository)
39 protected
40 procedure Execute(Parameters: array of string);
41 public
42 procedure Init; override;
43 end;
44
45
46implementation
47
48{ TRepositorySubversion }
49
50procedure TRepositorySubversion.Execute(Parameters: array of string);
51var
52 ToolPath: string;
53begin
54 {$IFDEF Linux}
55 ToolPath := '/usr/bin/svnadmin';
56 {$ENDIF}
57 {$IFDEF Windows}
58 ToolPath := 'c:\Program Files\Subversion\bin\svnadmin.exe';
59 if not FileExists(ToolPath) then
60 ToolPath := 'C:\Program Files\TortoiseSVN\bin\svnadmin.exe';
61 {$ENDIF}
62 ExecuteProcess(ToolPath, Parameters);
63end;
64
65procedure TRepositorySubversion.Init;
66begin
67 Execute(['create', Path]);
68end;
69
70{ TBackendSubversion }
71
72constructor TBackendSubversion.Create;
73begin
74 Name := 'Subversion';
75 HomePage := 'https://subversion.apache.org/';
76 WorkingCopyClass := TSubversion;
77 RepositoryClass := TRepositorySubversion;
78end;
79
80function TBackendSubversion.IsWorkingCopy(Directory: string): Boolean;
81begin
82 Result := DirectoryExists(Directory + DirectorySeparator + '.svn') and
83 FileExists(Directory + DirectorySeparator + '.svn' + DirectorySeparator + 'wc.db');
84end;
85
86{ TSubversion }
87
88procedure TSubversion.Execute(Parameters: array of string);
89var
90 ToolPath: string;
91begin
92 {$IFDEF Linux}
93 ToolPath := '/usr/bin/svn';
94 {$ENDIF}
95 {$IFDEF Windows}
96 ToolPath := 'c:\Program Files\Subversion\bin\svn.exe';
97 if not FileExists(ToolPath) then
98 ToolPath := 'C:\Program Files\TortoiseSVN\bin\svn.exe';
99 {$ENDIF}
100 ExecuteProcess(ToolPath, Parameters);
101end;
102
103procedure TSubversion.Checkout;
104begin
105 Execute(['checkout', RepositoryURL, Path]);
106end;
107
108procedure TSubversion.Update;
109begin
110 Execute(['update']);
111end;
112
113procedure TSubversion.CleanUp;
114begin
115 Execute(['cleanup']);
116end;
117
118procedure TSubversion.Commit(Message: string);
119begin
120 Execute(['commit', '-m "' + Message + '"']);
121end;
122
123procedure TSubversion.Move(Source, Dest: string);
124begin
125 Execute(['move', Source, Dest]);
126end;
127
128procedure TSubversion.Merge;
129begin
130 Execute(['merge']);
131end;
132
133procedure TSubversion.Add(FileName: string);
134begin
135 Execute(['add', FileName]);
136end;
137
138procedure TSubversion.Remove(FileName: string);
139begin
140 Execute(['remove', FileName]);
141end;
142
143procedure TSubversion.GetLog(FileName: string; Log: TLogItems);
144var
145 NewItem: TLogItem;
146 I: Integer;
147 Line: string;
148 ChangedFiles: Boolean;
149 Action: string;
150begin
151 NewItem := nil;
152 Log.Clear;
153 SilentExecution := True;
154 Execute(['log', FileName, '-v']);
155 SilentExecution := False;
156 for I := 0 to ExecutionOutput.Count - 1 do begin
157 Line := Trim(ExecutionOutput[I]);
158 if Line = '------------------------------------------------------------------------' then begin
159 if Assigned(NewItem) then Log.Add(NewItem);
160 NewItem := TLogItem.Create;
161 end else
162 if Pos('|', Line) > 0 then begin
163 NewItem.Revision := Trim(GetNext(Line, '|'));
164 NewItem.Author := Trim(GetNext(Line, '|'));
165 GetNext(Line, '|');
166 //NewItem.Time := StrToDateTime(Trim(GetNext(Line, '|')));
167 end else
168 if Line = 'Changed paths:' then begin
169 ChangedFiles := True;
170 end else
171 if ChangedFiles then begin
172 if (Line <> '') and (Copy(ExecutionOutput[I], 1, 3) = ' ') then begin
173 Action := GetNext(Line, ' ');
174 NewItem.Actions := NewItem.Actions + Action;
175 NewItem.ChangedFiles.Add(Line);
176 end else
177 if Line = '' then begin
178 ChangedFiles := False;
179 end;
180 end else
181 NewItem.Messages.Add(Line);
182 end;
183 if Assigned(NewItem) then Log.Add(NewItem);
184end;
185
186procedure TSubversion.GetStatus(FileName: string; Status: TFileStatuses);
187var
188 Doc: TXMLDocument;
189 S: TStringStream;
190 Node: TDOMNode;
191 RootNode: TDOMNode;
192 TargetNode: TDOMNode;
193 StatusNode: TDOMNode;
194 StatusItem: TFileStatus;
195 CommitNode: TDOMNode;
196 ItemState: string;
197begin
198 Status.Clear;
199 SilentExecution := True;
200 Execute(['status', '--xml', '-v']);
201 SilentExecution := False;
202 S := TStringStream.Create(ExecutionOutput.Text);
203 try
204 // Read complete XML document
205 ReadXMLFile(Doc, S);
206 RootNode := Doc.DocumentElement;
207 if RootNode.NodeName = 'status' then begin
208 TargetNode := RootNode.FindNode('target');
209 if Assigned(TargetNode) then begin
210 Node := TargetNode.FirstChild;
211 while Assigned(Node) do begin
212 if Node.NodeName = 'entry' then begin
213 StatusItem := TFileStatus.Create;
214 StatusItem.FileName := TDOMElement(Node).GetAttribute('path');
215 StatusNode := Node.FindNode('wc-status');
216 if Assigned(StatusNode) then begin
217 ItemState := TDOMElement(StatusNode).GetAttribute('item');
218 if ItemState = 'normal' then StatusItem.State := fssNotModified;
219 if ItemState = 'modified' then StatusItem.State := fssModified;
220 if ItemState = 'deleted' then StatusItem.State := fssRemoved;
221 if ItemState = 'added' then StatusItem.State := fssAdded;
222
223 CommitNode := StatusNode.FindNode('commit');
224 if Assigned(CommitNode) then begin
225 StatusItem.Version := TDOMElement(CommitNode).GetAttribute('revision');
226 StatusItem.Author := ReadString(CommitNode, 'author', '');
227 StatusItem.Time := ReadDateTime(CommitNode, 'date', 0);
228 end;
229 end;
230 Status.Add(StatusItem);
231 end;
232 Node := Node.NextSibling;
233 end;
234 end;
235 end;
236 finally
237 Doc.Free;
238 S.Free;
239 end;
240end;
241
242end.
243
Note: See TracBrowser for help on using the repository browser.