make.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 = 'lazpaint';
  16. Dependencies: array of string = ();
  17. type
  18. TLog = (audit, info, error);
  19. Output = record
  20. Success: boolean;
  21. Output: string;
  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.Success := RunCommand('lazbuild', ['--build-all', '--recursive',
  62. '--no-write-project', Path], Result.Output);
  63. if Result.Success 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.Success 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. function LintPython(Path: string): Output;
  154. begin
  155. OutLog(audit, 'Linting Python file: ' + Path);
  156. if not RunCommand('python3', ['-m', 'pylint', Path], Result.Output) then
  157. begin
  158. OutLog(error, Result.Output);
  159. //ExitCode += 1;
  160. end
  161. end;
  162. function LintC(Path: string): Output;
  163. begin
  164. OutLog(audit, 'Linting C file: ' + Path);
  165. if not RunCommand('cppcheck', ['--language=c', '--enable=warning,style', '--template=gcc', Path], Result.Output) then
  166. begin
  167. OutLog(error, Result.Output);
  168. //ExitCode += 1;
  169. end
  170. end;
  171. function LintShell(Path: string): Output;
  172. begin
  173. OutLog(audit, 'Linting Shell file: ' + Path);
  174. if not RunCommand('shellcheck', ['--external-sources', Path], Result.Output) then
  175. begin
  176. OutLog(error, Result.Output);
  177. //ExitCode += 1;
  178. end
  179. end;
  180. procedure BuildAll;
  181. var
  182. Each, Item: string;
  183. List: TStringList;
  184. begin
  185. CheckModules;
  186. InitSSLInterface;
  187. for Item in Dependencies do
  188. begin
  189. List := FindAllFiles(InstallOPM(Item), '*.lpk', True);
  190. try
  191. for Each in List do
  192. AddPackage(Each);
  193. finally
  194. List.Free;
  195. end;
  196. end;
  197. List := FindAllFiles(GetCurrentDir, '*.lpk', True);
  198. try
  199. for Each in List do
  200. AddPackage(Each);
  201. finally
  202. List.Free;
  203. end;
  204. List := FindAllFiles(Target, '*.lpi', True);
  205. try
  206. for Each in List do
  207. if not ContainsStr(Each, 'zengl') then
  208. if ContainsStr(ReadFileToString(ReplaceStr(Each, '.lpi', '.lpr')),
  209. 'consoletestrunner') then
  210. RunTest(Each)
  211. else
  212. BuildProject(Each);
  213. finally
  214. List.Free;
  215. end;
  216. if ExitCode <> 0 then
  217. OutLog(error, #10 + 'Errors: ' + IntToStr(ExitCode))
  218. else
  219. OutLog(info, #10 + 'Errors: ' + IntToStr(ExitCode));
  220. end;
  221. begin
  222. BuildAll;
  223. end.