Changeset 9
- Timestamp:
- Aug 21, 2022, 7:07:10 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Install/deb/debian/control
r2 r9 5 5 Standards-Version: 1.0.0 6 6 #Build-Depends: fpc, lazarus, lcl, lcl-utils, debhelper (>= 8) 7 Build-Depends: fpc-laz, lazarus-project, debhelper (>= 8)7 Build-Depends: fpc-laz, lazarus-project, libsqlite3-dev, debhelper (>= 8) 8 8 9 9 Package: svnzero 10 10 Architecture: any 11 Depends: ${shlibs:Depends}, ${misc:Depends}, 11 Depends: ${shlibs:Depends}, ${misc:Depends}, libsqlite3 12 12 Description: Subversion zero pristine wrapper. 13 13 HomePage: https://app.zdechov.net/svnzero -
trunk/Languages/svnzero.cs.po
r6 r9 11 11 "Language: cs\n" 12 12 "X-Generator: Poedit 3.0\n" 13 14 #: sqlite3wrap.sdatabasenotconnected 15 msgid "SQLite3 error: database is not connected." 16 msgstr "" 17 18 #: sqlite3wrap.serrormessage 19 #, object-pascal-format 20 msgid "SQLite3 error: %s" 21 msgstr "" 22 23 #: sqlite3wrap.snotransactionopen 24 msgid "No transaction is open" 25 msgstr "" 26 27 #: sqlite3wrap.stransactionalreadyopen 28 msgid "Transaction is already opened." 29 msgstr "" 13 30 14 31 #: usvnzero.spristinerecoveryfail -
trunk/Languages/svnzero.pot
r6 r9 1 1 msgid "" 2 2 msgstr "Content-Type: text/plain; charset=UTF-8" 3 4 #: sqlite3wrap.sdatabasenotconnected 5 msgid "SQLite3 error: database is not connected." 6 msgstr "" 7 8 #: sqlite3wrap.serrormessage 9 #, object-pascal-format 10 msgid "SQLite3 error: %s" 11 msgstr "" 12 13 #: sqlite3wrap.snotransactionopen 14 msgid "No transaction is open" 15 msgstr "" 16 17 #: sqlite3wrap.stransactionalreadyopen 18 msgid "Transaction is already opened." 19 msgstr "" 3 20 4 21 #: usvnzero.spristinerecoveryfail -
trunk/SVNZero.lpi
r6 r9 28 28 <SearchPaths> 29 29 <IncludeFiles Value="$(ProjOutDir)"/> 30 <OtherUnitFiles Value="SQLite3"/> 30 31 <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(BuildMode)"/> 31 32 </SearchPaths> … … 91 92 <IsPartOfProject Value="True"/> 92 93 </Unit> 94 <Unit> 95 <Filename Value="UExecute.pas"/> 96 <IsPartOfProject Value="True"/> 97 </Unit> 98 <Unit> 99 <Filename Value="SQLite3/SQLite3.pas"/> 100 <IsPartOfProject Value="True"/> 101 </Unit> 102 <Unit> 103 <Filename Value="SQLite3/SQLite3Utils.pas"/> 104 <IsPartOfProject Value="True"/> 105 </Unit> 106 <Unit> 107 <Filename Value="SQLite3/SQLite3Wrap.pas"/> 108 <IsPartOfProject Value="True"/> 109 </Unit> 93 110 </Units> 94 111 </ProjectOptions> … … 100 117 <SearchPaths> 101 118 <IncludeFiles Value="$(ProjOutDir)"/> 119 <OtherUnitFiles Value="SQLite3"/> 102 120 <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(BuildMode)"/> 103 121 </SearchPaths> -
trunk/SVNZero.lpr
r8 r9 5 5 cthreads, 6 6 {$ENDIF} 7 Classes, SysUtils, CustApp, USubversion, UTest, USvnZero, UTestCases 7 Classes, SysUtils, CustApp, USubversion, UTest, USvnZero, UTestCases, UExecute 8 8 { you can add units after this }; 9 9 … … 27 27 28 28 procedure TSvnZeroApp.DoRun; 29 var 30 I: Integer; 29 31 begin 32 if HasOption('print') then begin 33 SvnZero.PrintOutput := True; 34 end; 30 35 if HasOption('t', 'test') then begin 31 36 with TTestCases.Create do … … 37 42 AddNew('Merge', TTestCaseMerge); 38 43 AddNew('Update multiple', TTestCaseUpdateMultiple); 44 AddNew('Delete update', TTestCaseDeleteUpdate); 45 AddNew('Delete update duplicate files', TTestCaseDeleteUpdateDuplicateFiles); 46 for I := 0 to Count - 1 do 47 if Items[I] is TTestCaseSvn then begin 48 TTestCaseSvn(Items[I]).Subversion.PrintOutput := SvnZero.PrintOutput; 49 TTestCaseSvn(Items[I]).Subversion.PrintCommand := SvnZero.PrintOutput; 50 end; 39 51 Run; 40 52 finally … … 69 81 Params: TStringArray; 70 82 I: Integer; 83 J: Integer; 71 84 begin 72 85 Params := Default(TStringArray); 73 86 SetLength(Params, ParamCount); 74 for I := 0 to ParamCount - 1 do 75 Params[I] := GetParams(I + 1); 87 J := 0; 88 for I := 0 to ParamCount - 1 do begin 89 if GetParams(I + 1) <> '--print' then begin 90 Params[J] := GetParams(I + 1); 91 Inc(J); 92 end; 93 end; 94 SetLength(Params, J); 76 95 77 96 SVNZero.ExecuteOutput(Params); -
trunk/USubversion.pas
r5 r9 4 4 5 5 uses 6 Classes, SysUtils, Process, FileUtil 6 Classes, SysUtils, Process, FileUtil, UExecute 7 7 {$IFDEF UNIX}, baseunix{$ENDIF}; 8 8 … … 15 15 end; 16 16 17 { TExecute }18 19 TExecute = class20 protected21 function GetExecutable: string; virtual;22 public23 StandardOutput: string;24 ErrorOutput: string;25 procedure Execute(Parameters: array of string); virtual;26 procedure ExecuteOutput(Parameters: array of string);27 function GetInfo(Text: string): TSubversionInfo;28 end;29 30 17 { TSubversion } 31 18 … … 35 22 function GetExecutable: string; override; 36 23 public 24 function GetInfo(Text: string): TSubversionInfo; 37 25 end; 38 26 … … 50 38 implementation 51 39 52 { TExecute } 53 54 function TExecute.GetExecutable: string; 55 begin 56 Result := ''; 57 end; 58 59 procedure TExecute.Execute(Parameters: array of string); 60 var 61 Process: TProcess; 62 I: Integer; 63 Buffer: string; 64 Count: Integer; 65 begin 66 StandardOutput := ''; 67 ErrorOutput := ''; 68 Buffer := ''; 69 try 70 Process := TProcess.Create(nil); 71 Process.Executable := GetExecutable; 72 for I := 0 to Length(Parameters) - 1 do 73 Process.Parameters.Add(Parameters[I]); 74 Process.Options := [poUsePipes, poNoConsole]; 75 Process.Execute; 76 while Process.Running or (Process.Output.NumBytesAvailable > 0) or 77 (Process.Stderr.NumBytesAvailable > 0) do 78 begin 79 if Process.Output.NumBytesAvailable > 0 then begin 80 SetLength(Buffer, 1000); 81 Count := Process.Output.Read(Buffer[1], Length(Buffer)); 82 SetLength(Buffer, Count); 83 StandardOutput := StandardOutput + Buffer; 84 end; 85 if Process.Stderr.NumBytesAvailable > 0 then begin 86 SetLength(Buffer, 1000); 87 Count := Process.Stderr.Read(Buffer[1], Length(Buffer)); 88 SetLength(Buffer, Count); 89 ErrorOutput := ErrorOutput + Buffer; 90 end; 91 Sleep(1); 92 end; 93 finally 94 Process.Free; 95 end; 96 end; 97 98 procedure TExecute.ExecuteOutput(Parameters: array of string); 99 begin 100 Execute(Parameters); 101 if StandardOutput <> '' then Write(StandardOutput); 102 if ErrorOutput <> '' then Write(ErrorOutput); 103 end; 104 105 function TExecute.GetInfo(Text: string): TSubversionInfo; 40 function TSubversion.GetInfo(Text: string): TSubversionInfo; 106 41 var 107 42 Index: Integer; -
trunk/USvnZero.pas
r8 r9 17 17 function GetWorkingCopyRootPath(FileName: string): string; 18 18 function CheckErrorOutput(Text: string): Boolean; 19 function GetFileInfoByMd5(Md5Hash: string): TSubversionInfo; 19 20 procedure ZeroPristine; 20 21 procedure RestorePristine; … … 33 34 implementation 34 35 36 uses 37 SQLite3, SQLite3Wrap; 38 35 39 const 36 40 SvnBaseExt = '.svn-base'; … … 130 134 LastErrorOutput: string; 131 135 begin 136 Subversion.PrintOutput := PrintOutput; 137 Subversion.PrintCommand := PrintCommand; 132 138 LastErrorOutput := ''; 133 139 StandardOutputMerged := ''; … … 176 182 PristineFileName: string; 177 183 Info: TSubversionInfo; 184 Md5Hash: string; 185 const 186 StartText = 'expected:'; 178 187 begin 179 188 Result := False; 180 189 if Pos(': Checksum mismatch', Text) > 0 then begin 181 I := Pos('''', Text); 190 I := Pos(StartText, Text); 191 if I > 0 then begin 192 Md5Hash := Copy(Text, I + Length(StartText), MaxInt); 193 I := Pos(#10, Md5Hash); 194 if I > 0 then 195 Delete(Md5Hash, I, MaxInt); 196 Md5Hash := Trim(Md5Hash); 197 Info := GetFileInfoByMd5(Md5Hash); 198 ExportedFileName := GetSvnDir('.') + DirectorySeparator + 'tmp' + 199 DirectorySeparator + 'ExportedFile.bin'; 200 PristineFileName := GetPristineDir('.') + DirectorySeparator + Copy(Info.Checksum, 1, 2) + 201 DirectorySeparator + Info.Checksum + '.svn-base'; 202 Subversion.Execute(['export', '-r', Info.Revision, '--force', Info.URL, ExportedFileName]); 203 MakeFileWriteable(PristineFileName); 204 CopyFile(ExportedFileName, PristineFileName); 205 Subversion.Execute(['cleanup']); 206 Result := True; 207 end; 208 209 { I := Pos('''', Text); 182 210 if I > 0 then begin 183 211 FileName := Copy(Text, I + 1, MaxInt); … … 198 226 Result := True; 199 227 end; 228 } 229 end; 230 end; 231 232 function TSvnZero.GetFileInfoByMd5(Md5Hash: string): TSubversionInfo; 233 var 234 Database: TSQLite3Database; 235 Statement: TSQLite3Statement; 236 begin 237 Database := TSQLite3Database.Create; 238 try 239 Database.Open(GetSvnDir('.') + DirectorySeparator + 'wc.db'); 240 Statement := Database.Prepare('SELECT checksum FROM PRISTINE WHERE md5_checksum=''$md5 $' + Md5Hash + ''''); 241 try 242 while Statement.Step = SQLITE_ROW do begin 243 Result.Checksum := Statement.ColumnText(0); 244 end; 245 finally 246 Statement.Free; 247 end; 248 249 Statement := Database.Prepare('SELECT repos_path,changed_revision FROM NODES WHERE checksum="' + Result.Checksum + '" LIMIT 1'); 250 try 251 while Statement.Step = SQLITE_ROW do begin 252 Result.Path := Statement.ColumnText(0); 253 Result.Revision := Statement.ColumnText(1); 254 end; 255 finally 256 Statement.Free; 257 end; 258 259 Statement := Database.Prepare('SELECT root FROM REPOSITORY LIMIT 1'); 260 try 261 while Statement.Step = SQLITE_ROW do begin 262 Result.URL := Statement.ColumnText(0) + '/' + Result.Path; 263 end; 264 finally 265 Statement.Free; 266 end; 267 268 if Result.Checksum.StartsWith('$sha1$') then 269 Result.Checksum := Copy(Result.Checksum, 7); 270 finally 271 Database.Free; 200 272 end; 201 273 end; -
trunk/UTest.pas
r8 r9 45 45 procedure Translate; 46 46 procedure SaveStringToFile(S, FileName: string); 47 function LoadFileToStr(const FileName: TFileName): AnsiString; 47 48 48 49 … … 70 71 end; 71 72 73 function LoadFileToStr(const FileName: TFileName): AnsiString; 74 var 75 FileStream: TFileStream; 76 Read: Integer; 77 begin 78 Result := ''; 79 FileStream := TFileStream.Create(FileName, fmOpenRead); 80 try 81 if FileStream.Size > 0 then begin 82 SetLength(Result, FileStream.Size); 83 Read := FileStream.Read(Pointer(Result)^, FileStream.Size); 84 SetLength(Result, Read); 85 end; 86 finally 87 FileStream.Free; 88 end; 89 end; 90 72 91 { TTestCase } 73 92 74 93 procedure TTestCase.Initialize; 75 94 begin 95 TestResult := trNone; 76 96 end; 77 97 … … 119 139 Failed: Integer; 120 140 begin 141 Passed := 0; 142 Failed := 0; 121 143 for I := 0 to Count - 1 do 122 144 with Items[I] do begin … … 125 147 Run; 126 148 Finalize; 149 if TestResult = trPassed then Inc(Passed); 150 if TestResult = trFailed then Inc(Failed); 127 151 end; 128 152 129 Passed := 0;130 Failed := 0;131 153 for I := 0 to Count - 1 do 132 154 with Items[I] do begin 133 155 WriteLn(Name + ': ' + ResultText[TestResult]); 134 if TestResult = trPassed then Inc(Passed);135 if TestResult = trFailed then Inc(Failed);136 156 end; 137 157 WriteLn('Total: ' + IntToStr(Count) + ', Passed: ' + IntToStr(Passed) + -
trunk/UTestCases.pas
r8 r9 11 11 TTestCaseSvn = class(TTestCase) 12 12 private 13 Subversion: TExecute;14 SubversionAdmin: TSubversionAdmin;15 13 function CheckError(Text: string): Boolean; 16 14 protected … … 22 20 procedure SvnAdmin(Parameters: array of string); 23 21 public 22 Subversion: TSubversion; 23 SubversionAdmin: TSubversionAdmin; 24 24 procedure Initialize; override; 25 25 procedure Run; override; … … 53 53 end; 54 54 55 { TTestCaseDeleteUpdate } 56 57 TTestCaseDeleteUpdate = class(TTestCaseSvn) 58 procedure Run; override; 59 end; 60 55 61 { TTestCaseMerge } 56 62 … … 62 68 63 69 TTestCaseUpdateMultiple = class(TTestCaseSvn) 70 procedure Run; override; 71 end; 72 73 { TTestCaseDeleteUpdateDuplicateFiles } 74 75 TTestCaseDeleteUpdateDuplicateFiles = class(TTestCaseSvn) 64 76 procedure Run; override; 65 77 end; … … 69 81 uses 70 82 USvnZero; 83 84 { TTestCaseDeleteUpdateDuplicateFiles } 85 86 procedure TTestCaseDeleteUpdateDuplicateFiles.Run; 87 var 88 TestFile: string; 89 TestFile2: string; 90 const 91 TestText = 'Some text'; 92 begin 93 TestFile := 'TestFile.txt'; 94 TestFile2 := 'TestFile2.txt'; 95 SaveStringToFile(TestText, TestFile); 96 SaveStringToFile(TestText, TestFile2); 97 Svn(['add', TestFile]); 98 Svn(['add', TestFile2]); 99 Svn(['commit', '-m', '"Commit message"']); 100 Svn(['delete', TestFile]); 101 Svn(['commit', '-m', '"Commit message 2"']); 102 Svn(['update', '-r', '1']); 103 Evaluate(LoadFileToStr(TestFile) = TestText); 104 end; 105 106 { TTestCaseDeleteUpdate } 107 108 procedure TTestCaseDeleteUpdate.Run; 109 var 110 TestFile: string; 111 TestFile2: string; 112 begin 113 TestFile := 'TestFile.txt'; 114 TestFile2 := 'TestFile2.txt'; 115 SaveStringToFile('Some text', TestFile); 116 Svn(['add', TestFile]); 117 Svn(['commit', '-m', '"Commit message"']); 118 Svn(['delete', TestFile]); 119 SaveStringToFile('File2 test', TestFile2); 120 Svn(['add', TestFile2]); 121 Svn(['commit', '-m', '"Commit message 2"']); 122 Svn(['delete', TestFile2]); 123 Svn(['commit', '-m', '"Commit message 3"']); 124 Svn(['update', '-r', '1']); 125 Svn(['update', '-r', '2']); 126 Svn(['update', '-r', '3']); 127 Svn(['update']); 128 Evaluate(True); 129 end; 71 130 72 131 { TTestCaseSvn }
Note:
See TracChangeset
for help on using the changeset viewer.