make.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. program Make;
  2. {$mode objfpc}{$H+}
  3. uses
  4. Classes,
  5. SysUtils,
  6. StrUtils,
  7. FileUtil,
  8. Zipper,
  9. fphttpclient,
  10. RegExpr,
  11. openssl,
  12. opensslsockets,
  13. Process;
  14. const
  15. Target: string = 'demos';
  16. Dependencies: array of string = ('Rhl', 'XMailer', 'dOPF', 'Brookframework', 'Synapse40.1');
  17. type
  18. TLog = (audit, info, error);
  19. Output = record
  20. Code: boolean;
  21. Output: ansistring;
  22. end;
  23. procedure OutLog(Knd: TLog; Msg: string);
  24. begin
  25. case Knd of
  26. error: Writeln(stderr, #27'[31m', Msg, #27'[0m');
  27. info: Writeln(stderr, #27'[32m', Msg, #27'[0m');
  28. audit: Writeln(stderr, #27'[33m', Msg, #27'[0m');
  29. end;
  30. end;
  31. function CheckModules: Output;
  32. begin
  33. if FileExists('.gitmodules') then
  34. if RunCommand('git', ['submodule', 'update', '--init', '--recursive',
  35. '--force', '--remote'], Result.Output) then
  36. OutLog(info, Result.Output);
  37. end;
  38. function AddPackage(Path: string): Output;
  39. begin
  40. with TRegExpr.Create do
  41. begin
  42. Expression :=
  43. {$IFDEF MSWINDOWS}
  44. '(cocoa|x11|_template)'
  45. {$ELSE}
  46. '(cocoa|gdi|_template)'
  47. {$ENDIF}
  48. ;
  49. if not Exec(Path) and RunCommand('lazbuild', ['--add-package-link', Path],
  50. Result.Output) then
  51. OutLog(audit, 'added ' + Path);
  52. Free;
  53. end;
  54. end;
  55. function BuildProject(Path: string): Output;
  56. var
  57. Line: string;
  58. begin
  59. OutLog(audit, 'build from ' + Path);
  60. try
  61. Result.Code := RunCommand('lazbuild', ['--build-all', '--recursive',
  62. '--no-write-project', Path], Result.Output);
  63. if Result.Code then
  64. for Line in SplitString(Result.Output, LineEnding) do
  65. begin
  66. if ContainsStr(Line, 'Linking') then
  67. begin
  68. Result.Output := SplitString(Line, ' ')[2];
  69. OutLog(info, ' to ' + Result.Output);
  70. break;
  71. end;
  72. end
  73. else
  74. begin
  75. ExitCode += 1;
  76. for Line in SplitString(Result.Output, LineEnding) do
  77. with TRegExpr.Create do
  78. begin
  79. Expression := '(Fatal|Error):';
  80. if Exec(Line) then
  81. OutLog(error, #10 + Line);
  82. Free;
  83. end;
  84. end;
  85. except
  86. on E: Exception do
  87. OutLog(error, E.ClassName + #13#10 + E.Message);
  88. end;
  89. end;
  90. function RunTest(Path: string): Output;
  91. var
  92. Temp: string;
  93. begin
  94. Result := BuildProject(Path);
  95. Temp:= Result.Output;
  96. if Result.Code then
  97. try
  98. if not RunCommand(Temp, ['--all', '--format=plain', '--progress'], Result.Output) then
  99. begin
  100. ExitCode += 1;
  101. OutLog(error, Result.Output);
  102. end;
  103. except
  104. on E: Exception do
  105. OutLog(error, E.ClassName + #13#10 + E.Message);
  106. end;
  107. end;
  108. function InstallOPM(Each: string): string;
  109. var
  110. OutFile, Uri: string;
  111. Zip: TStream;
  112. begin
  113. Result :=
  114. {$IFDEF MSWINDOWS}
  115. GetEnvironmentVariable('APPDATA') + '\.lazarus\onlinepackagemanager\packages\'
  116. {$ELSE}
  117. GetEnvironmentVariable('HOME') + '/.lazarus/onlinepackagemanager/packages/'
  118. {$ENDIF}
  119. + Each;
  120. OutFile := GetTempFileName;
  121. Uri := 'https://packages.lazarus-ide.org/' + Each + '.zip';
  122. if not DirectoryExists(Result) then
  123. begin
  124. Zip := TFileStream.Create(OutFile, fmCreate or fmOpenWrite);
  125. with TFPHttpClient.Create(nil) do
  126. begin
  127. try
  128. AddHeader('User-Agent', 'Mozilla/5.0 (compatible; fpweb)');
  129. AllowRedirect := True;
  130. Get(Uri, Zip);
  131. OutLog(audit, 'Download from ' + Uri + ' to ' + OutFile);
  132. finally
  133. Free;
  134. end;
  135. end;
  136. Zip.Free;
  137. CreateDir(Result);
  138. with TUnZipper.Create do
  139. begin
  140. try
  141. FileName := OutFile;
  142. OutputPath := Result;
  143. Examine;
  144. UnZipAllFiles;
  145. OutLog(audit, 'Unzip from ' + OutFile + ' to ' + Result);
  146. finally
  147. Free;
  148. end;
  149. end;
  150. DeleteFile(OutFile);
  151. end;
  152. end;
  153. procedure BuildAll;
  154. var
  155. Each, Item: string;
  156. List: TStringList;
  157. begin
  158. CheckModules;
  159. InitSSLInterface;
  160. for Item in Dependencies do
  161. begin
  162. List := FindAllFiles(InstallOPM(Item), '*.lpk', True);
  163. try
  164. for Each in List do
  165. AddPackage(Each);
  166. finally
  167. List.Free;
  168. end;
  169. end;
  170. List := FindAllFiles(GetCurrentDir, '*.lpk', True);
  171. try
  172. for Each in List do
  173. AddPackage(Each);
  174. finally
  175. List.Free;
  176. end;
  177. List := FindAllFiles(Target, '*.lpi', True);
  178. try
  179. for Each in List do
  180. if ContainsStr(ReadFileToString(ReplaceStr(Each, '.lpi', '.lpr')),
  181. 'consoletestrunner') then
  182. RunTest(Each)
  183. else
  184. BuildProject(Each);
  185. finally
  186. List.Free;
  187. end;
  188. if ExitCode <> 0 then
  189. OutLog(error, #10 + 'Errors: ' + IntToStr(ExitCode))
  190. else
  191. OutLog(info, #10 + 'Errors: ' + IntToStr(ExitCode));
  192. end;
  193. begin
  194. BuildAll;
  195. end.