make.pas 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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 = 'QRCodeGenLib.Demo';
  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(const Knd: TLog; const 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: string;
  32. begin
  33. if FileExists('.gitmodules') then
  34. if RunCommand('git', ['submodule', 'update', '--init', '--recursive',
  35. '--force', '--remote'], Result) then
  36. OutLog(info, Result)
  37. else
  38. OutLog(error, Result);
  39. end;
  40. function AddPackage(const Path: string): string;
  41. begin
  42. if RunCommand('lazbuild', ['--add-package-link', Path], Result) then
  43. OutLog(audit, 'Add package:'#9 + Path);
  44. end;
  45. function SelectString(const Input, Reg: string): string;
  46. var
  47. Line: string;
  48. begin
  49. Result := ' ';
  50. for Line in Input.Split(LineEnding) do
  51. with TRegExpr.Create do
  52. begin
  53. Expression := Reg;
  54. if Exec(Line) then
  55. Result += Line + LineEnding;
  56. Free;
  57. end;
  58. end;
  59. function RunTest(const Path: String): string;
  60. begin
  61. OutLog(audit, #9'run:'#9 + Path);
  62. if RunCommand(Path, ['--all', '--format=plain'], Result) then
  63. OutLog(info, #9'success!')
  64. else
  65. ExitCode += 1;
  66. OutLog(audit, Result);
  67. end;
  68. function BuildProject(const Path: string): Output;
  69. begin
  70. OutLog(audit, 'Build from:'#9 + Path);
  71. Result.Success := RunCommand('lazbuild',
  72. ['--build-all', '--recursive', '--no-write-project', Path], Result.Output);
  73. Result.Output := SelectString(Result.Output, '(Fatal:|Error:|Linking)');
  74. if Result.Success then
  75. begin
  76. Result.Output := Result.Output.Split(' ')[3].Replace(LineEnding, '');
  77. OutLog(info, #9'to:'#9 + Result.Output);
  78. if ContainsStr(ReadFileToString(Path.Replace('.lpi', '.lpr')), 'consoletestrunner') then
  79. RunTest(Result.Output.Replace(#10, ''));
  80. end
  81. else
  82. begin
  83. ExitCode += 1;
  84. OutLog(error, Result.Output);
  85. end;
  86. end;
  87. function DownloadFile(const Uri: string): string;
  88. var
  89. OutFile: TStream;
  90. begin
  91. InitSSLInterface;
  92. Result := GetTempFileName;
  93. OutFile := TFileStream.Create(Result, fmCreate or fmOpenWrite);
  94. with TFPHttpClient.Create(nil) do
  95. begin
  96. try
  97. AddHeader('User-Agent', 'Mozilla/5.0 (compatible; fpweb)');
  98. AllowRedirect := True;
  99. Get(Uri, OutFile);
  100. OutLog(audit, 'Download from ' + Uri + ' to ' + Result);
  101. finally
  102. Free;
  103. OutFile.Free;
  104. end;
  105. end;
  106. end;
  107. procedure UnZip(const ZipFile, ZipPath: string);
  108. begin
  109. with TUnZipper.Create do
  110. begin
  111. try
  112. FileName := ZipFile;
  113. OutputPath := ZipPath;
  114. Examine;
  115. UnZipAllFiles;
  116. OutLog(audit, 'Unzip from'#9 + ZipFile + #9'to'#9 + ZipPath);
  117. DeleteFile(ZipFile);
  118. finally
  119. Free;
  120. end;
  121. end;
  122. end;
  123. function InstallOPM(const Path: string): string;
  124. begin
  125. Result :=
  126. {$IFDEF MSWINDOWS}
  127. GetEnvironmentVariable('APPDATA') + '\.lazarus\onlinepackagemanager\packages\'
  128. {$ELSE}
  129. GetEnvironmentVariable('HOME') + '/.lazarus/onlinepackagemanager/packages/'
  130. {$ENDIF}
  131. + Path;
  132. if not DirectoryExists(Result) then
  133. begin
  134. CreateDir(Result);
  135. UnZip(DownloadFile('https://packages.lazarus-ide.org/' + Path + '.zip'), Result);
  136. end;
  137. end;
  138. function BuildAll: string;
  139. var
  140. List: TStringList;
  141. begin
  142. CheckModules;
  143. List := FindAllFiles(GetCurrentDir, '*.lpk', True);
  144. try
  145. for Result in Dependencies do
  146. List.AddStrings(FindAllFiles(InstallOPM(Result), '*.lpk', True));
  147. for Result in List do
  148. AddPackage(Result);
  149. List := FindAllFiles(Target, '*.lpi', True);
  150. for Result in List do
  151. BuildProject(Result);
  152. finally
  153. List.Free;
  154. end;
  155. case ExitCode of
  156. 0: OutLog(info, 'Errors:'#9 + IntToStr(ExitCode));
  157. else
  158. OutLog(error, 'Errors:'#9 + IntToStr(ExitCode));
  159. end;
  160. end;
  161. begin
  162. try
  163. BuildAll
  164. except
  165. on E: Exception do
  166. Writeln(E.ClassName, #9, E.Message);
  167. end;
  168. end.